C语言-const和volatile深度分析

1、const只读变量

  const修饰的变量是只读的。本质还是变量

  const修饰的局部变量在栈上分配空间

  const修饰的全局变量在全局数据区分配空间

  const只在编译期有用,在运行期无用

  const修饰的变量不是真的变量,它只是告诉

  编译器该变量不能出现在赋值符号的左边
实例一.cpp:

  

 1 #include <stdio.h>
 2
 3 const int g_cc = 2;
 4
 5 int main()
 6 {
 7     const int cc = 1;
 8
 9     int* p = (int*)&cc;
10
11     printf("cc = %d\n", cc);
12
13     *p = 3;
14
15     printf("cc = %d\n", cc);
16
17     p = (int*)&g_cc;
18
19     printf("g_cc = %d\n", g_cc);
20
21     *p = 4;
22
23     printf("g_cc = %d\n", g_cc);
24
25     return 0;
26 }

从上面的代码我们发现,const并不是真正意义上的常量,而只是read-only;

提示:GCC编译器如果编译上面的代码,在第21行代码会发生段错误,因为GCC编译器会把const全局数据放置在只读存储区,不能再修改。

但const仍然不能定义真正的意义上的常量。

实例二.cpp

 1 #include <stdio.h>
 2
 3 const int g_array[5] = {0};
 4
 5 void modify(int* p, int v)
 6 {
 7     *p = v;
 8 }
 9
10 int main()
11 {
12     int const i = 0;
13     const static int j = 0;
14     int const array[5] = {0};
15
16     modify((int*)&i, 1);           // ok
17     modify((int*)&j, 2);           // error
18     modify((int*)&array[0], 3);    // ok
19     modify((int*)&g_array[0], 4);  // error
20
21     printf("i = %d\n", i);
22     printf("j = %d\n", j);
23     printf("array[0] = %d\n", array[0]);
24     printf("g_array[0] = %d\n", g_array[0]);
25
26     return 0;
27 }

2.const修饰函数参数和返回值 

  -const修饰函数参数表示在函数体内不希望改变参数的值

  -const修饰函数返回值表示返回值不可改变,多用于返回指针的情形

小贴士:

  -C语言中的字符串字面量存储于只读存储区,

  -在程序中需要使用  const char* 指针。

实例3.cpp

 1 #include <stdio.h>
 2
 3 const char* f(const int i)
 4 {
 5     i = 5;
 6
 7     return "Delphi Tang";
 8 }
 9
10 int main()
11 {
12     char* pc = f(0);
13
14     printf("%s\n", pc);
15
16     pc[6] = ‘_‘;
17
18     printf("%s\n", pc);
19
20     return 0;
21 }

上面的代码 第5行和第16行将会报错,这里不再讲述。

3.volatile分析

volatile可理解为“编译器警告提示符”

volatile告诉编译器必须每次去内存中取变量值

volatile主要修饰可能被多个线程访问的变量

volatile也可以修饰可能被未知因数更改的变量

 1   int obj = 10;
 2
 3     int a = 0;
 4     int b = 0;
 5
 6     a = obj;
 7
 8     Sleep(100);
 9
10     b = obj;  

编译器在编译的时候发现obj没有被当成左值使用,

因此会“聪明”的直接将obj替换成10,而把a和b都赋值为10。(优化)

volatile主要用于多线程编程环境和嵌入式开发领域

此时若改变obj的值,a和b又如何???

volatile int obj = 10后,a和b又如何???

有趣的问题

const volatile int i = 0;

- 变量 i 具有什么样的特性?

- 编译器如何处理这个变量?

正解:  每次用i都会到内存取i的值,i不能出现在赋值符号左边

小结:

const使得变量具有只读属性

const不能定义真正意义上的常量

const将具有全局生命期的变量存储于只读存储区

volatile强制编译器减少优化,必须每次到内存中取值

原文地址:https://www.cnblogs.com/lemaden/p/10123347.html

时间: 2024-10-09 20:21:03

C语言-const和volatile深度分析的相关文章

c语言const、volatile问题小结

之前百度面试的时候被volatile虐了,内核中很多地方也会用到,这个面试的时候出现概率太大了,所以搜集了一些结果供大家参考,大部分是百度到的,说得挺明确的,以后读代码的时候遇到了再更新. 百度知道有人提如下问题: #include "stdio.h" int main(void){ const char i = 1; char * j = (char *)&i; printf("%d,%d,%p,%p\n",i,*j,&i,j);//1,1 *j

C语言中关键字auto、static、register、const、volatile、extern的作用

