C中多个文件中的静态二维数组

时间:2013-06-17 15:43:47

标签: c arrays static header

我使用了应该写的二维字符数组&由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()返回,数组是正确的,然后它被释放),怎么样有可能吗?

3 个答案:

答案 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关键字从其他源文件引用它。