微妙的指针和数组的概念
我有一个非常奇怪的指针示例,它需要你的帮助。一般来说,指针用于指向一个变量(见下面的第一个例子),但是当它指向一个数组时。我不明白为什么它不再需要推理来获得阵列(参见下面的第二个例子)微妙的指针和数组的概念
printf("TEST: %i\n", x[i]);// I expect this should be *x[i]
这确实很奇怪。它只是一个C约定,或者你如何解释这个?正如所有人提到x [i] = *(x + i),那么x [i]是什么意思呢?关于x [i] [j]为2维数组?它相当于什么?它需要解引用吗?
与正常的可变
int j = 4;
int* pointerj=&j;//pointerj holds address of j or points to j
printf("%d",*pointerj); returns the value that pointer j points to
随着阵列:
#include <stdio.h>
#include <stdlib.h>
int *function(unsigned int tags) {
int i;
int *var;
var = (int*)malloc(sizeof(int)*tags); // malloc is casted to int* type , allocated dynamical memory, it returns a pointer!
//so now var holds the address to a dynamical array.
for (i = 0; i < tags; i++) {
var[i] = i;
}
return var;
}
int main() {
int *x;
int i;
x = function(10);
for (i = 0; i < 10; i++) {
printf("TEST: %i\n", x[i]);// I expect this should be *x[i]
}
free(x); x = NULL;
return 0;
}
不明白为什么它没有。不再需要解引用,获得数组(元素)
嗯,你是提领,它只是不使用dereferen ce运营商*
。
数组下标运算符[]
在此处作为取消引用的工作。引用C11
,章§6.5.2.1
后缀表达式后跟表达式在方括号
[]
是一个数组对象的元素的下标 指定。下标运算符[]
的定义是E1[E2]
与(*((E1)+(E2)))
相同。因为 应用于二进制+
操作者,如果E1
是一个数组对象(等同于一个指针数组对象的 初始元件),并E2
是整数的转换规则的,E1[E2]
指定的第E2
元件E1
(从零开始计数)。
这是一个语法糖。表达式x[i]
和*(x+i)
是等效的。后者满足您的期望,而第一个则掩饰了解除引用操作符,但完成了与您期望的完全相同的工作。
也就是说,也要紧跟数据类型。你所期望的,沿着*x[i]
这条线的东西将是明显无效的,因为它归结为像'((x + i))。现在,
-
x
是int []
型的(整数阵列,它衰减到一个指向整数) -
x+i
给你一个指针int
类型的结果。 - 将内部解除引用运算符应用于它,结果为
int
。 - 外
*
,现在将尝试在int
类型的操作数(不是指针)操作,并且,这个操作将是一个语法错误,因为,引用操作约束表示,
一元运算符
*
的操作数应具有指针类型。
in C11
,chapter§6.5.3.2。
回答了另一个问题:
让我用报价,再一次,这一次的从第2款,章§6.5.2.1
连续下标运算符指定的元素多维数组对象。 如果
E
是n
维阵列(n ≥ 2)
与尺寸i × j × . . . × k
,然后E
(用作 比左值除外)被转换为一个指向(n − 1)
维阵列 尺寸j × . . . × k
。如果明确地将一元运算符*
应用于此指针,或者由于下标而隐式地应用 ,则结果为引用的(n − 1)
维数组,其本身在被用作非左值的情况下转换为指针。它遵循 从这个数组存储行主要顺序(最后下标变化最快)。考虑由该声明定义的阵列对象
int x[3][5];
这里
x
是3 × 5
阵列的int
秒;更准确地说,x
是一个由三个元素对象组成的数组,其中每个元素都是一个由5个整数组成的 数组。在相当于(*((x)+(i)))
的表达式x[i]
中,x
首先被转换为 指向五个整数的初始数组的指针。然后i
根据x
的类型进行调整,其在概念上 需要将指针指向的对象的大小乘以i
,即,对象的五个对象的数组。结果被添加并且间接被应用以产生五个整数的数组。当在 表达式x[i][j]
中使用时,该阵列又被转换为指向第一个整数的指针,所以x[i][j]
产生int
。
非常抱歉,您能否以简单的语言解释这部分内容?从第一个开始,x首先被转换为一个指向5个整数的初始数组的指针。我迷路了.. –
@elpsyCongroo我一定会尝试,请允许我一些时间,我现在有点被占用了,我会回来一个非正式的解释。这就说得通了? –
这是确定。不在这里。
如果有指针int *a
指向有效数据的阵列,例如:
int *a;
int arr[5] = {1, 2, 3, 4, 5];
a = arr;
通过使用a[0]
您已经解除引用指针和*
作为a[0]
相同*(a + 0)
不是必需的。
您可以为读者进一步甚至更复杂的代码。
您可以使用i[x]
代替x[i]
。为什么? x[i]
等于*(x + i)
但也相当于*(i + x)
这正是数组是C.
它的工作原理,即使号码,如x[3]
或3[x]
会给你同样的结果。
你误会了数组的工作方式。事实上,使用一个变量,例如int
时,你应该访问的地址通过
int x; int *p2x = &x
但使用数组时,这是一个有点不同。 int y[SOME_SIZE];
是内存中的一大块字节,并且*y
会将您带到该内存位置中的第一个元素,并将其解引用。 y[0]
也会这样做。 *y[0]
将首先采用y[0]
中的值,然后尝试对其进行解引用...不是你平时想什么:(
简单回答你的问题是:
数组的名称是指向数组的第一个元素
不是真的,你没有解释什么,只是一个经验法则...... –
@elpsyCongroo肯定是真的。如果直接使用变量,则使用指向第一个元素的指针。 – tilz0R
在尝试回答更多问题之前,请阅读[如何编写好的答案?](http://stackoverflow.com/help/how-to-answer)。 –
'x [i]'相当于'*(x + i)'。所以实际上,这意味着可以将'* x'写为'x [0]'。 –
你可能想检查[this](https://stackoverflow.com/questions/381542/with-arrays-why-is-it-the-case-that-a5-5a) – Badda
@OliverCharlesworth哦!作为一名Python程序员,我被这个公约误导了!干杯 –