C语言声明与定义的区别
转自:https://blog.csdn.net/gatieme/article/details/50640424
C++程序通常由许多文件组成,为了让多个文件访问相同的变量,C++区分了声明和定义。
变量的定义(definition)用于为变量分配存储空间,还可以为变量指定初始值。在程序中,变量有且仅有一个定义。
声明(declaration)用于向程序表明变量的类型和名字。定义也是声明:当定义变量的时候我们声明了它的类型和名字。可以通过使用extern声明变量名而不定义它。不定义变量的声明包括对象名、对象类型和对象类型前的关键字extern。
extern声明不是定义,也不分配存储空间。事实上它只是说明变量定义在程序的其他地方。程序中变量可以声明多次,但只能定义一次。
只有当声明也是定义时,声明才可以有初始化式,因为只有定义才分配存储空间。初始化式必须要有存储空间来进行初始化。如果声明有初始化式,那么它可被当作是定义,即使声明标记为extern。
任何在多文件中使用的变量都需要有与定义分离的声明。在这种情况下,一个文件含有变量的定义,使用该变量的其他文件则包含该变量的声明(而不是定义)。
如何清晰的区分变量声明和定义
extern通知编译器变量在其他地方被定义
1.extern告诉编译器变量在其他地方定义了。
例如:
extern int i; //声明,不是定义
int i; //声明,也是定义,未初始化
- 1
- 2
带有初始化式的声明必定式定义
2.如果声明有初始化式,就被当作定义,即使前面加了extern。
只有当extern声明位于函数外部时,才可以被初始化。
例如:
extern double pi=3.141592654; //定义
- 1
函数的声明和定义
3.函数的声明和定义区别比较简单,带有{ }的就是定义,否则就是声明。
例如:
extern double max(double d1,double d2); //声明
- 1
除非有extern关键字,否则都是变量的定义。
4.除非有extern关键字,否则都是变量的定义。
例如:
extern int i; //声明
int i; //定义
- 1
- 2
程序模块化设计风格
概要
1. 不要把变量定义放入.h文件,这样容易导致重复定义错误。
永远不要在.h文件中定义变量。定义变量和声明变量的区别在于定义会产生内存分配的操作,是汇编阶段的概念;而声明则只是告诉包含该声明的模块在连接阶段从其它模块寻找外部函数和变量
2. 尽量使用static关键字把变量定义限制于该源文件作用域,除非变量被设计成全局的。
3. 可以在头文件中声明一个变量,在用的时候包含这个头文件就声明了这个变量。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
模块化要点
(1) 模块即是一个.c文件和一个.h文件的结合,头文件(.h)中是对于该模块接口的声明;
(2) 某模块提供给其它模块调用的外部函数及数据需在.h中文件中冠以extern关键字声明;
(3) 模块内的函数和全局变量需在.c文件开头冠以static关键字声明;
(4) 永远不要在.h文件中定义变量!定义变量和声明变量的区别在于定义会产生内存分配的操作,是汇编阶段的概念;而声明则只是告诉包含该声明的模块在连接阶段从其它模块寻找外部函数和变量。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
一般情况下头文件中只放变量的声明,因为头文件要被其他文件包含(即#include),如果把定义放到头文件的话,就不能避免多次定义变量,C++不允许多次定义变量,一个程序中对指定变量的定义只有一次,声明可以无数次。
不过有三个例外,一下三中实体的定义也可放到头文件中。
1.值在编译时就已知的const 变量的定义可以放到头文件中
如:const int num(10);
2.类的定义可以放到头文件中
3.inline 函数
- 1
- 2
- 3
- 4
这三个实体可以定义在多个源文件中,只要在每个源文件中的定义相同。
示例程序
#include <stdio.h>
#include <stdlib.h>
// 是定义,定义了A为整型的外部变量
// C中定义的变量默认就是extern的,
// 因此一般来说int a = 10 <==> extern int a = 10;
/*extern */int a = 10;
//如果声明有初始化式,就被当作定义,即使前面加了extern。
//只有当extern声明位于函数外部时,才可以被初始化。
int main(void)
{
extern int a; // 声明一个外部extern的int型变量a
// 这是个声明而不是定义,声明A是一个已经定义了的外部变量
// 注意:声明外部变量时可以把变量类型去掉如:extern a;
printf("a = %d\n", a);
return EXIT_SUCCESS;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
在这个程序中,我们再函数外部定义了一个变量
注extern int a = 10;只有当extern声明位于函数外部时,才可以被初始化。
我们后面还会提到这个问题
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int a; // 定义一个变量, 不初始化
int b = 10; // 定义一个变量, 同时进行初始化
extern int c; // 声明一个外部extern的int型变量a
printf("a = %d\n", a);
printf("b = %d\n", b);
printf("c = %d\n", c);
extern int d = 10;
return EXIT_SUCCESS;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
在这个程序中,
int a;是个定义,但是未初始化,打印他的值式不确定的,因此编译时会报未初始化的异常。
int b = 10; 是个定义,并且被正确初始化,打印b的值没有问题。
但是是个声明,如果要对c进行读写操作,而我们并没有对c进行定义,因此语法检查没有问题,但是在链接时,连接器会找不到c的地址。
对于d再明显不过了,前面我们提到过如果声明有初始化式,就被当作定义,即使前面加了extern。但是只有当extern声明位于函数外部时,才可以被初始化。
现在这个定义很明显被gcc编译器认为是错误的。
C语言声明与定义的区别的更多相关文章
- 在源文件(.c)和头文件(.h)中声明和定义的区别——C语言
最近在看多文件编程的时候遇到的一个问题,本来以为理解了声明和定义的区别(然而并没有····),也算是重新认识了一次声明和定义,下面上代码 情形一:在源文件(.c)中 相信大部分读者对声明和定义的理解是 ...
- PHP中变量声明和定义的区别
先记录一下(不知道PHP是不是一样,但是C语言是这样的):把建立空间的声明称之为“定义”,而把不需要建立存储空间的声明称之为“声明”.声明的最终目的是为了提前使用,即在定义之前使用,如果不需要提前使用 ...
- [转载]C++中声明与定义的区别
C++学了这么多年你知道为什么定义类时,类的定义放在.h文件中,而类的实现放在cpp文件中.它们为什么能够关联到一起呢?你知道什么东西可以放在.h文件中,什么不能.什么东西又可以放在cpp文件中.如果 ...
- C++ 变量的声明与定义的区别
变量声明和定义的区别 我们在程序设计中,时时刻刻都用到变量的定义和变量的声明,可有些时候我们对这个概念不是很清楚,知道它是怎么用,但却不知是怎么一会事,下面我就简单的把他们的区别介绍如下:(望我的指点 ...
- C++之声明与定义的区别
直接举例,在C++中,声明与定义的区别如下: extern int a;//若有extern关键字,则只是声明 int b;//若没有extern关键字,则为声明+定义 int a;//若之前已经声明 ...
- 【非原】c语言之声明和定义的区别
原创地址:http://www.cnblogs.com/haore147/p/3647466.html 什么是定义?什么是声明?它们有何区别? 举个例子: 1 2 A)int i; B)extern ...
- 陈正冲老师讲c语言之声明和定义的区别
什么是定义?什么是声明?它们有何区别? 举个例子: A)int i; B)extern int i;(关于extern,后面解释) 哪个是定义?哪个是声明?或者都是定义或者都是声明?我所教过的学生几乎 ...
- 浅谈声明与定义的区别 分类: C/C++ 2015-06-01 15:08 157人阅读 评论(4) 收藏
以下代码使用平台是VS2012. 清楚明白声明与定义是一名合格的程序猿的基本要求. 本人认为,C++编码过程中谈及"声明"和"定义"是因为我们要使用一个变量.类 ...
- [转载]C++声明和定义的区别
<C++Primer>第四版 2.3.5节中这么说到: ①变量定义:用于为变量分配存储空间,还可为变量指定初始值.程序中,变量有且仅有一个定义. ②变量声明:用于向程序表明变量的类型和名字 ...
- [C/C++] C++声明和定义的区别
·变量定义:用于为变量分配存储空间,还可为变量指定初始值.程序中,变量有且仅有一个定义. ·变量声明:用于向程序表明变量的类型和名字. ·定义也是声明:当定义变量时我们声明了它的类型和名字. ·ext ...
随机推荐
- mongodb对Obeject对象进行增删改操作
1.插入某个对象,如User对象 mongoTemplate.insert(user, "users");//第一个参数是实体类对象User, 第二个参数是mongodb对应的集合 ...
- 像MIUI一样做Zabbix二次开发(1)——MIUI之于Android,乐维监控之于Zabbix
摘要 文章主要介绍:7年做Zabbix二次开发,讲述那些从技术方向的选择,到开发.架构设计.深度定制,到我们的更多前瞻性想法. 关于MIUI "专注.极致.口碑.快"成了雷布斯的口 ...
- hdrp package导入工程
补充: 可以直接把包提出来放一个单独文件夹 然后在package manager中load from disk,跟下面手动改效果没区别 如果发现有各种引用丢失,在工程内对包reimport下 1 需要 ...
- Joseph Problem With Passwords In Java
问题描述: 编号为1,2,......,n的n个人(每个人的信息有编号.姓名和密码三项)按照顺时针方向围坐一圈, 每个人有且只有一个密码(正整数,密码用随机方式赋值,范围1-15).一开始任选一个正整 ...
- SQL SERVER 多表联合修改
sql server中有时候会用到多表联合修改,下面是简单的多表修改的例子 UPDATE a SET a.a1 = b.b1 , a.a2 = b.b2 FROM A a, B b WHERE a.a ...
- Expected space(s) after "default" keyword-spacing
添加空格
- miscmisc --攻防世界
题目: (1)解压后将图片放入16进制编辑器,搜索字符串flag发现 图片应该还包含其他文件 (2)使用foremost进行分离,得到压缩包,打开压缩包又有一张图片 (3) 图片同样使用编辑器查看,也 ...
- ant design vue的tooltip的宽度修改不生效
// 注意,vue 项目,style 标签不能加 scoped 选项,否则样式不生效 <a-tooltip placement="top" :overlayClassName ...
- 学习dash篇-layout页面布局
Dash介绍 Dash官网教程地址:https://dash.plotly.com/introduction 数据分析工作的结果,通常是数据表格.图表,分析报告.这些东西office的三件套基本都能满 ...
- opencv基本函数详解笔记
一.读取保存图片 Mat scrImage = imread("1.jpg"); //显示图像 imshow("原图", scrImage); //窗口等待 w ...