事實上這個概念誰都有,只是三種聲明方式非常相似很容易記混。?
Bjarne在他的The C++ Programming Language里面給出過一個助記的方法:?
把一個聲明從右向左讀。?
char * const cp; ( * 讀成 pointer to )?
cp is a const pointer to char?
const char * p;?
p is a pointer to const char;?
char const * p;?
同上因為C++里面沒有const*的運算符,所以const只能屬于前面的類型。
C++標準規定,const關鍵字放在類型或變量名之前等價的。
~~~
const int n=5; //same as below
int const m=10;
~~~
~~~
const int *p; //same as below const (int) * p
int const *q; // (int) const *p
~~~
~~~
char ** p1;
// pointer to pointer to char
const char **p2;
// pointer to pointer to const char
char * const * p3;
// pointer to const pointer to char
const char * const * p4;
// pointer to const pointer to const char
char ** const p5;
// const pointer to pointer to char
const char ** const p6;
// const pointer to pointer to const char
char * const * const p7;
// const pointer to const pointer to char
const char * const * const p8;
// const pointer to const pointer to const char
~~~
說到這里,我們可以看一道以前Google的筆試題:
[題目]const char *p="hello";
foo(&p);//函數foo(const char *pp)
下面說法正確的是[]
A.函數foo()不能改變p指向的字符串內容
B.函數foo()不能使指針p指向malloc生成的地址
C.函數foo()可以使p指向新的字符串常量
D.函數foo()可以把p賦值為 NULL.
至于這道題的答案是眾說紛紜。針對上面這道題,我們可以用下面的程序測試:
<table border="1" cellspacing="0" cellpadding="2" width="400" align="center" style="color:rgb(51,51,51); font-family:Arial; font-size:14px; line-height:26px"><tbody><tr><td class="code" bgcolor="#e6e6e6" style="font-size:9pt">#include <stdio.h><br/>#include <stdlib.h><br/>#include <stdio.h><br/><br/><br/>void foo(const char **pp)<br/>{<br/>//??? *pp=NULL;<br/>//??? *pp="Hello world!";<br/>??????? *pp = (char *) malloc(10);<br/>??????? snprintf(*pp, 10, "hi google!");<br/>//?????? (*pp)[1] = 'x';<br/><br/>}<br/><br/>int<br/>main()<br/>{<br/>??? const char *p="hello";<br/>??? printf("before foo %s/n",p);<br/>??? foo(&p);<br/>??? printf("after foo %s/n",p);<br/>??? p[1] = 'x';<br/><br/>??? return;<br/>}<br/></td></tr></tbody></table>
結論如下:
1. 在foo函數中,可以使main函數中p指向的新的字符串常量。
1. 在foo函數中,可以使main函數中的p指向NULL。
1. 在foo函數中,可以使main函數中的p指向由malloc生成的內存塊,并可以在main中用free釋放,但是會有警告。但是注意,即使在foo中讓p指向了由malloc生成的內存塊,但是仍舊不能用p[1]='x';這樣的語句改變p指向的內容。
1. 在foo中,不能用(*pp)[1]='x';這樣的語句改變p的內容。
所以,感覺gcc只是根據const的字面的意思對其作了限制,即對于const char*p這樣的指針,不管后來p實際指向malloc的內存或者常量的內存,均不能用p[1]='x'這樣的語句改變其內容。但是很奇怪,在foo里面,對p指向malloc的內存后,可以用snprintf之類的函數修改其內容。