c - GCC 对堆栈中的 `array` 和 `&array` 使用相同的地址/指针

标签 c arrays pointers gcc memory

在学校,我们必须编写一个小程序,该程序应该查看文件的前 2 个字节,以检查它是否像 JPEG 文件那样启动。 (这是UNIX初学者类(class))

一组提供了以下解决方案(删除了错误处理):

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>

int main(int argc, char** argv) {

    int fd = open(argv[1], 0);
    unsigned char buffer[2];
    ssize_t readBytes = read(fd, &buffer, 2);

    if(buffer[0] == 0xFF && buffer[1] == 0xD8) {

        printf("The file starts with a JPEG header\r\n");
    } else {

        printf("The file does not start with a JPEG header\r\n");
    }
}

它编译时没有任何警告(即使使用 -Win兼容指针类型)并按其应有的方式工作,但不是我期望的那样。

我了解到,至少在 C++ 中,数组实际上只是指向数组第一个元素的指针,并使用 array[index]语法实际上只是 *(array+index)

所以我编译了这个版本的程序,还有一个,我只使用 buffer ,因为我希望它是数组地址,因此,什么 read需要。事实证明,两个程序反汇编后看起来完全一样。

那么这是怎么回事?我一直在和一位同事讨论这个问题,我们猜测这是因为数组实际上只是堆栈中的一些空间,它将在编译时静态分配,因此编译器将在 buffer[index] 的任何地方使用静态地址。用来。因此,为了模拟在堆存储中动态分配的数组,GCC 使用 buffer[0] 的地址。无论在哪里buffer用来。但为什么会&buffer甚至是合法的语法?

这整件事真的让我很困惑,我真的很想知道这里到底发生了什么。

最佳答案

I've learned, that in C++ at least, an array is actually just a pointer to the first element of the array

一点也不。数组是一种不同于指针的类型。

数组的地址与其第一个元素的地址一致,并且数组隐式转换(衰减)为指向其第一个元素的指针,因此array == &array[0] == array + 0.

参见array-to-pointer decay :

There is an implicit conversion from lvalues and rvalues of array type to rvalues of pointer type: it constructs a pointer to the first element of an array. This conversion is used whenever arrays appear in context where arrays are not expected, but pointers are.

关于c - GCC 对堆栈中的 `array` 和 `&array` 使用相同的地址/指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44310939/

相关文章:

c - 为什么当我在子目录中调用 make 时 Make 会重新链接?

c - mips-openwrt-linux-gcc : unrecognized option '-rpath-link'

ios - 访问对象数组中对象的属性

c++ - 如何为模板类的成员函数定义静态数组?

c++ - 将对象的指针添加到链表c++

c - C 中多维数组中指针的使用

c - 使用 strtok 分组 false 标记分割字符串

javascript - Cloud Function 中的数组减少错误

c - C中 volatile 结构中的指针

c - 错误 "assignment makes integer from pointer without a cast array = NULL"