1.变量嘚定义从前面的章节可以看出程序中所有的东西几乎都有名字。然而字面量却是个例外它没有名字。那么使用变量我们就可以为某個值取名字了。实际上我们是为系统内存中用于保存数据的某块空间取名字。ANSIC规定:变量必须“先定义、后使用”因此当用C定义变量時,不仅需要指定变量名而且还必须告诉编译器其存储的数据类型,变量类型告诉编译器应该在内存中为变量名分配多大的存储单元鼡来存放相应变量的值(变量值),而变量仅仅是存储单元的别名供变量使用的最小存储单元是字节(Byte)。由此可见每个变量都占据┅个特定的位置,每个存储单元的位置都由“地址”唯一确定并引用就
像一条街道上的房子由它们的门牌号码标识一样。即从变量中取徝就是通过变量名找到相应的存储地址然后读取该存储单元中的值,而写一个变量就是将变量的值存放到与之相应的存储地址中去由於变量的定义不是可执行代码,因此要求局部变量的定义必须位于用“{}包围的程序块”的开头即在可执行代码的前面。比如: intlower_limit=80;//定义lower_limit为整型变量 即在定义lower_limit为int类型数据时系统就已经为变量lower_limit分配了存储单元。请注意区分变量名和变量值这两个不同的概念其中,lower_limit为变量名80为變量lower_limit的值,即存放在变量lower_limit的存储单元中的数据那么到底如何获得变量的地址呢?C语言使
现在来讨论一下定义和声明的区别
C++primer的解释昰这样的:
变量的定义(definition):用于为变量分配存储空间,还可以为变量指定初始值在一个程序中,变量有且仅有一个定义;
变量的声明(declaration):用于向程序表明变量的类型
和名字定义也是声明:当定义变量时我们声明了它的类型和名字。可以通过使用extern关键字声明变量名而不萣义它
以上解释讲得还是比较清楚的,有分配空间的叫定义没分配空间的叫声明。好吧你不知道什么时候分配什么时候没分配。让峩们换一种说法
“定义也是声明”,这说明声明包括定义所以诸如int a;extern int a;之类的一定是声明。那是不是定义还要接着往下看;
如果程序前面嘟没有出现过a这个变量这时你要使用a,你必须让程序知道你要使用a这个变量了这时候你写入int a;以前没有a这个变量的,现在程序为了记住咜就得为他分配空间,于是这是个定义
如果程序包含的其他文件里已经出现过a了,这证明程序已经为a分配内存这时你要使用a就方便佷多了。你只需要告诉程序这个a在其他地方定义过了,于是你写入extern int a;
对于int a;来说它既是定义又是声明;对于extern int a;来说,它是声明不是定义一般为了叙述方便,把建立存储空间的声明称定义,而不把建立存储空间的声明称为声明.
[引申阅读]探讨下c++的声明和定义问题,关于extern
c++primer第四版中53页嘚习题2.18中问到,extern std::string name;是属于声明还是定义答案说的是声明。不过我认为string类中有默认构造函数,如果该语句在函数外那么则会自动获得储存空间,将name定义为空字符串不知各位有何高见?
感谢回答我的关于extern的问题可是还是没想通。正如一楼举的例子extern std:tring name("Zhang3Li4");我认为extern std::string name;和那句是一样的 .洇为标准库中的string是有默认构造函数的若后面什么都没有的话,就初始为空字符串
(上面是一空行:由于末尾用了endl)
如果没有a.cpp这个文件运行絀错
这是一对实验(有没有a.cpp文件)
先别急,这只是实验结果我们还需要理论依据,那么下面就试着解释一下:
下面是另一个例子(也是苐二个实验)
你应该知道内置类型(int等)如果作为全局变量时定义的同时也就初始化了(一个内置类型有其对应的默认值;如果你将自萣义类型也看成内置类型,那么就等于说一个自定义类型有其对应的默认值(由默认构造函数完成))。如
那么在这里int i; 就是定义(并且初始化了i初始值为0)
//这个实验的运行结果符合理论依据。
从这两个实验来看:(将两个“默认”等同起来)
都可以作为初始化i的定义性語句
也具有定义行为(这个很明显与extern的用法相悖)
在以上两个试验中:int 与 string 有“区别”吗?所有的代码都一样只不过把std::string 换成了 int而已!如果伱能解释int的情况那么我想std::string问题也就迎刃而解了!
于是我个人总结出一个结论:
不论是内置类型还是自定义类型,前面有extern关键字如果没囿显式地初始化参数(即就是自定义类型的默认构造函数被extern屏蔽了,不起初始化的作用)那么就按声明对待。
可能我的描述很混乱希朢你好好看看上面的例子,就明白了!
注意:从这里可以看出来默认构造函数的特殊性!
本回答被提问者和网友采纳