C/C++中define定义的常量与const常量
常量是在程序中不能更改的量,在C/C++中有两种方式定义常量,一种是利用define宏定义的方式,一种是C++中新提出来的const型常变量,下面主要讨论它们之间的相关问题;
define定义的常量:
define是预处理指令的一种,它用来定义宏,宏只是一个简单的替换,将宏变量所对应的值替换,如下面的代码:
#define NUM 2
int main()
{
printf("%d", NUM);
}
编译器在编译时处理的并不是这样的代码,编译器会首先处理预处理指令,根据预处理指令生成相关的代码文件,然后编译这个文件,得到相关的.obj文件,最后通过链接相关的.obj文件得到一个可执行文件,最典型的是我们一般在.cpp文件中写的#include指令,在处理时首先将所需包含的头文件整个拷贝到这个.cpp文件中,并替换这个#include指令,然后再编译生成的文件,这个中间文件在Windows中后缀为.i,在Visual C++ 6.0中以此点击Project-->Settings-->C/C++,在Project Options最后一行加上'/P'(P为大写)这样在点击编译按钮时不会编译生成obj文件,只会生成.i文件,通过这个.i文件可以看到在做预处理的时候会将 NUM替换成2然后在做编译处理,这个时候点击生成时会出错,因为我们将编译选项修改后没有生成.obj文件但是在生成时需要这个文件,因此会报错,所以在生成时要去掉这个/P选项。而我们看到在使用const 定义的时候并没有这个替换的操作,与使用正常的变量无异。const型变量只是在语法层面上限定这个变量的值不可以修改,我们可以通过强制类型转化或者通过内嵌汇编的形式修改这个变量的值,比如下面的代码:
int main(int argc, char* argv[])
{
const nNum = ;
int *pNum = (int*)&nNum;
printf("%d\n", nNum);
return ;
}
const nNum = ;
__asm
{
mov [ebp - ],
}
printf("%d\n", nNum);
return ;
但是我们看到,这两种方式修改后,输出的值仍然是10,这个原因我们可以通过查看反汇编代码查看
;printf("%d\n", nNum);
push 0Ah
push offset string "%d\n" (0042001c)
0040103D call printf ()
add esp,
在调用printf的时候,入栈的参数是10,根本没有取nNum值得相关操作,在利用const定义的常量时,编译器认为既然这是一个常量,应该不会修改,为了提升效率,在使用时并不会去对应的内存中寻址,而是直接将它替换为初始化时的值,为了防止这种事情的发生,可以利用C++中的关键字:volatile。这个关键字保证每次在使用变量时都去内存中读取。
我们可以总结出const和define的几个不同之处:
1)define是一个预处理指令,const是一个关键字。
2)define定义的常量编译器不会进行任何检查,const定义的常量编译器会进行类型检查,相对来说比define更安全
3)define的宏在使用时是替换不占内存,而const则是一个变量,占内存空间
4)define定义的宏在代码段中不可寻址,const定义的常量是可以寻址的,在数据段或者栈段中。
5)define定义的宏在编译前的预处理操作时进行替换,而const定义变量是在编译时决定
6)define定义的宏是真实的常量,不会被修改,const定义的实际上是一个变量,可以通过相关的手段进行修改。
C/C++中define定义的常量与const常量的更多相关文章
- Vue 中如何定义全局的变量和常量
Vue 中如何定义全局的变量和常量 我想要定义一个变量, 在项目的任何地方都可以访问到, 不需要每一次使用的时候, 都引入. 尝试1:创建 global.js 并且在其中定义 let a = 10 ...
- #define宏常量和const常量的区别
C++ 语言可以用const 来定义常量,也可以用#define 来定义常量.但是前者比后者有更多的优点:(1) const 常量有数据类型,而宏常量没有数据类型.编译器可以对前者进行类型安全检查.而 ...
- 字符串常量与const常量内存区(——选自陈皓的博客)
1. 一个常见的考点: char* p = "test"; 那么理利用指针p来改变字符串test的内容都是错误的非法的. 例如: p[0] = 's'; strcpy(p, &qu ...
- 在php中定义常量时,const与define的区别?
问]在php中定义常量时,const与define的区别? [答]使用const使得代码简单易读,const本身就是一个语言结构,而define是一个函数.另外const在编译时要比define快很 ...
- PHP 中 define() 和 const 定义常量时的区别
自 PHP 5.3.0 起,有两种方式定义常量,使用 const 关键字或者 define() 函数: 1 2 const FOO = 'BAR'; define('FOO', 'BAR'); 这 ...
- PHP中const和define()定义常量的细节区别
转自:http://www.365mini.com/page/difference-of-define-and-const.htm 众所周知,在PHP中(php 4及以后),我们可以使用函数defin ...
- PHP中define()和const定义常量的区别
在PHP中可以通过define()和const两种方式定义常量可是在开发中我们应该什么时候用define()定义常量,什么时候用const定义常量? 这两种方式定义常量的主要区别是什么? 从5.3版本 ...
- 宏定义(#define)和常量(const)的区别
最近开始准备一边做实验室的研究,一边记录一些遇到的编程中的小知识点.今天在测试对矩阵进行SVD分解时,需要定义矩阵的行和列的大小,我习惯性的用宏定义来定义了这两个变量,在运行的时候,就开始思考宏定义和 ...
- const define 定义常量的区别
1.用const定义常量在编译的时候,提供了类型安全检查,而define 只是简单地进行字符串的替换 2.const定义的常量,会分配相应的内存空间.而define没有分配空间,只是在程序中与处理的时 ...
随机推荐
- 链方法[C# 基础知识系列]专题三:如何用委托包装多个方法——委托链
最近研究链方法,稍微总结一下,以后继续补充: 弁言: 上一专题分析了下编译器是如何来翻译委托的,从中间语言的角度去看委托,希望可以帮助大家进一步的理解委托,然而之前的分析都是委托只是封装一个方法,那委 ...
- 给你的git仓库瘦身
很久没有写博客了,最近遇到了一个git问题,比较典型,记录下来与大家分享. 我们使用git版本控制的时候享受了很多便利,不管是代码合并,分支提供给我们的并发,但我们也往往忽略了每次提交之后在我们本地项 ...
- [ios2]蓝牙通信【转】
iPhone开发应用中关于GameKit蓝牙实例讲解是本文要介绍的内容,主要是来了解并学习GameKit蓝牙实例.介绍一下这个实例实现的是两个带有蓝牙设备的touch之间的一个小游戏,在界面上有个可以 ...
- TortoiseSVN历史版本安装及svn服务器搭建
一.TortoiseSVN安装 1.TortoiseSVN下载 网址如下:https://tortoisesvn.net/downloads.html 进入客户端下载页面,根据你的电脑选择是64位 ...
- openresty 前端开发轻量级MVC框架封装一(控制器篇)
通过前面几章,我们已经掌握了一些基本的开发知识,但是代码结构比较简单,缺乏统一的标准,模块化,也缺乏统一的异常处理,这一章我们主要来学习如何封装一个轻量级的MVC框架,规范以及简化开发,并且提供类似p ...
- ASP.NET Zero--6.菜单加权限
1.打开文件MpaNavigationProvider.cs [..\MyCompanyName.AbpZeroTemplate.Web\Areas\Mpa\Startup\MpaNavigation ...
- nodejs,http,get,post,请求
本文源于实践及其部分网络搜索: 其实大部分,官方都有介绍... 官方参考链接:https://nodejs.org/api/http.html var http = require('http'); ...
- linux面试题集锦《转》
1. 下面的网络协议中,面向连接的的协议是: A . A 传输控制协议 B 用户数据报协议 C 网际协议 D 网际控制报文协议 2. 在/etc/fstab文件中指定的文件系统加载参数中, D 参数一 ...
- scrapy在ubuntu上安装总结
此文档是本人学习时使用的,采用一个实例作为引导进行安装测试. 实例下载地址如下: https://github.com/sans-serif/scrapy-german-news#introducti ...
- Python map多线程
import os import PIL from multiprocessing import Pool from PIL import Image SIZE = (75,75) SAVE_DIRE ...