global char []变量,如何在其他文件中声明它?

问题描述 投票:2回答:5

我在一个文件中定义了一个全局变量char buf[1024],在其他文件中声明它的正确性是什么? extern char buf[1024]extern char buf[]extern char *buf?我发现extern char buf[]的作品和extern char *buf没有,但想知道更多的解释。

c arrays pointers global extern
5个回答
4
投票

您可以使用

extern char buf[];

但不是

extern char *buf;

因为数组不是指针。

参考:C FAQ


0
投票

extern char buf []和extern char buf [1024]都可以。

在某些情况下,数组由指针实现,例如在两个函数之间传递参数。


0
投票

当您将变量设置为extern时,您向编译器指示变量的符号(地址)将在另一个.o文件中找到 - (这在链接阶段完成)。

因此,当您将变量设置为extern时,您只需要提及名称,因为它将提供有关地址和大小的信息不是必需的


0
投票

这是数组和指针可以互换的老问题。数组和指针不可互换:它们恰好恰好在大多数情况下,因为大多数时候你在表达式中使用数组名称,它会衰减成指针。

在Expert C Programming - Deep C Secrets中详细解释了在一个文件中定义为char数组并在另一个文件中声明为char指针的特定情况。见第4章。

数组的声明为您提供了一个数组,指针的声明为您提供了一个指针。不同之处在于数组是一个地址 - 第一个元素的地址 - 并且它不是可修改的l值,即它不能被赋值。另一方面,指针是保存地址的变量。

通常,上下文足以判断您是指变量的地址还是赋值中变量的内容。该声明

i = j;

是说将j的内容存储在i的地址中。在编译器行话中,i被认为是l值,而j是r值。编译器必须生成将j的内存地址的内容写入i的内存地址的代码。

考虑这些声明:

char a[1024];
char *a;

a[i] = j;会发生什么?

对于前一种情况,编译器将只选择a内容的地址,其在数组中是第一个元素的地址;缩放i,并将其加到基址。然后它会将存储j的地址内容写入该地址。

对于后一种情况,它是完全不同的:编译器必须检查存储a的内存位置,加载该内存位置的内容,使用THAT作为地址,并将j的内容写入该地址。

如果在file1.c中声明这样的字符数组:

char a[] = "Hello";

然后在file2中定义

extern char *a;

然后,在a[0] = 'x';中执行file2.c将崩溃:因为你告诉编译器a是一个指针,它将检查存储a值的地址。实际上,这个地址持有'H'的字符代码,但是编译器错误地将其解释为地址,并最终生成代码以将'x'写入地址'H',如果你很幸运,它将使你的程序崩溃分段违规。

因此,这是声明和定义必须匹配的情况:如果您将其声明为数组,则将其定义为数组;如果您将其声明为指针,请将其定义为指针。您必须将buf声明为其他文件中的字符数组。这些表格中的任何一种都是合法且等同的:

extern char buf[1024];

要么

extern char buf[];

0
投票

可分配的全局char变量。让所有人都看得见:

// shared_header.h
extern char current_mode[];

定义,实例化和更新:

// main.c
#include "shared_header.h"

char current_mode[160];

int main(int argc, char * argv [])
{
    strcpy(current_mode, "MODE_CONFIGURE");
    int a = randomNumber(102);

    strcpy(current_mode, "MODE_EXECUTE");
    int b = do_foo(a);
    // other stuff

    strcpy(current_mode, "MODE_TEARDOWN");
    // close up shop
}

阅读或更新:

// foo.c
#include "shared_header.h"

int do_foo(int a)
{
    printf("Current mode is %s", current_mode);

    if (a > 100) {
        strcpy(current_mode, "MODE_EXECUTE_SPECIAL_CASE");
        printf("Switching to mode %s", current_mode);
    }

    // do useful things
}
© www.soinside.com 2019 - 2024. All rights reserved.