C语言深度剖析--读书笔记7_const关键字
2013-03-19 09:32
337 查看
1.const修饰只读变量
(1)在GCC中,const修饰的是只读变量。注意,在GCC中,只读变量可以用来定义数组,但是不可以用作case 后面的判断条件。
(2)在ANSI C中,const修饰的也是只读变量。
与GCC不同的是,在ANSI C中,只读变量不能用于定义数组。这里要注意 只读变量和常量的区别:只读变量在定义之后, 不可以再被赋值,修改。同时只读变量仍是一个变量,在编译的时候,编译器不知道其存储的内容。
2.const修饰变量,数组,指针
(1)修饰一般变量,数组
const作为修饰符,可以放在类型说明符前,也可以放在后。注意,const修饰数组的时候,数组中元素不可被修改。
const修饰指针的时候,存在一个限定范围的问题(即指针本身不可改,还是指针指向的内容不可改)。编译器在处理的时候,先忽略类型描述符,看距离const右边紧邻的是谁,那么就认为const限定谁。
3.const修饰函参,函数
(1)修饰函数参数。当不希望参数值在函数体内被意外改变的时候使用。
如果返回值采用值传递的方式,那么加const是没有意义的。因为函数返回该值后,需要有一个变量来接收函数的返回值。而这个变量,其实是可以修改的。另一方面,如果返回值采用的是指针传递的方式(即返回:在函数执行过程中,保存在在堆上的变量的指针),那么才是有意义的。
(1)在GCC中,const修饰的是只读变量。注意,在GCC中,只读变量可以用来定义数组,但是不可以用作case 后面的判断条件。
#include "stdio.h" int main(void) { int i; const int a=1; const int b=2; const int c=3; const int size=10; int iarr[size]; //没有问题,编译可以通过! i=2; switch(i) { case a: //报错:case标号不能还原为一个整常量 printf("a is %d\n",a); break; case b: //报错:case标号不能还原为一个整常量 printf("b is %d\n",b); break; case c: //报错:case标号不能还原为一个整常量 printf("c is %d\n",c); break; default: printf("default\n"); break; } return 0; }分析上面的例子,在case处报错。因为case后面必须跟:整型常量或整型类型的常量表达式(字符型也可以,因为字符在内存中,是ASCII值,也是整型)。所以可以说明const修饰的仍是一个变量(只读的)。
(2)在ANSI C中,const修饰的也是只读变量。
与GCC不同的是,在ANSI C中,只读变量不能用于定义数组。这里要注意 只读变量和常量的区别:只读变量在定义之后, 不可以再被赋值,修改。同时只读变量仍是一个变量,在编译的时候,编译器不知道其存储的内容。
int main(void) { const int size=10; int array[size]; //报错!只读变量不能用于定义数组 return 0; }(3)只读变量一旦定义,不能再被赋值,修改。
const int i; i=10; //报错:不可以向只读变量i赋值
2.const修饰变量,数组,指针
(1)修饰一般变量,数组
const作为修饰符,可以放在类型说明符前,也可以放在后。注意,const修饰数组的时候,数组中元素不可被修改。
int const i1=2; const int i2=2;//两个式子等价 int const array1[3]={1,2,3}; const int array2[3]={1,2,3}; //两个式子等价 array1[1]=0; //报错,向只读位置array[1]赋值(2)修饰指针
const修饰指针的时候,存在一个限定范围的问题(即指针本身不可改,还是指针指向的内容不可改)。编译器在处理的时候,先忽略类型描述符,看距离const右边紧邻的是谁,那么就认为const限定谁。
#include "stdio.h" int main(void) { int i=1; int j=2; const int *p1=&i; //const 离*近,修饰的是*p1,即p1所指的对象。而p1本身是可以修改的,所以p1可以指向其它位置。。 p1=&j; //正常通过 *p1=j; //报错:向只读位置‘*p1’ 赋值 int const *p2=&i; //此时与上一种情况相同 p2=&j; //ok~ *p2=j; //报错:向只读位置‘*p1’ 赋值 int * const p3=&i; //const 离p3近,修饰的是p3,p3不能指向其他内容。而p3所指向的内容可以被修改 p3=&j; //报错:向只读变量‘p3’赋值 *p3=j; //ok~ const int * const p4=&i; //前一个const修饰*p4,后一个const修饰p4,所以p4和*p4都不可以被修改 p4=&j; //错误:向只读变量‘p4’赋值 *p4=j; //错误:向只读位置‘*p4’赋值 }
3.const修饰函参,函数
(1)修饰函数参数。当不希望参数值在函数体内被意外改变的时候使用。
int func(const int *p)//建议一般的函数参数都按照此方式定义 { int i=10; p++; //ok~p指针本身是可以被修改的 *p=10; //错误:向只读位置‘*p’赋值 return 0; } int main(void) { int array[5]={1,2,3,4,5}; func(array); return 0; }(2)修饰函数返回值
如果返回值采用值传递的方式,那么加const是没有意义的。因为函数返回该值后,需要有一个变量来接收函数的返回值。而这个变量,其实是可以修改的。另一方面,如果返回值采用的是指针传递的方式(即返回:在函数执行过程中,保存在在堆上的变量的指针),那么才是有意义的。
#include "stdlib.h" const int * func(void) { int *p; p=malloc(10*sizeof(int));// 在堆上分配的10*4个字节内存,不会随func函数的结束而被销毁 return p; // 而返回类型是const int * ,即说明此段内存,不允许被修改 } int main(void) { int *p1; const int *p2; p1=func(); //GCC会警告:该赋值,会导致func函数返回值的const性质被忽略(因为接收它的) p2=func();//正确! }最后补充一点:用于接收const类型返回值的变量,也应该是cosnt类型的,如上代码。
相关文章推荐
- C语言深度剖析--读书笔记_void 关键字
- struct关键字---C语言深度剖析读书笔记9
- C语言深度剖析--读书笔记2_static关键字
- C语言深度剖析--读书笔记4_signed/unsigned关键字
- 读书笔记:c语言深度剖析之关键字
- C语言深度剖析--读书笔记6_return关键字
- C语言深度剖析——读书笔记
- 读c语言深度剖析 -- 闲谈const(1)
- 读c语言深度剖析 --闲谈const(2)
- <<C语言深度剖析>>学习笔记之一:C语言中32个关键字
- 读c语言深度剖析 -- 闲谈const(3)
- C语言深度剖析读书笔记
- 【C语言深度剖析】读书笔记之 signed ,unsigned
- Mohican_11/18 C语言深度剖析 - 关键字
- C深度剖析读书笔记-第一章关键字
- C语言深度剖析学习心得之关键字
- 6.读c语言深度剖析 -- 第一章 关键字(32个)
- 《c语言深度剖析》整理--关键字
- C语言深度剖析--读书笔记3_sizeof
- 读书笔记之:C语言深度剖析