我們都知道,至少聽(tīng)說(shuō)過(guò)指針對(duì)于C語(yǔ)言中的重要意義,但是在使用指針時(shí)卻常常讓我們痛不欲生,這里有幾個(gè)在聲明指針有關(guān)的變量時(shí)易錯(cuò)的地方。 1. int* 和 int * (注意空格的位置)
對(duì)于單變量聲明,即一條語(yǔ)句中只聲明一個(gè)指針變量的情況,沒(méi)有區(qū)別;原因是C語(yǔ)言允許形式的自由性。即以下兩種聲明方式效果相同。
[c++]
view plaincopyprint?int *a;
int *a;[c++]
view plaincopyprint?int* a;
int* a;
對(duì)于一條語(yǔ)句中聲明多個(gè)指針變量的情況,有很大區(qū)別。
[c++]
view plaincopyprint?int* a, b,c;
int* a, b,c;
對(duì)于這條語(yǔ)句,常會(huì)造成我們的誤解:認(rèn)為聲明了三個(gè)整型指針。但是正解是:只有a是整型指針,b和c都是普通的整數(shù)。
這里的星號(hào)“*”號(hào)只是聲明變量a的一部分,以上的變量聲明相當(dāng)于:
[c++]
view plaincopyprint?int *a;
int b;
int c;
int *a;int b;int c;
如果希望在一條語(yǔ)句中聲明多個(gè)整型指針,正確的方式應(yīng)該是:
[c++]
view plaincopyprint?int *a, *b, *c;
int *a, *b, *c;2. typedef 和 #define 在創(chuàng)建類型別名時(shí)的區(qū)別
在C語(yǔ)言中實(shí)現(xiàn)創(chuàng)建類型別名的方法有兩種:一種是使用typedef;一種是使用#define。使用方法也類似。
[c++]
view plaincopyprint?typedef int NEW_INT_TYPE1; /*int在前*/
NEW_INT_TYPE1 a1 = 1;
#define NEW_INT_TYPE2 int /*int在后*/
NEW_INT_TYPE2 a2 = 2;
printf("%d /n",a1);
printf("%d /n",a2);
typedef int NEW_INT_TYPE1; /*int在前*/ NEW_INT_TYPE1 a1 = 1; #define NEW_INT_TYPE2 int /*int在后*/ NEW_INT_TYPE2 a2 = 2; printf("%d /n",a1); printf("%d /n",a2);
但是如果需要?jiǎng)?chuàng)建新類型名時(shí),我們只應(yīng)該使用typedef,而不是#define。因?yàn)?define僅僅是在編譯的時(shí)候做簡(jiǎn)單的替換工作,所以在處理一些問(wèn)題上會(huì)有缺陷。
[c++]
view plaincopyprint?int m=2;
typedef int* NEW_INT_TYPE3; /*int在前*/
NEW_INT_TYPE3 a3, a4;
a3 = &m; /*指針賦值*/
a4 = &m; /*指針賦值*/
#define NEW_INT_TYPE4 int* /*int在后*/
NEW_INT_TYPE4 a5, a6=6;
a5 = &m; /*指針賦值*/
printf("%d /n",*a3);
printf("%d /n",*a4);
printf("%d /n",*a5);
printf("%d /n",a6);
/*運(yùn)行結(jié)果:
2
2
2
6*/
int m=2; typedef int* NEW_INT_TYPE3; /*int在前*/ NEW_INT_TYPE3 a3, a4; a3 = &m; /*指針賦值*/ a4 = &m; /*指針賦值*/ #define NEW_INT_TYPE4 int* /*int在后*/ NEW_INT_TYPE4 a5, a6=6; a5 = &m; /*指針賦值*/ printf("%d /n",*a3); printf("%d /n",*a4); printf("%d /n",*a5); printf("%d /n",a6); /*運(yùn)行結(jié)果: 2 2 2 6*/
分析:a3和a4是整型指針,a5是整型指針,但是a6只是整型(只要記住#define 僅僅是做替換操作,將NEW_INT_TYPE4替換為int*,而int* a5, a6; 的結(jié)果是“a5是整型指針,a6是整數(shù)”);
3. “常量指針”和”指向常量的指針”
對(duì)于常量變量:int const a 和const int a 效果相同;都是聲明一個(gè)整型的變量a,且a是常量,其值不能改變(由于其值不能改變,其賦值方式只有兩種:一種是聲明時(shí)初始化,如int const a=1; 一種是其作為函數(shù)的形式參數(shù),函數(shù)被調(diào)用時(shí)用實(shí)參來(lái)初始化)。
對(duì)于含有指針時(shí),根據(jù)聲明時(shí)const和星號(hào)"*" 的位置,有三種形式:
形式
名稱
說(shuō)明
分析方法
int const *p指向常量的指針能修改指針本身的值,但是不能修改其指向的值從變量標(biāo)識(shí)符開(kāi)始(即從右向左),①*p指向一個(gè)整數(shù);②const修飾”*p”,表示*p是一個(gè)常量,即p指向的值是一個(gè)常量。所以,不可以修改”*p”,即不可修改p指向的值。
const int *p指向常量的指針同上同上
int * const p指針常量能修改其指向的整型的值,但是不能修改指針本身的值從變量標(biāo)識(shí)符開(kāi)始(即從右向左),const修飾p,表示p是常量,即不能修改p本身,但p指向的值可以修改。
總結(jié),區(qū)分這兩種類型的順序是:從右向左看,一步一步的確定。
衍生的更為特殊的指針:指向常量的常量指針,聲明方式是 int const * const p; 對(duì)于它,“指針本身的值”和“指向的值”都不能修改。
注意:有常量聲明的變量只有兩種賦值方式;一種是在聲明時(shí)直接賦值,如int m; int * const p = &m; 另一種方法針對(duì)在函數(shù)中聲明的形式參數(shù),在函數(shù)被調(diào)用時(shí)被賦值,例如:當(dāng)是不需要修改數(shù)組的元素時(shí),形式參數(shù)使用int const a[],即a指向的內(nèi)容不能修改。
[c++]
view plaincopyprint?void firstTest(){
int m = 2;
int * const p = &m;/*指針p 是常量指針,要在聲明時(shí)賦值*/
/*不能寫為 int * const p; p = &m;*/
printf("%d /n",*p);
*p = 5; /*可以改變指針p 指向的值*/
printf("%d /n",*p);
getchar();
p=&m; /*編譯報(bào)錯(cuò),因?yàn)椴荒芨淖冎羔榩本身 的值,*/
}
void secondTest(){
int m = 2;
int n = 3;
int const *p; /*指向常量的指針*/
p = &m;
/*也可以寫為 int const *p = &m; */
printf("%d /n",*p);
p = &n; /*可以改變指針p本身的值*/
printf("%d /n", *p);
*p = 3;/* 編譯報(bào)錯(cuò),不能修改它指向的值。雖然這里*p的值本來(lái)就是2*/
}