Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C语言中多个文件中的静态二维数组_C_Arrays_Static_Header - Fatal编程技术网

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

C语言中多个文件中的静态二维数组,c,arrays,static,header,C,Arrays,Static,Header,我使用一个2D字符数组,该数组应该由C中的多个函数写入和读取 这是我的阵列: static char array[3][6]; 假设我有一个函数“function()”修改这个数组。 如果函数是在main中定义的,则没有问题(数组是正确写入的,然后是读取的),但是如果我想在另一个文件中使用我的函数,则数组是正确写入的,但是当我返回main时,数组会神奇地变空! 这是我的密码 main.c #include "support.h" int main(int argc, char *argv[]

我使用一个2D字符数组,该数组应该由C中的多个函数写入和读取

这是我的阵列:

static char array[3][6];
假设我有一个函数“function()”修改这个数组。 如果函数是在main中定义的,则没有问题(数组是正确写入的,然后是读取的),但是如果我想在另一个文件中使用我的函数,则数组是正确写入的,但是当我返回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;
}
支持.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中的所有内容都移动,如果我将它们分成两个不工作的文件(数组从函数()返回时是正确的,那么它就被释放了),这怎么可能呢?

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

extern char array[3][6];

char array[3][6];

到单个源文件。

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

extern char array[3][6];

char array[3][6];

到单个源文件。

声明文件级实体
静态
的全部目的是为其提供内部链接,即确保该实体对其他翻译单元不可见,并且每个翻译单元都有自己的独立副本。这适用于函数和对象。在您的例子中,包含
support.h
的每个翻译单元都有自己的
数组
对象的独立副本。这正是通过在头文件中声明
静态
数组实现的。这就是为什么
main.c
无法在
support.c
中看到任何修改的原因-这两个翻译单元使用两个完全独立的数组

现在,当我说数组在其他翻译单元中“不可见”时,我的意思是,您将无法从其他翻译单元按名称引用它(即,您将无法链接到它)。这不一定是坏事。如果您仍然希望将数组声明为
静态
,并从其他翻译单元访问它,您仍然可以“手动”实现此访问:在一个翻译单元中将该数组定义为
静态
,然后将该数组作为参数传递给所有其他函数

(注意,在大多数情况下,通过函数参数传递数组可能比引入全局变量要好得多。这甚至允许您在
main
中将数组声明为本地对象)


但如果坚持使用真正的全局变量,则应停止使用
静态变量。根据@simonc answer在头文件中声明您的arrray,并在其中一个翻译单元中将其定义为具有外部链接的对象。

声明文件级实体
静态
的关键在于为其提供内部链接,也就是说,确保该实体对其他翻译单位不可见,并且每个翻译单位拥有该实体的独立副本。这适用于函数和对象。在您的例子中,包含
support.h
的每个翻译单元都有自己的
数组
对象的独立副本。这正是通过在头文件中声明
静态
数组实现的。这就是为什么
main.c
无法在
support.c
中看到任何修改的原因-这两个翻译单元使用两个完全独立的数组

现在,当我说数组在其他翻译单元中“不可见”时,我的意思是,您将无法从其他翻译单元按名称引用它(即,您将无法链接到它)。这不一定是坏事。如果您仍然希望将数组声明为
静态
,并从其他翻译单元访问它,您仍然可以“手动”实现此访问:在一个翻译单元中将该数组定义为
静态
,然后将该数组作为参数传递给所有其他函数

(注意,在大多数情况下,通过函数参数传递数组可能比引入全局变量要好得多。这甚至允许您在
main
中将数组声明为本地对象)


但如果坚持使用真正的全局变量,则应停止使用
静态变量。根据@simonc answer在头文件中声明您的数组,并在其中一个翻译单元中将其定义为具有外部链接的对象。

实际上,您的程序中定义了两个
array
:一个在编译单元main中,另一个在编译单元支持中。编译器将一边编译main.c,另一边支持.c,通常创建对象文件(通常是.obj或.o)。链接器将两者放在一起,解析地址

因为您将数组定义为静态:

static char array[3][6];
您告诉编译器数组是编译单元的私有数组。因为main.c和support.c都包含support.h,所以它们都在创建自己的私有
数组。main中的代码只能看到main.c中定义的数组,support.c中的代码只能看到support.c中定义的数组。调用
函数()
时,这是在修改support.c中的数组,而不是main.c中可见的数组


如果从support.h中的
数组
定义中删除
static
关键字,则会出现链接器错误,因为该符号定义了两次(在main.c和support.c中)。您必须决定要在何处定义数组(在support.c或main.c中),并使用
extern
关键字从其他源文件中引用它。

实际上,您的程序中定义了两个
array
:一个在编译单元main中,另一个在编译单元支持中。编译器将