这个类型结构定义的指针是啥意思(在C中)?

Posted

技术标签:

【中文标题】这个类型结构定义的指针是啥意思(在C中)?【英文标题】:What does this pointer of type structure definition mean (in C)?这个类型结构定义的指针是什么意思(在C中)? 【发布时间】:2018-04-14 04:25:50 【问题描述】:

在 K&R 第 6 章中,声明如下:

struct
    int len;
    char *str;
 *p;

我无法理解这个指针 p 指向哪个结构,以及这样的指针定义是否有效,因为在书中给出的所有其他示例以及我所看到的其他示例中,在定义指向结构的指针时,需要提及结构的名称,即所定义的类型。例如,

struct example
    int a;
    ...
s1;

然后,

struct example *ptr = &s1;

所以,提到 ptr 指向的是一个类型结构示例,而不仅仅是结构。

另外,特别感兴趣的是:

*p->str 获取 str 指向的任何内容; *p->str++ str 在访问它指向的任何内容后递增(就像 *s++);

我一开始就无法理解 p 是什么,因此也不能理解增量和取消引用。

这是怎么回事?

提前致谢!

附:我是新来的,所以对问题格式的任何反馈也将不胜感激。

【问题讨论】:

在第一个例子中,结构是一个anonymous结构,p是一个指向该匿名结构的指针。 它只是一个没有名字的结构,如图所示。它不经常使用,因为它的用途有限。 它是一个没有名字的结构类型,所以不能声明任何其他具有相同结构类型的变量。 The use of a pointer to an unnamed struct in C?的可能重复 @RaymondChen 显然这个问题并不是关于匿名结构,而是关于指针 type 而不仅仅是指向此类的指针。 【参考方案1】:

struct 关键字的工作方式有点像typedef 的扩展版本,不同之处在于您创建了一个复杂的自定义类型(称为结构)而不是为现有类型设置别名。如果您只有一件事需要使用声明的类型,则无需为该类型提供显式名称。

您正在查看的第一条语句声明了一个具有两个字段的结构,但没有命名它。这称为匿名结构。但是,声明确实提供了该类型的指针。

这种声明的一个可能用例是当您为外部库创建标头时,可能甚至不是用 C 编写的。在这种情况下,结构的类型可能是不透明或不完整的,并且您只需要对它的某些部分有一个方便的参考。使结构匿名会阻止您自己轻松分配它,但允许您通过指针与它进行交互。

更常见的是,您会看到这种表示法与命名或至少别名结构一起使用。第二条语句可以改写为

struct example  ...  s1, *ptr;

在这种情况下,struct example *ptr = &s1; 将只是 ptr = &s1;

更常见的情况是使用带有typedef 的匿名结构,创建不包含struct 关键字的自定义类型名称。您的第二个示例可以重写为

typedef struct  ...  example, *pexample;
example s1;
pexample ptr; // alternatively example *ptr;
ptr = &s1;

注意s1 的类型是example,而不是struct example

【讨论】:

“provide a pointer to that type”应该更准确地写成“provide a pointer of that type”吗?我误读了你的回答,意思是我们有一个指向类型本身的指针。 @丹。固定的。感谢收看。【参考方案2】:

首先考虑以下简单程序

#include <stdlib.h>
#include <stdio.h>
#include <string.h> 

int main(void) 

    struct 
        int len;
        char *str;
     *p;

    p = malloc( sizeof( *p ) );

    p->str = "Hello Nihal Jain";
    p->len = strlen( p->str );

    while ( *p->str ) putchar( *p->str++ );
    putchar( '\n' );

    free( p );

    return 0;

它的输出是

Hello Nihal Jain

所以在这个声明中

    struct 
        int len;
        char *str;
     *p;

声明了一个未命名结构类型的指针。指针本身未初始化。你可以写例如

    struct 
        int len;
        char *str;
     *p = malloc( sizeof( *p ) );

对于这个简单的程序,不需要结构名称,因为程序中既不存在也不需要结构类型对象的声明。

所以你不能声明结构类型的对象,但在这种情况下不需要。

根据C标准结构或联合声明如下

结构或联合说明符: 结构或联合标识符opt struct-declaration-list 结构或联合标识符

可见,如果有struct-declaration-list,则标识符是可选的。因此,未命名的结构可以用作类型说明符。

另一个使用枚举的例子。您可以在不声明枚举类型的情况下声明枚举数。例如

enum  EXIT_SUCCESS = 0, EXIT_FAILURE = -1 ; 

如果程序中没有这样的要求,你可以使用类型为int的枚举器而不声明枚举类型的对象。

【讨论】:

直到您仍然可以通过sizeof(*p) 提取大小。非常 +1。 @MadPhysicist 或sizeof *p() 不需要。 (风格问题) @chux。取点。我只是碰巧更喜欢把括号放在任何地方。 @MadPhysicist 你可能会喜欢(LISP) 字符串没有被分配,怎么可能呢?我认为在处理 LHS 表达式上未初始化的指向 char 的指针以及用作 RHS 的常量字符串时,应该对该代码使用发出警告。【参考方案3】:

(匿名结构)的另一种用途是在联合或其他结构中使用它们,这基本上将该结构的使用限制为特定父联合或结构而不是其他任何东西,这从程序员的角度来看非常有用,因为查看这样的代码,它为我们提供了在其内部结构或联合的上下文中本地使用的信息 - 仅此而已。 (也使我们免于命名)。


此外,如果您使用这种匿名结构,您将无法分配它的一个实例,而不是已经存在的实例。

例子:-(stark的评论:怎么用?)

struct 
  int a;
  int b;
 p;

scanf("%d",&p.a);

【讨论】:

或者不小心分配了我们自己的一个。 @MadPhysicist.: 是的没错。当它是匿名的时候你不能分配......就像一次性使用...... 如何引用匿名结构元素? @stark.: 像这样 @coderredoc p=malloc(sizeof(*p))。 (在 p 是指针的原始情况下).. 更新 - 哦,我看到它在另一个答案中提到了..【参考方案4】:

如果您需要一个临时的、一次性使用的结构(或联合)定义,并且在声明它的范围之外将无用,您将使用所谓的anonymous or unnamed structs and unions。这使您不必在使用之前声明结构,并且在复杂类型的情况下,无需声明内部类型,例如here。

【讨论】:

以上是关于这个类型结构定义的指针是啥意思(在C中)?的主要内容,如果未能解决你的问题,请参考以下文章

c语言里面的结构体是啥意思

c语言中num是啥意思

C语言不允许使用不完整的类型报错是啥意思啊

c语言赋值是啥?

C语言中的typedef是啥意思啊

c语言中c->num 是啥意思