关于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. 1.       使用了extern

extern const int N=3;

因为使用了extern我们将可能在外部文件使用N,而const默认的是内部链接,所以我们必须要为之分配内存的。

  1. 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;

}

  1. 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的内存分配问题的总结的更多相关文章

  1. 面试问题5:const 与 define 宏定义之间的区别

    问题描述:const 与 define 宏定义之间的区别 (1) 编译器处理方式不同     define宏是在预处理阶段展开:     const常量是编译运行阶段使用: (2) 类型和安全检查不同 ...

  2. const和#define 区别

    1: 编译器处理不同     define宏是在预处理阶段展开,const常量是编译运行阶段使用. 2:类型和安全检查不同 const常量有数据类型,而宏常量没有数据类型,仅仅是展开.编译器可以对前者 ...

  3. iOS—— static和const联合使用;使用static const 与 #define

    static和const联合使用:   static将一个全局变量变成局部变量   const将一个局部变量变成局部常量 // 定义了一个局部常量      static const CGFloat ...

  4. C++编程中const和#define的区别

    (1) 编译器处理方式不同 define宏是在预处理阶段展开. const常量是编译运行阶段使用.(2) 类型和安全检查不同 define宏没有类型,不做任何类型检查,仅仅是展开. const常量有具 ...

  5. const和#define常量的区别

    (1) 编译器处理方式不同 define宏是在预处理阶段展开. const常量是编译运行阶段使用. (2) 类型和安全检查不同 define宏没有类型,不做任何类型检查,仅仅是展开. const常量有 ...

  6. 【编程基础】const与#define的区别

    [前言] 相信大家看别人代码的时候都遇到过,有人用#define定义,也有人用const定义. 那么两者的区别到底是什么呢?哪个更好用呢? 网上查了又查,下面总结一下. [总结] 编译器处理方式不同 ...

  7. 函数定义从零开始学C++之从C到C++(一):const与#define、结构体对齐、函数重载name mangling、new/delete 等

    今天一直在学习函数定义之类的问题,下午正好有机会和大家共享一下. 一.bool 类型 逻辑型也称布尔型,其取值为true(逻辑真)和false(逻辑假),存储字节数在不同编译系统中可能有所不同,VC+ ...

  8. const和#define的区别

    在刷题的时候经常遇到定义全局常量我一般都是用#define(可能是因为很少接触const的原因) 在昨天做到51nod1082时照常暴力用#define定义最大.可是提交超时..... 后来看他人写的 ...

  9. 15分钟弄懂 const 和 #define

    什么是const ? 什么是#define? 他们有什么用? 他们有什么区别? 应该怎么用? 总结 1. 什么是const ? const是C/C++中的一个关键字(修饰符), const一般用来定义 ...

随机推荐

  1. spring框架面试相关问题

    Spring 框架中核心组件有三个:Core.Context 和 Beans.其中最核心的组件就是Beans, Spring提供的最核心的功能就是Bean Factory. Spring 解决了的最核 ...

  2. java攻城狮之路(Android篇)--BroadcastReceiver&Service

    四大组件:activity 显示. contentProvider 对外暴露自己的数据给其他的应用程序.BroadcastReceiver 广播接收者,必须指定要接收的广播类型.必须明确的指定acti ...

  3. SEO优化之Title 和 Meta 标签

    对搜索引擎最友好(Search Engine Friendly)的网页是静态网页,但大部分内容丰富或互动型网站都不可避免采用到相关技术语言来实现内容管理和交互功能.SEO 思想指导下的技术支持,主要是 ...

  4. CentOS下Redis服务器安装配置

    说明: 操作系统:CentOS 1.安装编译工具 yum install wget  make gcc gcc-c++ zlib-devel openssl openssl-devel pcre-de ...

  5. 认识SuperSocket 1.6.4

    SuperSocket 是一个轻量级的可扩展的 Socket 开发框架,由江振宇先生开发,之所以选用它是因为一下几点恰好复合项目需求: 开源,基于Apache 2.0协议,可以免费使用到商业项目. 高 ...

  6. POJ 3345 Bribing FIPA 树形DP

    题目链接: POJ 3345 Bribing FIPA 题意: 一个国家要参加一个国际组织,  需要n个国家投票,  n个国家中有控制和被控制的关系, 形成了一颗树. 比如: 国家C被国家B控制, 国 ...

  7. Android性能优化之运算篇

    下面是运算篇章的学习笔记,部分内容与前面的性能优化典范有重合,欢迎大家一起学习交流! 1)Intro to Compute and Memory Problems Android中的Java代码会需要 ...

  8. Nginx: could not build the server_names_hash 解决办法

    # /etc/init.d/nginx reload * Reloading nginx configuration nginx [fail] # nginx -t nginx: [emerg] co ...

  9. 妹味6:ajax与ajax封装

    (功能)ajax能且仅能 从服务器读取文件 (环境)需要服务器环境才能测试,可以用工具建立本地服务器环境 (缓存)解决缓存问题:url加时间戳让每次请求地址唯一,如 url='abc.txt?t='+ ...

  10. 3D拓扑自动布局之Web Workers篇

    2D拓扑的应用在电信网管和电力SCADA领域早已习以为常了,随着OpenGL特别是WebGL技术的普及,3D方式的数据可视化也慢慢从佛殿神堂步入了寻常百姓家,似乎和最近高档会所被整改为普通茶馆是一样的 ...