《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. codeforces 338(Div 2) B. Longtail Hedgehog 解题报告

    题目链接:http://codeforces.com/problemset/problem/615/B 题目意思:要画一只 hedgehog,由 tail 和 spines 组成.我们要求得 beau ...

  2. WCF服务跟踪

    如果在开发过程中,WCF服务出现问题,我们可以通过服务引用,然后直接断点调试进去.然而,对于已经发布的服务,出现错误时,寻找错误信息会变得麻烦. 幸好,微软提供了服务跟踪查看器工具 (SvcTrace ...

  3. Linux中环境变量文件及配置(转载)

    一.环境变量文件介绍 转自:http://blog.csdn.net/cscmaker/article/details/7261921 Linux中环境变量包括系统级和用户级,系统级的环境变量是每个登 ...

  4. io流对文件读写操作

    public static void main(String[] args) throws IOException { BufferedReader reader = new BufferedRead ...

  5. [Android Pro] Android 6.0 Root

    reference : http://bbs.gfan.com/android-8001827-1-1.html 2. 刷机和刷入recovery 建议参考 置顶教程: [15年3月31日更新]Nex ...

  6. 验证码的种类与实现 C#封装类 - .NET MVC WEBFORM

    验证码方式 1.随机字母或者数字,纯文本验证码 这种非常容易破解 ,市场上有大量的现成接口或者工具,背景越复杂难度越高. 2.题库验证码 要破解这种验证码,需要人工收集题库才可以破解,可以免疫不是专门 ...

  7. MVC - 11(下)jquery.tmpl.js +ajax分页

    继续 mvc-11(上).dto:http://www.cnblogs.com/tangge/p/3840060.html jquery.tmpl.js 下载:http://pan.baidu.com ...

  8. Oracle Redhat5.5

    http://blog.csdn.net/yakson/article/details/9012129 http://www.cnblogs.com/cnmarkao/p/3670153.html h ...

  9. async/await 异步编程(转载)

    转载地址:http://www.cnblogs.com/teroy/p/4015461.html 前言 最近在学习Web Api框架的时候接触到了async/await,这个特性是.NET 4.5引入 ...

  10. sdut 487-3279【哈希查找,sscanf ,map】

    487-3279 Time Limit: 2000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 题目链接: sdut:   http://acm.sdut.ed ...