在程序运行过程中,其值不能被改变的量成为常量。

下面是符号常量的例子:

1 #include <stdio.h>
2 #define  PRICE 30   //符号常量
3 void main()
4 {
5     int num,total;
6     num = 10;
7     total = num * PRICE;
8     printf("total= %d\n",total);
9 }

同样的,我们汇编代码瞅瞅

 1 00401010 >|> \55            push    ebp
 2 00401011  |.  8BEC          mov     ebp, esp
 3 00401013  |.  83EC 48       sub     esp, 48
 4 00401016  |.  53            push    ebx
 5 00401017  |.  56            push    esi
 6 00401018  |.  57            push    edi
 7 00401019  |.  8D7D B8       lea     edi, dword ptr [ebp-48]
 8 0040101C  |.  B9 12000000   mov     ecx, 12
 9 00401021  |.  B8 CCCCCCCC   mov     eax, CCCCCCCC
10 00401026  |.  F3:AB         rep     stos dword ptr es:[edi]
11 00401028  |.  C745 FC 0A000>mov     dword ptr [ebp-4], 0A            ;  num=10
12 0040102F  |.  8B45 FC       mov     eax, dword ptr [ebp-4]
13 00401032  |.  6BC0 1E       imul    eax, eax, 1E                     ;  price=0x1e
14 00401035  |.  8945 F8       mov     dword ptr [ebp-8], eax
15 00401038  |.  8B4D F8       mov     ecx, dword ptr [ebp-8]
16 0040103B  |.  51            push    ecx                              ; /<%d>
17 0040103C  |.  68 1C204200   push    0042201C                         ; |format = "total= %d",LF,""
18 00401041  |.  E8 2A000000   call    printf                           ; \printf
19 00401046  |.  83C4 08       add     esp, 8
20 00401049  |.  5F            pop     edi
21 0040104A  |.  5E            pop     esi
22 0040104B  |.  5B            pop     ebx
23 0040104C  |.  83C4 48       add     esp, 48
24 0040104F  |.  3BEC          cmp     ebp, esp
25 00401051  |.  E8 9A000000   call    _chkesp
26 00401056  |.  8BE5          mov     esp, ebp
27 00401058  |.  5D            pop     ebp
28 00401059  \.  C3            retn

我们用IDA来看看,这个PRICE在哪里?

 1 int __cdecl main()
 2 {
 3   char v1; // [sp+Ch] [bp-48h]@1
 4   int v2; // [sp+4Ch] [bp-8h]@1
 5   int v3; // [sp+50h] [bp-4h]@1
 6
 7   memset(&v1, 0xCCCCCCCCu, 0x48u);
 8   v3 = 10;
 9   v2 = 300;
10   printf("total= %d\n", 300);
11   return _chkesp();
12 }

我修改为

 1 int __cdecl main()
 2 {
 3   char v1; // [sp+Ch] [bp-48h]@1
 4   int total; // [sp+4Ch] [bp-8h]@1
 5   int num; // [sp+50h] [bp-4h]@1
 6
 7   memset(&v1, 0xCCCCCCCCu, 0x48u);
 8   num = 10;
 9   total = 300;
10   printf("total= %d\n", 300);
11   return _chkesp();
12 }

发现计算的过程没有了。还是看汇编代码吧:

 1 main proc near
 2
 3 var_48= byte ptr -48h
 4 total= dword ptr -8
 5 num= dword ptr -4
 6
 7 push    ebp
 8 mov     ebp, esp
 9 sub     esp, 48h
10 push    ebx
11 push    esi
12 push    edi
13 lea     edi, [ebp+var_48]
14 mov     ecx, 12h
15 mov     eax, 0CCCCCCCCh
16 rep stosd
17 mov     [ebp+num], 0Ah
18 mov     eax, [ebp+num]
19 imul    eax, 30
20 mov     [ebp+total], eax
21 mov     ecx, [ebp+total]
22 push    ecx
23 push    offset aTotalD  ; "total= %d\n"
24 call    printf
25 add     esp, 8
26 pop     edi
27 pop     esi
28 pop     ebx
29 add     esp, 48h
30 cmp     ebp, esp
31 call    __chkesp
32 mov     esp, ebp
33 pop     ebp
34 retn
35 main endp

我们再看看Release版的有什么变化-----主函数

1 00401000  /$  68 2C010000   push    12C
2 00401005  |.  68 30704000   push    00407030                         ;  ASCII "total= %d",LF
3 0040100A  |.  E8 11000000   call    00401020
4 0040100F  |.  83C4 08       add     esp, 8
5 00401012  \.  C3            retn

我们没有发现计算的过程,视乎在编译的过程中就完成了计算。

我们用IDA来看看

1 ; int __cdecl main(int argc, const char **argv, const char **envp)
2 _main proc near
3 push    12Ch
4 push    offset Format   ; "total= %d\n"
5 call    _printf
6 add     esp, 8
7 retn
8 _main endp

果然是这样。

工程下载地址:http://files.cnblogs.com/tk091/rl005.7z

