Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.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/6/codeigniter/3.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
在C语言中,extern buffer[]和extern*buffer之间有什么区别?_C_Arrays_Pointers - Fatal编程技术网

在C语言中,extern buffer[]和extern*buffer之间有什么区别?

在C语言中,extern buffer[]和extern*buffer之间有什么区别?,c,arrays,pointers,C,Arrays,Pointers,我在微软的一篇文章中读到了以下信息 下面的文本给出了一个常见编程错误的示例,即混淆数组和指针声明: 考虑一个应用程序分为几个模块。在一个模块中,声明一个数组,如下所示: signed char buffer[100]; 在另一个模块中,声明以下变量以访问数组: extern signed char *buffer; // FAILS extern signed char buffer[]; // WORKS 如果在CodeView调试器中查

我在微软的一篇文章中读到了以下信息

下面的文本给出了一个常见编程错误的示例,即混淆数组和指针声明: 考虑一个应用程序分为几个模块。在一个模块中,声明一个数组,如下所示:

  signed char buffer[100];
在另一个模块中,声明以下变量以访问数组:

 extern signed char *buffer;           // FAILS  
 extern signed char buffer[];          // WORKS
如果在CodeView调试器中查看代码,则表明
*buffer
声明生成的地址与
buffer[]
声明不同

  • 但我不明白为什么我们不能使用
    *缓冲区
    
    我们可以使用
    buffer[]
    访问它

  • 请解释一下这两种类型的区别是什么


  • 两者的区别

    extern signed char *buffer;
    extern signed char buffer[]; 
    
    与您在使用时看到的相同

    signed char *buffer;
    signed char buffer[100];
    
    在函数中

    我看到以下区别:

    差异1

    如果您有:

    extern signed char *buffer;
    
    extern signed char buffer[]; 
    
    您可以使用:

    buffer = malloc(10);
    
    printf("pointer 1: %p\n", &buffer+1);
    
    如果您有:

    extern signed char *buffer;
    
    extern signed char buffer[]; 
    
    你不能那样做

    差异2

    在第一种情况下,
    buffer
    可能为空。在第二种情况下,情况并非如此

    差异3

    &buffer
    会导致不同的类型。例如,您可以使用:

    buffer = malloc(10);
    
    printf("pointer 1: %p\n", &buffer+1);
    

    在第一种情况下,但不能在第二种情况下使用。要使
    &buffer+1
    在第二种情况下工作,您必须知道数组的大小。

    这个问题更多的是关于C链接器而不是关于C语言

    虽然有一个上下文,其中
    signed char*buffer
    signed char buffer[]
    的意思是相同的,但
    extern
    不是其中之一。使用
    extern
    要求编译器将外部定义的解析延迟到链接器。链接器必须特别注意指针和数组之间的区别,因为它们在内存中具有不同的结构,不能互换处理


    请注意,尽管这些声明与链接器不同,但它们不会改变程序员对此类外部数组的操作:在这两种情况下,您都无法访问所声明数组的大小(即100),访问数组元素的语法保持不变,指针算法保持不变

    在一个模块中,您可以定义一个名为
    缓冲区
    签名字符数组
    。此对象将使用100字节的内存:

    signed char buffer[100];
    
    在另一个模块中,
    缓冲区
    声明为另一个对象,一个指向
    有符号字符
    的指针,即4或8字节的内存,可以保存数组的地址或单个
    字符的地址

    extern signed char *buffer;
    
    编译器一次只知道一个模块,因此无法检查此声明是否与实际的定义一致。它按照此声明编译代码,发出机器代码,该代码引用将在链接时解析的外部符号
    缓冲区

    在链接时,链接器不知道类型,它只依赖于名称。因此,它将一个模块对
    缓冲区的引用解析为另一个模块定义的实际地址

    在运行时,您会得到未定义的行为,因为一个模块使用
    缓冲区
    作为
    有符号字符
    的数组,而另一个模块从同一地址加载指针的值,对字节的解释完全不同

    声明属于头文件中,并且应始终包含在源文件中,该文件实际上定义了头文件中声明的对象

    extern signed char buffer[];
    
    是一块有地址的内存

    extern signed char *buffer;
    

    是一个变量,可能指向也可能不指向内存块-它是一个变量,包含一个可能有效也可能无效的地址。

    请参见C FAQ列表中的这些问题:


    这必须是一个副本,我总是交替使用它们。获取不同的地址对我来说毫无意义。确定的可能重复,指针和数组不一样。当指针是数组时,您试图告诉编译器查找指针。简而言之,取消引用指针比访问数组更为间接。由于额外的间接性,使用指针声明(当标识符是数组时)的代码会爆炸。彼得·范德林登(Peter van der Linden)的《C编程专家-深层C秘密》(Expert C Programming-Deep C Secrets)中有一个非常清晰的解释,这就解决了我的问题!非常感谢Steve.+1的链接。