C語言指標系列三 指標運算本質

2021-06-28 18:59:33 字數 2350 閱讀 6519

c語言指標系列三——指標運算本質

對於如下的宣告:

int arr=;

int *p;

p=arr;

儘管最後乙個語句看起來是將乙個指標賦值為陣列名,但c語言中並不存在指向陣列的指標,日常說某某個指標指向了陣列只不過是一種習慣,並不是說真的有乙個陣列型的指標指向了陣列。事實上,如上面的程式段,因為arr是乙個int型別的陣列,arr裡面的元素全都是int型,p=arr實際上是將整型指標p指向了陣列的首元素1(是乙個整型),更具體的是p指向了陣列首元素的首位元組——p儲存的是陣列首元素的首位元組的位址。

因為p是乙個整型指標變數(假設int佔4個位元組),它指向了乙個int。所以對p進行自加的結果是p原來的值加上4(4剛好是乙個int佔的位元組數)。有了這個鋪墊,也就有了下面的巧合:

#includeint main()

; int* p;

for (p=arr; p < arr + 5; p++)

printf_s("%p--%p", arr,arr+5);

return 0;

}

在for迴圈裡,因為p指向了乙個整型變數,對p進行自加是在原來的值上加上4,因為陣列在記憶體中是連續儲存的,所以對p進行自加的結果恰好是下乙個元素的首位址。此時輸出*p就是陣列的下乙個元素。arr+5就是在arr本身的值的基礎上加上5個int所佔的位元組,也就是20。輸出結果如下:

記憶體位址是用16進製表示的,可以看到,每一次自加p,p的值就相差4。在最後的輸出中,arr與arr+5相減的結果是00000014,它等當10進製數20(5個int佔的位元組數)。

再看下面的**:

#includeint main()

; char arr2 = ;

double arr3 = ;

int* p=arr;

char *p2=arr2;

double *p3=arr3;

printf_s("int佔%d位元組數,char佔%d位元組數,double佔%d位元組數\n",sizeof(int),sizeof(char),sizeof(double));

printf_s("%p----%p\n",p,p+1);

printf_s("%p----%p\n", p2,p2+1);

printf_s("%p----%p\n", p3,p3+1);

return 0;

}

輸出為:

試著將對應的16進製制數相減,然後再轉換為10進製,看看有什麼發現…

原來,將乙個指標變數加

1(或自加

)就是在指標變數原始的值的基礎上加上指標變數所指向的型別在記憶體所佔的位元組數。如指向

int型的指標加

1將會加上

4,指向

char

型的指標加

1將會加上

1,指向

double

型的指標加

1將會加上8。

讓我們再來看一下陣列,arr[1]是選取陣列arr的第1位元素(從第0開始),事實上,陣列名再加一對中括號選取陣列元素是乙個語法糖,編譯器並不是按照這種方式來處理陣列的。對編譯器說arr[1]相當於*(arr+1),這才是編譯器處理陣列的方式。語句*(arr+1)首先對括號裡的arr+1進行運算,它將得到陣列元素第1個元素(從第0開始)的位址,然後利用*號取得這個位置的值,它等價於arr[1]。由於編譯器是按照*(arr+1)的方式來處理陣列的。因此下面的這兩種方式可能非常常見:

#includeint main()

; int* p=arr;

for (int i = 0; i < 5; i++)

printf_s("\n");

//or

for (; p < arr + 5;)

return 0;

}

輸出為:

通過指標來訪問陣列被認為是高效的,畢竟這是編譯器處理陣列的方式。但不得不說,這是一種古老的說法(以前的確是更加高效),現代的編譯器都是經過高度優化的,使用*(arr+1)來訪問陣列並不比使用arr[1]訪問陣列帶來實質的效率提公升,但它的壞處非常明顯——它更難以閱讀,到底使用何種方式來使用陣列,這裡不給出建議。

c指標點滴三(指標運算)

1 include 2 include 3 4void main3 512 13 void main4 14 24 system pause 25 26 27void main5 28 30int p5 a 2 31 printf d a 2 32 p5 p5 2 相當於在陣列內部向後移動兩個元素的...

C語言筆記系列 六 指標

指標的值是位址,大多系統內部由無符號整數表示,但它是一種新的資料型別,不是整數型別。int n 20 printf d p n,n 分別輸出值和位址 四種宣告等價 intsum int a,int n intsum int int intsum int a,int n intsum int int ...

24 指標的本質

變數代表一段儲存空間的別名,但並不是只能通過變數才能訪問一段記憶體了,指標也可以 1 號的意義 p i p i 為什麼指標的大小占用為4個位元組?因為如果系統是32位,位址定址範圍為4個位元組,所有的32位位址值都可以用4個位元組表示,所以32位系統指標的大小都為4個位元組 2 傳值呼叫與傳址呼叫 ...