2011-10-21 172 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)相同,并产生相同的输出。正如其他答案所指出的,这种方法不是一种功能,只是一种有趣的技术。

相关问题