在 C 語言中用的最多的就是指針了,指針一樣也是 C 語言的精華所在了。咱們今天就來看看指針究竟是什麼,它是如何使用的。面試
咱們先來回想下變量,在程序中的變量只是一段存儲空間的別名,那麼是否是必需要經過這個別名才能使用這段存儲空間呢?答案確定不是的,咱們還能夠經過指針來使用這段存儲空間。在指針聲明時,* 號表示所聲明的變量爲指針。在指針使用時,* 號表示取指針所指向的內存空間中的值。咱們經過下面這幅圖能夠更加直觀的看出他們的關係ide
經過這個圖片咱們是否是更加直觀的看出它們的關係呢。上面即表示的是變量 p 保存着變量 i 的內存地址,即 p <--> &i; *p <--> i。函數
下來咱們經過示例代碼進行分析說明,代碼以下學習
#include <stdio.h> int main() { int i = 0; int* pI; char* pC; float* pF; pI = &i; *pI = 10; printf("%p, %p, %d\n", pI, &i, i); printf("%d, %d, %p\n", sizeof(int*), sizeof(pI), &pI); printf("%d, %d, %p\n", sizeof(char*), sizeof(pC), &pC); printf("%d, %d, %p\n", sizeof(float*), sizeof(pF), &pF); return 0; }
咱們在678行分別定義了 int* char* float* 類型的指針,在第10行經過指針 pI 指向了 i 的地址,再經過第12行的取指針的內容並賦值來達到改變 i 的值。那麼咱們接下來打印下指針 pI 的地址,i 的地址還有 i 的值分別是什麼。還有看下三種不一樣類型的指針所佔的內存大小和地址各是什麼,編譯結果以下spa
那麼咱們看到指針 pI 和 i 的地址相同,而且 i 的值已經經過指針成功改變爲10。接着咱們看到不論是什麼類型的指針所佔的內存大小都是4,並非咱們以前所認爲的 int 爲4,char 爲1,float 爲4啦,它們的地址連續着。說明指針在內存中並無類型之分,所存儲的內存都是在同一個段上。指針
咱們接下來再來看個傳值調用和傳址調用。那麼在程序中,指針也是變量,所以能夠聲明指針參數。當一個函數體內部須要改變實參的值,則須要使用指針參數。函數調用時實參值將複製到形參,指針適用於複雜數據類型做爲參數的函數中。咱們下來利用示例代碼進行說明傳值調用和傳址調用的區別,代碼以下blog
#include <stdio.h> int swap(int a, int b) { int c = a; a = b; b = c; } int main() { int aa = 1; int bb = 2; printf("aa = %d, bb = %d\n", aa, bb); swap(aa, bb); printf("aa = %d, bb = %d\n", aa, bb); return 0; }
咱們想固然是 swap 函數能完成兩個數交換的功能,咱們來編譯下,看看是否能交換呢?圖片
結果是這樣的,臥槽,是咱們搞錯了嘛。看來看去以爲程序就該這麼寫啊,咱們再來仔細分析下。咱們在第19行只是將變量 aa 和 bb 的值複製給了 swap 函數的實參 a 和 b。在 swap 函數內部確實完成 a 和 b 的值交換,但只是 a 和 b 的值交換了而已。換句話說,這時他兩跟變量 aa 和 bb 沒啥關係,咱們這種就屬於傳值調用。咱們再將 swap 函數改爲下面這樣呢?看看結果如何內存
int swap(int* a, int* b) { int c = *a; *a = *b; *b = c; }
再將 main 函數中第19行改爲 swap(&aa, &bb); 咱們來看看編譯結果如何it
咱們看到加了個 * 號,居然神奇般改變了 aa 和 bb 的值。感受很神奇啊,咱們仔細分析下,這就是屬於利用指針指向變量 aa 和 bb 的地址,而後再經過 * 取地址處的內容再賦值改變。這樣就是咱們所說的傳址調用啦。
咱們下來再來看看一個筆試面試中常常會問到的問題:a> const int* p;b> int const* p;c> int* const p;d> const int* const p 四種有什麼區別。咱們來一一分析:a> p 可變但它指向的內容不可變;b> p 可變但它指向的內容不可變;c> p 不可變但它所指向的內容是可變的;d> p 和它所指向的內容都是不可變的。咱們對待這種問題有個口訣就是:左數右指(這是唐長老總結出來的)。什麼意思呢?就是當 const 出如今 * 號左邊時指針指向的數據爲常量,當 const 出如今 * 號右邊時指針自己爲常量。這樣是否是就很好記了呢?反正博主是記住了哈。
咱們下來再來個示例代碼對其進行說明,代碼以下
#include <stdio.h> int main() { int i = 0; const int* p1 = &i; int const* p2 = &i; int* const p3 = &i; const int* const p4 = &i; *p1 = 1; // compile error p1 = NULL; // ok *p2 = 2; // compile error p2 = NULL; // ok *p3 = 3; // ok p3 = NULL; // compile error *p4 = 4; // compile error p4 = NULL; // compile error return 0; }
咱們看到第12行明顯會出錯,由於 const 出如今 * 號的左邊,左數右指嘛,就是它所指向的內容是不可變的。第15行也是一樣的錯誤。第19行則是由於 p3 是 const 出如今 * 號的右邊,因此它自己不可變。p4 先後都有 const,因此第2一、22行均會出錯。咱們來看看分析是否正確呢
咱們看到結果與咱們分析的是一致的,咱們之後遇到這種筆試面試題豈不是送分題啦?哈哈,開個玩笑了,其實仍是很簡單的只需記住口訣就好。咱們看看指針是不是那樣傳說中的難呢?其實也不難的。經過對指針的學習,咱們總結以下:一、指針是 C 語言中一種特別的變量;二、指針所保存的值是內存的地址;三、能夠經過指針修改內存中的任意地址內容。
歡迎你們一塊兒來學習 C 語言,能夠加我QQ:243343083。