指針和引用
1. 引用和指針有什么區(qū)別擦俐?
- 引用是 C++ 中新增的變量類(lèi)型,是對(duì) C 的一個(gè)擴(kuò)充握侧。引用給變量起一個(gè)別名蚯瞧,引用和對(duì)應(yīng)的變量代表同一個(gè)變量單元。
- 指針是 C 語(yǔ)言中一個(gè)重要的數(shù)據(jù)類(lèi)型品擎。指針用于指向?qū)ο蟮牡刂纷粗瑥亩`活的實(shí)現(xiàn)對(duì)對(duì)象的操作。
區(qū)別:
(1)引用必須被初始化孽查,指針可以不用初始化饥悴;
(2)引用初始化以后就不能改變,而指針可以改變所指的對(duì)象盲再;
(3)不存在指向空值的引用西设,而指針可以指向一個(gè)空值;
(4)" sizeof(&a) " 得到的是所指向的變量(對(duì)象)的大小答朋,而 " sizeof(*p) " 得到的是指針本身的大写俊;
2. void 指針是空指針嗎梦碗?
void 指針一般被稱為通用指針禽绪,用于指向一個(gè)不屬于任何類(lèi)型的對(duì)象。和空指針完全是兩回事洪规。
3. 指針的定義
- *int a[10];
指針數(shù)組:一個(gè)有 10 個(gè)指針的數(shù)組印屁,該指針是指向一個(gè)整型數(shù)的 -
int (a)[10];*
數(shù)組指針:一個(gè)指向有 10 個(gè)整型數(shù)數(shù)組的指針 -
int (a)(int);*
函數(shù)指針:一個(gè)指向函數(shù)的指針,該函數(shù)有一個(gè)整型參數(shù)并返回一個(gè)整型數(shù) -
int (a[10])(int);*
函數(shù)數(shù)組指針:一個(gè)有 10 個(gè)指針的數(shù)組斩例,且每個(gè)指針指向一個(gè)函數(shù)雄人,每個(gè)函數(shù)有一個(gè)整型參數(shù)并返回一個(gè)整型數(shù)
4. 各種復(fù)雜指針的聲明
-
float (**fa)[10]:fa 是一個(gè)二級(jí)指針,它指向的是一個(gè)一維數(shù)組的指針念赶,數(shù)組的元素都是 float础钠。
先找到標(biāo)識(shí)符 fa恰力,它外面有一個(gè)圓括號(hào),先看括號(hào)內(nèi)旗吁。fa 的左邊是兩個(gè)緊挨著的 * 號(hào)踩萎,這說(shuō)明 fa 是一個(gè)二級(jí)指針;括號(hào)里面解析完畢很钓,看括號(hào)外面的右側(cè)香府,有一個(gè) [10] ,表明這個(gè)指針指向一個(gè)包含 10 個(gè)元素的一維數(shù)組履怯;再看括號(hào)的左邊回还,有一個(gè) float 表明這個(gè)一維數(shù)組是 float 類(lèi)型的。 -
double *(*sp)[10]:sp 是一個(gè)指針叹洲,它指向一個(gè)一維數(shù)組柠硕,該數(shù)組元素都是 double* 。
sp 的左邊是一個(gè) * 號(hào)表示它是一個(gè)指針运提,跳出圓括號(hào)蝗柔,右邊是 [ ] 運(yùn)算符,表明這個(gè)指針指向一個(gè)一維數(shù)組民泵;再看左邊声离,是一個(gè) * 號(hào)赁濒,再左邊是 double 類(lèi)型,表明這個(gè)一維數(shù)組的元素都是指向 double 類(lèi)型的指針。 - double(*arr[10])():arr 是一個(gè)數(shù)組斜友,arr 有十個(gè)元素皿哨,元素都是函數(shù)的指針滥比,指向的函數(shù)類(lèi)型是沒(méi)有參數(shù)且返回 double 的函數(shù)盗扇。
技巧:首先要找到要定義的標(biāo)識(shí)符,一個(gè)聲明里只能有一個(gè)要聲明的標(biāo)識(shí)符寥假。找到標(biāo)識(shí)符后市框,從標(biāo)識(shí)符所在最里面的括號(hào)看起,先往右看糕韧,再往左看枫振。每當(dāng)遇到圓括號(hào)就調(diào)轉(zhuǎn)閱讀方向。括號(hào)里面的內(nèi)容解析完成后就跳出括號(hào)重復(fù)這個(gè)過(guò)程直到結(jié)束萤彩。
5. 指針與函數(shù)
下面 3 個(gè)函數(shù)中有指針問(wèn)題的是:
int *f1(void)
{
int x = 123;
return (&x);
}
int *f2(void)
{
int *p;
*p = 123;
return p;
}
int *f3(void)
{
int *p;
p = (int*) malloc(sizeof(int));
return p;
}
函數(shù) f1 返回一個(gè)局部變量的指針粪滤,而局部變量是保存在棧中的,退出函數(shù)后乒疏,局部變量就銷(xiāo)毀了额衙,保留其指針沒(méi)有意義,因?yàn)槠渲赶虻臈怕吴?臻g可能被其它變量覆蓋了窍侧。
函數(shù) f2 也有問(wèn)題,p 是局部變量转绷,未初始化伟件,它的值是未知的,*p 不知道指向哪里了议经,直接給 *p 賦值可能會(huì)覆蓋該位置的重要的內(nèi)容斧账,會(huì)引起不可預(yù)料的錯(cuò)誤。
函數(shù) f3 使用指針指向了一塊新申請(qǐng)的內(nèi)存煞肾,然后返回這塊內(nèi)存的地址咧织,所以沒(méi)有問(wèn)題。
6. 什么是 “ 野指針 ” 籍救?
闡釋對(duì) “ 野指針 ” 的理解习绢,它又是如何產(chǎn)生的以及對(duì)程序有什么影響?
“ 野指針 ” 是在定義指針后沒(méi)有對(duì)其進(jìn)行初始化蝙昙,或者指針指向的內(nèi)存被釋放闪萄,而指針沒(méi)有被設(shè)置為 NULL 。野指針隨機(jī)指向一個(gè)地址奇颠,使用這個(gè)指針進(jìn)行操作時(shí)败去,就會(huì)更改該內(nèi)存的數(shù)據(jù),造成程序數(shù)據(jù)的破壞烈拒,嚴(yán)重威脅程序的安全圆裕。