const define static extern
const
const意味着”只读”,欲阻止一个变量被改变,可以使用const关键字
const仅仅用来修饰右边的变量(基本数据变量p,指针变量*p)
define
#define指令有三种用法:
第一种是定义标识,标识有效范围为整个程序,形如#define XXX,常与#if配合使用
第二种是定义常数,如#define max 100,则max代表100(这种情况下使用const定义常数更好,因为:const常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查,而对后者只进行字符替换,没有类型安全检查,并且在字符替换时可能会产生意料不到的错误 )
第三种是定义”函数”,如#define get_max(a, b) ((a)>(b)?(a):(b)) 则以后使用get_max(x,y)就可以得到x和y中较大的数(这种方法存在一些弊病,如get_max(a++, b)时,a++会被执行多少次取决于a和b的大小!所以建议还是用内联函数而不是这种方法提高速度。虽然有这样的弊病,但这种方法的确非常灵活,因为a和b可以是各种数据类型。)。
const常量与define宏定义的区别
1. 编译器处理方式不同
- define宏是在预处理阶段展开
- const常量是编译运行阶段使用
2. 类型和安全检查不同
- define宏没有类型,不做任何类型检查,仅仅是展开
- const常量有具体的类型,在编译阶段会执行类型检查
3. 存储方式不同
- define宏仅仅是展开,有多少地方使用,就展开多少次,不会分配内存
- const常量会在内存中分配(可以是堆中也可以是栈中)
4. 内存空间分配不同
- const可以节省空间,避免不必要的内存分配
#define PI 3.14159 //常量宏
const doulbe Pi=3.14159; //此时并未将Pi放入ROM中 ……
double i=Pi; //此时为Pi分配内存,以后不再分配!
double I=PI; //编译期间进行宏替换,分配内存
double j=Pi; //没有内存分配
double J=PI; //再进行宏替换,又一次分配内存!
const定义常量从汇编的角度来看,只是给出了对应的内存地址,而不是象#define一样给出的是立即数,所以,const定义的常量在程序运行过程中只有一份拷贝(因为是全局的只读变量,存在静态区),而 #define定义的常量在内存中有若干个拷贝。
5. 提高了效率
- 编译器通常不为普通const常量分配存 大专栏 const define static extern储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高
6. 宏替换只作替换,不做计算,不做表达式求解
- 宏预编译时就替换了,程序运行时,并不分配内存
7. 总结
宏:只是在预处理器里进行文本替换,没有类型,不做任何类型检查,编译器可以对相同的字符串进行优化。只保存一份到 .rodata 段。甚至有相同后缀的字符串也可以优化,你可以用GCC 编译测试,”Hello world” 与 “world” 两个字符串,只存储前面一个。取的时候只需要给前面和中间的地址,如果是整形、浮点型会有多份拷贝,但这些数写在指令中。占的只是代码段而已,大量用宏会导致二进制文件变大
变量:共享一块内存空间,就算项目中N处用到,也不会分配N块内存空间,可以被修改,在编译阶段会执行类型检查
常量:共享一块内存空间,就算项目中N处用到,也不会分配N块内存空间,可以根据const修饰的位置设定能否修改,在编译阶段会执行类型检查
Constants should be declared as
static
constants and not#define
s unless explicitly being used as a macro.
static
修饰局部变量:延长局部变量的生命周期,程序结束才会销毁;局部变量只会生成一份内存,只会初始化一次
修饰全局变量:只能在本文件中访问,修改全局变量的作用域,生命周期不会改,避免重复定义全局变量
在模块内的 static 全局变量可以被模块内所用函数访问,但不能被模块外其它函数访问
在模块内的 static 函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明 它的模块内
在类中的 static 成员变量属于整个类所拥有,对类的所有对象只有一份拷贝
在类中的 static 成员函数属于整个类所拥有,这个函数不接收 this 指针,因而只能访问类的static 成员变量
extern
作用: 只是用来获取全局变量(包括全局静态变量)的值,不能用于定义变量
工作原理: 先在当前文件查找有没有全局变量,没有找到,才会去其他文件查找。
联合使用
static与const作用:声明一个只读的静态变量;
开发使用场景:在一个文件中经常使用的字符串常量,可以使用static与const组合开发中使用场景:在多个文件中经常使用的同一个字符串常量,可以使用extern与const组合。
static与const组合:在每个文件都需要定义一份静态全局变量。
extern与const组合:只需要定义一份全局变量,多个文件共享。
const define static extern的更多相关文章
- const define static extern 关键词详解
const const关键词并不能把一个变量变成一个常量, 在符号前加上const表示这个符号不能被赋值, 即他的值对这个符号来说是只读的, 但并不代表这个值不能用其他方法去改变. 通过下面的例子就能 ...
- C语言关键字—-sizeof 、typedef、const、static、register、extern、#define
关键字:sizeof .#define.typedef.const.static.register.extern sizeof 1. 作用:求数据所占得内存空间大小 2. 本质:求数据得类型所占的内存 ...
- const,static,extern 简介
const,static,extern 简介 一.const与宏的区别: const简介:之前常用的字符串常量,一般是抽成宏,但是苹果不推荐我们抽成宏,推荐我们使用const常量. 执行时刻:宏是预编 ...
- 李洪强iOS经典面试题155 - const,static,extern详解(面试必备)
李洪强iOS经典面试题155 - const,static,extern详解(面试必备) 一.const与宏的区别(面试题): const简介:之前常用的字符串常量,一般是抽成宏,但是苹果不推荐我们抽 ...
- iOS正确使用const,static,extern
static 修饰局部变量 让局部变量只初始化一次 局部变量在程序中只有一份内存 并不会改变局部变量的作用域,仅仅是改变了局部变量的生命周期(只到程序结束,这个局部变量才会销毁) 修饰全局变量 全局变 ...
- 如何正确使用const、static、extern
转自:http://www.jianshu.com/p/2fd58ed2cf55 前言 本篇文章主要介绍在开发中怎么使用const.static.extern关键字. 一.const 与宏的区别: c ...
- const、static和extern的正确使用方式
我们在看一些大牛的第三方时,里面会出现很多const.static和extern,尤其是const和static,const和extern的结合使用,直接令很多小伙伴懵逼了,今天就详细讲解一下这三个关 ...
- 《OOC》笔记(1)——C语言const、static和extern的用法
<OOC>笔记(1)——C语言const.static和extern的用法 C语言中const关键字用法不少,我只喜欢两种用法.一是用于修饰函数形参,二是用于修饰全局变量和局部变量. 用c ...
- iOS 中 const static extern 关键字总结
在看一些高手所写的代码时,总是可以看到我们小白平常不用的关键字,一次,两次,三次,不能总是不明不白,现在总结一下日常开发中常用的关键字的作用: 关键字const/static/extern的释义和用法 ...
随机推荐
- cf1172E Nauuo and ODT(LCT)
首先可以转化问题,变为对每种颜色分别考虑不含该颜色的简单路径条数.然后把不是当前颜色的点视为白色,是当前颜色的点视为黑色,显然路径数量是每个白色连通块大小的平方和,然后题目变为:黑白两色的树,单点翻转 ...
- 获取文件MD5值(JS、JAVA)
文章HTML代码翻译于地址:https://www.cnblogs.com/linyihai/p/7040786.html 文件MD5有啥用? 文 ...
- drf中的jwt使用与手动签发token、校验用户
jwt认证 1)session存储token,需要数据库参与,耗服务器资源.低效2)缓存存token,需要缓存参与,高效,不易集群3)客户端存token,服务器存签发与交易token的算法,高效,易集 ...
- Python这五个坑,80%你不知道(对的,五个你知道1个就达到一般水平了)
1 含单个元素的元组 Python中有些函数的参数类型为元组,其内有1个元素,这样创建是错误的: c = (5) # NO! 它实际创建一个整型元素5,必须要在元素后加一个逗号: ! c = (5,) ...
- java 计算函数运行时间
long start,end; start = System.currentTimeMillis(); for (int i = 0; i < 2000000000; i++) {} end = ...
- CodeForces 993A Two Squares(数学 几何)
https://codeforces.com/problemset/problem/993/A 题意: 给你两个矩形,第一行是一个正面表示的矩形,第二个是一个旋转四十五度角的矩形,问这两个矩形是否相交 ...
- [LC] 451. Sort Characters By Frequency
Given a string, sort it in decreasing order based on the frequency of characters. Example 1: Input: ...
- bootstrap 学习 ---css样式学习
bootstrap 适用于响应式布局,移动设备优先的web项目 1.学习bootstrap需要引入bootstrap的css,jquery,bootstrap的js,注意:jquery文件必须在boo ...
- 如何查看Linux系统下程序运行时使用的库?
Linux系统下程序运行会实时的用到相关动态库,某些场景下,比如需要裁剪不必要的动态库时,就需要查看哪些动态库被用到了. 以运行VLC为例. VLC开始运行后,首先查看vlc的PID,比如这次查到的V ...
- 管理Exchange Online用户介绍(一)
一.管理收件人 1.在“Office 365管理中心”主页,依次选择用户->添加用户 2.输入相关信息,其中包括名称.用户名.电子邮件地址等信息. 二.Exchange Online对用户邮箱的 ...