(以下代码用gcc或g++编译)
1.修饰普通变量
const int a;
int const a;
这两种是一样的,没有区别,另外 int a const 是错误的。
其实上述两种方式也是错的,必须初始化才行!
如果不初始化,C++编译器会提示错误,没有initialize,而C编译器正常,但是如果在下面在赋值的话就错了,不能对常量赋值。
2.修饰指针变量
有很多种写法,逐个分析。
const int * a;
这个const修饰的重点是int,也就是说,a并不是常量,a是可以变的,(*a)是不能变的,详细见如下代码。
- #include<stdio.h>
- int main()
- {
- const int * a;
- int b;
- a=&b;
- b=5;
- (*a)=5;
- return 0;
- }
test.cpp:8: 错误:assignment of read-only location
我们可以对b进行赋值,但是不能用(*a)对其赋值。明白了吧?
int const * a;
这个与 const int *a是一样的,a可以赋值,但是(*a)不能赋值。
int * const a;
这个修饰的是a,a是什么类型的?a是指针类型,所以说a必须初始化,a只能指向一个地址,但是地址里的内容是可以改的。
看如下代码
- #include<stdio.h>
- int main()
- {
- int * const a;
- }
- test.cpp: In function ‘int main()’:
- test.cpp:4: 错误:未初始化的常量 ‘a’
必须初始化。
然后再看
- #include<stdio.h>
- int main()
- {
- int b;
- int c;
- int * const a=&b;
- (*a)=5;
- a=&c;
- }
- test.cpp: In function ‘int main()’:
- test.cpp:8: 错误:assignment of read-only variable ‘a’
const int * const a;
这个就是定死了,a也不能修改,(*a)也不能修改,而且a必须初始化。
- #include<stdio.h>
- int main()
- {
- int b;
- int c;
- int const* const a=&b;
- (*a)=5;
- a=&c;
- }
- test.cpp: In function ‘int main()’:
- test.cpp:7: 错误:assignment of read-only location
- test.cpp:8: 错误:assignment of read-only variable ‘a’
还有其中区别方法:
沿着*号划一条线,
如果const位于*的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量;
如果const位于*的右侧,const就是修饰指针本身,即指针本身是常量。
3.修饰函数参数
int fun (int const a) 或者 int fun (const int a);
传递过来的变量不能修改,也就是a不能在函数体内进行赋值什么的,但是这个意义不大,因为a是形参。
- using namespace std;
- int fun(const int a)
- {
- a=5;
- return a;
- }
- int fun1(int const a)
- {
- a=2;
- return a;
- }
- int main()
- {
- int b;
- fun(b);
- return 0;
- }
- test.cpp:5: error: assignment of read-only parameter ‘a’
- test.cpp: In function ‘int fun1(int)’:
- test.cpp:10: error: assignment of read-only parameter ‘a’
int fun ( const char * a) ;
a可以变,但是(*a)不可以变。但是我们可不可以通过另外一个指针变量给(*a)赋值呢?
比如 int *c=a; (*c)=5,这不就实现对a所指向的地方的间接修改了吗?
错了,int *c=a是错的,因为c与a不是一个类型。必须const int * c=a才行,那既然这样,还是不能修改a指向的那个地方,因此,这个用法是很有用的,传指针过去,但是你不能通过指针改我的值,主要的好处是节省了开销。看下面的例子
- #include<iostream>
- using namespace std;
- int fun(const int* a)
- {
- int b;
- int * c;
- c=a;
- (*a)=b;
- a=&b;
- (*c)=5;
- return b;
- }
- int main()
- {
- int b;
- fun(&b);
- return 0;
- }
- test.cpp: In function ‘int fun(const int*)’:
- test.cpp:7: error: invalid conversion from ‘const int*’ to ‘int*’
- test.cpp:8: error: assignment of read-only location
int fun (int * const a);
这个跟第一种差不多,没多少意义,就是不能修改a,但是a也是形参,(*a)是可以改的。
修饰引用int fun (const int& a);
a不能被修改,这个也很常用。就着一种形式,int fun( int & const a)没有这种形式。
- #include<iostream>
- using namespace std;
- int fun( const int& a)
- {
- int b;
- a=5;
- b=a;
- return b;
- }
- int main()
- {
- int b;
- fun(b);
- return 0;
- }
- test.cpp: In function ‘int fun(const int&)’:
- test.cpp:5: error: assignment of read-only reference ‘a’
4.修饰返回值
const int fun (int a);
这个无意义,因为返回的本身就是一个常量。
const int * fun (int a);
这个怎么理解的,其实就可以把const int *看作一种类型,返回值是const int *类型的,这个需要好几个代码
首先,下面代码
- #include<iostream>
- using namespace std;
- const int* fun( int a)
- {
- a=5;
- return &a;
- }
- int main()
- {
- int b;
- fun(b);
- return 0;
- }
- test.cpp: In function ‘const int* fun(int)’:
- test.cpp:3: warning: address of local variable ‘a’ returned
局部变量的地址返回是没意义的,但是没错,说明在函数体内返回不是const int *类型的没关系。
然后
- #include<iostream>
- using namespace std;
- const int* fun( int& a)
- {
- a=5;
- return &a;
- }
- int main()
- {
- int b;
- int *c;
- const int *d;
- c=fun(b);
- d=fun(b);
- return 0;
- }
- test.cpp: In function ‘int main()’:
- test.cpp:13: error: invalid conversion from ‘const int*’ to ‘int*’
说明这个只在赋值的时候有影响,必须赋给const int *类型的才行。
int * const fun(int a);
这个的用法还没搞清楚,不过一般没有这么用的。
- #include<iostream>
- using namespace std;
- int* const fun( int& a)
- {
- a=5;
- return &a;
- }
- int main()
- {
- int b;
- int *c;
- int *d;
- c=fun(b);
- d=fun(b);
- int *e=fun(b);
- int * const f=fun(b);
- return 0;
- }
5.修饰成员对象/对象指针/对象引用
跟普通变量一样,但是有一点要注意,被const修饰的对象不能调用内部没有被const修饰过的成员函数,因为这样的函数有修改内部成员变量的嫌疑。
本文转自nxlhero 51CTO博客,原文链接:http://blog.51cto.com/nxlhero/405863,如需转载请自行联系原作者