C语言 赋值使指针来自整数而不进行强制转换

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2074009/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 04:09:44  来源:igfitidea点击:

Assignment makes pointer from integer without cast

cwarnings

提问by Pieter

Coming from a Java background I'm learning C, but I find those vague compiler error messages increasingly frustrating. Here's my code:

来自 Java 背景的我正在学习 C,但我发现那些模糊的编译器错误消息越来越令人沮丧。这是我的代码:

/*
 * PURPOSE
 *      Do case-insensetive string comparison.
 */
#include <stdio.h>
#include <string.h>
#include <ctype.h>

int compareString(char cString1[], char cString2[]);
char strToLower(char cString[]);

int main() {
    // Declarations
    char cString1[50], cString2[50];
    int isEqual;

    // Input
    puts("Enter string 1: ");
    gets(cString1);
    puts("Enter string 2: ");
    gets(cString2);

    // Call
    isEqual = compareString(cString1, cString2);
    if (isEqual == 0)
        printf("Equal!\n");
    else
        printf("Not equal!\n");

    return 0;
}

// WATCH OUT
//      This method *will* modify its input arrays.
int compareString(char cString1[], char cString2[]) {
    // To lowercase
    cString1 = strToLower(cString1);
    cString2 = strToLower(cString2);

    // Do regular strcmp
    return strcmp(cString1, cString2);
}

// WATCH OUT
//      This method *will* modify its input arrays.
char strToLower(char cString[]) {
    // Declarations
    int iTeller;

    for (iTeller = 0; cString[iTeller] != '
int compareString(char cString1[], char cString2[]) { 
    // To lowercase 
    strToLower(cString1); 
    strToLower(cString2); 

    // Do regular strcmp 
    return strcmp(cString1, cString2); 
} 
'; iTeller++) cString[iTeller] = (char)tolower(cString[iTeller]); return cString; }

This generates two warnings.

这会生成两个警告。

  • assignment makes pointer from integer without a cast
    • cString1 = strToLower(cString1);
    • cString2 = strToLower(cString2);
  • return makes integer from pointer without a cast
    • return cString;
  • 赋值使指针来自整数而不进行强制转换
    • cString1 = strToLower(cString1);
    • cString2 = strToLower(cString2);
  • return 从指针生成整数而不进行强制转换
    • 返回 cString;

Can someone explain these warnings?

有人可以解释这些警告吗?

回答by Uri

C strings are not anything like Java strings. They're essentially arrays of characters.

C 字符串与 Java 字符串不同。它们本质上是字符数组。

You are getting the error because strToLower returns a char. A char is a form of integer in C. You are assigning it into a char[] which is a pointer. Hence "converting integer to pointer".

您收到错误是因为 strToLower 返回一个字符。char 是 C 中的一种整数形式。您将它分配给一个 char[] ,它是一个指针。因此“将整数转换为指针”。

Your strToLower makes all its changes in place, there is no reason for it to return anything, especially not a char. You should "return" void, or a char*.

您的 strToLower 进行了所有更改,它没有理由返回任何内容,尤其是不是字符。您应该“返回”void 或 char*。

On the call to strToLower, there is also no need for assignment, you are essentially just passing the memory address for cString1.

在调用 strToLower 时,也不需要赋值,您实际上只是传递 cString1 的内存地址。

In my experience, Strings in C are the hardest part to learn for anyone coming from Java/C# background back to C. People can get along with memory allocation (since even in Java you often allocate arrays). If your eventual goal is C++ and not C, you may prefer to focus less on C strings, make sure you understand the basics, and just use the C++ string from STL.

根据我的经验,对于从 Java/C# 背景回到 C 的任何人来说,C 中的字符串是最难学习的部分。人们可以适应内存分配(因为即使在 Java 中你也经常分配数组)。如果您的最终目标是 C++ 而不是 C,您可能更愿意少关注 C 字符串,确保您了解基础知识,并且只使用 STL 中的 C++ 字符串。

回答by James

strToLower's return type should be char*not char(or it should return nothing at all, since it doesn't re-allocate the string)

strToLower 的返回类型应该char*不是char(或者它应该什么都不返回,因为它不会重新分配字符串)

回答by AnT

As others already noted, in one case you are attempting to return cString(which is a char *value in this context - a pointer) from a function that is declared to return a char(which is an integer). In another case you do the reverse: you are assigning a charreturn value to a char *pointer. This is what triggers the warnings. You certainly need to declare your return values as char *, not as char.

正如其他人已经指出的那样,在一种情况下,您试图从声明为返回 a (这是一个整数)的函数返回cStringchar *在此上下文中是一个值 - 一个指针char)。在另一种情况下,您做相反的事情:您将char返回值分配给char *指针。这就是触发警告的原因。您当然需要将返回值声明为char *,而不是char

Note BTW that these assignments are in fact constraint violationsfrom the language point of view (i.e. they are "errors"), since it is illegal to mix pointers and integers in C like that (aside from integral constant zero). Your compiler is simply too forgiving in this regard and reports these violations as mere "warnings".

注意顺便说一句,从语言的角度来看,这些赋值实际上是违反约束的(即它们是“错误”),因为在 C 中混合指针和整数是非法的(除了整数常量零)。您的编译器在这方面过于宽容,并将这些违规行为报告为仅仅是“警告”。

