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
}