函数fread
的声明方式如下
size_t fread(void * restrict ptr, size_t size,
size_t nmemb,
FILE * restrict stream);
其第一个参数具有不合格类型void *
(实际上参数类型是合格类型void * restrict
).可以将指向任何类型对象的指针指定给类型void *
的指针.
表达式&header
具有指针类型uint8_t ( * )[HEADER_SIZE]
,并产生由数组占用的内存范围的初始地址,
用作fread
调用的参数的表达式header
隐式转换为uint8_t *
类型的指针,如果数组占用的内存范围不同,则会生成相同的初始地址.
因此,这些调用
fread(&header, sizeof(uint8_t), HEADER_SIZE, input);
fwrite(header, sizeof(uint8_t), HEADER_SIZE, output);
在函数fread
为其参数获取相同值的意义上是等效的.
考虑以下简单的演示程序.
#include <stdio.h>
int main( void )
{
char s[6] = "Hello";
printf( "The value of the expression s is %p\n", ( void * )s );
printf( "The value of the expression &s is %p\n", ( void * )&s );
}
程序输出可能如下所示
The value of the expression s is 0x7fffa4577a2a
The value of the expression &s is 0x7fffa4577a2a
正如您所看到的,虽然在第一次调用中,使用的参数表达式的类型为char *
,而在第二次调用中,使用的参数表达式的类型为char ( * )[6]
,但两个输出值都是相等的.
但是,如果您将编写示例
#include <stdio.h>
int main( void )
{
char s[6] = "Hello";
printf( "%s\n", s );
printf( "%s\n", &s );
}
然后,编译器可以为第二次调用printf
发出一条消息,表示函数需要char *
类型的参数,而不是char ( * )[6]
类型的参数,尽管表达式的两个值彼此相等.