关于const和define的内存分配问题的总结
关于const和define的内存分配问题
const与#define宏定义的区别----C语言深度剖析
1, const定义的只读变量在程序运行过程中只有一份拷贝(因为它是全局的只读变量,存放在静态区),而#define定义的宏常量在内存中有若干个拷贝。
2, #define宏是在预编译阶段进行替换,而const修饰的只读变量是在编译的时候确定其值。
3, #define宏没有类型,而const修饰的只读变量具有特定的类型。
总结:const节省了空间,避免了不必要的内存分配,同时提高了效率。编译器通常不为普通的const只读变量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的值,没有了存储与读内存的操作,使得它的效率也很高。C++中是不太推荐用宏的,尽量少用.因为C++是强类型的语言,希望通过类型检查来降低程序中的很多错误,而宏只是在编译期前做简单替换,绕过了类型检查,失去了强类型系统的优势支撑。
例如:
#define M 3 //宏常量
const int N=5; // 此时并未将N放入内存中
..............
int i=N; //此时为N分配内存,以后不再分配!
int I=M; //预编译期间进行宏替换,分配内存
int j=N; //没有内存分配
int J=M; //再进行宏替换,又一次分配内存!
原因:const定义的只读变量从汇编的角度来看,只是给出了对应的内存地址,而不是像#define一样给出的是立即数,所以const定义的只读变量在程序运行过程中只有一份拷贝。
在c++我们知道一般是采用const来进行替代#define的。
例如:
const int N=3;//注意采用的是赋值的形式并且末尾有分号
#define N 3
特殊情况
在C中我们知道#define进行预定义的某个数是被分配内存的,其文件在编译预处理过程中就会用定义好的数据去替代文中的符号。
但是const却是不一样的,一般情况下编译器也是不为const创建空间的,只是将这个定义的数字保存在符号表中的。但是在下列几种情况下编译器会为const定义的常量分配内存的。
- 1. 使用了extern头
extern const int N=3;
因为使用了extern我们将可能在外部文件使用N,而const默认的是内部链接,所以我们必须要为之分配内存的。
- 2. 取地址操作
#include<iostream>
using namespace std;
const int M=3;
int main()
{
const int *p=&M;
//当编译器发现有对const定义的常量进行取地址操作时候会对M进行内存分配,
//注意这个地址是const int*类型的,地址中的内容不可以改变的
int *pp=(int*)(&M)
//此处我们将const int*类型强制转化成int * 但是对于*pp的任何赋值操作还是会报错的,
//因为本质上的M是常量不可改变的,这也是const的优点
cout<<*p<<endl;
return 0;
}
- 3. const定义的常量未知的时候,这是#define无法实现的。
#include<iostream>
using namespace std;
int main()
{
const int b=cin.get();//此处const定义的b是未知的所以要为它分配内存,但是一旦分配就不可以改变的。
//但是如果读者此处想在利用未知的const常量来定义数组还是会报错的。
//即int array[b]是不行的,因为编译器在从上往下走的时候是要确定数组的大小的
//但是采用new操作就不会报错的int *array=new int(b);
cout<<b<<endl;
return 0;
}
关于const和define的内存分配问题的总结的更多相关文章
- 面试问题5:const 与 define 宏定义之间的区别
问题描述:const 与 define 宏定义之间的区别 (1) 编译器处理方式不同 define宏是在预处理阶段展开: const常量是编译运行阶段使用: (2) 类型和安全检查不同 ...
- const和#define 区别
1: 编译器处理不同 define宏是在预处理阶段展开,const常量是编译运行阶段使用. 2:类型和安全检查不同 const常量有数据类型,而宏常量没有数据类型,仅仅是展开.编译器可以对前者 ...
- iOS—— static和const联合使用;使用static const 与 #define
static和const联合使用: static将一个全局变量变成局部变量 const将一个局部变量变成局部常量 // 定义了一个局部常量 static const CGFloat ...
- C++编程中const和#define的区别
(1) 编译器处理方式不同 define宏是在预处理阶段展开. const常量是编译运行阶段使用.(2) 类型和安全检查不同 define宏没有类型,不做任何类型检查,仅仅是展开. const常量有具 ...
- const和#define常量的区别
(1) 编译器处理方式不同 define宏是在预处理阶段展开. const常量是编译运行阶段使用. (2) 类型和安全检查不同 define宏没有类型,不做任何类型检查,仅仅是展开. const常量有 ...
- 【编程基础】const与#define的区别
[前言] 相信大家看别人代码的时候都遇到过,有人用#define定义,也有人用const定义. 那么两者的区别到底是什么呢?哪个更好用呢? 网上查了又查,下面总结一下. [总结] 编译器处理方式不同 ...
- 函数定义从零开始学C++之从C到C++(一):const与#define、结构体对齐、函数重载name mangling、new/delete 等
今天一直在学习函数定义之类的问题,下午正好有机会和大家共享一下. 一.bool 类型 逻辑型也称布尔型,其取值为true(逻辑真)和false(逻辑假),存储字节数在不同编译系统中可能有所不同,VC+ ...
- const和#define的区别
在刷题的时候经常遇到定义全局常量我一般都是用#define(可能是因为很少接触const的原因) 在昨天做到51nod1082时照常暴力用#define定义最大.可是提交超时..... 后来看他人写的 ...
- 15分钟弄懂 const 和 #define
什么是const ? 什么是#define? 他们有什么用? 他们有什么区别? 应该怎么用? 总结 1. 什么是const ? const是C/C++中的一个关键字(修饰符), const一般用来定义 ...
随机推荐
- WCF 遇到的问题
1.只有项目的net版本2.0以上的才可以引用到wcf的类库 2.HTTP 错误 404.17 - Not Found 映射问题 WCF服务建立好,提示这个错误,缺少映射问题,要将应用程序池和项 ...
- SPI总线通信电路设计
数据带宽=(总线频率×数据位宽)÷8 B表示带宽,F表示存储器时钟频率,D表示存储器数据总线位数,则带宽为: B(峰值带宽)=F(时钟频率MHz)×D(总线位数bit)/8 例如,PC-100的SDR ...
- 2014 网选 5024 Wang Xifeng's Little Plot
题意:从任意一个任意一个可走的点开始找一个最长的路,这条路如果有转弯的话, 那么必须是 90度,或者没有转弯! 思路: 首先用dfs将所有可走点开始的 8 个方向上的线段的最长长度求出来 ! step ...
- [Tango] Basic Knowledge
Project Tango类设备能够给开发者在哪些领域带来机会. 室内导航*:室内GPS信号的缺失,使得Project Tango设备会成为室内导航重要应用场景之一.有了它,你就不会在不熟悉的室内商场 ...
- 【干货分享】Google 的设计准则,素材和资源
在谷歌,他们说, “专注于用户,所有其它的就会水到渠成 ”.他们遵循设计原则,寻求建立让用户惊喜的用户体验.谷歌一直挑战自己,为他们的用户创造一种视觉语言,综合优秀设计的经典原则和创新.谷歌设计规范是 ...
- Java对象的复制
Java中对象的赋值分为浅拷贝和深拷贝 1.对象浅拷贝 public class CloneTest{ static class Emp{ String name; int age; Date h ...
- Redis设计与实现-附加功能
发布与订阅 redis订阅分为精准的频道订阅与模糊匹配的模式订阅: redis将所有频道的订阅关系都保存在服务器状态pubsub_channels字典里,键是频道名,值是一个记录所有订阅此频道的客户端 ...
- BZOJ1015 并查集
1015: [JSOI2008]星球大战star war Description 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系.某一天,凭着一个偶然的机遇,一支反抗军摧毁了 ...
- Mysql数据库安全管理配置
1.删除test库 原因: The default MySQL installation comes with a database named test that anyone can access ...
- 登陆mysql时提示异常的解决方法
[root@host2 ~]# mysql -uroot -p Enter password: ERROR (HY000): Can't connect to local MySQL server t ...