What I also wanted to note is that in several answers you might notice the relatively strange suggestion to return voidfrom your functions, since you are modifying the string in-place. While it will certainly work (since you indeed are modifying the string in-place), there's nothing really wrong with returning the same value from the function. In fact, it is a rather standard practice in C language where applicable (take a look at the standard functions like strcpyand others), since it enables "chaining" of function calls if you choose to use it, and costs virtually nothing if you don't use "chaining".

我还想指出的是,在几个答案中,您可能会注意到void从函数返回的相对奇怪的建议,因为您正在就地修改字符串。虽然它肯定会起作用(因为您确实在就地修改字符串),但从函数返回相同的值并没有什么问题。事实上,在适用的情况下,这是 C 语言中相当标准的做法(看看标准函数strcpy和其他函数),因为如果您选择使用它,它可以实现函数调用的“链接”,如果您不使用它,则几乎没有任何成本不要使用“链接”。

That said, the assignments in your implementation of compareStringlook complete superfluous to me (even though they won't break anything). I'd either get rid of them

也就是说,你的实现中的分配compareString对我来说完全是多余的(即使它们不会破坏任何东西)。我要么摆脱他们

int compareString(char cString1[], char cString2[]) { 
    return strcmp(strToLower(cString1), strToLower(cString2)); 
} 

or use "chaining" and do

或使用“链接”并做

 strToLower(cString1);
 strToLower(cString2);

(this is when your char *return would come handy). Just keep in mind that such "chained" function calls are sometimes difficult to debug with a step-by-step debugger.

(这是你的char *回报会派上用场的时候)。请记住,这种“链式”函数调用有时很难用逐步调试器进行调试。

As an additional, unrealted note, I'd say that implementing a string comparison function in such a destructive fashion (it modifiesthe input strings) might not be the best idea. A non-destructive function would be of a much greater value in my opinion. Instead of performing as explicit conversion of the input strings to a lower case, it is usually a better idea to implement a custom char-by-char case-insensitive string comparison function and use it instead of calling the standard strcmp.

作为一个额外的、未实现的说明,我想说以这种破坏性的方式实现字符串比较函数(它修改输入字符串)可能不是最好的主意。在我看来,非破坏性功能将具有更大的价值。与其将输入字符串显式转换为小写,不如实现自定义的逐个字符区分大小写的字符串比较函数并使用它而不是调用标准的strcmp.

回答by kennytm

  • 1) Don't use gets! You're introducing a buffer-overflow vulnerability. Use fgets(..., stdin)instead.

  • 2) In strToLoweryou're returning a charinstead of a char-array. Either return char*as Autopulated suggested, or just return voidsince you're modifying the input anyway. As a result, just write

  • 1)不要使用gets!您正在引入缓冲区溢出漏洞。使用fgets(..., stdin)来代替。

  • 2)在strToLower你返回一个char而不是一个char数组。要么char*按照 Autopulated 的建议返回,要么直接返回,void因为您正在修改输入。结果,只写

 

 

cString1 = strToLower(cString1); 
cString2 = strToLower(cString2);
  • 3) To compare case-insensitive strings, you can use strcasecmp(Linux & Mac) or stricmp(Windows).
  • 3) 要比较不区分大小写的字符串,您可以使用strcasecmp(Linux & Mac) 或stricmp(Windows)。

回答by Ariel

You don't need these two assigments:

您不需要这两个分配:

char *strToLower(char *cString)

you are modifying the strings in place.

您正在修改字符串。

Warnings are because you are returning a char, and assigning to a char[] (which is equivalent to char*)

警告是因为您正在返回一个字符,并分配给一个字符 [](相当于字符 *)

回答by Hernán

You are returning char, and not char*, which is the pointer to the first character of an array.

您返回的是 char,而不是 char*,后者是指向数组第一个字符的指针。

If you want to return a new character array instead of doing in-place modification, you can ask for an already allocated pointer (char*) as parameter or an uninitialized pointer. In this last case you must allocate the proper number of characters for new string and remember that in C parameters as passed by value ALWAYS, so you must use char** as parameter in the case of array allocated internally by function. Of course, the caller must free that pointer later.

如果你想返回一个新的字符数组而不是就地修改,你可以要求一个已经分配的指针 (char*) 作为参数或一个未初始化的指针。在最后一种情况下,您必须为新字符串分配适当数量的字符,并记住在 C 参数中始终按值传递,因此在函数内部分配数组的情况下,您必须使用 char** 作为参数。当然,调用者必须稍后释放该指针。

回答by Suresh Krishnan

strToLower should return a char * instead of a char. Something like this would do.

strToLower 应该返回一个字符 * 而不是一个字符。像这样的事情会做。

char cString1[]

回答by Alexander Gessler

char strToLower(...)

This is an array, i.e. a pointer to the first element of a range of elements of the same data type. Note you're not passing the array by-value but by-pointer.

这是一个数组,即指向相同数据类型元素范围的第一个元素的指针。请注意,您不是按值传递数组,而是按指针传递数组。

cString1 = strToLower(cString1);

However, this returns a char. So your assignment

但是,这会返回一个字符。所以你的任务

##代码##

has different types on each side of the assignment operator .. you're actually assigning a 'char' (sort of integer) to an array, which resolves to a simple pointer. Due to C++'s implicit conversion rules this works, but the result isrubbish and further access to the array causes undefined behaviour.

赋值运算符的每一侧都有不同的类型..您实际上是将一个“char”(某种整数)分配给一个数组,该数组解析为一个简单的指针。由于 C++ 的隐式转换规则,这有效,但结果垃圾,进一​​步访问数组会导致未定义的行为。

The solution is to make strToLowerreturn char*.

解决办法是 make strToLowerreturn char*