2

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

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

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

然后我将这一行修改为

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

并且警告现在不再出现。

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

4

5 回答 5

4

如果你有一个十个字符的数组,即

char array[10];

然后做array[10]访问该数组的第十一个元素。

只需传递数组变量,它就像一个指针:

fwrite(array, 1, 10, file);
于 2013-02-26T08:18:42.177 回答
1

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

char array[100];

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

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

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

于 2013-02-26T08:18:35.800 回答
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 被解释为从第 11 个位置开始的字符串array

于 2013-02-26T08:21:25.717 回答
1

似乎您的印象是array[10]指定整个数组 - 它没有。它指定 的第十一个元素array,该元素不存在(假设您将其声明为some_type array[10])。

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

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

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

fwrite (array, sizeof *array, sizeof array/sizeof *array, file);

其中sizeof *array计算元素大小并sizeof array/sizeof *array计算数组中元素的数量。请注意,这适用于数组,不适用于指针。同样可以实现

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

或者

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

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

于 2013-02-26T08:42:30.473 回答
0

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

那么您的数组类型将是int (*)[n],而不是int [n]。这就是我们有类型系统的原因。

于 2013-02-26T09:01:56.423 回答