变量的声明有两种情况:
    1、一种是需要建立存储空间的。例如:int a 在声明的时候就已经建立了存储空间。
    2、另一种是不需要建立存储空间的。 例如:extern int a 其中变量a是在别的文件中定义的。
    声明是向编译器介绍名字--标识符。它告诉编译器“这个函数或变量在某处可找到,它的模样象什么”。
    而定义是说:“在这里建立变量”或“在这里建立函数”。它为名字分配存储空间。无论定义的是函数还是变量,编译器都要为它们在定义点分配存储空间。 对于变量,编译器确定变量的大小,然后在内存中开辟空间来保存其数据,对于函数,编译器会生成代码,这些代码最终也要占用一定的内存。
    总之就是:把建立空间的声明成为“定义”,把不需要建立存储空间的成为“声明”。
    基本类型变量的声明和定义(初始化)是同时产生的;而对于对象来说,声明和定义是分开的。
    例如:类A
    如果A a;就是一个声明,告诉编译器a是A类的一个对象变量,但是不进行初始化;
    如果以后a=new A();这就是初始化,分配了空间。
    (我们声明的最终目的是为了提前使用,即在定义之前使用,如果不需要提前使用就没有单独声明的必要,变量是如此,函数也是如此,所以声明不会分配存储空间,只有定义时才会分配存储空间。)
    用static来声明一个变量的作用有二:
    (1)对于局部变量用static声明,则是为该变量分配的空间在整个程序的执行期内都始终存在。
    (2)外部变量用static来声明,则该变量的作用只限于本文件模块。
    补充:
    什么是定义?什么是声明?它们之间的区别是什么?
    所谓定义就是(编译器)创建一个对象,为这个对象分配一块内存,并给它取上一个名字,这个名字就是就是我们经常所说的变量名或对象名。
    声明有2重含义:
    (1) 告诉编译器,这个名字已经匹配到一块内存上,下面的代码用到变量或者对象是在别的地方定义的。声明可以出现多次。
    (2) 告诉编译器,这个名字已经被预定了,别的地方再也不能用它来作为变量名或对象名。
    定义和声明的最重要区别就是:
    定义创建对象并为这个对象分配了内存,声明没有分配内存。

因此,更好不要在头文件中愚蠢地定义任何东西。 例如全局变量:

/*xx头文件*/

# _XX_头文件.H

# _XX_头文件.H

整数A;

#万一

嗯,很糟糕的是,这里的int A是一个全局变量的定义,所以如果多次引用这个头文件,你的A就会被重复定义,这显然是一个语法错误。 只不过有了这个#的条件编译,可以保证你的头文件只被引用一次,但可能还是不会出错,但是如果多个C文件都包含这个头文件,还是会出错,因为宏name 的有效范围仅限于这个 C 源文件,所以编译这多个 C 文件时不会出错,但是链接时会报错,说你在多个地方定义了同一个变量。

...

incl2.obj:错误:incl1.obj 中的“int glb”(?glb@@3HA)

Debug/incl.exe:致命错误:发现一个或多个

注意! ! !

二,

这个关键词实在是太恶心了。 定义变量时,this其实可以省略(定义时默认省略); 声明变量时,必须在变量之前添加 this ,所以有时会让你感到困惑。 是声明还是定义。 换句话说,变量出现在变量之前并不一定是声明,而变量的缺失只能是定义。 注意:定义需要为变量分配内存空间; 声明不需要为变量分配内存空间。

下面分为两类:变量和函数:

(1)变量

特别是对于变量。

int a;//声明一个全局变量a

整数a; //定义一个全局变量a

int a =0;//定义一个全局变量a并赋予初始值。

整数a=0; //定义一个全局变量a并赋予其初始值。

第四个和第三个是一样的,都是定义一个可以外部使用的全局变量,并给它一个初始值。

你很困惑,他们看起来如此相似。 但定义只能出现在一处。 也就是说,是否是int a; 或 int a=0; 或者int a=0;,只能出现一次,但是int a可以出现很多次。

当要引用全局变量时,必须声明,int a; 这个不能省略,因为省略的话就变成int a; 这是一个定义,而不是声明。 注:int a中的类型为int; 可以省略,即a; 但其他类型不能省略。

(2) 功能

函数,函数也是如此,也是定义和声明的。 定义的时候就意味着该函数可以被外部引用。 当声明时,就意味着它是一个声明。 不过,由于函数的定义和声明是有区别的,定义的函数必须有函数体,而声明的函数没有函数体(并且以分号结尾),所以定义时可以省略并声明该函数。 反正其他文件也知道。 这个函数是在别处定义的,所以不添加也没关系。 两者差异如此之大,省略它们也没有问题。

例如:

/*某个cpp文件*/

int 乐趣(无效)

0;

太好了,我们定义了一个全局函数

/*另一个cpp文件*/

int 乐趣(无效);

