《C++Primer》第四版 2.3.5节中这么说到:

①变量定义:用于为变量分配存储空间,还可为变量指定初始值。程序中,变量有且仅有一个定义。

②变量声明:用于向程序表明变量的类型和名字。

③定义也是声明:当定义变量时我们声明了它的类型和名字。

④extern关键字:通过使用extern关键字声明变量名而不定义它。

1.定义也是声明,分配了存储空间;而extern声明不是定义,即不分配存储空间。extern告诉编译器变量在其他地方定义了。

例如:extern int i; //声明,不是定义,

int i; //声明,也是定义

也可以这么理解:

变量的“声明”有两种情况:

1、一种是需要建立存储空间的。例如:int a 在声明的时候就已经建立了存储空间。

2、另一种是不需要建立存储空间的。 例如:extern int a 其中变量a是在别的文件中定义的。

前者是“定义性声明(defining declaration)”或者称为“定义(definition)”,而后者是“引用性声明(referncing declaration)”,从广义的角度来讲声明中包含着定义,即定义是声明的一个特例,所以并非所有的声明都是定义,例如:int a 它既是声明,同时又是定义。然而对于 extern a 来讲它只是声明不是定义。一般的情况下我们常常这样叙述,把建立空间的声明称之为“定义”,而把不需要建立存储空间的声明称之为“声明”。很明显我们在这里指的声明是范围比较窄的,即狭义上的声明,也就是说非定义性质的声明,例如:在主函数中:

int main() {
extern int A;
//这是个声明而不是定义,声明A是一个已经定义了的外部变量
//注意:声明外部变量时可以把变量类型去掉如:extern A;
dosth(); //执行函数
}
int A; //是定义,定义了A为整型的外部变量

2.如果声明有初始化式,就被当作定义,即使前面加了extern。只有当extern声明位于函数外部时,才可以被初始化。

例如:extern double pi=3.1416;  //定义,分配了存储空间

3.函数的声明和定义区别比较简单,带有{ }的就是定义,否则就是声明。

例如:extern double max(double d1,double d2);  //声明

4.除非有extern关键字,否则都是变量的定义。

例如:extern int i; //声明,没有分配存储空间

int i; //定义,分配了存储空间

程序设计风格:

    1. 不要把变量定义放入.h文件,这样容易导致重复定义错误。

    2. 尽量使用static关键字把变量定义限制于该源文件作用域,除非变量被设计成全局的。

    3. 可以在头文件中声明一个变量,在用的时候包含这个头文件就声明了这个变量。

总结:

变量在使用前就要被定义或者声明。

在一个程序中,变量只能定义一次,却可以声明多次。

定义分配存储空间,而声明不会。

C++程序通常由许多文件组成,为了让多个文件访问相同的变量,C++区分了声明和定义。

变量的定义(definition)用于为变量分配存储空间,还可以为变量指定初始值。在程序中,变量有且仅有一个定义。

声明(declaration)用于向程序表明变量的类型和名字。定义也是声明:当定义变量的时候我们声明了它的类型和名字。可以通过使用extern声明变量名而不定义它。不定义变量的声明包括对象名、对象类型和对象类型前的关键字extern。

extern声明不是定义,也不分配存储空间。事实上它只是说明变量定义在程序的其他地方。程序中变量可以声明多次,但只能定义一次。

只有当声明也是定义时,声明才可以有初始化式,因为只有定义才分配存储空间。初始化式必须要有存储空间来进行初始化。如果声明有初始化式,那么它可被当作是定义,即使声明标记为extern。

任何在多文件中使用的变量都需要有与定义分离的声明。在这种情况下,一个文件含有变量的定义,使用该变量的其他文件则包含该变量的声明(而不是定义)。

--------------------------------------------------------------------头文件中定义与声明

