2

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

#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;
}

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

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

int days[];
void ChangeDay(void)
{
    days[0] = 31;
}

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

这是代码输出:

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

如果您向我解释这个结果,我将不胜感激。

我的问题:

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

3 回答 3

5

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

在第一个文件中,使用:

int *days;

在第二个文件中,使用:

extern int *days;

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

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

有时对声明存在混淆,例如int days[]因为在函数形参中使用 this 会将形参声明为 type int *。这是一个特殊的调整,只发生在函数参数中,而不发生在其他声明中。

于 2013-07-24T19:38:45.060 回答
1

分段错误的原因:

int days[]; // is errror 
void ChangeDay(void)
{
    days[0] = 31;
}

声明这是错误int days[];,你不给它大小并初始化它。所以你不能使用 day[0] = 31;-- 这是非法的并且会导致分段错误。

要获得错误而不是警告,请编译您的代码,例如:

gcc -pedantic -error那么只有它会给你一个错误。

否则这段代码不会给你一个错误,它令人困惑,但检查这段代码它的工作Codepade。如果您按照我的建议编译正确的标志,此代码会给您一个错误。

此外,由于您想共享相同day[]的数组,请按照@Eric Postpischil 的建议声明它

我目前没有删除我的答案,因为我希望其他用户查看链接代码@codepade 并告诉我是否应该使用新的编译器进行编译?还是编译器中的错误?

于 2013-07-24T19:40:17.953 回答
0

您必须在一个 c 文件中声明该数组,并在另一个 c 文件中将该变量声明为 extern。

于 2013-07-24T19:34:13.780 回答