[英]Confusion between declaration and definition of a variable in C
我是C的新手,我在变量的声明和定义之间经历了一些混淆。 我想知道的另一件事是如果以下情况属实:
“宣言多次出现,定义一次。”
也:
int x;
这只是一个声明吗? 由于内存是为x
分配的,为什么这不是一个定义而不是声明?
只需编写int x;
无论是全局范围还是局部范围, 都是声明和定义。 通常,声明告诉编译器“此变量将在某个时候以此名称存在,因此您可以使用它”。 该定义告诉编译器实际安排要创建的变量 - 显然这只能发生一次。
通常,您使用此方法的方法是输入头文件:
// Foo.h
#ifndef FOO_H
#define FOO_H // make sure structs aren't redefined
extern int bar; // Declare a variable bar
#endif
而在一个源文件
#include "foo.h"
int bar; // Define bar
如果要在多个文件中定义条形,则会出现错误; 你不能两次创建变量。 但是,你必须告诉它你使用每个源文件编译bar
中。因此, extern
声明。
精确语义在C标准的第6.9.2节中定义,可归纳如下:
static
存储类说明符,则它是一个暂定的定义 。 如果转换单元(文件)具有一个或多个暂定定义而没有外部定义 ,则编译器会自动在转换单元的末尾添加一个真正的文件范围声明,并使用零初始值设定项。 (§6.9.2/ 2) 这意味着严格地说, int x;
不是定义; 但是当且仅当没有初始化程序的其他定义且没有static
定义时,它会自动创建定义(由于链接不一致,第3种情况是未定义的行为,根据§6.2.2/ 7)
注意extern int x;
不是外部定义 。 它是一个带有extern
存储类说明符的声明。 因此, extern int x;
单独不会导致创建定义,但如果您同时具有:
extern int x;
int x;
然后,您将最终在文件中的某个位置创建定义。
从技术上讲,这也是合法的:
extern int x;
int x;
int x = 42;
在这种情况下, int x;
在中间是多余的,没有任何影响。 也就是说,这是一种糟糕的形式,因为在实际定义的情况下这是令人困惑的。
这不是你在C中看得太多的东西,但它的工作原理如下:
在头文件中,您可以使用如下行:
extern int x; //declaration
由于extern
修饰符,这告诉编译器在某处有一个名为x的int。 编译器不为它分配空间 - 它只是将int x
添加到您可以使用的变量列表中。 当它看到像这样的一行时,它只会为x
分配空间:
int x; //definition
你可以看到因为只有int x;
line更改你的可执行文件,你可以拥有尽可能多的extern int x;
你想要的线条。 只要只有int x;
行,一切都会像你想要的那样工作 - 拥有多个声明不会改变一件事。
一个更好的例子来自C ++(对不起,如果这是一个只有C的问题 - 这也适用于struct
s,但我不知道我头脑中的语法):
class Pineapple; //declaration
Pineapple* ptr; //this works
Pineapple pine; //this DOES NOT work
该声明告诉编译器有一个名为“Pineapple”的类。 它没有告诉我们关于班级的任何信息(它有多大,它的成员是什么)。 我们现在可以使用指向Pineapples的指针,但是我们还没有实例 - 我们不知道Pineapple的构成是什么,所以我们不知道实例占用了多少空间。
class Pineapple
{
public:
int ounces;
char* name;
}; //definition
Pineapple* ptr; //still works
Pineapple pine; //this works now too!
//we can even get at member variables, 'cause we know what they are now:
pine.ounces = 17;
在定义之后 ,我们知道关于类的所有内容,因此我们也可以拥有实例。 和C示例一样,您可以有多个声明,但只有一个定义。
希望这可以帮助!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.