「那swap裡面的int temp =*x和下面的操作是什麽意思啊?」
「這裡就涉及到了指針中最常用的兩個運算符了:*和&。
取地址符&算是我們的老朋友了,它能夠將一個變量藏在靈魂深處地址取出來。在我們最初使用scanf函數的時候,就用到了它,例如我們要從小黑屏上面輸入一個數字,然後把這個數字賦值給a:
int a = 0;
scanf(“%d“,&a);
現在我們學了指針了,其實這兩句代碼和下面的代碼起到過效果完全一樣:
int a = 0;
int* p =&a;
scanf(“%d“, p);
在上面的代碼中,咱們把a的地址取出來了,然後把這個地址賦值給了一個指向int類型的指針變量p,在scanf函數中,實際上就通過這個指針變量p給a進行了賦值。
至於*嘛,它可是&的好夥伴,&能夠將一個變量的地址取出來,*可以從這個地址中獲取變量的值,它們倆加起來可以說的狼狽為奸,無惡不作,沒有哪個變量能夠逃出它們的手掌心。
用另外一個方式說,這兩貨就是那種遊戲中開掛的,能力強得一塌糊塗。
我們還是拿可憐的變量a來舉例子:
int a = 0;
int* p =&a;
*p = 10;
這個時候*p就相當於a本身了,也就是說,我們可以通過*p來操作變量a所在那四個字節內存。我們對*p進行賦值,效果和對a賦值一樣,而我們把*p賦值給一個變量,就和把a賦值給一個變量效果一樣。例如:
int b =*p;
和
int b = a;
效果完全一樣。」
「那這麽看來指針的使用也不是那麽難嘛,就這麽兩個運算符。」
從老爹目前的講述來看,指針真的沒有什麽難的,無非就是通過利用指針地址給某個變量賦值,或者獲取某個變量的值。只是讓我想不明白的是,明明我們已經有了變量名,為什麽還要設計指針這種東西?
等等,我似乎明白老爹那個swap函數的原理了。
「老爹,我好像明白那個用指針實現a、b兩個變量內容交換的原理了。」
我腦中劃過一道電光,整個人猶如醍醐灌頂,想明白了一切。
「哦,說說看!」
老爹饒有趣味地看著我。
「指針變量,指針變量,首先它是一個變量,那麽指針變量在函數中傳參的時候肯定也要遵守和普通變量一樣的規則——值傳遞!
swap函數之所以能夠實現交換兩個交換,是因為指針變量傳遞的值不是普通的值,而是一個地址。
按照老爹你之前的說法,在調用函數時,將會把實際參數的值複製一份給形式參數,所以形式參數同樣也拿到了要進行交換的那兩個變量的地址,那麽我們通過地址進行讀寫操作最後同樣會作用在變量上!」
「啪……啪……啪……不錯不錯,居然一下子就明白這其中的原理所在!想當年我領悟到這一層的時候可是花了不少的時間!」
老爹一臉拍了十來下手掌,毫不吝惜他的讚揚之詞。
就連旁邊的小弦子也面露佩服之色,
看來我總算是贏了小弦子一次了! 「不錯,這就是指針存在的意義所在。而且指針之所以說它是C語言的精髓所在,並不是說它的用法有多麽複雜,而是它可以和任意數據類型結合在一起,非常的靈活。
但是它也有讓人抓狂的時候,一旦指針出問題,可能讓你抓破腦袋也想不明白問題出在哪兒。放心,以後你們都會遇到的。」
老爹神秘地笑了笑。
「現在的內容還能聽懂麽?」
「嗯~」
「好,能聽懂的話我們就進行下部分內容——指針和數組的結合使用,睜大你們的眼睛看清楚了:
int a[]={1, 2, 3, 4, 5};
int *p = a;
看到沒,我現在把一個int數組賦值給了一個指向int類型的指針,你們大膽地猜測一下會不會出錯?」
「呵呵,我才懶得猜,把代碼寫出來編譯一下不就知道會不會出錯了麽?」
我都被自己的機智感動了,當然了,這是因為我有所依仗。這一來嘛,區區兩句代碼而已,二來就是我打字速度快啊!
一頓操作猛如虎,編寫、編譯分分鍾搞定。
「咦,還真的可以啊!」
「所以啊,記住,一個數組的數組名,就是這個數組的指針地址,也是數組首個元素的地址,換言之,上面的代碼這句等效:
int* p =&a[0];
既然我們都已經拿到一個數組的指針地址了,那麽接下來就可以對它的元素進行任意讀寫操作了。不過有一點要記住,一定不能超過數組的上下限,不然你就死翹翹!
我們可以利用指針來獲取元素,或者給元素賦值:
for(int i = 0; i < 5; i++)
{
printf(“%d,%d,%d“,a[i], p[i],*(p + i));
}
來來來,猜猜結果,猜中了有獎勵哦!」
「哈哈,它們輸出的內容是相同的!」
老爹話音剛落, 我這邊就已經看到了運行結果。
「嘿,任靈玥同學,你這麽喜歡敲代碼是吧,信不信我讓你手寫50遍!」
老爹做出一副很凶的樣子說道。
「沒錯,它們輸出的內容的確是相同的,那是因為它們的作用一模一樣。剛剛我說了,數組名就是一個數組的指針地址,既然可以用a[i]來獲取元素值,我們把a賦值給了p,那麽p當然也是可以這樣操作的。
至於p + 1嘛,是將指針指向的位置往從前位置移動一個單位。注意,這裡的單位就和指針的指向的數據類型有關系了,如果指針指向的數據類型是一個int,那麽它指向的就是下一個int數據,是double的話,就移動到下一個double數據。
換句話說,*(p + i)等效於p =(int*)((int)p + i * 4)。
我們首先把p的值,也就是一個地址值轉換成int類型,假設數組a在內存中的地址是1234,p + i其實就是執行了1234 + i * 4,然後再把這個值,那麽*(p + i)自然就是取的起始地址為1234 + i * 4這個int數據的值了。
而a[0]的地址是1234;
a[1」的地址是1234 + 1 * 4;
a[2」的地址是1234 + 2 * 4;
a[3」的地址是1234 + 3 * 4;
a[4」的地址是1234 + 4 * 4;