1.知識點
1.1指針常量——指針類型的常量
(1)指針常量本質是常量,指針用來說明常量的類型,表示該常量是一個指針類型的常量。
(2)在指針常量中,指針的值不可變,即始終指向同一個位址。
(3)但指針所指向的位址的值是可以通過*p來改變的。
用法如下:
1 //技巧:
2 //(1)讀法:從左到右讀,前面的是修飾詞,後面的是主語
3 //如先出現指針(*),後出現常量(const),是以是指針常量
4 //(2)哪個東西不可變:直接看const後邊是什麼就什麼不可變
5 //const後邊是指針(p),是以是指針本身的值不可變。
6 int a = 10, b = 20;
7 int * const p = &a;
8 *p = 30;
1.2常量指針——指向常量的指針
(1)常量指針本質上是一個指針,常量表示指針指向的内容,說明指針指向的是一個“常量”。
(2)在常量指針中,指針指向的内容是不可變的,不可以通過*p來改變,但變量(指針指向的位址)可以通過自身指派改變。
(3)另指針指向的位址是可以變的,即指向其他位址。
1 //技巧:
2 //(1)讀法:從左到右讀,前面的是修飾詞,後面的是主語
3 //如下先出現常量(const),然後出現指針(*),是以是常量指針
4 //(2)哪個東西不可變:直接看const後邊是什麼就什麼不可變
5 //如下const後面是*p,是以是指針指向的位址的值不可變(隻限定了不可以通過*p來改變)
6 int a = 10, b = 20;
7 int const *p = &a;//不可以通過*p改變a的值
8 p = &b;//指針的位址是可以變的
9 a = 30;//也可以通過變量本身改變值
1.3const int 與int consts是等價的
const int *p==int const *p
2.面試題
2.1指針常量和常量指針的常見錯誤
1 int main(int argc, char *argv[]) {
2 int m = 10;
3 const int n = 20;
4
5 const int *ptr1 = &m;
6 int * const ptr2 = &m;
7
8 ptr1 = &n;
9 ptr2 = &n;
10
11 *ptr1 = 3;
12 *ptr2 = 4;
13
14 int *ptr3 = &n;
15 const int *ptr4 = &n;
16
17 int *const ptr5;
18 ptr5 = &m;
19
20 const int * const ptr6 = &m;
21 *ptr6 = 5;
22 ptr6 = &n;
23
24 getchar();
25 return 0;
26 }
答案解析:
1 int main(int argc, char *argv[]) {
2 int m = 10; //正确,變量
3 const int n = 20; //正确,常量
4
5 const int *ptr1 = &m; //正确,常量指針,指向的位址的内容不可變
6 int * const ptr2 = &m; //正确,指針常量,指針指向不可變,是常量是以必須賦初值
7
8 ptr1 = &n;//正确
9 ptr2 = &n;//錯誤,指針常量,指針的指向不可變
10
11 *ptr1 = 3;//錯誤,常量指針,指針指向的位址的内容不可變
12 *ptr2 = 4;//正确
13
14 int *ptr3 = &n;//錯誤,不能将常量的位址指派給普通指針,常量位址隻能指派給常量指針
15 const int *ptr4 = &n;//正确
16
17 int *const ptr5;//錯誤,指針常量是常量,所有常量在定義時都必須賦初值
18 ptr5 = &m;//錯誤,應該定義時直接賦初值
19
20 const int * const ptr6 = &m;//正确,同時包含指針常量和常量指針的性質
21 *ptr6 = 5;//錯誤,不符合常量指針的性質
22 ptr6 = &n;//錯誤,不符合指針常量的性質
23 getchar();
24 return 0;
25 }
2.2指針常量用作函數參數
寫出程式的輸出結果,并說明在函數exchange2中将參數聲明為const的意義,是否可以将const修飾符放在*之前。
1 void exchange1(int a, int b) {
2 int temp = a;
3 a = b;
4 b = temp;
5 }
6 void exchange2(int * const a, int * const b) {
7 int temp = *a;
8 *a = *b;
9 *b = temp;
10 }
11 int main(int argc, char *argv[]) {
12 int m = 10, n = 20;
13 exchange1(m, n);
14 cout << "m=" << m << ";n=" << n << endl; //輸出:m=10;n=20
15 exchange2(&m, &n);
16 cout << "m=" << m << ";n=" << n << endl; //輸出:m=20,n=10
17 getchar();
18 return 0;
19 }
答案:第一行輸出的是:m=10,n=20;第二行輸出是:m=20,n=10.
解析:exchange1按值傳遞,函數中a,b值交換與m,n無任何聯系,故無法改變m,n的值;exchange2中傳入m,n的位址,通過解引用可以在函數内部改變m,n的值。在函數exhange2的參數中,const的作用是将指針聲明為指針常量,防止指針a和b在使用過程中意外發生改變(改變将會報錯)。如果将const放在*之前,指針a和b變成常量指針,無法修改指針指向的内容,進而無法實作交換m和n的目的。
2.3指針常量和字元串常量的沖突
請寫出下面程式的運作結果:
1 int main(){
2 char *const str="apple";
3 *str="orange";
4 cout<<str<<endl;
5 getchar();
6 return 0;
7 }
答案1(其實有問題,看下面說明,):
int main(){
char *const str="apple"; //錯誤,為了修改str的值應該去掉const
*str="orange";//錯誤,根據字元串指派規則應該改為str="orange"
cout<<str<<endl;
getchar();
return 0;
}
說明:(1)一個字元串傳回的是首字母的位址,故*str的值為'a'.
(2)字元串常量是存儲在常量區,而常量的值不可以修改,是以在VC編譯器中下面的語句是編譯不過去的
char *str = "apple";
最正确的語句應該是(因為字元串常量本身是常量,不應該指派給一個普通指針,這意味着通過指針可以改變常量的值,前後沖突,上面語句在一些地方能通過編譯,其實是由于曆史遺留問題):
const char *str = "apple";
(3)字元串正确指派給變量應該是給str,因為字元串傳回的其實是字元串的首位址,是以應該指派給指針str,而不是*str,該指針指向首位址。
綜上最正确的答案應該如下:
1 int main(){
2 const char *str = "apple";//常量指針,指向的内容不可變
3 str = "oragne";//指針的指向是可變的
4 cout<<str<<endl;
5 getchar();
6 return 0;
7 }