您的位置:首页 > 编程语言 > C语言/C++

C语言深度剖析--读书笔记7_const关键字

2013-03-19 09:32 337 查看
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类型的,如上代码。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: