1. 程式人生 > >正確理解C語言指標中的 &a+1,假設a為一個數組

正確理解C語言指標中的 &a+1,假設a為一個數組

1.int a[5]={1,2,3,4,5}; int p=(int)(&a+1); printf("%d",*(p-1)); 答案為什麼是5?

這個問題的關鍵是理解 &a

a是一個數組名,也就是陣列的首地址。
對a進行取地址運算子,得到的是一個指向陣列的指標!!!!這句話尤為重要!
也就相當於
int (*p) [5] = &a;
p 是一個指向陣列的指標,它指向的是一個包含 5 個 int 元素的陣列!!

那麼執行 &a+1 後,p 移動了一個數組的距離,p 的偏移量相當於 p + sizeof(int) * 5,指向 a 陣列最後一個元素的後一位 !!

而程式中強制將指標p轉換成一個int*,那麼 p -1 其實就是 p - sizeof(int)
所以,p -1 指向了陣列中的最後一個元素,也就是 5

  1. 以下輸出分別是多少?
#include <stdio.h>
int main()
{
	int a[5] = {1,2,3,4,5};
	int *ptr = (int *)( &a + 1);
	printf("%d, %d, \n", *(a+1), *(ptr-1) );
	return 0;
}

答案:2, 5
解釋: a 為大小為5的陣列,a表示陣列的首地址,&a表示陣列a的地址,&a+1表示移動了一個a陣列的大小的距離,ptr + sizeof(int) * 5

, 因此 ptr是一個指向a的最後一個元素的後一位的指標(ptr跨過了a的所有元素)。
因此,
(1)*(a+1) 表示 a 的首地址之後的一個元素,即 a[1]=2; C 語言和 Python都是 0-index;*
(2)*(ptr-1) 表示指標 ptr 移動了一位,ptr - sizeof(int), 因此指向a的最後一個元素a[4]=5;
(3)因此輸出為2和5。

這裡的關鍵在於區分 a + 1&a + 1中移動的“1”是不同的,前者只移動 sizeof(int),後者移動
sizeof(int) * sizeof(a)

陣列名 a 的特殊之處:
&a

: 代指 陣列的整體 的地址,這裡的 a是陣列整體
a: 代指 陣列的第一個成員,這裡的 a是陣列首地址

  1. 已知語句 int a=6, 則執行了語句 a+=a-=a*a 後,變數 a 的值為多少?

解:只有C語言才會有可讀性這麼神奇的表述。
程式是從右到左執行的,a的初始值為6:
(1)第一步:a=a-a*a=6-6*6=-30,此時 a=-30
(2)第二步:a=a+(a-a*a)=(-30)+(-30)=-60,此時 a=-60

注意:在開發過程中,寫這種語句的程式設計師是要被槍擊的(手動滑稽)~