const和volatile以及引用

const

定义:修饰一个变量,表示不能在作为赋值的左值。
c中:
(1)const修饰的变量不一定要初始化。
(2)const修饰的变量变为常变量。
(3)不能作为常量使用,例如定义数组的大小。
(4)常变量的编译方式和普通变量没有区别。
c++中:
(1)const修饰的变量必须初始化。
(2)const修饰的变量变为常量。
(3)可定义数组的大小(完全可以当作常量使用)。
(4)常量的编译方式,在编译的过程中,把常量名字替换成值(取常量地址时,不需要替换)。
(5)若初始值是变量,那么c++中的常量,变为c的常变量。

const和一级指针的结合?

保证const安全:代码上不能有直接或间接的修改常量值的可能。

const和多级指针的结合?

是共存亡的关系(即要么等号两边都有const 要么都没有)。

引用以及const和引用的结合

左边有类型,叫引用;没类型叫,取地址。
引用:更安全的指针。
1.变量定义时,名字左边有&符号,就是定义了一个引用变量。
2.引用必须初始化,指针不需要。
3.引用定义时,引用了哪块内存,就不能改变了也不能在引用其它内存块。
4.在c++99中只能定义一级引用,不能出现多级引用(c++11中有二级引用)。
5.使用引用变量,永远访问的是它所引用的内存(不能访问4字节的指针内存)。

引用成功必须满足以下条件:

1.引用必须初始化。
2.初始化的值能取地址:
普通的引用变量蹦引用常量,必须是常引用才或const指针能引用或指向常量;

固执的const与易变的volatile

10-31

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

const/volatile修饰标识符的进一步论证

05-12

const int *p = NULL; 相当于 int const *p = NULL;rn下面要写一对与上面一对表达式更清晰的陈述:rnrnconst int (*p) = NULL; 相当于 int const (*p) = NULL;rnrn这样其实比起第一对看起来更加清晰。const修饰(*p),即限定p指针所指地址内容的值。rnrn再看下面:rnrnint * const p = NULL;rnrn更清晰地表述为:int (* const p) = NULL;rnrn这样,很明显可以看到const修饰标识符p,即限定p指针的值。rnrn要注意的是没有int (const * p) = NULL;这样的语法。rn因为这样一来,对int的修饰会产生冲突。由于const *p对于C/C++而言本身就是一个合法的正则表达式语句。const *p = NULL; 完全OK,这时p作为int const*类型。rnrn利用括号对指针类型进行限定是比较有用的分析技巧。rnrn比如说以下情况:rnrntypedef int ARRAY[10];rnrnvoid main(void)rnrn ARRAY *p; // p是什么类型?rnrnrn那么对于类型定义情况,我们公司很多程序员都搞不清楚。尤其像以上这种情况。rn加个括号看看:ARRAY (*p);rnrn分析:由于ARRAY是int[10]类型,将它代入就成为:int[10] (*p);rn调整一下:int (*p)[10]; 所以比较自然地得出了p的类型为:int(*)[10]。rnrn指针标记*与标识符靠拢时总是与标识符进行一同规归约。rnrntypedef const int CINT;rnrnCINT *p = NULL; // p是什么类型?rnrn同样地,加括号:CINT (*p) = NULL; 就和const int (*p)一样了。rnrntypedef int* PINT;rnrnPINT const p = NULL; // p是什么类型?rnrn同样地,加括号,不过这里实际上没什么必要了,因为p作为一个单独的标识符没有指针对它进行修饰。const PINT (p) = NULL; 由于PINT为(int*)类型,因此这里的const就是对标识符p作修饰,由于p已经为(int*),因此p的类型为int* const。rnrn若为:PINT const (*p) = NULL;那么p类型为:int* const *。第一个int*是由PINT得到的。rnrn若是:PINT (* const p) = NULL; 那么p类型为int* * const

没有更多推荐了,返回首页

私密
私密原因:
请选择设置私密原因
  • 广告
  • 抄袭
  • 版权
  • 政治
  • 色情
  • 无意义
  • 其他
其他原因:
120
出错啦
系统繁忙,请稍后再试