问题描述
我的理解是,数组被简单地定指针值的序列,而当你宣布C中的数组,你声明指针和它所指向的顺序分配空间。
但是,这混淆了我:以下code:
字符Y [20];
字符* Z = Y;的printf(Y大小%lu个\\ N的sizeof(Y));
的printf(y是%P \\ N,Y);
的printf(Z大小为%lu \\ n的sizeof(Z));
的printf(z是%P \\ N,Z);
在与苹果的GCC编译给出了以下结果:
y值是20
y是0x7fff5fbff930
ž大小为8
z是0x7fff5fbff930
(我的机器是64位的,指针是8个字节长)。
如果Y是一个常量指针,为什么它有一个大小为20,如价值观它所指向的顺序?是变量名Y在编译时,只要是通过appropiate内存地址取代?是数组,然后,在C某种语法糖,这只是编译时转换为指针的东西?
下面是从C标准的确切语言(的):
The important thing to remember here is that there is a difference between an object (in C terms, meaning something that takes up memory) and the expression used to refer to that object.
When you declare an array such as
int a[10];
the object designated by the expression a
is an array (i.e., a contiguous block of memory large enough to hold 10 int
values), and the type of the expression a is "10-element array of int
", or int [10]
. If the expression a
appears in a context other than as the operand of the sizeof
or &
operators, then its type is implicitly converted to int *
, and its value is the address of the first element.
In the case of the sizeof
operator, if the operand is an expression of type T [N]
, then the result is the number of bytes in the array object, not in a pointer to that object: N * sizeof T
.
In the case of the &
operator, the value is the address of the array, which is the same as the address of the first element of the array, but the type of the expression is different: given the declaration T a[N];
, the type of the expression &a
is T (*)[N]
, or pointer to N-element array of T. The value is the same as a
or &a[0]
(the address of the array is the same as the address of the first element in the array), but the difference in types matters. For example, given the code
int a[10];
int *p = a;
int (*ap)[10] = &a;
printf("p = %p, ap = %p\n", (void *) p, (void *) ap);
p++;
ap++;
printf("p = %p, ap = %p\n", (void *) p, (void *) ap);
you'll see output on the order of
p = 0xbff11e58, ap = 0xbff11e58
p = 0xbff11e5c, ap = 0xbff11e80
IOW, advancing p
adds sizeof int
(4) to the original value, whereas advancing ap
adds 10 * sizeof int
(40).
More standard language:
Thus, when you subscript an array expression, what happens under the hood is that the offset from the address of the first element in the array is computed and the result is dereferenced. The expression
a[i] = 10;
is equivalent to
*((a)+(i)) = 10;
which is equivalent to
*((i)+(a)) = 10;
which is equivalent to
i[a] = 10;
Yes, array subscripting in C is commutative; for the love of God, never do this in production code.
Since array subscripting is defined in terms of pointer operations, you can apply the subscript operator to expressions of pointer type as well as array type:
int *p = malloc(sizeof *p * 10);
int i;
for (i = 0; i < 10; i++)
p[i] = some_initial_value();
Here's a handy table to remember some of these concepts:
Declaration: T a[N]; Expression Type Converts to Value ---------- ---- ------------ ----- a T [N] T * Address of the first element in a; identical to writing &a[0] &a T (*)[N] Address of the array; value is the same as above, but the type is different sizeof a size_t Number of bytes contained in the array object (N * sizeof T) *a T Value at a[0] a[i] T Value at a[i] &a[i] T * Address of a[i] Declaration: T a[N][M]; Expression Type Converts to Value ---------- ---- ------------ ----- a T [N][M] T (*)[M] Address of the first subarray (&a[0]) &a T (*)[N][M] Address of the array (same value as above, but different type) sizeof a size_t Number of bytes contained in the array object (N * M * sizeof T) *a T [M] T * Value of a[0], which is the address of the first element of the first subarray (same as &a[0][0]) a[i] T [M] T * Value of a[i], which is the address of the first element of the i'th subarray &a[i] T (*)[M] Address of the i-th subarray; same value as above, but different type sizeof a[i] size_t Number of bytes contained in the i'th subarray object (M * sizeof T) *a[i] T Value of the first element of the i'th subarray (a[i][0]) a[i][j] T Value at a[i][j] &a[i][j] T * Address of a[i][j] Declaration: T a[N][M][O]; Expression Type Converts to ---------- ---- ----------- a T [N][M][O] T (*)[M][O] &a T (*)[N][M][O] *a T [M][O] T (*)[O] a[i] T [M][O] T (*)[O] &a[i] T (*)[M][O] *a[i] T [O] T * a[i][j] T [O] T * &a[i][j] T (*)[O] *a[i][j] T a[i][j][k] T
From here, the pattern for higher-dimensional arrays should be clear.
So, in summary: arrays are not pointers. In most contexts, array expressions are converted to pointer types.
这篇关于在C语言中,是数组指针或用作指针?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!