作为C90增加的一个受限类型关键字,const赋予了它修饰的变量一个新属性——不变性,如果一个变量声明中带有关键字const,则无法通过赋值、增减运算来修改该变量的值。

一、指针与const结合

const与指针的结合较为复杂,因为我们需要把'让指针本身成为const'和'让指针指向的值成为const'区分开来。

1.1 int const *p

该声明表明我们声明了一个指针p,const在*左边,代表整个'*p'为不可修改的,也即p指向的值不可变。

  1. int a = 2;  
  2. int b = 10;  
  3.     
  4. const int *p = &a;  
  5.     
  6. printf("%x %d\n",p,*p);  
  7. *p = 4;  
  8. printf("%x %d\n",p,*p);  

尝试修改指针p指向的值,编译后报错:[Error] assignment of read-only location '*p',p指向的位置为只读。

修改一下a的值,看运行结果。

没有报错,a的值被成功修改。

再试一下,修改p的值:

  1.     int a = 2;  
  2.     int b = 10;  
  3.         
  4.     const int *p = &a;  
  5.     
  6.     printf("%x %d\n",p,*p);  
  7. //  *p = 4;     //[Error] assignment of read-only location '*p'   
  8.     p = &b;   
  9.     printf("%x %d\n",p,*p);  

运行成功,由结果能看出,const的只读限制只对*p起作用,而p、p指向的对象的操作(a)都可读可写。

再看一个,将有const的指针赋值给没有const的指针:

  1. int a = 2;  
  2. int b = 10;  
  3.     
  4. const int *p = &a;  
  5.     
  6. printf("%x %d\n",p,*p);  
  7. int *p1 = &a;  
  8. printf("%x %d\n",p1,*p1);  
  9. p1 = p;  

被const修饰的p与没有被修饰的p1值相同,指向位置的值也相同。不过在第九行'p1 = p;',弹出警告,继续运行:[Warning] assignment discards 'const' qualifier from pointer target type

1.2 int * const p

const在*右边,代表指针p不可修改,也即p总是指向同一个地址。

先修改个地址试一试。

  1. int a = 2;  
  2. int b = 10;  
  3.     
  4. int * const p2 = &a;   
  5. printf("%x %d\n",p2,*p2);  
  6. p2 = &b;      

第六行报错:[Error] assignment of read-only variable 'p2',p2为只读变量。

再折腾折腾,直接修改它指向的值,引用对象的值试试。

p2指向的地址都没变,只要不修改地址,其余的操作都可行。

1.3 const int * const p

第一个const表示p指向的值不可变,第二个const表示p本身不可变。也即p必须指向同一个位置,且所指位置存储的值也不可改变。

  1.     int a = 2;  
  2.     int b = 10;  
  3.         
  4.     const int * const p3 = &a;  
  5.     printf("%x %d\n",p3,*p3);  
  6.         
  7.     a = 3;  
  8.     printf("%x %d\n",p3,*p3);  
  9.         
  10. //[Error] assignment of read-only variable '*p3'  
  11. //  p3 = &b;  
  12.     printf("%x %d\n",p3,*p3);  
  13.         
  14. //[Error] assignment of read-only location '*p3'  
  15. //  *p3 = 1;      
  16.     printf("%x %d\n",p3,*p3);  

1.4 总结

当const与指针一同出现时,位于*左边的const使得数据成为常量,位于*const右边的const使得指针自身成为常量。更直白点来说就是:修饰谁,谁的内容就不可变,其余的都可变。

二、const与全局变量

由于程序的任何部分都可以修改全局变量的之,因此使用全局变量是一种很冒险的写法。但当我们用上了const后,这个问题就解决了。

2.1 extern

在一个工程中,如果我们在一个.c文件中声明了一个全局常量,在该工程其他文件中,对该全局常量的引用就需要使用关键字'extern'。

  1. /* file1.c---存放有全局常量的文件*/  
  2. const int num = 100;  
  3.     
  4. /* file2.c---需要引用全集常量的文件*/  
  5. extern const int num;  

2.2 include与static

通过将全局声明放入头文件.h中,可以不必再纠结在哪个文件定义了声明、哪个文件引用了声明。不过需要注意的是,在声明时,const前必须加上static关键字,否则每一个引用该.h的文件都会得到该数据的一个副本,从而导致不同文件间的数据交流出问题。

  1. /*constant.h*/  
  2. static const int num = 100;  

使用头文件的缺点在于每一次引用.h都复制了数据,当.h中含有大量的数据时,就会引发新的问题了。