重学C---------第五节:常量相关推荐

  1. mysql支持的并发数_重学MySQL系列(五):谈谈对MySQL的存储引擎的理解

    原创作者,公众号[程序员读书],欢迎关注公众号,转载文章请注明出处哦. MySQL关于存储引擎的架构设计,相较于其他关系数据库管理系统,比如Oracle,SQL Server等数据库,这是MySQL最 ...

  2. 五节课从零起步(无需数学和Python基础)编码实现AI人工智能框架电子书V1

    五节课从零起步  (无需数学和Python 基础)  编码实现AI 人工智能框架          王  家  林        2018/4/15                          ...

  3. 五年级计算机教案及反思,2014-2015学年度下册五年级信息技术教案(有教学反思).doc...

    2014-2015学年度下册五年级信息技术教案(有教学反思) 课题扫描识别快又准备课 方式□集体 √个人课时分配1课时问题收集与学情分析学生对计算机很熟悉,但对计算机的某些功能并不了解. 学生很少见过 ...

  4. 讲透学烂二叉树(五):分支平衡—AVL树与红黑树伸展树自平衡

    简叙二叉树 二叉树的最大优点的就是查找效率高,在二叉排序树中查找一个结点的平均时间复杂度是O(log₂N): 在<讲透学烂二叉树(二):树与二叉/搜索/平衡等树的概念与特征>提到 二叉排序 ...

  5. 重学Java(四):操作符

    之前我写了一篇<重学Java(四):对象.引用.堆.栈.堆栈>,本以为凭借自己8年的Java编程经验足够把这些"吃人"的Java名词解释清楚了,但有网友不以为然,在文章 ...

  6. 重学网络系列之(Ping与网关)

    前言 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/bin392328206/six-finger 种一棵树最好的时间是十年前,其次是现在 叨絮 网关,路由,其 ...

  7. 【java】兴唐课程第五节到第九节知识点总结

    第九节 1. 代码:void readBook(String- bookNames) 表示不确定参数的个数,此时变量为一个数组. 2.当方法中的参数名称(如stuname)和属性名称相同时. this ...

  8. 重学JavaScript深入理解系列(一)

    JavaScript深入理解--执行上下文(Execution Context) 定义 每当控制器到达ECMAScript可执行代码的时候,控制器就进入了一个执行上下文. 执行上下文(简称:EC) 以 ...

  9. Simulink仿真 第五节 复用器和分路器

    第五节 复用器和分路器 1.复用器(将多个输入信号合并为矢量) Mux 模块可将其输入合并为单个矢量输出.输入可以是标量或矢量信号.所有输入都必须具有相同的数据类型和数值类型.矢量输出信号元素采用输入 ...

  10. 移动重定位表到新增节

    一.为什么要移动重定位表 数据目录中的表是分散在各个节里的,如果对节进行加密,操作系统找不到表,就无法加载程序.因此加密前要先把表移动到新的节里. 二.怎么移动 计算重定位表的大小,首先要遍历重定位表 ...

最新文章

  1. C++中的友元函数friend
  2. RDKit | 基于RDKit绘制带原子和键的索引、注释和立体化学
  3. mysql批量导入 导出数据_MySQL批量导入导出数据
  4. JSP、EL和JSTL-学习笔记01【JSP基础语法】
  5. Spring+Hibernate+c3p0连接池配置-连接无法释放的问题解决方案
  6. Java程序员如何做到Java架构师
  7. Python 链接汇总
  8. RS-485中继器的多种使用方法
  9. 有什么推荐的计算机视觉项目?来自微软亚研院的清单
  10. codeforces 776C Molly's Chemicals(连续子序列和为k的次方的个数)
  11. hadoop开启后jps只有jps一个进程
  12. POJ 1094 Sorting It All Out 【拓扑排序】
  13. 新闻发布系统,我学会了什么?
  14. GIS + 现代农业”,将会擦出怎样的火花?——智慧农业专题论坛侧记
  15. fixed在ios失效解决方案
  16. 21天 mysql_java基础第21天_mysql
  17. 技术文档的写作规范总结
  18. AIX root用户密码遗忘的处理
  19. springcloudAlibaba设置allow-bean-definition-overriding=true不生效问题解决
  20. 假设有一个池塘,里面有无穷多的水。现有2个空水壶,容积分别为5升和7升。问题是如何只用这2个水壶从池塘里取得6升的水?

热门文章

  1. 计算机网络基础知识 帮助学习网络管理的初学者快速了解网络管理的初步结构知识...
  2. docker machine介绍和使用
  3. vue 监听state 任意值变化、监听mutations actions
  4. angular—— Dynamic Templates
  5. 树莓派 4G模块 PPP 拨号 NDIS 拨号
  6. Linux的nfs文件服务
  7. 微软签署最大规模风电购买协议 打造“无碳”数据中心
  8. Linux脚本(1)__批量下载
  9. ASP.NET母版页和内容页之间如何互相传值?
  10. ACM算法书籍推荐zz