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



我使用了一个2D字符数组,应该写成&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] = '';
     strcpy(array[0], hello);            
}

没有编译错误和运行时错误。再一次,如果我试图移动main.c中的所有内容,如果我将其分成两个文件,它不会(数组从Function()返回后立即正确,然后它被释放),这怎么可能?

通过在头文件中声明array为静态,您为每个包含support.h的源文件提供了自己的副本。你需要将标题改为

extern char array[3][6];

并添加

char array[3][6];

声明文件级实体static的全部要点是给它内部链接,即确保该实体对其他翻译单元不可见,并且每个翻译单元获得该实体的独立副本。这对函数和对象都适用。在您的示例中,包含support.h的每个翻译单元都获得array对象的独立副本。这正是通过在头文件中声明static数组所实现的。这就是为什么main.csupport.c中看不到任何修改——这两个翻译单元在两个完全独立的数组中工作。

现在,当我说数组从其他翻译单元"不可见"时,我的意思是您将无法从其他翻译单元通过名称引用它(即您将无法链接到它)。这未必是件坏事。如果您仍然希望将数组声明为static并从其他翻译单元访问它,您仍然可以"手动"实现此访问:在一个翻译单元中将该数组定义为static,然后将该数组作为参数传递给所有其他函数。(注意,在大多数情况下,通过函数参数传递数组可能比引入全局变量要好得多。这甚至允许你在main中声明你的数组为本地对象。)

但是如果你坚持使用一个真正的全局变量,你应该停止使用static。根据@simonc答案,在头文件中声明您的数组,并将其定义为具有外部链接的对象。

实际上,你的程序中定义了两个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中的array定义中删除static关键字,则会出现链接器错误,因为该符号被定义了两次(在main.c和support.c中)。您必须决定在哪里定义数组(在support.c或main.c中),并使用extern关键字从另一个源文件引用它。

最新更新