C编译器警告

时间:2013-02-26 08:16:09

标签: c

我有一个非常普遍的问题,当我尝试将字符数组写入文件时,我将代码编写为

fwrite(array[10],1,10,file_ptr)

并且编译器发出警告argument 1 makes from integer to pointer without a cast.

然后我将该行修改为

fwrite(&array[10],1,10,file_ptr)

现在警告不再出现了。

问题:编译器如何区分地址和值?如果array[10]的值类似于正确的地址怎么办?

5 个答案:

答案 0 :(得分:4)

如果您有一个包含十个字符的数组,即

char array[10];

然后执行array[10]访问该数组的第11个元素。

只需传递数组变量,它就可以作为指针:

fwrite(array, 1, 10, file);

答案 1 :(得分:1)

C是静态类型的语言。每当你写

char array[100];

您告诉C编译器array是一个包含100个字符的数组。然后,它知道array[10]是一个字符,&array[10]是指向一个字符(char *)的指针。

但是,

fwrite被定义为将const void *作为其第一个参数,即无类型指针。如果你传递的东西不是指针,那么编译器会知道这一点并会抱怨。

您的C编译器不会尝试根据其值“猜测”某事物的类型。

答案 2 :(得分:1)

fwrite()的签名是:fwrite(const void *ptr, size_t size, size_t count, FILE *fptr)

fwrite()期待一个地址(或一个包含地址的指针变量,也就是指针)而不是一个字符,但是, a[10]是一个字符,而不是指针。这是警告的原因!

&a[10] 一个地址,是fwrite()的第一个参数的有效拟合。因此没有警告!


它如何保存信息在其词法分析器+解析器组合和语义分析器中称为“符号表”。

- 在问题编辑后 -

fwrite(&array[10],1,10,file_ptr)< - argument-1被解释为从array

中的第11个位置开始的字符串

答案 3 :(得分:1)

看来你的印象是array[10]指定整个数组 - 它没有。它指定了array的第11个元素,它不存在(假设你将其声明为some_type array[10])。

既然你说要编写整个数组,你需要传递fwrite()array的第一个元素的地址,恰好是array(或{{1} }),因为在C中,表达式中使用的数组名称是其第一个元素的地址(&array[0]运算符除外)。

编译器具有关于数组类型和元素类型的完整信息,因此它可以检测何时在需要指针的位置编写类型为sizeof的表达式。

有一种方法可以使用数组标识符fwrite()一个完整的数组,与大小和元素类型无关,只需使用数组标识符:

int

其中fwrite (array, sizeof *array, sizeof array/sizeof *array, file); 计算元素大小,sizeof *array计算数组中元素的数量。请注意,这对于数组而言仅适用于 ,而不适用于指针。

可以实现同样的目标
sizeof array/sizeof *array

fwrite (array, sizeof array, 1, file);

这主要是你喜欢的风格问题;它们都是等价的,并且将以相同的速度执行。

答案 4 :(得分:0)

  

如果数组[10]的值类似于正确的地址怎么办?

然后您的数组类型为int (*)[n],而不是int [n]。这就是为什么我们有一个类型系统。