2011-10-21 174 views
4

一位朋友問我在C中寫一個函數返回數組的第100個元素。我對C不是很熟悉,所以我不確定如何創建一個可以對任何類型的數組進行這樣操作的泛型函數,所以我欺騙並假定它是一個整數數組,並且編寫了這個函數:這看起來不像一個功能。這是什麼?

int GetHundredthElement(int *array) { 
    return array[100 - 1]; 
} 

(該- 1是那裏,因爲數組是零索引)

我問他怎麼做,將任何類型的數組的工作的功能。他告訴我,有一個簡單的方法來做到這一點:

int GetHundredthElement = 100 - 1; 

而且這種「功能」可以這樣調用:

GetHundredthElement[array]; 

我試了一下,和它的工作,但不對我來說看起來像一個函數,因爲它使用了括號表示法,這不是函數調用用C編寫的方式。我並不十分清楚這些代碼在做什麼或者它是如何做的。這裏發生了什麼?

+0

@ K-ballo有正確答案。但是,在將來,當你想要製作更復雜的函數時,可以使用任意精度類型(int,float,double等),並且如果你有權訪問C++(我認識到C語言特別提到的問題),進入'模板'。它們是C++的一個驚人的補充。 – Amit

回答

9

你是對的事實,GetHundredthElement不是一個函數 - 正如你所期望的那樣,它是一個整數。

但是,這說明了在C中一個令人驚訝的能力,您可以顛倒數組訪問的順序!

assert(a[5] == 5[a]); 

這是因爲數組訪問可以在指針運算來實現:

assert(a[5] == *(a+5)); 
assert(*(a+5) == *(5+a)); 
assert(*(5+a) == 5[a]); 
5

使用指針時,pointer[ index ]index[ pointer ]實際上是相同的。這不是一個功能,它是一個普通的運營商;它與array[ GetHundredthElement ]array[ 100 - 1 ]相同。

11

這不是一個函數,它只是利用一個鮮爲人知的C事實,即數組索引可以互換。所有x[y]表示法的真正含義是您正在訪問y數組的第x個偏移量。但你可以在你的案例中輕鬆地寫出y[x]並獲得相同的結果。

99[array]array[99]是可以互換的並且意味着相同的東西。通過聲明GetHundredthElement是99,你的朋友玩了一個巧妙把戲:)

但是,您可以編寫一個通用函數來獲得一個數組很容易使用C++模板(不是C)的百分之元素。

+6

請注意,這是因爲x [y]等於*(x + y)。由於加法是可交換的,所以這是*(y + x),然後是y [x]。 –

2

這是你可以訪問陣列特殊的時髦方式。讓我們回想一下,數組可以像指針一樣對待,並且可以使用算術。

例如:

x是一些任意數組:

int x[4]; 

蘊涵訪問x的第五元件,其是*(x+4)。的存儲器佈局

可怕例如:

x -> [0][1][2][3][4] 

現在,可以用C數組做奇怪的事情/指針塊,是在翻轉括號符號的數目和變量。

x[4] is equal to 4[x] 

因爲它們分解成:

*(x+4) and *(4+x) 
+0

只是爲了好奇,你會如何向後代表'x [4] [4]'?它會是'(4 * 4)[x]'嗎? – Amit

+2

@Amit - 我必須承認,我不知道如何做到這一點與多維陣列奇怪的小方法。 '(4 * 4)[x]'不會編譯,因爲它就像是在說'x [16]'(只有一個維度,所以如果你想要一個值,那麼這是行不通的)。由於數組名只出現一次,所以你只能像這樣'4 [x] [4]'這樣做。但是,算術方法是'*(*(x + 4)+4);'。是的,我知道這看起來很時髦。 – birryree

+0

非常真實。感謝:) – Amit

2

在C中,括號表示法是用於指針運算手短。像x[i]這樣的正常用法在語法上等同於*(x + i)(記住數組是指針)。如果您使用的是i[x],則它與*(i + x)相同,併產生相同的輸出。正如其他答案所指出的,這種方法不是一種功能,只是一種有趣的技術。

相關問題