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

时间:2021-03-07 16:45:59

I defined a global variable char buf[1024] in one file, and what's the correct may to declare it in other files? extern char buf[1024], extern char buf[], or extern char *buf? I found extern char buf[] works and extern char *buf doesn't, but would like to know more explanations.

我在一个文件中定义了一个全局变量char buf[1024],在其他文件中声明它的正确值是什么?外面的char buf[1024],外面的char buf[],或者外面的char *buf?我发现extern char buf[]起作用,而extern char *buf未起作用,但我想知道更多的解释。

5 个解决方案

#1


4  

You can use

您可以使用

extern char buf[];

but NOT

但不是

extern char *buf;

Because arrays are not pointers.

因为数组不是指针。

Reference: C FAQ

参考:C常见问题解答

#2


0  

extern char buf[] and extern char buf[1024] both are ok.

extern char buf[]和extern char buf[1024]均表现良好。

In some case, the array is implemented by pointer, such as transfering arguments between two functions.

在某些情况下,数组是通过指针实现的,比如在两个函数之间传递参数。

#3


0  

When you are making a variable as extern , you are indicating to the compiler that the symbol (address) of the variable would be found in another .o file - ( This is done during linking stage ) .

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

So while you are making a variable as extern , you just need to mention the name as it will give the information about address and size is not required

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

#4


0  

This is the old problem of arrays and pointers being interchangeable. Arrays and pointers are not interchangeable: they just happen to be most of the time, because most of the time you use an array name in an expression, where it decays into a pointer.

这是数组和指针可以互换的老问题。数组和指针不是可互换的:它们只是碰巧在大多数时间内发生,因为大多数情况下,在表达式中使用数组名称时,它会在一个指针中衰变。

This specific case of defining as char array in one file and declaring as char pointer in the other file is thoroughly explained in Expert C Programming - Deep C Secrets; see chapter 4.

这个在一个文件中定义为char数组并在另一个文件中声明为char指针的具体案例在专家C编程中得到了详细的解释——深入的C秘密;见第四章。

The declaration of an array gives you an array, and the declaration of a pointer gives you a pointer. The difference is that an array is an address - the address of the first element - and it is not a modifiable l-value, i.e., it can't be assigned to. On the other hand, a pointer is a variable holding an address.

数组的声明给你一个数组,指针的声明给你一个指针。不同之处在于数组是一个地址—第一个元素的地址—并且它不是一个可修改的l值,例如。,不能赋值。另一方面,指针是保存地址的变量。

Usually, the context is enough to tell whether you mean the address of a variable or the contents of the variable in an assignment. The statement

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

i = j;

我= j;

Is saying to store the contents of j in the address of i. In compilers jargon, i is said to be an l-value, and j an r-value. The compiler has to generate code that writes the contents of the memory address of j in the memory address of i.

表示将j的内容存储在i的地址中,在编译器术语中,i是l值,j是r值。编译器必须生成代码,将j的内存地址内容写入i的内存地址中。

Consider these declarations:

考虑这些声明:

char a[1024];
char *a;

What happens when you write a[i] = j;?

当你写一个[i] = j;时会发生什么?

For the former case, the compiler will just pick the address of a's contents, which, in arrays, is the address of the first element; scale i, and sum it to the base address. Then it will write the contents of the address where j is stored into that address.

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

For the latter case, it is quite different: the compiler has to check the memory location where a is stored, load the contents of that memory location, use THAT as an address, and write the contents of j into that address.

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

If you declare a characters array like this in file1.c:

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

char a[] = "Hello";

And then define, in file2

然后在file2中定义

extern char *a;

Then, executing a[0] = 'x'; in file2.c will crash: since you told the compiler that a is a pointer, it will check the address where a's value is stored. In reality, this address is holding the character code for 'H', but the compiler mistakenly interprets that as an address, and ends up generating code to write 'x' into the address 'H', which, if you're lucky, will crash your program with a segmentation violation.

然后,执行[0]= 'x';file2。c会崩溃:因为你告诉编译器a是一个指针,它会检查a值存储的地址。实际上,这个地址包含了“H”的字符代码,但是编译器错误地将其解释为一个地址,并最终生成代码将“x”写入地址“H”中,如果幸运的话,这将导致程序出现分段冲突。

Thus, this is a case where declaration and definition must match: if you declared it as an array, define it as an array; if you declared it as a pointer, define it as a pointer. You have to declare buf as a characters array in other files. Either of these forms is legal and equivalent:

因此,这是一个声明和定义必须匹配的情况:如果您将它声明为一个数组,那么将它定义为一个数组;如果您将它声明为指针,则将它定义为指针。您必须将buf声明为其他文件中的字符数组。这两种形式都是合法的和同等的:

extern char buf[1024];

or