原文:C语言中关键字auto.static.register.const.volatile.extern的作用 关键字auto.static.register.const.volatile.extern 这些关键词都是c++基础知识,我整理了一下,希望对新学的朋友们有用: (1)auto 这个这个关键字用于声明变量的生存期为自动,即将不在任何类.结构.枚举.联合和函数中定义的变量视为全局变量,而在函数中定义的变量视为局部变量.这个关键字不怎么多写,因为所有的变量默认就是auto的. (2)reg

C语言中关键字volatile的含义【转】

本文转载自:http://m.jb51.net/article/37489.htm 本篇文章是对C语言中关键字volatile的含义进行了详细的分析介绍,需要的朋友参考下 volatile 的意思是“易失的,易改变的”.这个限定词的含义是向编译器指明变量的内容可能会由于其他程序的修改而变化.通常在程序中申明了一个变量时,编译器会尽量把它存放在通用寄存器中,例如ebx.当CPU把其值放到ebx中后就不会再关心对应内存中的值.若此时其他程序(例如内核程序或一个中断)修改了内存中它的值,ebx中的值并

C之 const 和 volatile(九)

在  C 语言中,我们经常会见到 const 和 volatile 这两个关键字,那么我们今天就来介绍下这两个关键字. 先来介绍 const 关键字.提起 const 关键字,我们可能首先想到的是经过它修饰的变量便是常量了.其实我们这种想法是错误的,其实 const 修饰的变量是只读的,其本质还是变量.它修饰的局部变量是在栈上分配空间的,它修饰的全局变量在全局数据区分配空间(也就是我们平时所说的 read-only data 段),const 只在编译期有用,在运行期无效.注意:const 修饰

Socket与系统调用深度分析

Socket与系统调用深度分析 可以想象的是,当应用程序调用socket()接口,请求操作系统提供服务时,必然会系统调用,内核根据发起系统调用时传递的系统调用号,判断要执行的程序,若为socket对应的编号,则执行socket对应的中断服务程序.服务程序内部,又根据你要请求的不同服务,来执行不同服务对应的处理程序.当处理结束,执行返回,从中断服务程序到发起中断的int 0x80,再到用户态我们执行的用户程序,层层返回,socket()也就执行完毕了. 本次,我们关心三个问题: 1.应用程序如何如

C++的类型转换:static_cast、dynamic_cast、reinterpret_cast和const_cast(dynamic_cast还支持交叉转换,const_cast将一个类的const、volatile以及__unaligned属性去掉)

在C++中,存在类型转换,通常意味着存在缺陷(并非绝对).所以,对于类型转换,有如下几个原则:(1)尽量避免类型转换,包括隐式的类型转换(2)如果需要类型转换,尽量使用显式的类型转换,在编译期间转换(3)避免使用reinterpret_cast和老式的强制类型转换操作符通常,隐式的类型转换会导致警告,需要重视这些警告,并使用显式的类型转换代替,例如static_cast代替一些算术类型转换. 在C++中,对象的类型通常有如下几种:(一)内置类型,如int ,bool ,枚举类型等(二)自定义类型

深度分析LINUX环境下如何配置multi-path

首先介绍一下什么是多路径(multi-path)?先说说多路径功能产生的背景,在多路径功能出现之前,主机上的硬盘是直接挂接到一个总线(PCI)上,路径是一对一的关系,也就是一条路径指向一个硬盘或是存储设备,这样的一对一关系对于操作系统而言,处理相对简单,但是缺少了可靠性.当出现了光纤通道网络(Fibre Channle)也就是通常所说的SAN网络时,或者由iSCSI组成的IPSAN环境时,由于主机和存储之间通过光纤通道交换机或者多块网卡及IP来连接时,构成了多对多关系的IO通道,也就是说一台主机

【转】话说C语言const用法

原文:话说C语言const用法 const在C语言中算是一个比较新的描述符,我们称之为常量修饰符,意即其所修饰的对象为常量(immutable). 我们来分情况看语法上它该如何被使用. 1.函数体内修饰局部变量.例:void func(){const int a=0;} 首先,我们先把const这个单词忽略不看,那么a是一个int类型的局部自动变量,我们给它赋予初始值0. 然后再看const. const作为一个类型限定词,和int有相同的地位.const int a;int const a;是

C语言const与define的使用

const是一个C语言的关键字,它限定一个变量不允许被改变.使用const在一定程度上可以提高程序的健壮性,另外,在观看别人代码的时候,清晰理解const所起的作用,对理解对方的程序也有一些帮助. 虽然这听起来很简单,但实际上,const的使用也是c语言中一个比较微妙的地方,微妙在何处呢?请看下面几个问题. 问题:const变量 & 常量 为什么我象下面的例子一样用一个const变量来初始化数组,ANSI C的编译器会报告一个错误呢? const int n = 5;int a[n]; 答案与分