“char (*p)[5];”是什么意思?

发布于 2024-11-16 21:45:51 字数 1914 浏览 6 评论 0原文

我试图掌握这三个声明之间的差异:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

倒带 2024-11-23 21:45:51

第三个是一个指向 5 个字符的数组的指针,而第二个是一个包含 5 个字符的指针的数组。

想象一下这样的情况:

________          _____________________
|0x7777| -------> | H | e | l | l | o |
|______|          |_0_|_1_|_2_|_3_|_4_|
    p             ^
                  |
                  0x7777  

而第二个看起来像这样:

   "abc"  "def"  "ghi"  "jkl"  "mno"
    ^      ^      ^      ^      ^
    |      |      |      |      |
____________________________________
|0x9999|0x7777|0x3333|0x2222|0x6666|
|___0__|___1__|___2__|___3__|___4__|
                  p

这是理解指针和数组之间的差异至关重要的情况之一。数组是一个对象,其大小是其每个元素的大小乘以计数,而指针只是一个地址。

在第二种情况下,sizeof(p) 将产生 5 * the_size_of_a_pointer

在第三种情况下,sizeof(p) 将产生 the_size_of_a_pointer,通常为 48,具体取决于目标机器。

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:

________          _____________________
|0x7777| -------> | H | e | l | l | o |
|______|          |_0_|_1_|_2_|_3_|_4_|
    p             ^
                  |
                  0x7777  

Whereas the second one looks like that:

   "abc"  "def"  "ghi"  "jkl"  "mno"
    ^      ^      ^      ^      ^
    |      |      |      |      |
____________________________________
|0x9999|0x7777|0x3333|0x2222|0x6666|
|___0__|___1__|___2__|___3__|___4__|
                  p

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 yield 5 * the_size_of_a_pointer.

In the third case, sizeof(p) will yield the_size_of_a_pointer, which is usually 4 or 8, depending on the target machine.

信仰 2024-11-23 21:45:51

它是一个指向字符数组的指针。 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 or cdecl(1).

指尖上得阳光 2024-11-23 21:45:51
char p[5];      // p is a 5-element array of char
char *p[5];     // p is a 5-element array of pointer to char
char (*p)[5];   // p is a pointer to a 5-element array of char

C 声明语法是围绕表达式的类型构建的,而不是对象。这个想法是声明的形式与代码中出现的表达式的形式相匹配。

在上面的例子中,我们处理的是数组。在第一种情况下,p 是一个 char 数组;要访问特定字符值,我们只需对数组进行索引:

val = p[i];

表达式 p[i] 的类型是 char,因此声明 p< /code> 是 char p[5]

在下一个例子中,p 是一个指向 char 的指针数组;为了访问该值,我们对数组进行索引并取消引用结果:

val = *p[i];

[] 这样的后缀运算符比像 * 这样的一元运算符具有更高的优先级,因此上面的内容被解析为

val = *(p[i]);

表达式*p[i]的类型是char,因此p的声明是char *p[5]< /代码>。

在最后一种情况下,p 是一个指向 char 数组的指针,因此要访问 char 值,我们必须取消引用该数组指针,然后将下标放入结果中:

val = (*p)[i];

因为 [] 的优先级高于一元 *,我们必须使用括号将 *p 显式分组(而不是 p[我])。同样,表达式 (*p)[i] 的类型为 char,因此 p 的声明为 char (* p)[5]

编辑

指向数组的指针出现在以下上下文中:

  1. 您显式获取 N 维数组的地址:

    int x[10] ;
    int (*px)[10] = &x;
    

    请注意,虽然表达式 x&x 产生相同的(第一个元素的地址)数组),它们具有不同的类型int *int (*)[10])。

  2. 您正在动态分配数组类型对象:

    int (*px)[10] = malloc(sizeof *px);
    

  3. N 维数组表达式“衰减”为指向 (N-1) 维数组的指针:

    int x[10][20];
    foo(x);
    ...
    无效 foo(int (*px)[20]){...}
    

char p[5];      // p is a 5-element array of char
char *p[5];     // p is a 5-element array of pointer to char
char (*p)[5];   // p is a pointer to a 5-element array of char

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 of char; to access a particular character value, we would simply index into the array:

val = p[i];

The type of the expression p[i] is char, thus the declaration of p is char 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:

val = *p[i];

Postfix operators like [] have a higher precedence than unary operators like *, so the above is parsed as

val = *(p[i]);

The type of the expression *p[i] is char, thus the declaration of p is char *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:

val = (*p)[i];

Because [] has higher precedence than unary *, we have to use parentheses to explicitly group * with p (as opposed to p[i]). Again, the type of the expression (*p)[i] is char, so the declaration of p is char (*p)[5].

EDIT

Pointers to arrays show up in the following contexts:

  1. You're explicitly taking the address of an N-dimensional array:

    int x[10];
    int (*px)[10] = &x;
    

    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 * vs int (*)[10]).

  2. You're dynamically allocating an array-type object:

    int (*px)[10] = malloc(sizeof *px);
    

  3. An N-dimensional array expression "decays" into a pointer to an (N-1)-dimension array:

    int x[10][20];
    foo(x);
    ...
    void foo(int (*px)[20]){...}
    

嘦怹 2024-11-23 21:45:51
char (*p3)[5];

实际上声明了一个指向 5 个字符数组的指针。这意味着它应该指向一个指向 5 个字符数组的指针。它不会分配任何 5 个字符,而只是分配一个指针,并且它应该指向指向 5 个 char 的内容。

因此,正确的用法是:

#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 = &p1;                                                               

        printf("p1 = %s\np2[0] = %s\np3 = %s\n", p1, p2[0], *p3);               

        return 0;                                                               
}

例如,如果您想使用 p3 来访问 p1 字符串的单个位置,则必须执行 (*p3)[2] 。它将进入第三个位置。这是因为您首先必须将 p3 转换为 p1(在进行位置算术之前 (*p3) 取消引用),然后访问该地址的第三个位置(由取消引用的指针指向)。

char (*p3)[5];

actually declares a pointer to an array of 5 char. It means it should point to a pointer that points to an array of 5 char. It doesn't allocate 5 of anything, just a pointer, and it should point to something that points to 5 char.

So, the correct use is:

#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 = &p1;                                                               

        printf("p1 = %s\np2[0] = %s\np3 = %s\n", p1, p2[0], *p3);               

        return 0;                                                               
}

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).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文