我使用了应该写的二维字符数组&由C中的多个函数读取。
这是我的阵列:
static char array[3][6];
让我们说我有一个函数'Function()'来修改这个数组。 如果函数在main中定义没有问题(数组被正确写入并且然后读取),但是如果我想将我的函数放在另一个文件中,那么数组是正确写入的,但是当我返回主函数时神奇地空着! 这是我的代码。
的main.c
#include "support.h"
int main(int argc, char *argv[])
{
Function();
unsigned i, j;
for(i = 0; i < 3; i++)
{
for(j = 0; j < 6; j++)
printf("[%c]", array[i][j]);
printf("\n");
}
system("PAUSE");
return 0;
}
support.h
static char array[3][6];
support.c
void Function()
{
char hello[6];
hello[0] = 'H';
hello[1] = 'E';
hello[2] = 'L';
hello[3] = 'L';
hello[4] = 'O';
hello[5] = '\0';
strcpy(array[0], hello);
}
没有编译错误也没有运行时错误。再一次,如果我尝试移动main.c中的所有内容都可以工作,如果我分成两个文件则不然(一旦从Function()返回,数组是正确的,然后它被释放),怎么样有可能吗?
答案 0 :(得分:5)
通过在头文件中将array
声明为静态,您可以为每个包含support.h
个自身副本的源文件。您需要将标题更改为
extern char array[3][6];
并添加
char array[3][6];
到单个源文件。
答案 1 :(得分:3)
声明文件级实体static
的重点是给它内部链接,即确保实体对其他翻译单元不可见,并且每个翻译单位获得该实体的独立副本。这适用于功能和对象。在您的情况下,包含support.h
的每个翻译单元都会获得自己的array
对象的独立副本。这正是您通过在头文件中声明static
数组而实现的。这就是main.c
无法在support.c
中看到任何修改的原因 - 这两个翻译单元可以使用两个完全独立的数组。
现在,当我说来自其他翻译单元的数组“不可见”时,我的意思是你将无法从其他翻译单元中引用名称(即你将会无法链接到它)。这不一定是坏事。如果您仍想将数组声明为static
并从其他翻译单元访问它,您仍然可以“手动”实现此访问:在一个翻译单元中将该数组定义为static
然后传递该数组将所有其他函数作为参数。
(注意,在大多数情况下,通过函数参数传递数组可能比引入全局变量更好。这甚至允许您在main
中将数组声明为本地对象。 )
但如果您坚持使用真正的全局变量,则应停止使用static
。根据@simonc答案在头文件中声明你的arrray,并在其中一个翻译单元中将其定义为具有外部链接的对象。
答案 2 :(得分:1)
嗯,实际上,你的程序中定义了两个array
:一个在编译单元main中,另一个在编译单元支持中。编译器将由一方编译main.c而另一方编译support.c,通常创建目标文件(通常为.obj或.o)。链接器将两者放在一起,解析地址。
因为您将数组定义为静态:
static char array[3][6];
您告诉编译器该数组是编译单元的私有数组。因为main.c和support.c都包含support.h,所以它们都创建了自己的私有array
。 main中的代码只能看到main.c中定义的数组,而support.c中的代码只能看到support.c中定义的数组。当您调用Function()
时,即修改support.c中的数组,而不是main.c中可见的数组。
如果从support.h中的static
定义中删除array
关键字,则会出现链接器错误,因为该符号定义了两次(在main.c和support.c中) 。您必须决定在哪里定义数组(在support.c或main.c中),并使用extern
关键字从其他源文件引用它。