const char * const months[12]={"January","February","March","April","May","June","July","August","Septermber","October","November"}
第一个const表示字符串是常量,第二个const表示指针是常量。
int *const a; //a是一个指针常量 指向的是变量
const int * a; //指针a是一个变量 它指向的是一个常量(其实是对于指针a而言,它指向的是常量)
比如
int age=39;
const int *pt=&age;
*pt=20; //错误
age=20;//正确
//int const *a和上面的那种是同一个效果
//而引用(&)从不能二次赋值上来讲也是一个指针常量。
总结一下
int b = 500;
const int* a = &b; //[1]
int const *a = &b; //[2]
int* const a = &b; //[3]
const int* const a = &b;// [4]
void change(const int *a);
const 修饰形参。上面的例子表示,不会修改形参a指向的内容。如果是 void change(int * const a);就表示不会修改形参a了,如果在change函数体内使用a++就是错误的了(不过我没有想到这样做的意义)。
指针作为参数传递时,传递的是指针的一个拷贝,尽管可以通过间接操作符或者下标来改变实参所指向的内存,但是实参依旧不会改变,也就是实参指向的地址不会改变。
const修饰形参有至少三个好处:
1.这是一个良好的文档习惯,有些人希望看到函数的原型就知道该值不会被修改,而不用去完整的阅读函数的定义(读者可能看不到)
2.编译器可以捕捉到任何试图修改该数据的的意外错误。
3.这类声明允许想函数传递const参数。(这点有疑惑)
const修饰返回值,修饰参数
const在类成员函数后面表示,不会修改数据成员
char *des="iteration";
*(des+1)='a';
编译通过,运行出错;为什么呢?因为"iteration"是个常量,所以des指向常量的指针,不能通过对指针取变量来改变常量的值。
要达成目标可以写成下面
char des[]="iteration";
*(des+1)='a';
这时候变成了一个数组,可以赋值,数组的名字就是第一个元素的首地址
不能把const int * 传递给int *,因为有可能把人家值给变了
#include<stdio.h> void change(int *a) { ; } int main(int argc,char **argv) { int b = 1; const int *a = &b; change(a); return 0; } //ConstToNonconst.c: In function 'main': //ConstToNonconst.c:10: warning: passing argument 1 of 'change' discards qualifiers from pointer target type //ConstToNonconst.c:2: note: expected 'int *' but argument is of type 'const int *'
把int * 传递给 const int * 是可以的,变量变不变无所谓啊
typedef的问题
typedef char *charp;
const charp p;
结果是p而不是p所指向的字符为const。
因为typedef的替换并不是完全基于原文的(这也正是typedef的有点之一)
式中p被声明位const和const int i; i被声明为const一样。p的声明不会深入typedef的内容来发现涉及了指针。