不明白为什么这四个符号是相同的?

  • 本文关键字:符号 四个 明白 c
  • 更新时间 :
  • 英文 :


数组声明:

int arr [ ]={34, 65, 23, 75, 76, 33}; 

四种表示法:(考虑 i=0)

arr[i]

*(arr+i)

*(i+arr)

i[arr]

让我们看一下数组在内存中的布局:

低地址高地址 |                            | 五 五 +----+----+----+----+----+----+ |34 |65 |23 |75 |76 |33 | +----+----+----+----+----+----+ ^    ^    ^    ^ |   |   |   ...等 |   |   | |   |   到达[2] |   | |   到达[1] | arr[0]

第一个元素是arr[0],第二个arr[1]很清楚,这是每个人都学到的。不太清楚的是,编译器实际上将诸如arr[i]之类的表达式转换为*(arr + i)

*(arr + i)所做的是首先获取指向第一个元素的指针,然后执行指针算术以获取指向索引i处所需元素的指针,然后取消引用指针以获取其值。

由于加法的交换性质,表达式*(arr + i)等于*(i + arr)由于上述翻译等于i[arr]


arr[i]*(arr + i)的等价性也是数组衰减到指向其第一个元素的指针背后的原因。

指向数组第一个元素的指针将是&arr[0]。现在我们知道arr[0]应该等于*(arr + 0)这意味着&arr[0]必须等于&*(arr + 0)。向任何内容添加零都是无操作,因此导致表达式&*(arr)。也可以删除只有一个项且没有运算符的括号,留下&*arr.最后,地址和取消引用运算符彼此对立并相互抵消,给我们留下简单的arr。所以&arr[0]等于arr.

数组中的每个元素在内存中都有一个位置。数组中的位置是连续的。C 中的数组是指针,始终指向集合(数组的第一个元素)内存上的第一个方向。

arr[i]=> 获取数组中 "i-position" 的值。arr[i] = *(arr + i)

*(arr+i)=> 通过添加内存中指向arri value的位置来获取内存中的值。

*(i+arr)=> 与*(arr+i)相同。总和是可交换的。

i[arr]=> 与*(i+arr)相同。这是另一种表现方式。

它们是相同的,因为 C 语言规范是这样说的。读取 n1570

符号a[i]*(a+i)的语法糖。

第一个是数学语法(更接近人脑教育的符号),而第二个直接对应于一个汇编指令。

另一方面*(a+i)=*(i+a)=i[a]因为指针的算术是可交换的。

由于数组下标运算符[]的定义方式,这些是相同的。

从C标准第6.5.2.1节:

2后缀表达式后跟方括号中的表达式[]是数组对象的元素的下标指定。这 下标运算符的定义[]E1[E2]是 与(*((E1)+(E2)))相同。由于转换规则 应用于二进制+运算符(如果E1是数组对象) (等效地,指向数组对象的初始元素的指针)E2是一个整数,E1[E2]表示 的E2个元素E1(从零开始计数)。

示例中arr[i]的表达式的格式为E1[E2]。 因为标准规定这与*(E1+E2)相同,这意味着arr[i]*(arr + i)相同。

由于加法的交换性质,*(arr + i)*(i + arr)相同。 将上面的等价规则应用于此表达式会得到i[arr]

简而言之,这 4 个表达式是等价的,因为标准如何定义数组下标以及加法的交换属性。

它之所以有效,是因为 C 中的数组变量(即示例中的 arr)只是指向内存位置数组开头的指针。 指针是数字,表示特定内存位置的地址。 当您在指针前面放置和"*"时,它表示"给我该内存位置中的数据"。

因此,如果 arr 是指向数组开头的指针,则 *(arr) 或 *(arr + 0) 是
  • 数组第0 个索引中的数据,*(arr + 1) 是第一个索引中的数据,依此类推。
  • 看起来像A[B]的表达式本质上被翻译成类似*(A+B)的东西。 因此,arr[0] = *(arr + 0) 和arr[i] = *(arr+i),依此类推。
  • 由于A+B = B+A,因此两者是可以互换的。 意思*(arr+i) = *(i+arr)。
  • 因为 arr[i] = *(arr+i) 和 *(
  • arr+i) = *(i+arr),所以 arr[i]= i[arr]应该是有意义的。

最新更新