注意头文件中不可以放变量的定义!!!一般情况下头文件中只放变量的声明,因为头文件要被其他文件包含(即#include),如果把定义放到头文件的话,就不能避免多次定义变量,C++不允许多次定义变量,一个程序中对指定变量的定义只有一次,声明可以无数次。

不过有三个例外,一下三中实体的定义也可放到头文件中。

1.值在编译时就已知的const 变量的定义可以放到头文件中

如:const int num(10);

但是需要注意的是,如果const 变量不是用常量表达式初始化,那么它就不应该在头文件中定义,相反,它应该和其他的变量一样在源文件中定义,而在头文件中为他添加extern声明,以使其能够被多个文件共享。

2.类的定义可以放到头文件中

3.inline 函数

这三个实体可以定义在多个源文件中,只要在每个源文件中的定义相同。

/--------------------------------------------------------------------头文件中定义与声明

[转载]C++声明和定义的区别的更多相关文章

  1. [转载]C++中声明与定义的区别

    C++学了这么多年你知道为什么定义类时,类的定义放在.h文件中,而类的实现放在cpp文件中.它们为什么能够关联到一起呢?你知道什么东西可以放在.h文件中,什么不能.什么东西又可以放在cpp文件中.如果 ...

  2. C++ 变量的声明与定义的区别

    变量声明和定义的区别 我们在程序设计中,时时刻刻都用到变量的定义和变量的声明,可有些时候我们对这个概念不是很清楚,知道它是怎么用,但却不知是怎么一会事,下面我就简单的把他们的区别介绍如下:(望我的指点 ...

  3. 在源文件(.c)和头文件(.h)中声明和定义的区别——C语言

    最近在看多文件编程的时候遇到的一个问题,本来以为理解了声明和定义的区别(然而并没有····),也算是重新认识了一次声明和定义,下面上代码 情形一:在源文件(.c)中 相信大部分读者对声明和定义的理解是 ...

  4. C++之声明与定义的区别

    直接举例,在C++中,声明与定义的区别如下: extern int a;//若有extern关键字,则只是声明 int b;//若没有extern关键字,则为声明+定义 int a;//若之前已经声明 ...

  5. PHP中变量声明和定义的区别

    先记录一下(不知道PHP是不是一样,但是C语言是这样的):把建立空间的声明称之为“定义”,而把不需要建立存储空间的声明称之为“声明”.声明的最终目的是为了提前使用,即在定义之前使用,如果不需要提前使用 ...

  6. 浅谈声明与定义的区别 分类: C/C++ 2015-06-01 15:08 157人阅读 评论(4) 收藏

    以下代码使用平台是VS2012. 清楚明白声明与定义是一名合格的程序猿的基本要求. 本人认为,C++编码过程中谈及"声明"和"定义"是因为我们要使用一个变量.类 ...

  7. 【非原】c语言之声明和定义的区别

    原创地址:http://www.cnblogs.com/haore147/p/3647466.html 什么是定义?什么是声明?它们有何区别? 举个例子: 1 2 A)int i; B)extern  ...

  8. 陈正冲老师讲c语言之声明和定义的区别

    什么是定义?什么是声明?它们有何区别? 举个例子: A)int i; B)extern int i;(关于extern,后面解释) 哪个是定义?哪个是声明?或者都是定义或者都是声明?我所教过的学生几乎 ...

  9. [C/C++] C++声明和定义的区别

    ·变量定义:用于为变量分配存储空间,还可为变量指定初始值.程序中,变量有且仅有一个定义. ·变量声明:用于向程序表明变量的类型和名字. ·定义也是声明:当定义变量时我们声明了它的类型和名字. ·ext ...

随机推荐

  1. ffmpeg-20160526-git-bin

    ESC 退出 0 进度条开关 1 屏幕原始大小 2 屏幕1/2大小 3 屏幕1/3大小 4 屏幕1/4大小 S 下一帧 [ -2秒 ] +2秒 ; -1秒 ' +1秒 下一个帧 -> -5秒 f ...

  2. 20151130test->20160530

    过了6个月了,有些长进么?哈 go go go 开源镜像 http://mirrors.163.com/

  3. ios调用c#后台接口报文格式

    - NSString *soapMessage = - [NSString stringWithFormat: - @"<?xml version=\"1.0\" ...

  4. Java异常题库

    一.填空题 __异常处理__机制是一种非常有用的辅助性程序设计方法.采用这种方法可以使得在程序设计时将程序的正常流程与错误处理分开,有利于代码的编写和维护. 在Java异常处理中可以使用多个catch ...

  5. UICollectionView cellForItemAtIndexPath 方法不走

    在storyboard 中 UICollectionView cellForItemAtIndexPath not called 被坑了好久,各种问题点查找,终于解决了 解决办法: self.auto ...

  6. September 23rd 2016 Week 39th Friday

    Even a small star shines in the darkness. 星星再小,也会发光. In the darkness, even a small star can shine. N ...

  7. Redis事件管理(一)

    Redis统一的时间管理器,同时管理文件事件和定时器, 这个管理器的定义: #if defined(__APPLE__) #define HAVE_TASKINFO 1 #endif /* Test ...

  8. 如何解决exe4j生成exe文件后弹出提示信息

    使用exe4j生成exe文件时会提示以上一段信息,这个主要是没有注册导致的,在welcome to exe4j的右下角有一个注册信息的地方,去找个注册码,就OK了. 通用注册码:L-g782dn2d- ...

  9. Mysql 基于BinaryLog的复制

    .Mysql Master将更新[Update]和变化[Change]作为事件[events]写入Binary log.Mysql slaves 被配置为读取Binary log from maste ...

  10. JS ——window.onload与$(document).ready()

    我们常常在页面加载完成以后做一些操作,比如一些元素的显示与隐藏.一些动画效果.我们通常有两种方法来完成这个事情,一个就是window.onload事件,另一个就是JQuery的ready()方法.那么 ...