GCC对堆栈中的“array”和“&array”使用相同的地址/指针
在一所学校里,我们必须编写一个小程序,检查文件的前两个字节,以检查它是否应该像JPEG文件一样启动。这是一门UNIX初学者课程 一组提供了以下解决方案,以消除错误处理:GCC对堆栈中的“array”和“&array”使用相同的地址/指针,c,arrays,pointers,gcc,memory,C,Arrays,Pointers,Gcc,Memory,在一所学校里,我们必须编写一个小程序,检查文件的前两个字节,以检查它是否应该像JPEG文件一样启动。这是一门UNIX初学者课程 一组提供了以下解决方案,以消除错误处理: #include <stdio.h> #include <unistd.h> #include <fcntl.h> int main(int argc, char** argv) { int fd = open(argv[1], 0); unsigned char buff
#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");
}
}
即使使用-Wincompatible指针类型,它也可以在没有任何警告的情况下编译,并且可以正常工作,但不是我所期望的那样
我知道,至少在C++中,数组实际上只是指向数组第一元素的指针,而使用数组[index ]语法实际上只是*数组+索引< /p> 所以我编译了这个版本的程序,还有一个版本,我只使用了缓冲区,因为我希望它是数组地址,因此是读取所需的。结果表明,两个程序在反汇编时看起来完全相同
这是怎么回事?我一直在和一位同事讨论这个问题,我们猜测这是因为数组实际上只是堆栈中的一些空间,在编译时将静态分配这些空间,因此编译器将在使用buffer[index]的地方使用静态地址。因此,为了模拟在堆存储中动态分配的阵列,GCC在仅使用缓冲区的位置使用缓冲区[0]的地址。但是为什么&buffer甚至是一种合法的语法呢 这整件事真的让我困惑,我真的很想知道这里到底发生了什么我知道,至少在C++中,数组实际上是指向数组的第一个元素
的指针。 一点也不。数组是一种不同于指针的类型 数组的地址与其第一个元素的地址一致,并且数组隐式地将衰减转换为指向其第一个元素的指针,因此数组==&数组[0]==数组+0 见: 存在从数组类型的左值和右值到指针类型的右值的隐式转换:它构造指向数组第一个元素的指针。每当数组出现在不需要数组但需要指针的上下文中时,就会使用此转换数组实际上只是指向数组第一个元素的指针-不,不是。虽然在本例中您确实注意到了任何差异,但当您写入&buffer+1时,差异会很明显,因为这会增加数组大小的一倍,因此会指向不存在的缓冲区[3]。正如一位C专家向我解释的那样,它与类型语义有关。古鲁,请给他解释清楚。在C语言中,数组和指向数组的指针经常混淆、混淆,并被误认为相等。我建议你多读书,谢谢。这肯定把事情弄清楚了。但是&buffer不是char*[2]类型还是类似的类型吗?既然需要char*,GCC为什么不发出警告呢?@Link64你说得对。