指向多个源文件之间共享的数组的指针

bol*_*eto 2 c gcc gcc4

这是我的文件1,名为main.c

#include <stdio.h>
#include <stdlib.h>

#define MONTHS 12
void ChangeDay(void);
int* days;

int main(void)
{
    days = (int*) malloc(MONTHS * sizeof(int));
    if(days != NULL)    
        ChangeDay();    
    else    
        return 1;   
    printf("%2d.\n", days[0]);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

全局变量days被声明为指向type的指针int, malloc用于为12个整数分配空间.

这是我的文件2,名为day.c

int days[];
void ChangeDay(void)
{
    days[0] = 31;
}
Run Code Online (Sandbox Code Playgroud)

ChangeDay调用该函数时,十进制值31将分配给数组的第一个元素.

这是代码输出:

root @ where:~gcc -m32 -Wall -o day main.c day.c
day.c:1:warning:数组'days'假设有一个元素
root @ where:〜./ day分段错误

如果你向我解释这个结果,我将不胜感激.

我的问题:

  • 在多个源文件中声明变量(包括数组)的正确方法是什么?
  • 当在不同的文件中声明它们时,如何使用指针访问数组的元素?

Eri*_*hil 5

对象的标识符的每个声明必须与其他声明具有兼容的类型.int *days并且int days[]是不同的类型.前者是指向的指针int.后者是一个数组int.

在第一个文件中,使用:

int *days;
Run Code Online (Sandbox Code Playgroud)

在第二个文件中,使用:

extern int *days;
Run Code Online (Sandbox Code Playgroud)

另外:int *days;是一种试探性的定义days.当编译器到达转换单元的末尾(正在编译的源文件)时,它会将暂定定义更改为对象的定义(初始化程序为零).extern int *days;是一个声明days是不是一个定义.它告诉编译器这days是一个存在于其他地方的对象的名称.

每个对象应该只有一个定义.引用该对象的其他文件应仅声明名称而不定义该对象.

有时会对声明产生混淆,例如int days[]因为在函数参数中使用此声明会将参数声明为类型int *.这是一种特殊调整,仅在函数参数中发生,而不在其他声明中发生.