[C语言]类型限定词const解析的更多相关文章

  1. 类型限定词——const

    类型限定词有三个:const  volatile restrict. const:一般也叫常量修饰符. 作用:是修饰变量,被修饰的变量就变成常量了,不能被二次修改了. const int a=12:a ...

  2. java内存分配和String类型的深度解析

    [尊重原创文章出自:http://my.oschina.net/xiaohui249/blog/170013] 摘要 从整体上介绍java内存的概念.构成以及分配机制,在此基础上深度解析java中的S ...

  3. 解剖SQLSERVER 第四篇 OrcaMDF里对dates类型数据的解析(译)

    解剖SQLSERVER 第四篇  OrcaMDF里对dates类型数据的解析(译) http://improve.dk/parsing-dates-in-orcamdf/ 在SQLSERVER里面有几 ...

  4. WCF 已知类型和泛型解析程序 KnownType

    数据协定继承 已知类型和泛型解析程序 Juval Lowy 下载代码示例 自首次发布以来,Windows Communication Foundation (WCF) 开发人员便必须处理数据协定继承方 ...

  5. C#匿名类型和动态解析减少定义传输类模板

    C#作为强类型语言,在序列化和反序列化(json)场景中对字符串解析常常需要定义强类型模板,造成编码上的繁琐.其实可以使用匿名类型和动态解析减少json序列化时候的数据模板定义: string a = ...

  6. 变量和基本类型——复合类型,const限定符,处理类型

    一.复合类型 复合类型是指基于其他类型定义的类型.C++语言有几种复合类型,包括引用和指针. 1.引用 引用并非对象,它只是为一个已存在的对象所起的另外一个名字. 除了以下2种情况,其他所有引用的类型 ...

  7. 【转】java内存分配和String类型的深度解析

    一.引题 在java语言的所有数据类型中,String类型是比较特殊的一种类型,同时也是面试的时候经常被问到的一个知识点,本文结合java内存分配深度分析关于String的许多令人迷惑的问题.下面是本 ...

  8. c语言类型修饰符及内存

    今天来学习一下c语言类型修饰符及内存分布 1.auto int a; 默认在内存 2.register int a; 限制变量定义在寄存器上的修饰符 编译器会尽量安排CPU的寄存器去存放这个a,如果寄 ...

  9. C语言类型(上)

    前提说明 格式说明:以[signed] int 为例 表明该类型的完整表达是 signed int 只不过signed可以省略 所以 int 也代表 signed int 类型 signed和unsi ...

随机推荐

  1. .NET 4中的多线程编程之一:使用Task(转载)

    原文地址:http://www.cnblogs.com/yinzixin/archive/2011/11/04/2235233.html .NET 4为了简化多线程编程,提供了System.Threa ...

  2. 微软DevOps软件开发高级培训课程(深圳站) 2016.04.06

    深圳特区云集了国内众多大型IT企业,作为北上广深的一线城市,当之无愧! 我们在深圳同方信息港的微软办公室是举行培训,60人的培训教室,生生被挤满了80人,过道都被全部占用了.可惜由于换了电脑,把照片搞 ...

  3. 修改jenkins启动的默认用户

    # 背景 通过yum命令安装的jenkins,通过service jenkins去启动jenkins的话,默认的用户是jenkins,但jenkins这个用户是无法通过su切换过去的 ,在某些环节可能 ...

  4. 对Cookie和Session的理解

    本篇文章系自己总结经验,如果有朋友感觉哪里有问题,欢迎留言评论,谢谢~! Cookie和Session的产生背景: 在动态页面里面,每个变量都是有有效期的,所有的变量的最大生命周期就是一个脚本的周期( ...

  5. WPS 多文档独立显示

    打开wps,点击右上角:WPS表格 =>选项=>勾选在任务栏中显示所有窗口

  6. WinForm中的图表控件Chart

    第一次接触Chart控件,发现了这个Chart控件的实例项目,非常强大,用示例的方法介绍了该控件各式各样的用法. 下载链接

  7. 201621123012 《java程序设计》第5周学习总结

    作业05-继承.多态.抽象类与接口 标签(空格分隔): java 1. 本周学习总结 1.1 写出你认为本周学习中比较重要的知识点关键词 答:接口,比较器,has-a,Comparator. 1.2 ...

  8. JavaWeb -学生信息管理实践(JDBC+web+三层架构+DBUtil构造思路)

    前言: 1 该程序使用动态web项目 2 该程序使用SQL server需导入对应包( 具体可看前篇----JDBC的使用) 3 三层架构思想: ①表示层 前台:jsp/html等 作为前台与用户交互 ...

  9. 推荐算法之 slope one 算法

    1.示例引入 多个吃货在某美团的某家饭馆点餐,如下两道菜: 可乐鸡翅: 红烧肉: 顾客吃过后,会有相关的星级评分.假设评分如下: 评分 可乐鸡翅 红烧肉 小明 4 5 小红 4 3 小伟 2 3 小芳 ...

  10. centos安装python与jdk

    安装python #压缩包安装 [root@china ~]# yum -y install zlib* Loaded plugins: fastestmirror, refresh-packagek ...