const 和 volatile为什么能同时定义一个变量

< c primer plus > 书上的一段话,请前辈不吝执教,const 和 volatile怎么能同时定义一个变量呢,不明白。谢谢。
  一个值可以同时是vonst和volatile。例如,硬件时钟一般设定为不能由程序改变,这一点使他成为const; 但它被程序以外的代理改变,这使它成为volatile的。只需在声明中同时使用这两个限定词,如下所示,顺序并不重要:  
volatile const int ioc; 
const volatile int *ploc;

问题点数:12分

1 0

引用 ・ 举报 ・ 管理

c#中实现的万能变量类

CSDN推荐

CSDN今日推荐

很菜的小李

Bbs5

回复于 2007-12-10 14:25:44 #1 得分:0

lz第2行开始的一段话好像是贴出来的,我觉得这段话已经把原因说得很清楚了。

0 0

引用 ・ 举报 ・ 管理

java基础总结大全

伊始

Bbs1

回复于 2007-12-10 14:27:50 #2 得分:0

他是说了,但我不理解,呵呵。 const 是为了不变的目的而进入ANSI C, 而volatile是可变的含义, 总是觉得两者冲突。

0 0

引用 ・ 举报 ・ 管理

创建一个日期类,定义几个变量:年、月、日、小时、分钟、秒;

伊始

Bbs1

回复于 2007-12-10 14:31:18 #3 得分:0

具体说,作者的解释 ”但它被程序以外的代理改变,这使它成为volatile的“ 这句话,没理解。其他程序把硬件时钟改变了?即把定义为const的一个时钟变量的值改了,是吗,而const定义的常量的值是不允许改动的呀?究竟把什么改了呢?

1 1

引用 ・ 举报 ・ 管理

   char型变量中能不能存储一个中文汉字?为什么

很菜的小李

Bbs5

回复于 2007-12-10 14:38:31 #4 得分:4

volatile标识一个变量意味着这个变量可能被非本程序的其他过程改变,例如某个访问这一变量的某中断程序。为变量加上这一标识可以禁止编译器的优化,使程序正确地按设计者的意图运行。例如下面的程序,我们将intr_func注册为中断函数,某个中断发生时触发这一函数:

unsigned char flag = 1;

int main(int argc, char **argv) {
    reg_intr(XXX, intr_func);
    while(flag) {
        printf("hello\n");
    }
    return 0;
}

void intr_func(void) {
    flag = 0;
}

当不加volatile时,编译器会直接将while条件中的flag换成1,因此即使中断发生也无法结束循环;如果给flag加上volatile标识,编译器就不会做前述的优化,程序得以按设计的意图工作。

3 0

引用 ・ 举报 ・ 管理

html文件 声明变量部分代码

很菜的小李

Bbs5

回复于 2007-12-10 14:43:19 #5 得分:0



如果一个变量不会被本程序改变,通常可能给它加上const,但如果该变量可能被其他程序改变而本程序又在检测这个变量的值,就需要给它加上volatile,于是变量就同时有volatile和const了。

2 0

引用 ・ 举报 ・ 管理

AVR-GCC 中如何使用volatile 关键字.pdf

很菜的小李

Bbs5

回复于 2007-12-10 14:44:40 #6 得分:0

不好意思,本人语文不太好,不知道意思说清楚没。

1 0

引用 ・ 举报 ・ 管理

Const,Const函数,Const变量,函数后面的Const.txt

flyingscv

Bbs2

回复于 2007-12-10 14:47:34 #7 得分:0

const是给编译器看的,作为编译期间检查用

那句话我倒是明白,但也不是完全理解

0 0

引用 ・ 举报 ・ 管理

volatile变量

flyingscv

Bbs2

回复于 2007-12-10 14:54:32 #8 得分:0

const   volatile   int   *ploc; 
这个感觉还有点意义

volatile   const   int   ioc;  
想不出这个做什么用
得回去试试

0 0

引用 ・ 举报 ・ 管理

C#多线程互斥实例 多线程获取同一变量

Jim_King_2000

Bbs7

回复于 2007-12-10 15:01:58 #9 得分:0

const表示我们自己的代码不会改变这个值(别的代码或者硬件有可能改变这个值)。volatile表示禁止优化。因为编译器会认为如果代码没有改变变量,那么这个变量就不会改变,因此编译器会用寄存器把该变量缓存起来,每次需要读取变量值的时候,就从缓存中读取。这在大多数时候是正确的,但是在多线程或者中断的场合就不正确了。

1 0

引用 ・ 举报 ・ 管理

C语言关键字volatile(易变的)表示不经过赋值,其值也可能被改变

伊始

Bbs1

回复于 2007-12-10 15:16:17 #10 得分:0

reg_intr(XXX,   intr_func);   这个函数,是什么?

0 0

引用 ・ 举报 ・ 管理

define与const静态变量的用法

伊始

Bbs1

回复于 2007-12-10 15:21:11 #11 得分:0

Jim_King_2000  你说的“因为编译器会认为如果代码没有改变变量,那么这个变量就不会改变,因此编译器会用寄存器把该变量缓存起来,每次需要读取变量值的时候,就从缓存中读取。” 这句话的前提是  没有使用volatile, 才使用寄存器吧?

如果使用volatile,就应该直接从初始的内存区 去读数据吧。

0 0

引用 ・ 举报 ・ 管理

c/c++语言中const的用法,const 定义变量,指针的用法和不同

伊始

Bbs1

回复于 2007-12-10 15:24:38 #12 得分:0

 To skywarship :

 李哥 写的 那段程序段 有的地方没看明白 :

  reg_intr(XXX,       intr_func);       这个函数,是什么?

  如果使用volatile的话, 是把flag的定义变为 volatile unsigned   char   flag   =   1; 是这样么?

0 0

引用 ・ 举报 ・ 管理

const extern static volatile 小结

Treazy

Bbs7

Blank Blank

回复于 2007-12-10 15:30:46 #13 得分:0

const是只读的意思,被const定义的变量一般被认为无法修改(如果想修改也是可以的)

volatile是易变的,被volatile定义的变量一般认为是易改变的,因此编译器对其声明或定义的变量
不会进行优化,何为优化?就是为了提高运算速度,编译器对代码进行的代码优化

这2个关键字本身并没有使用上的冲突。

0 0

引用 ・ 举报 ・ 管理

const,extern,static,volatile的使用

伊始

Bbs1

回复于 2007-12-10 15:55:45 #14 得分:0

只读不就是不允许修改么?

0 0

引用 ・ 举报 ・ 管理

Const与Volatile

Jim_King_2000

Bbs7

回复于 2007-12-10 16:01:43 #15 得分:0

to wendy_welcom

Jim_King_2000     你说的“因为编译器会认为如果代码没有改变变量,那么这个变量就不会改变,因此编译器会用寄存器把该变量缓存起来,每次需要读取变量值的时候,就从缓存中读取。”   这句话的前提是     没有使用volatile,   才使用寄存器吧?

如果使用volatile,就应该直接从初始的内存区   去读数据吧。
=========================================

0 0

引用 ・ 举报 ・ 管理

第五课 - const和volatile分析

blackboycpp

Bbs3

回复于 2007-12-10 16:02:27 #16 得分:0

我好象记得在C#中写多线程程序时, 有的时候要把某变量设为volatile,
已使得另一线程可以改变它的值.
如果记错了请狠狠地批评我

0 1

引用 ・ 举报 ・ 管理

下面程序是定义一个结构体,并为其定义结构体变量,对其值输入、输出。

伊始

Bbs1

回复于 2007-12-10 16:10:48 #17 得分:0

我想问的问题就在这儿, volatile 目的是允许其他程序改变该变量的值。 而const 目的是把该值变为常量,不允许变动, const volatile int a; 这两个关键字放在一起为什么不矛盾呢?

难道是把a 存放在两个地方, 寄存器里的a是变量,内存里的a的值是常量? 是这样么?
加上volatile后, 还能从寄存器里面读取a 么?

0 0

引用 ・ 举报 ・ 管理

C语言面试题大汇总之华为面试题:1、局部变量能否和全局变量重名;2、如何引用一个已经定义过的全局变量;3、全局变量可不可以定义在可被多个.C文件包含的头文件中 为什么;4、语句for( ;1 ;)有什么问题 它是什么意思……

晨星

Bbs9

Blank Blank Blank

回复于 2007-12-10 16:12:19 #18 得分:3

发表于:2007-12-10 15:55:4514楼 得分:0 
只读不就是不允许修改么? 
=====================
不允许这里修改不代表不允许别处修改,再比如:
int i = 5;
const int* p = &i;
*p = 6; // 不可以;
i = 7;  // 完全可以,而且那个“const”的“*p”也跟着变成了7。

1 0

引用 ・ 举报 ・ 管理

结构体变量(包括年、月、日),编程序,要求输入年月日,程序能计算并输出该日在本年中是第几天

晨星

Bbs9

Blank Blank Blank

回复于 2007-12-10 16:14:31 #19 得分:0

const和volatile放在一起的意义在于:
(1)本程序段中不能对a作修改,任何修改都是非法的,或者至少是粗心,编译器应该报错,防止这种粗心;
(2)另一个程序段则完全有可能修改,因此编译器最好不要做太激进的优化。

1 0

引用 ・ 举报 ・ 管理

C++ 作用域规则

晨星

Bbs9

Blank Blank Blank

回复于 2007-12-10 16:17:07 #20 得分:0

“const”含义是“请做为常量使用”,而并非“放心吧,那肯定是个常量”。
“volatile”的含义是“请不要做没谱的优化,这个值可能变掉的”,而并非“你可以修改这个值”。
因此,它们本来就不是矛盾的啊。

1 0

引用 ・ 举报 ・ 管理

C语言知识点集锦(const、struct、volatile、宏、typedef、变参数函数、指针、restric等)

Jim_King_2000

Bbs7

回复于 2007-12-10 16:23:52 #21 得分:5

只读表示编译器不允许代码修改变量。但并不表示这个变量在其它地方不能够被修改(不能被修改岂不就成了常量?)。比如:

C/C++ code?

1

2

3

4

void f(const char *str)

{

...

}


在上面的程序中,str所指向的内存区域就是只读的,但这个只读性只在函数f内部,出了f,这块内存完全有可能是能够被修改的。

C/C++ code?

1

2

3

4

5

6

void g(void)

{

    char name[] = "Jim King";

    f(name);

...

}



另外一个例子在嵌入式系统中比较常见。很多嵌入式系统允许我们访问外部寄存器,该寄存器的地址可能是0x0018,该寄存器的最低位可能表示设备状态,1为忙碌,0为空闲。

C/C++ code?

1

2

3

4

5

6

#define GET_REG_VALUE(reg)              (*reg)       /* get register value */

const unsigned char *STATUS_REG   = 0x0018;    /* status register */

const unsigned char  STATUS_BUSY = 0x01;        /* busy bit */

while (GET_REG_VALUE(STATUS_REG) & STATUS_BUSY); /* wait until free */

// do something to operate the device

...


这段代码很可能会死循环。因为编译器强奸民意的将地址0x0018处的值缓存起来,然后每次while的时候都从缓存中读取。虽然STATUS_REG的值是const unsigned char *,但这仅仅表示STATUS_REG寄存器是个只读寄存器,我们不能够在代码中去写这个寄存器,但并不表示这个寄存器是不能够改变的。硬件完成了它的任务之后,就会把状态设置成空闲,因此该寄存器的最后一位在我们循环的时候很可能已经发生了变化。因此在这样的地方,我们要禁止编译器自作聪明的优化,方法如下:

C/C++ code?

1

const volatile unsigned char *STATUS_REG   = 0x0018;    /* status register */

5 0

引用 ・ 举报 ・ 管理

stm32 volatile变量的正确使用

blackboycpp

Bbs3

回复于 2007-12-10 16:26:58 #22 得分:0

咦?我刚回复了下怎么没了?
-------------
想到了在C#中使用过volatile: (以下摘自MSDN)
volatile 关键字表示字段可能被多个并发执行线程修改。声明为 volatile 的字段不受编译器优化(假定由单个线程访问)的限制。这样可以确保该字段在任何时间呈现的都是最新的值。

volatile 修饰符通常用于由多个线程访问而不使用 lock 语句(C# 参考) 语句对访问进行序列化的字段。



所以,如果用const volatile两个关键词声明变量,
则指明该变量不能在声明它的线程中被修改,
而可以被其他线程所修改.C#以外的语言等待道理类似.
我的理解.

0 0

引用 ・ 举报 ・ 管理

伊始

Bbs1

回复于 2007-12-10 16:30:32 #23 得分:0

const volatile int *p; 可以理解

const volatile int a; 怎么解释呢?  

 a 这个变量不能改变这个地址的值,别的变量可以改变? const volatile int a=4;
                                              int b=a;
                                              a=6;   //错误
                                                     b=6;  // 正确
请问我这样理解对么?

0 0

引用 ・ 举报 ・ 管理

Jim_King_2000

Bbs7

回复于 2007-12-10 16:34:05 #24 得分:0

const   volatile   int   a;应该来说很少会遇到吧?在这里没有必要加上volatile的。

0 0

引用 ・ 举报 ・ 管理

Betree Xing

Bbs1

回复于 2007-12-10 16:41:49 #25 得分:0

skywarship 

Jim_King_2000 

steedhorse 

几位兄台都说得很明白了

0 0

引用 ・ 举报 ・ 管理

firemcu123

Bbs1

回复于 2007-12-10 16:55:10 #26 得分:0


const volatile int a is uaually used in multithreading and Interrupt Service Program.

0 0

引用 ・ 举报 ・ 管理

晨星

Bbs9

Blank Blank Blank

回复于 2007-12-10 16:55:36 #27 得分:0

对于非指针非引用的变量,const volatile同时修饰的意义确实不大。
个人觉得。

0 0

引用 ・ 举报 ・ 管理

伊始

Bbs1

回复于 2007-12-10 17:04:50 #28 得分:0

谢谢各位前辈们的悉心指点, 感激之感用分数和话语不足以表达。 真的谢谢大家。

0 0

引用 ・ 举报 ・ 管理

晨星

Bbs9

Blank Blank Blank

回复于 2007-12-10 17:05:41 #29 得分:0

只不过需要明白“volatile”的含义并非是“non-const”。所以他们才可以放在一起。
在C++语言中,const没有反义词,如果一个变量没有const修饰,那它本身就是const的反义词,而并非加上volatile才是const的反义词。

1 0

引用 ・ 举报 ・ 管理

天上星,亮晶晶,永灿烂,长安宁

Bbs5

回复于 2007-12-10 17:17:59 #30 得分:0

这个非常类似 static 修饰变量的时候,如果只是声明,可以这样写;
那么以后,赋过初值了就不可以再变了;OK?

0 0

引用 ・ 举报 ・ 管理

很菜的小李

Bbs5

回复于 2007-12-10 17:19:09 #31 得分:0

回12楼

那个函数只是表示将intr_func注册到中断处理的意思,并不是真实的函数

0 0

引用 ・ 举报 ・ 管理

hunter15

Bbs1

回复于 2007-12-10 20:52:22 #32 得分:0

同意29

0 0

引用 ・ 举报 ・ 管理

cyberspace.or...

Bbs1

回复于 2007-12-10 23:08:20 #33 得分:0

The code with volatile is more likely to break at optimization. For example, the following code may not print what you think it should be with this type qualifier.

C/C++ code?

1

2

3

4

5

6

7

8

9

int main(void)

{

  int volatile const len = 10;

  int                m;

 

  m = len * 2;

  printf("%d\n", m);

  return 0;

}

0 0

引用 ・ 举报 ・ 管理

朋友的淘宝网http://...

Bbs1

回复于 2007-12-11 00:57:34 #34 得分:0

ls的英文太糟糕了,no offence,but...建议你用中文翻译一下吧,老子看不懂。

“volatile       const       int       ioc”
这个通常用于声明,而不是定义,比如:
file A:
int ioc;//定义变量

file B:
extern volatile const int ioc;//

或许file C:
extern volatile int ioc;//

这样B不能修改ioc,且每次读取ioc的时候都会从内存里读。

不过上面的例子在VC上不能运行,因为VC试图保证联接的时候的类型安全(无聊的决策),gcc是没有问题的

0 0

引用 ・ 举报 ・ 管理

prime number

Bbs2

回复于 2007-12-11 09:42:24 #35 得分:0

up

0 0

引用 ・ 举报 ・ 管理

internazelo

Bbs1

回复于 2007-12-11 10:46:49 #36 得分:0

举个简单的例子。只读的状态寄存器,它是volatile,因为它可能被意想不到地改变。
它是const,因为程序不应该试图去修改它。

0 0

引用 ・ 举报 ・ 管理

shuaihonggao

Bbs1

回复于 2007-12-11 11:17:06 #37 得分:0

对于const来说,应该理解为只读的意思,如果一个变量被定义为const了,那么它告诉使用者这个变量是只读的,不要试图在当前的模块中改变它。
而对于volatile来说,它是告诉编译器,这个被声明的变量可能在本程序之外被修改,告诉编译器每次在使用这个变量的时候都需要重新加载,不能优化。
举个例子:
我们现在有个变量A ,它表示的是一个寄存器的内容,而在我们的程序当中如果是不可以修改寄存器内容的,因此A应该声明为const,而寄存器的值是和外设相关的,是不受我们程序控制的,程序可能只是检测这个值,因此A又应该设置为volatile。

本人愚见,忘高手赐教!

1 0

引用 ・ 举报 ・ 管理

shuaihonggao

Bbs1

回复于 2007-12-11 11:21:25 #38 得分:0

对于const来说,应该理解为只读的意思,如果一个变量被定义为const了,那么它告诉使用者这个变量是只读的,不要试图在当前的模块中改变它。
而对于volatile来说,它是告诉编译器,这个被声明的变量可能在本程序之外被修改,告诉编译器每次在使用这个变量的时候都需要重新加载,不能优化。
举个例子:
我们现在有个变量A ,它表示的是一个寄存器的内容,而在我们的程序当中如果是不可以修改寄存器内容的,因此A应该声明为const,而寄存器的值是和外设相关的,是不受我们程序控制的,程序可能只是检测这个值,因此A又应该设置为volatile。

本人愚见,忘高手赐教!

0 0

引用 ・ 举报 ・ 管理

xx_hzbzlp

Bbs1

回复于 2007-12-11 22:00:38 #39 得分:0

const:变量不能为代码直接修改,但可以间接或通过外部的一些触发(如管脚或寄存器等).
volatile:编译器不能假设程序在运行中执有变量的一个副本.

0 0

引用 ・ 举报 ・ 管理

cyberspace.or...

Bbs1

回复于 2007-12-11 22:02:14 #40 得分:0

>   JobSeeker   
>   朋友的淘宝网 
>   等   级: 
>     发表于:2007-12-11   00:57:3434楼   得分:0   
>   ls的英文太糟糕了,no       offence,but...建议你用中文翻译一下吧,老子看不懂。   
>   

You're   not   expected   to   understand   that   because   you're   a   fool.   You   know   neither   English   language   nor   the   C   language. 

>   “volatile                               const                               int                               ioc”   
>   这个通常用于声明,而不是定义,比如:   
>   file       A:   
>   int       ioc;//定义变量   
>   
>   file       B:   
>   extern       volatile       const       int       ioc;//   
>   
>   或许file       C:   
>   extern       volatile       int       ioc;//   
>   
>   这样B不能修改ioc,且每次读取ioc的时候都会从内存里读。   
>   
>   不过上面的例子在VC上不能运行,因为VC试图保证联接的时候的类型安全(无聊的决策),gcc是没有问题的   
>     

You   told   people   that   you're   really   a   fool   by   presenting   this   rubbish. 

By   the   way,   if   there're   some   people   can   explain   why   that   fool   was   wrong   with   that   code,   they   will   be   given   awards   :-D 

0 0

引用 ・ 举报 ・ 管理

ForestDB

Bbs8

Blank Blank

回复于 2007-12-13 08:57:05 #41 得分:0

const说的是不让你改,并没有说不让别的东西改;而volatile说的就是可能会被别人改的。

0 0

引用 ・ 举报 ・ 管理

laoshizhuce

Bbs1

回复于 2010-10-04 20:29:03 #42 得分:0

steedhorse回答的很精辟,不愧是CSDN专家

MARK

0 0

引用 ・ 举报 ・ 管理

cjwxiaoma

Bbs1

回复于 2011-07-19 08:25:37 #43 得分:0

学习ING

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值