extern char buf[];

#5


0  

Assignable global char variable. Make visible to all:

可转让的全球字符变量。让所有可见:

// shared_header.h
extern char current_mode[];

Define, instantiate and update:

定义、初始化和更新:

// 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
}

Read or update:

读取或更新:

// 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
}

#1


4  

You can use

您可以使用

extern char buf[];

but NOT

但不是

extern char *buf;

Because arrays are not pointers.

因为数组不是指针。

Reference: C FAQ

参考:C常见问题解答

#2


0  

extern char buf[] and extern char buf[1024] both are ok.

extern char buf[]和extern char buf[1024]均表现良好。

In some case, the array is implemented by pointer, such as transfering arguments between two functions.

在某些情况下,数组是通过指针实现的,比如在两个函数之间传递参数。

#3


0  

When you are making a variable as extern , you are indicating to the compiler that the symbol (address) of the variable would be found in another .o file - ( This is done during linking stage ) .

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

So while you are making a variable as extern , you just need to mention the name as it will give the information about address and size is not required

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

#4


0  

This is the old problem of arrays and pointers being interchangeable. Arrays and pointers are not interchangeable: they just happen to be most of the time, because most of the time you use an array name in an expression, where it decays into a pointer.

这是数组和指针可以互换的老问题。数组和指针不是可互换的:它们只是碰巧在大多数时间内发生,因为大多数情况下,在表达式中使用数组名称时,它会在一个指针中衰变。

This specific case of defining as char array in one file and declaring as char pointer in the other file is thoroughly explained in Expert C Programming - Deep C Secrets; see chapter 4.

这个在一个文件中定义为char数组并在另一个文件中声明为char指针的具体案例在专家C编程中得到了详细的解释——深入的C秘密;见第四章。

The declaration of an array gives you an array, and the declaration of a pointer gives you a pointer. The difference is that an array is an address - the address of the first element - and it is not a modifiable l-value, i.e., it can't be assigned to. On the other hand, a pointer is a variable holding an address.

数组的声明给你一个数组,指针的声明给你一个指针。不同之处在于数组是一个地址—第一个元素的地址—并且它不是一个可修改的l值,例如。,不能赋值。另一方面,指针是保存地址的变量。

Usually, the context is enough to tell whether you mean the address of a variable or the contents of the variable in an assignment. The statement

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

i = j;

我= j;

Is saying to store the contents of j in the address of i. In compilers jargon, i is said to be an l-value, and j an r-value. The compiler has to generate code that writes the contents of the memory address of j in the memory address of i.

表示将j的内容存储在i的地址中,在编译器术语中,i是l值,j是r值。编译器必须生成代码,将j的内存地址内容写入i的内存地址中。

Consider these declarations:

考虑这些声明:

char a[1024];
char *a;

What happens when you write a[i] = j;?

当你写一个[i] = j;时会发生什么?

For the former case, the compiler will just pick the address of a's contents, which, in arrays, is the address of the first element; scale i, and sum it to the base address. Then it will write the contents of the address where j is stored into that address.

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

For the latter case, it is quite different: the compiler has to check the memory location where a is stored, load the contents of that memory location, use THAT as an address, and write the contents of j into that address.

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

If you declare a characters array like this in file1.c:

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

char a[] = "Hello";

And then define, in file2

然后在file2中定义

extern char *a;

Then, executing a[0] = 'x'; in file2.c will crash: since you told the compiler that a is a pointer, it will check the address where a's value is stored. In reality, this address is holding the character code for 'H', but the compiler mistakenly interprets that as an address, and ends up generating code to write 'x' into the address 'H', which, if you're lucky, will crash your program with a segmentation violation.

然后,执行[0]= 'x';file2。c会崩溃:因为你告诉编译器a是一个指针,它会检查a值存储的地址。实际上,这个地址包含了“H”的字符代码,但是编译器错误地将其解释为一个地址,并最终生成代码将“x”写入地址“H”中,如果幸运的话,这将导致程序出现分段冲突。

Thus, this is a case where declaration and definition must match: if you declared it as an array, define it as an array; if you declared it as a pointer, define it as a pointer. You have to declare buf as a characters array in other files. Either of these forms is legal and equivalent:

因此,这是一个声明和定义必须匹配的情况:如果您将它声明为一个数组,那么将它定义为一个数组;如果您将它声明为指针,则将它定义为指针。您必须将buf声明为其他文件中的字符数组。这两种形式都是合法的和同等的:

extern char buf[1024];

or

extern char buf[];

#5


0  

Assignable global char variable. Make visible to all:

可转让的全球字符变量。让所有可见:

// shared_header.h
extern char current_mode[];

Define, instantiate and update:

定义、初始化和更新:

// 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
}

Read or update:

读取或更新:

// 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
}