Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
GCC对堆栈中的“array”和“&array”使用相同的地址/指针_C_Arrays_Pointers_Gcc_Memory - Fatal编程技术网

GCC对堆栈中的“array”和“&array”使用相同的地址/指针

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

在一所学校里,我们必须编写一个小程序,检查文件的前两个字节,以检查它是否应该像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 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你说得对。