文章目錄
- 1、指標與引用的區別?
- 2、下面5個函數哪個能成功進行兩個數的交換?
- 3、這個函數有什麼問題?該如何修改?
指標是C系語言的特色。指標是C++提供的一種頗具特色的資料類型,允許直接擷取和操縱資料地址,實現動態儲存裝置分配。
指標問題,包括常量指標、數組指標、函數指標、this指標、指標傳值、指向指標的指標等,這些問題也是各大公司常備考點,下面讓我們一起學習其中的重點與痛點。
1、指標與引用的區別?
答案:
(1)非空區別。在任何情況下都不能使用指向空值的引用。因此如果你使用一個變數並讓它指向一個對象,但是該變數在某些時候也可能不指向任何對象,這時你應該把變數聲明為指標,因為這樣你可以賦空值給該變數。相反,如果變數肯定指向一個對象,例如你的設計不允許變數為空白,這時你就可以把變數聲明為引用。不存在指向空值的引用這個事實意味著使用引用的代碼效率比使用指標要高。
(2)合法性區別。在使用引用之前不需要測試它的合法性。相反,指標則應該總是被測試,防止其為空白。
(3)可修改區別。指標與引用的另一個重要的區別是指標可以被重新賦值以指向另一個不同對象。但是引用則總是指向在初始化時被指定的對象,以後不能改變,但是指定的對象其內容可以改變。
2、下面5個函數哪個能成功進行兩個數的交換?
#include<iostream>using namespace std;void swap1(int p,int q){int temp;temp=p;p=q;q=temp;}void swap2(int *p,int *q){int *temp;*temp=*p;*p=*q;*q=*temp;}void swap3(int *p,int *q){int *temp;temp=p;p=q;q=temp;}void swap4(int *p,int *q){int temp;temp=*p;*p=*q;*q=temp;}void swap5(int &p,int &q){int temp;temp=p;p=q;q=temp;}int main (){int a=1,b=2;//swap1(a,b);//swap2(&a,&b);//swap3(&a,&b);//swap4(&a,&b);//swap5(a,b);cout << "a:"<< a <<endl;cout << "b:"<< b <<endl;return 0;}
解析:這道題考察的是參數傳遞、值傳遞、指標傳遞(地址傳遞)和引用傳遞。
swap1傳遞的是值的副本,在函數中只是修改了形參p、q(實際是a、b的一個拷貝),p、q的值確實交換了,但是它們是局部變數,不會影響到主函數a和 b 。當函數swap1生命週期結束時,p、q所在的棧也就被刪除了。
swap2傳遞的是一個地址進去,在函數體內的形參*p、*q是指向實際的參數a、b地址的兩個指標。
這裡要注意:
int *temp;
*temp=*p;
是不符合邏輯的,int *temp建立了一個指標(但是沒分配記憶體)。*temp=*p不是指向而是拷貝。把*p所指向的記憶體的值(也就是a 的值)拷貝到*temp所指向記憶體裡了。但是int *temp不是不分配記憶體嗎?的確不分配,於是系統在拷貝時臨時給了一個隨機地址,讓它存值。分配的隨機地址是個“意外”,且函數結束後不回收,造成記憶體流失。
swap3傳遞的是一個地址,在函數體內的參數*p、*q是指向實際參數a、b地址的兩個指標。
這裡要注意:
int *temp;
temp=p;
int *temp建立了一個指標(但是沒分配記憶體)。temp=p是指向而不是拷貝。temp指向了*p所指向的地址(也就是a )。而代碼:
int *temp;
q=temp;
但是函數swap3不能實現兩數的交換,這是因為函數體內只是指標的變化,而對地址中的值卻沒有變化。
swap4可以實現兩數的交換,因為它修改的是指標所指向地址中的值。
swap5函數與swap4相似,是一個引用傳遞,修改的結果直接影響實參。
答案:
swap4 函數和 swap5 函數。
3、這個函數有什麼問題?該如何修改?
char *strA(){char str[] = "hello world";return str;}
解析:這個str裡存在的地址是函數strA棧裡“hello world”的首地址。函數調用完成,棧幀恢複調用strA之前的狀態,臨時空間被重設,堆棧“回縮”,strA棧幀不再屬於應該訪問的範圍。這段程式可以正確輸出結果,但是這種存取方法違背了函數的棧幀機制。
但是只要另外一個函數調用的話,你就會發現,這種方式的不合理及危險性。
如果想獲得正確的函數,改成下面這樣就可以:
char *strA(){char *str = "hello world";return str;}
首先要搞清楚char *str 和 char str[] :
char str[] = "hello world";
是分配一個局部數組。局部數組是局部變數,它所對應的是記憶體中的棧。局部變數的生命週期結束後該變數不存在了。
char *str = "hello world";
是指向了常量區的字串,位於靜態儲存區,它在程式生命期內恒定不變,所以字串還在。無論什麼時候調用 strA,它返回的始終是同一個“唯讀”的記憶體塊。
另外想要修改,也可以這樣:
char *strA(){static char str[] = "hello world";return str;}
通過static開闢一段靜態存貯空間。
答案:
因為這個函數返回的是局部變數的地址,當調用這個函數後,這個局部變數str就釋放了,所以返回的結果是不確定的且不安全,隨時都有被收回的可能。
對於指標與引用這部分還有一些內容,都是比較難的,還需要花點時間研究研究,最近這幾天也比較忙,剩下的會給你們的,嗯,今天就這點了……