“char (*p)[5];”是什么意思?
我试图掌握这三个声明之间的差异:
char p[5];
char *p[5];
char (*p)[5];
我试图通过做一些测试来找出这一点,因为到目前为止,每份阅读声明和类似内容的指南都没有帮助我。我写了这个小程序,但它不起作用(我尝试了第三个声明的其他类型的使用,但我已经没有选择了):
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void) {
char p1[5];
char *p2[5];
char (*p3)[5];
strcpy(p1, "dead");
p2[0] = (char *) malloc(5 * sizeof(char));
strcpy(p2[0], "beef");
p3[0] = (char *) malloc(5 * sizeof(char));
strcpy(p3[0], "char");
printf("p1 = %s\np2[0] = %s\np3[0] = %s\n", p1, p2[0], p3[0]);
return 0;
}
第一个和第二个工作正常,我已经理解了它们的作用。第三个声明的含义是什么以及正确的使用方法?
谢谢你!
I'm trying to grasp the differences between these three declarations:
char p[5];
char *p[5];
char (*p)[5];
I'm trying to find this out by doing some tests, because every guide of reading declarations and stuff like that has not helped me so far. I wrote this little program and it's not working (I've tried other kinds of use of the third declaration and I've ran out of options):
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void) {
char p1[5];
char *p2[5];
char (*p3)[5];
strcpy(p1, "dead");
p2[0] = (char *) malloc(5 * sizeof(char));
strcpy(p2[0], "beef");
p3[0] = (char *) malloc(5 * sizeof(char));
strcpy(p3[0], "char");
printf("p1 = %s\np2[0] = %s\np3[0] = %s\n", p1, p2[0], p3[0]);
return 0;
}
The first and second works alright, and I've understood what they do. What is the meaning of the third declaration and the correct way to use it?
Thank you!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
第三个是一个指向 5 个字符的数组的指针,而第二个是一个包含 5 个字符的指针的数组。
想象一下这样的情况:
而第二个看起来像这样:
这是理解指针和数组之间的差异至关重要的情况之一。数组是一个对象,其大小是其每个元素的大小乘以计数,而指针只是一个地址。
在第二种情况下,
sizeof(p)
将产生5 * the_size_of_a_pointer
。在第三种情况下,
sizeof(p)
将产生the_size_of_a_pointer
,通常为4
或8
,具体取决于目标机器。The third is a pointer to an array of 5 chars, whereas the second is an array of 5 pointers to char.
Imagine it like this:
Whereas the second one looks like that:
This is one of the cases where understanding the difference between pointers and arrays is crucial. An array is an object whose size is the size of each of its elements times the count, whereas a pointer is merely an address.
In the second case,
sizeof(p)
will yield5 * the_size_of_a_pointer
.In the third case,
sizeof(p)
will yieldthe_size_of_a_pointer
, which is usually4
or8
, depending on the target machine.它是一个指向字符数组的指针。 C 常见问题解答中对此进行了解释。以后,当你不理解某个声明时,请使用
cdecl
或 <代码>cdecl(1)。It's a pointer to an array of chars. It is explained in the C FAQ. In the future, when you don't understand a declaration, use
cdecl
orcdecl(1)
.C 声明语法是围绕表达式的类型构建的,而不是对象。这个想法是声明的形式与代码中出现的表达式的形式相匹配。
在上面的例子中,我们处理的是数组。在第一种情况下,
p
是一个char
数组;要访问特定字符值,我们只需对数组进行索引:表达式
p[i]
的类型是char
,因此声明p< /code> 是
char p[5]
。在下一个例子中,
p
是一个指向 char 的指针数组;为了访问该值,我们对数组进行索引并取消引用结果:像
[]
这样的后缀运算符比像*
这样的一元运算符具有更高的优先级,因此上面的内容被解析为表达式
*p[i]
的类型是char
,因此p
的声明是char *p[5]< /代码>。
在最后一种情况下,
p
是一个指向 char 数组的指针,因此要访问 char 值,我们必须取消引用该数组指针,然后将下标放入结果中:因为
[] 的优先级高于一元
*
,我们必须使用括号将*
与p
显式分组(而不是p[我]
)。同样,表达式(*p)[i]
的类型为char
,因此p
的声明为char (* p)[5]
。编辑
指向数组的指针出现在以下上下文中:
您显式获取 N 维数组的地址:
请注意,虽然表达式
x
和&x
产生相同的值(第一个元素的地址)数组),它们具有不同的类型(int *
与int (*)[10]
)。您正在动态分配数组类型对象:
N 维数组表达式“衰减”为指向 (N-1) 维数组的指针:
C declaration syntax is built around the types of expressions, not objects. The idea is that the form of the declaration matches the form of the expression as it would appear in the code.
In the cases above, we're dealing with arrays. In the first case,
p
is an array ofchar
; to access a particular character value, we would simply index into the array:The type of the expression
p[i]
ischar
, thus the declaration ofp
ischar p[5]
.In the next case,
p
is an array of pointers to char; to access the value, we index into the array and dereference the result:Postfix operators like
[]
have a higher precedence than unary operators like*
, so the above is parsed asThe type of the expression
*p[i]
ischar
, thus the declaration ofp
ischar *p[5]
.In the final case,
p
is a pointer to an array of char, so to access a char value we have to dereference the array pointer and then subscript into the result:Because
[]
has higher precedence than unary*
, we have to use parentheses to explicitly group*
withp
(as opposed top[i]
). Again, the type of the expression(*p)[i]
ischar
, so the declaration ofp
ischar (*p)[5]
.EDIT
Pointers to arrays show up in the following contexts:
You're explicitly taking the address of an N-dimensional array:
Note that while the expressions
x
and&x
yield the same value (the address of the first element of the array), they have different types (int *
vsint (*)[10]
).You're dynamically allocating an array-type object:
An N-dimensional array expression "decays" into a pointer to an (N-1)-dimension array:
实际上声明了一个指向 5 个字符数组的指针。这意味着它应该指向一个指向 5 个字符数组的指针。它不会分配任何 5 个字符,而只是分配一个指针,并且它应该指向指向 5 个
char
的内容。因此,正确的用法是:
例如,如果您想使用 p3 来访问 p1 字符串的单个位置,则必须执行
(*p3)[2]
。它将进入第三个位置。这是因为您首先必须将 p3 转换为 p1(在进行位置算术之前(*p3)
取消引用),然后访问该地址的第三个位置(由取消引用的指针指向)。actually declares a pointer to an array of 5
char
. It means it should point to a pointer that points to an array of 5char
. It doesn't allocate 5 of anything, just a pointer, and it should point to something that points to 5char
.So, the correct use is:
If you want to access a single position of that p1 string using p3 to access it, you must do
(*p3)[2]
, for example. It'll access the third position. That is because you first must transform p3 into p1 (the(*p3)
dereferences before doing the position arithmetics) and then access the third position of that address (pointed by the dereferenced pointer).