在学校,我们必须编写一个小程序,该程序应该查看文件的前 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
.
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/