为什么可以在带有或不使用&amp的情况下写下缓冲区位置中的径向/fwrite中使用的数组;并产生相同的结果?

发布于 2025-02-07 14:42:29 字数 490 浏览 2 评论 0原文

为什么这些产生相同的结果?

uint8_t header[HEADER_SIZE];
fread(&header, sizeof(uint8_t), HEADER_SIZE, input);
fwrite(&header, sizeof(uint8_t), HEADER_SIZE, output);
uint8_t header[HEADER_SIZE];
fread(header, sizeof(uint8_t), HEADER_SIZE, input);
fwrite(header, sizeof(uint8_t), HEADER_SIZE, output);

在第一个版本中,&是否不仅可以访问数组的位置,而不是像第二版中的数组本身一样?我是否知道为什么会使用&,但我认为数组本身就是“指针”,因此一般来说,没有理由再获得地址?在这种情况下只是冗余吗?

Why do these yield the same result?

uint8_t header[HEADER_SIZE];
fread(&header, sizeof(uint8_t), HEADER_SIZE, input);
fwrite(&header, sizeof(uint8_t), HEADER_SIZE, output);
uint8_t header[HEADER_SIZE];
fread(header, sizeof(uint8_t), HEADER_SIZE, input);
fwrite(header, sizeof(uint8_t), HEADER_SIZE, output);

In the first version, would the & not give access just to the location of the array, and not the array itself like in the second version? Were it a single valuable I understand why an & would be used, but I assumed an array is itself a "pointer", generally speaking, so there would be no reason to get its address again? Is it just redundancy in that case?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

帅气尐潴 2025-02-14 14:42:29

函数fread声明以下方式

size_t fread(void * restrict ptr, size_t size, 
             size_t nmemb, 
             FILE * restrict stream);

其第一个参数具有不合格的类型void *(实际上,参数类型是合格类型void *限制 *限制 )。指向任何类型对象的指针可以分配给类型void *的指针。

表达式& header具有指针类型uint8_t( *)[header_size],并产生数组占据的内存程度的初始地址,

表达式标题用作fread的呼叫的参数,将其隐式转换为类型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] 虽然表达式的两个值彼此平等。

The function fread is declared the following way

size_t fread(void * restrict ptr, size_t size, 
             size_t nmemb, 
             FILE * restrict stream);

Its first parameter has the unqualified type void * (actually the parameter type is the qualified type void * restrict) . A pointer to object of any type may be assigned to a pointer of the type void *.

The expression &header has the pointer type uint8_t ( * )[HEADER_SIZE] and yields the initial address of the extent of memory occupied by the array,

The expression header used as an argument of a call of fread is implicitly converted to a pointer of the type uint8_t * and yields the same initial address of the extent of memory occupied by the array.

Thus these calls

fread(&header, sizeof(uint8_t), HEADER_SIZE, input);
fwrite(header, sizeof(uint8_t), HEADER_SIZE, output);

are equivalent in sense that the function fread gets the same values for its parameters.

Consider the following simple demonstration program.

#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 program output might look like

The value of the expression  s is 0x7fffa4577a2a
The value of the expression &s is 0x7fffa4577a2a

As you can see the both outputted values are equal each other though in the first call the used argument expression has the type char * while in the second case the used argument expression has the type char ( * )[6].

However if you will write for example

#include <stdio.h>

int main( void )
{
    char s[6] = "Hello";

    printf( "%s\n", s );
    printf( "%s\n", &s );
}

then the compiler can issue a message for the second call of printf that the function expects an argument of the type char * instead of the type char ( * )[6] though the both values of the expressions are equal each other.

獨角戲 2025-02-14 14:42:29

标题char的数组。将数组作为参数有效地传递给其第一个元素的指针,freadfwrite接受指示void作为其第一个参数,所以fread(标题,sizeof(uint8_t),header_size,input);很好,尽管为了与数组定义保持一致,但编写:

    fread(header, sizeof(*header), HEADER_SIZE, input);

&amp; header具有不同的类型:指向一个或多个数组的header_size字符(uint8_t(*)[header_size])。由于fread接受任何形式的指针,因此编译器将接受呼叫fread(&amp; header,sizeof(uint8_t),header_size,header_size,input);而无需警告。

因为header&amp; header具有相同的地址,fread将按预期行事,尽管该行为不能由C标准保证。但是请注意,如果header是指向char的指针,则传递&amp; header确实会产生非常不同的结果,但确实不确定的行为确实是指针将被覆盖,并且可能有更多字节以外...

header is an array of char. Passing an array as an argument effectively passes a pointer to its first element, fread and fwrite accept pointers to void as their first argument so fread(header, sizeof(uint8_t), HEADER_SIZE, input); is fine although for consistency with the array definition it would be safer to write:

    fread(header, sizeof(*header), HEADER_SIZE, input);

&header has a different type: pointer to one or more arrays of HEADER_SIZE characters (uint8_t (*)[HEADER_SIZE]). Since fread accepts any kind of pointer, the compiler will accept the call fread(&header, sizeof(uint8_t), HEADER_SIZE, input); without a warning.

Because header and &header have the same address, fread will behave as expected, albeit this behavior is not guaranteed by the C Standard. Note however that if header was a pointer to char, passing &header would produce a very different result, undefined behavior indeed as the value of the pointer would be overwritten and probably many more bytes beyond...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文