从编译原理上来说,声明是仅仅告诉编译器,有个某类型的变量会被使用,但是编译器并不会为它分配任何内存。而定义就是分配了内存。这对于以关键字extern进行声明是一定成立的,而对声明格式“int a;”来说,则需要取决于编译器的具体取舍。

对于下面的两句代码:

void func()
{
int a; // 《C++ Prime》认为此是定义变量,然而我们此处认为这是声明
int b=1; // 定义整型变量b
a=0;
}

对于第一行代码,编译器不会做任何事,它不会为它在栈中分配一点东西,直到第三句,a=0;时,编译器才会将其压入栈中。而对于int b=0;这一句,编译器就会生成一条指令,为它赋值。如果反汇编,看到的代码可能是这样的:

push 1;
push 0;

当然,并不一定编译器就会样做,也有可能在声明int a时,编译器就会把一个废值入栈,到第三条再为其赋值,这要看编译器的具体取舍,所以,声明不一定不是定义,而定义一定是定义。

但是,下面的声明,一定仅仅是声明:

extern int a;

这表时,有一个int变量a,它一定是在另外其他地方定义的,所以编译器此时一定不会做什么分配内存的事,因为它就是声明,仅仅表明下面的代码引用了一个符号,而这个符号是int类型的a而已。

【举例分析】

#include <iostream>
#include <cstdio> using namespace std; void testVarible1()
{
int a = 10;
int b; // 《C++ prime》中认为此是定义变量
int c = 10;
printf("a address: %#x\n", &a);
printf("a address: %#x\n", &b);
printf("c address: %#x\n", &c);
} void testVarible2()
{
int a = 10;
int b = 10;
int c = 10;
printf("a address: %#x\n", &a);
printf("a address: %#x\n", &b);
printf("c address: %#x\n", &c);
} int main()
{
testVarible1();
testVarible2();
return 0;
}

输出结果:

结论:由图可知,在我的编译器中,未赋初始值的变量b也有分配栈地址。

传送门:《C++ Prime》中对于变量声明和变量定义的理解

2018-3-24更新

  • 我们不再认为语句“int a;”为声明变量,而是定义变量,只是没有指定初始值。

声明变量&定义变量的更多相关文章

  1. 【Shell脚本学习6】Shell变量:Shell变量的定义、删除变量、只读变量、变量类型

    Shell支持自定义变量. 定义变量 定义变量时,变量名不加美元符号($),如: variableName="value" 注意,变量名和等号之间不能有空格,这可能和你熟悉的所有编 ...

  2. 【转】shell 教程——06 Shell变量:Shell变量的定义、删除变量、只读变量、变量类型

    Shell支持自定义变量. 定义变量 定义变量时,变量名不加美元符号($),如: variableName="value" 注意,变量名和等号之间不能有空格,这可能和你熟悉的所有编 ...

  3. css中定义变量

    css中定义变量 定义变量可分多种情况: 1.定义全局变量 :root { --borderColor: #ccc;} 2.定义某元素下的变量 .look{ --borderColor: #ccc;} ...

  4. 跟我一起写Makefile--- 变量(嵌套变量+追加变量+overrid+多行变量+环境变量+目标变量+模式变量)

    目录(?)[-] 使用变量 一变量的基础 二变量中的变量 三变量高级用法 四追加变量值 五override 指示符 六多行变量 七环境变量 八目标变量 九模式变量 使用变量 ———— 在Makefil ...

  5. 你好,C++(24)好大一个箱子!5.1.1 函数的声明和定义

    第5章 用函数封装程序功能 在完成功能强大的工资程序V1.0之后,我们信心倍增,开始向C++世界的更深远处探索. 现在,我们可以用各种数据类型定义变量来表达问题中所涉及的各种数据:用操作符连接这些变量 ...

  6. C语言中声明和定义详解(待看。。

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

  7. C++ 多文件编译简述:头文件、链接性、声明与定义

    目录 Commen Sense 头文件 链接性 static 与链接性控制 extern 与外部链接性 Reference Commen Sense C++ 在编译时对每个翻译单元(Translati ...

  8. 变量声明和定义及extern 转载

    在讨论全局变量之前我们先要明白几个基本的概念: 1. 编译单元(模块):    在IDE开发工具大行其道的今天,对于编译的一些概念很多人已经不再清楚了,很多程序员最怕的就是处理连接错误(LINK ER ...

  9. c++中变量声明和变量定义的区别。2016年12月6日

    整个流程: 1.程序告诉cpu,程序将要使用一个变量.(暂时不一定用到,先说一下.) 2.程序告诉CPU,程序现在就要使用一个变量.(现在就用) 3.cpu按照这个变量的类型,把内存划分出几个单位(b ...

随机推荐

  1. 洛谷P4383 [八省联考2018]林克卡特树lct(DP凸优化/wqs二分)

    题目描述 小L 最近沉迷于塞尔达传说:荒野之息(The Legend of Zelda: Breath of The Wild)无法自拔,他尤其喜欢游戏中的迷你挑战. 游戏中有一个叫做“LCT” 的挑 ...

  2. Cobbler实现自动化安装(上)--原理篇

    了解Cobbler之前,我们需要先对PXE及KickStart有一定的认识. PXE PXE(Pre-bootExecution Environment),预启动执行环境,通过网络接口启动计算机,支持 ...

  3. 数据库5.7-jdbc版本8.0.12驱动连接

    现在版本的jdbc连接方式和原来不一样了, 假如你使用String driver = "com.mysql.jdbc.Driver"; 会抛出错误: Loading class ` ...

  4. 【Spark】源码分析之SparkContext

    一.概述 SaprkContext非常重要,是Spark提交任务到集群的入口 SparkContext中没有main方法,在SparkContext主构造器中,主要做一下四件事情: 1. 调用crea ...

  5. visual studio进程或线程自上一个步骤以来已更改

    1.自己的解决方案:visual studio在多进程执行,在配置页面(webconfig)里把UseCounterThread参数设置为0 2.公司其他人解决方案,自己试了,多进程执行的时候没起作用 ...

  6. PHP的发展历程

    PHP的发展历程 了解一门语言,我们必须知道这门语言的发展史,现在我通过版本的变化以时间轴的形式来说明PHP的发展历程. 1.1995年初PHP1.0诞生 Rasmus Lerdof发明了PHP,这是 ...

  7. day 18 类与类之间的关系

    类与类之间的关系     在我们的世界中事物和事物之间总会有一些联系.    在面向对象中,类和类之间也可以产生相关的关系 1.依赖关系     执行某个动作的时候. 需要xxx来帮助你完成这个操作, ...

  8. Delphi并行库System.Threading 之ITask 1

    不知什么时候,也许是XE8,也许是XE8之前 .Delphi里面多了个System.Threading的并行库. 虽然己经有非常棒的第三方并行库QWorker,但我还是更喜欢官方的东西. 下面是一段使 ...

  9. 通过samba服务将centos7指定文件挂载到window下

    做嵌入式开发,windows下编辑代码,虚拟机上编译,为了方便打算在虚拟机下搭一个samba服务器,将文件夹映射到windows下,搜索网上的方法,内容大同小异,试了半天终于成功了.特此记录一下步骤, ...

  10. django-models 数据库取值

    django.shortcuts import render,HttpResponse from app01.models import * # Create your views here. def ...