在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的链接。