2013-11-22 102 views
2

我在一个文件中定义了一个全局变量char buf[1024],可以在其他文件中声明它的正确性是什么? extern char buf[1024],extern char buf[]extern char *buf?我发现extern char buf[]作品和extern char *buf没有,但想知道更多的解释。全局char []变量,如何在其他文件中声明它?

+0

看到一个非常详细的解答在这里:http://stackoverflow.com/a/1433387/694576 – alk

回答

4

您可以使用

extern char buf[]; 

extern char *buf; 

因为数组不是指针

参考:C FAQ

+1

+1。数组不是指针 – haccks

+0

数组不是指针,有时除外。如:void foo(char array [100]){strcpy(array,“我真的是一个指针,即使我的声明看起来像一个数组”); }' –

+0

不能使用相同语法的指针引用单维数组吗? – anishsane

0

的extern炭BUF []和extern炭BUF [1024]两者都OK。

在某些情况下,数组是通过指针实现的,例如在两个函数之间传递参数。

0

当您将一个变量作为extern时,您向编译器指示变量的符号(地址)会在另一个.o文件中找到 - (这是在链接阶段完成的)。

所以,当你是一个变量为extern,你只需要提及的名字,因为它会给有关地址的信息,不需要尺寸

0

这是数组和指针可以互换的老问题。数组和指针是不可互换的:它们恰好是大部分时间,因为大多数情况下,在表达式中使用数组名称时,它会衰减为指针。

在Expert C Programming - Deep C Secrets中详细解释了在一个文件中定义char数组并在另一个文件中声明为char指针的特定情况。请参阅第4章。

数组的声明为您提供了一个数组,并且指针的声明为您提供了一个指针。不同之处在于数组是一个地址 - 第一个元素的地址 - 它不是一个可修改的l值,即它不能被分配给。另一方面,指针是一个保存地址的变量。

通常,上下文足以说明您是指变量的地址还是赋值中变量的内容。声明

i = j;

是说给j内容存储在i地址。在编译器术语中,i被认为是l值,而j是r值。编译器必须生成代码,将内存地址j的内容写入内存地址i

考虑以下声明:

char a[1024]; 
char *a; 

什么,当你写a[i] = j;会怎么样?

对于前一种情况,编译器只会选择地址a的内容,它在数组中是第一个元素的地址;规模为i,并将其总和为基地址。然后它将把地址的内容写入j的地址。

对于后一种情况,那是相当不同:编译器必须检查其中a被存储的存储器位置,加载该存储器位置的内容,以此作为地址,并且写入的j内容到该地址。

如果声明中file1.c一个字符数组是这样的:

char a[] = "Hello"; 

,然后定义,在file2

extern char *a; 

然后,在执行a[0] = 'x';file2.c会崩溃:因为你告诉编译器a是一个指针,它会检查a值的存储地址。实际上,这个地址持有'H'的字符代码,但编译器错误地将其解释为一个地址,并最终生成代码,将'x'写入地址'H',如果幸运的话,它会使您的程序崩溃分割违规。

因此,这是一个声明和定义必须匹配的情况:如果您将其声明为一个数组,则将其定义为一个数组;如果您将其声明为指针,请将其定义为指针。您必须将buf声明为其他文件中的字符数组。下面这些形式是合法的,相当于:

extern char buf[1024]; 

extern char buf[];