繁体   English   中英

C中变量的声明和定义之间的混淆

[英]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节中定义,可归纳如下:

  • 当使用初始化程序在文件范围声明变量时,它是外部定义 (§6.9.2/ 1)
  • 如果在没有初始化程序的情况下在文件范围内声明变量,并且没有存储类说明符或使用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM