固执的const与易变的volatile

wangsong198753 2010-10-31 10:26:03
对于const与volatile这两个关键字可能在一些简单的C语言应用中比较少见,但是在实际的项目应用中这两个关键字身影却随处可见。下面我们就这两个关键进行讨论。
1,const 可能大家见到这个关键字会想到常量,即认为经过const声明的变量将会常量化,遗憾的是这又是一种错误的观点(注意:对于const的讨论限于C语言,在C++中const将会有新的意义,感兴趣的可以找我讨论)。
有:const int i = 10;
虽然有const的声明,i 依然是变量,但是是只读变量。如有:i = 50;//编译将报错,因为i不可写只可读。对其证明下一节将给出。下面将说说const的作用。
const 的冻结效应
上面也提到了const int i = 10;对于i只能读不能写,也就是说i的内容被冻结了。
那么还有:(1)const int *p; (2)int const *p; (3)int *const p; (4)int const *p const;
又做何解呢?
int a ; const int *p = &a; 冻结*p的值,如有*p = 10;//编译将报错。
同(1)
int a; int *const p = &a;//冻结p的值,即p的指向不可改。如有 p = &b//编译将报错。但是*p的值却可以改变。*p = 50;//正确
双冻结,p与*p都被冻结。
一旦内容被冻结就变成了只读,这样就可对数据起到保护作用了。在赋值语句中被冻结的内容不能再做左值了。
下面看以例子:
#include <stdio.h>
#include<stdlib.h>
#include<assert.h>
char* strcpy(char *des, const char *soure)//对源数据soure起到了保护作用
{
assert((NULL != des) && (NULL != soure));//函数入口出对指针进行检测
while((*des++ = *soure++) != '\0');
return des;
}
int main(int argc, char *argv[])
{
char s[50];
strcpy(s,"hello,baby!");
printf("%s",s);
}
对其变量性质的证明
有const int i = 10;int a[i];//编译将报错,i是变量,编译的时候编译器无法确定数组的大小,解决方法#define i 10就可以了。但在C++中可以直接用,而还有它自己的优点。比如类型验证。
还有一个例子可以说明在c中const int i = 10;中i是变量。
Switch(a)
{

case 1:statement1
break;
........
case i:statement2//编译报错,因为是变量。
break;
......
default:statementn

}//待续。。。。
...全文
247 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
伊娃码力 2010-11-02
  • 打赏
  • 举报
回复
学习。。。。
goodluckme2013 2010-11-01
  • 打赏
  • 举报
回复
没有别的方法,签个名,让大家都记住我
东大坡居士 2010-11-01
  • 打赏
  • 举报
回复
学习了~~~~
Athenacle_ 2010-11-01
  • 打赏
  • 举报
回复
某C语言小菜鸟认为volatile就是告诉编译器这个变量很易变,应该去内存中读取而不是从寄存器中读取~。。。这样可以避免一些错误~

在Mark下帖子~。。
箭于 2010-11-01
  • 打赏
  • 举报
回复
学习中············
try325 2010-11-01
  • 打赏
  • 举报
回复
const的用法知道一些,期待volatile
tianziczj 2010-11-01
  • 打赏
  • 举报
回复
楼上各位仁兄说的极是,我对const略作总结和补充:
(1)char *p:可以对任意位置(非系统敏感区域)进行读操作和写操作
(2)const char*p或者char const *p(因为没有const*p运算,因此const修饰的还是前面的char):可以对任意位置(非系统敏感区域)进行“只读”操作。(“只读”是相对于char *p来说所限定的内容)
(3)char *const p(const 修饰的是p):只能对“某个固定的位置”进行读写操作,并且在定义p时就必须初始化(因为在后面不能执行“p=..”的操作,因此就不能在后面初始化,因此只能在定义时初始化)。(“某个固定的位置”是相对于char *p来说所限定的内容)
可以总结以上3点为:char *p中的指针p通常是万能的“工作指针”,而(2)和(3)只是在(1)的基础上加了些特定的限制,这些限制在程序中并不是必须的,只是为了防止程序员的粗心大意而产生事与愿违的错误。
另外,要明白“每块内存空间都可有名字;都有每块内存空间内容皆可变(除非有所限)”。比如函数里定义的char s[]="hello";事实上在进程的栈内存里开辟了7个变量共10个字节的空间,其中6个字符变量的名字分别为:s1[0]、s1[1]、s1[2]、s1[3]、s1[4]、s1[5](内容是'\0') ,他们共占了6个字节,还有一个4字节的指针变量s。不过s是“有所限制“的,属于char *const类型,也就是前面说的(3)这种情况,s一直指向s[0],即(*s==s[0]=='h'),可以通过*s='k'来改变s所指向的s[0]的值,但不能执行(char *h=“aaa”;s=h;)来对s另外赋值。
freecodeMAN 2010-10-31
  • 打赏
  • 举报
回复
volatile 有时候会用一下。
例如:
你在debug下程序运行的很好。
在release下运行发现出错了,release下单步走,发现某些变量的赋值语句被跳过了,
这时候你可以得知 变量被编译器优化了。

你可以手动加volatile限制变量,不让他优化,然后程序就正常了。

我碰到这种情况,具体什么情况忘记了。


对于const 养成好的习惯就经常用啊。
并且如果你对外提供接口,用const限定参数,可以避免一些麻烦。

const在c标准函数的参数限定上,使用很频繁。
HonryZZ 2010-10-31
  • 打赏
  • 举报
回复
学习一下..

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