![](/img/trans.png)
[英]dereferencing function pointer to function returning void throws error: void value not ignored as it ought to be
[英]warning: dereferencing ‘void *’ pointer [enabled by default] and error: void value not ignored as it ought to be help c
我对这些错误感到困惑。 str1 是一个正在传递的字符串,但我在比较时收到警告,在 if 语句中出现错误
int stringcmp(void* str1, void* str2) {
int a = strlen(str1);
int b = strlen(str2);
int x;
if ( a < b ) {
x = a;
} else {
x = b;
}
int c = 0;
while ( c < x ) {
if (str1[c] < str2[c]) { //errors happen here
return 0;
}
if (str1[c] > str2[c]) {
return 1;
}
c++;
}
if ( a == x ) {
return 0;
}
return 1;
}
您的函数接收void*
参数,因此在您指出的行中,您正在取消引用指向void
指针,这就是您收到警告的原因。 我不确定为什么您收到的value not ignore as it ought to be
因为这意味着您正在分配一个返回 void 的函数的值,而 strlen 的情况并非如此(这是您正在调用的唯一函数) )。
并且您还应该在向 strlen 传递void*
参数时在调用中收到错误。
所以你必须将函数的签名更改为
int stringcmp(const char* str1, const char* str2);
抑制警告并能够在字符串上调用 strlen 。
void *
引用void *
永远没有意义。 在 C 中, void
表示“无类型”/“无”,如果你有void *p;
, *p
应该是什么?
在 C 中, void *
用作通用指针类型,“指向任何东西的指针”。 要使用上面的p
,您必须将其强制转换为它指向的对象的类型(以其他方式传递,编译器不知道)。 例如:
int i;
void *p = (void *) &i;
...
int j = *(int *)p;
你知道p
指向什么,编译器不知道。
void *
类型通常用于传递不透明数据,或编写通用函数(如qsort
,它获取未指定元素的数组和比较它们的函数)。
也就是说,作为(被误导的)扩展 GCC 允许对void *
进行指针运算,因此p + 1
就像((char *)p + 1)
,它指向下一个char
位置。
您的错误源于您试图在空指针上使用数组符号str1[c]
。 要理解为什么这是错误的,我们需要看看 C 中数组符号的实际含义。
让我们假设我们定义了char* str1
。 这里我们说过str1
是内存中某个有char
地方的地址。 要获取存储在str1
所指地址上的数据,我们可以使用*str1
。 这相当于说:“转到str1
持有的地址,并给我存储在该地址上的内容”。
当我们使用数组表示法时,我们可以使用str1[0]
,这将是从内存中某个位置获取的值,该位置存在与str1
定义为相同类型的元素。 这与说*str1
相同(转到str1
指向的地址并给我存储在那里的值)。
数组只是存储在内存中的一系列数据,而字符串只是大小正好为 1 个字节的字符数组,它们立即一个接一个地存储。 当我们说str1[1]
我们告诉编译器移动str1
定义为指向的类型的大小,在本例中为 1 字节( char
),然后获取存储在该位置的任何内容。 在字符串的情况下,这应该是另一个char
。
现在,当我们将str1
定义为void*
,编译器如何知道它应该在内存中移动多少才能获得数组中的下一个元素? 因为 void 没有大小,所以这是不可能的。
希望您现在了解在这一行中需要更改哪些内容以消除错误
int stringcmp(void* str1, void* str2)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.