我们声明它,然后我们就可以使用它

加不加都没关系

我们也可以将 fun 的声明放在头文件中dll文件声明,最终会是这样

/*有趣的.h*/

int 乐趣(无效); //函数声明,所以省略,更完整的是int fun(void);

/*对应的fun.cpp文件*/

int 乐趣(无效)

0;

}//一个完整的全局函数定义,因为有函数体,所以也省略了。

然后,一个客户端,一个想用你的乐趣的客户端,包含这个头文件,好吧,一个全局声明。 没问题。

但相应的,如果这个客户想要使用全局变量,那么就需要某个变量; 否则,它就成为一个定义。

总结:

至于变量,如果想在这个源文件(如文件名A)中使用另一个源文件(如文件名B)的变量,有两种方法: (1)在文件A中,必须声明它在文件B中定义的变量(当然是全局变量); (2)在文件A中添加文件B对应的头文件。当然,这个头文件包含了文件B中的变量声明,即变量必须在这个头文件中声明。 ,否则,重新定义该变量。

对于函数来说,如果想在这个源文件(如文件名A)中使用另一个源文件(如文件名B)的函数,有两种方法:(1)使用文件A中的声明并使用B文件中定义的函数(其实也可以省略,只要B文件定义函数原型出现在A文件中即可); (2)在A文件中添加B文件对应的头文件。 当然,这个头文件包含B文件。 函数原型,函数不需要在头文件中添加。

****************************************************** ********************************************************* ****************************************************** ***

重新表述一下上面的总结:

(a)对于一个文件中调用另一个文件的全局变量,由于全局变量一般定义在原file.c中,我们不能使用#来包含源文件而只能包含头文件,所以常用的方法是声明它用 int 表示外部变量。 另一种方法是在ac文件中定义全局变量int,并将int写入对应的ah头文件中,这样其他源文件就可以通过ah将其声明为外部变量。

(b) 变量和函数也有不同的例子

int 乐趣(); 和 int fun(); 都是声明(定义必须有一个实现主体)。 使用 int fun() 只是更清楚地表明它是一个语句。

和 int a; 是定义

整数a; 是一个声明。

(3)另外,可以使用修饰符来规范C++程序中c函数的调用。

例如,要在C++中调用C库函数,需要在C++程序中用“C”声明要引用的函数。 链接器使用它来告诉链接器在链接时使用 C 函数规范。 主要原因是C++和C程序编译后目标代码中的命名规则不同。

C++语言为了解决编译时的多态问题,会将名称和参数结合起来生成一个中间名称,但C语言不会,所以会导致链接时找不到对应的情况。 在这种情况下,C 需要使用“C”进行链接指定,这告诉编译器,请保留我的名字,不要给我生成用于链接的中间名。

3、与头文件的连接

此连接还解决了最初提出的两个问题:

(a) 可以使用#在其他头文件中包含变量和函数的声明。 为什么需要关键词?

(b) 如果我想引用全局变量或函数a,只需在源文件中直接包含#(xxx.h包含a的声明)即可。 我为什么要使用它? ?

答:如果一个文件(假设文件名A)要引用另一个文件(假设文件名B)中定义的大量变量或函数,使用头文件效率更高,程序结构也更规范。 如果其他文件(如文件名C、D等)想要引用文件名B中定义的变量或函数,只需要使用#包含文件B对应的头文件即可(当然,这个头文件只声明变量或函数,决不可以没有定义)。

****************************************************** ********************************************************* ** ******************************************

那是一个被遗忘的时代。 当时,编译器只知道.c(或.cpp)文件,不知道.h是什么。

当时,人们编写了很多.c(或.cpp)文件。 渐渐地,人们发现许多.c(或.cpp)文件中声明的变量或函数原型是相同的,但他们必须使用相同的单词,在每个.c(或.cpp)文件中重复输入这些单词一个单词时间。 但更可怕的是,当其中一条语句发生变化时,你需要检查所有.c(或.cpp)文件并修改其中的语句。 啊~,就像世界末日一样!

终于,有人(或许是某些人)再也无法忍受这种折磨了。 他们提取重复的部分,将它们放入一个新文件中,然后在所需的 .c(或 .cpp)文件中键入 #。 诸如 XXXX 之类的陈述。 这样,即使某个语句发生了变化,也无需到处查找、修改——世界依然如此美好!

由于这个新文件常常放在.c(或.cpp)文件的头部,因此被命名为“头文件”,扩展名为.h。

从那时起,编译器(实际上是预处理器)就知道除了.c(或.cpp)文件之外,还有一个.h文件和一个名为#的命令。

未经允许不得转载! 作者:admin,转载或复制请以超链接形式并注明出处天心神途传奇手游发布网

原文地址:《extern 头文件定义和声明》发布于:2024-03-18

发表评论

表情:
验证码
评论列表 (暂无评论,56人围观)

还没有评论,来说两句吧...