標籤:

求解一個C語言問題?

int main{
int a[5] = {1,2,3,4,5};
int *str = (int *)(a+1);
printf("%d
%d
", *(a+1), *(str-1));
return 0;
}

輸出結果為2和5,為什麼後面的是5?


雖然問的是C語言,不過你可以使用以下代碼在VC++裡面得到解答(不推薦g++是因為輸出的字元串不人性化):

#include &
#include &
#include &
using namespace std;

int main()
{
int a[5];
cout &<&< typeid(a).name() &<&< endl; cout &<&< typeid(a+1).name() &<&< endl; cout &<&< typeid(a).name() &<&< endl; return 0; }


這裡,a其實是一個指向數組(數組長度為5個整數,每個整數4位元組,共20個位元組)的指針,所以

int *str = (int *)(a + 1); //這裡的1應該是按照20個位元組的地址算,因此,str = a地址 + 20個位元組的地址

所以str - 1相當於 a的地址+16個位元組的地址,正好是a[4]。

上圖:

說明:0xe0 - 0xcc = 0x14,即20


這裡a是數組的首地址!然而a卻是數組的地址!因為類型不一樣,所以+1後的結果也就不一樣!


沒錯,這裡str指向了一整個數組的下一個地址


其實就倆重點。。

1. a+1 加的長度是整數組a的,因為的優先順序高,以及a是一個數組。

2. str-1 卻只減去了一個int長度的地址,因為str是int *類型的。。

最後,諸位大神說得都很對。


看下列印的內存地址的值。


作為數組名,a代表了數組的首地址,你對a做取地址運算 得到的自然是指向數組a的指針,所以int *str = (int *)(a+1)在內存中實際後移了1個數組單位(本題中是5個int×4位元組/int=20位元組),注意這裡有一個陷阱:str的類型是int*,a的類型可是int**哦。所以*(str-1)在內存中是前移1個int單位,即4位元組,於是輸出了數組的最後一個元素5


在數組中,a[5]={1,2,3,4,5}中,a指的是這個數組的首地址,a[0]指的是數組首元素的首地址。

a+1,跨越了整個數組。

小夥子(可能是小美女),一看就是php沒學好吧,哎,好可憐.........(逃


面試被虐了?

《程序員面試寶典》里有原題。。

你值得擁有。


看看《C和指針》這本書吧。系統地學習關於C語言的知識


a仍是數組的首地址,但類型是整個數組的長度,本例中長度是5個int的長度。

a+1的值,相當於是a[5]的地址。

強轉類型後,(int *)轉換後,指針指向的數據類型變為int型的,即str指針減一,減去的長度為一個int的長度,所以列印的值為a[4]的值。

推薦看c++ primer plus的第4章,正好前幾天剛看過,手機碼字太費勁了。


a提取了整個數組的地址,換句話說a就是一個指向整個數組的指針,而它的長度就是5*4 byte= 20(16h)byte。該指針的值和a數組的第一個元素a[0]的地址相同。我覺得如果理解了二維數組,理解這道題就比較容易了。


說點題外話

看到這麼多人肯來回答初學者的問題。我這個菜鳥好感動啊。

這個題目我們培訓老師問過我們。當時我就懵逼了。我問我一個同學他說如果沒有對指針的深刻理解是跟我說不同的。(我對指針的理解很差)

看了這個題目下的回答後我算是有點想的明白這個題目了。

一開始看到這個題目還以為會有人嘲諷你不會去問老師啊諸如此類的。


a指向一個元素,a+1指向數組的下一個元素

a指向一個數組,a+1指向下一個數組

a與a指向地址相同,類型不同


指針應該 取消運算功能。或者運算是以位元組為單位的


a是數組的地址,a[0]是首個元素地址,a+1是整個數組的下一個地址。


(a+1)是數組指針,+20個位元組,這裡用(int*)(a+1)轉換成int型指針,再-1的話就是減四個位元組了。


給@Thomas Huang 的答案補個圖

PS:總之是 a + 1 是增加了一個數組a長度( 5 * sizeof(int)),而a + 1是只增加了一個int的長度。


推薦閱讀:

在編程和演算法領域,有哪些經典問題?
有哪些適合實習程序員使用,性能上能媲美 Macbook Pro 的筆記本電腦值得推薦?
關於c++中用extern引用的變數類型與定義類型不一致的一個疑問?
怎麼樣才算得上熟悉多線程編程?

TAG:編程 |