int const * a / int * const a / int const * const a的区别

前两天在听OSChina开源会中图拉鼎(Ubuntu-Tweak作者)提到了int const * aint * const aint const * const a三者有什么区别,表示一脸蒙逼,在此总结一下。

想要理解这三者的关系,要从最简单的来说。先看下面的代码,会输出什么呢?

int b = 2;
int c = 3;
int *a = &b;
a = &c;
printf("a :%d b:%d c: %d\n", *a,b,c);

答案:a :3 b:2 c: 3 应该很好理解,a是一个普通的int型指针,在a指向b之后,我们将a在此指向c,因此,a的值会与c相等,因为他们所指的是同一快内存。而b在a离开后自然不会发生什么变化,还是2。

好的,再看下面的代码:

 int c = 3;
 	 int *a = &b;
 *a = c;
 	 printf("a :%d b:%d c: %d\n", *a,b,c);

答案:a :3 b:3 c: 3

同上,a是一个普通的int型指针,在a指向b之后,我们让a指向的值(*a)变为3,相当于更改了b的值,所以此时b也会变为3.此时,a与b是相同的地址,而c没有和上面两位没扯上联系。

接下来,难度升级,引入我们今天的主角—const。看下面代码:

int b = 2;
 	int c = 3;
 	int const * a =&b;
 	a = &c;
 	printf("a :%d b:%d c: %d\n", *a,b,c);

答案同第一段代码一样,a :3 b:2 c: 3

这个时候疑问来了,加了const之后有什么区别了吗?表面上没什么区别,但实际上你不可以再用第二段代码中a = c的这种形式了。why?没办法,这就是固定的语法规则,const在 * a的前面,就说明const是形容a的 ,也就是a所指向的值是不可以改变的,所以*a = c 或者b = c都会是编译不通过的。因此,此时我们尽量将b也声明为const,否则后面的代码如果不小心改变b的值也会出错。

通过对上面的理解,你应该可以举一反三的说出下面代码的运行结果:

 int b = 2;
 int c = 3;
 int * const a = &b;
 *a = c;
 printf("a :%d b:%d c: %d\n", *a,b,c);

这个的运行结果应该和第二段代码是一样的,但是,当const修饰a之后,说明a本身是不能改变的,即我们不能将a改变指向,即此时后面如果有a = &c,编译器就会报错。同理,如果你后面将b指向别处也同样会报错。

最后,这个最苛刻的形式你也应该理解了:

int b = 2;
int c = 3;
int const * const a = &b;
printf("a :%d b:%d c: %d\n", *a,b,c);

此时,a和*a的值我们都不能改变。

最后,const int a与int const a之间是没有区别的,同理是可以将此用于上述问题的,但我们一般的原则是const向右靠,int向左靠,const在谁前谁就不能变。


image           image
章节列表