美文网首页
一文理清c中的各种结构体定义和前向声明

一文理清c中的各种结构体定义和前向声明

作者: 梦落迹南天 | 来源:发表于2019-04-26 23:55 被阅读0次

一直都是半c++半c,用惯了class,使用struct的时候比较少, 偏偏经常见到c有各种各样的结构体定义,让人百思不得其解,本文理清它们的本质。

1.结构体的定义

c语言中的结构体定义一般是这么做的,大概是起初设计的不完善?导致使用结构体的使用需要在前面加上struct,而在C语言中,struct A 是被视为一个整体而不是struct, A,所以后面的变量哪怕和类型一样,也不会冲突

定义
struct A{
        int num;
}; 
使用
struct A A;

c语言作者为了方便定义变量(同时更是为了方便定义结构体类型,见2),开发了这样的语法,

struct A{
        int num;
}A; 

2. typedef和struct

typedef 和struct 混在一起是导致结构体定义方式丰富的一大原因,typedef 用于类型声明有好多看起来奇怪的地方,譬如:

声明一种变量类型
typedef int Integer; 

声明一个函数指针类型
typedef void (* fn)(int a, int b);

声明一个结构体的类型为A
typedef struct A{ 
        int num ;
}A;

但是只要把上面的typedef去掉,上面的语句就变成了定义了一个变量Integer, 定义了一个函数指针变量fn, 定义了一个结构体变量A,也就是说typedef用在任何定义变量语句前面,都会把它从变量定义改成类型定义, 设计者这么做也是为了一套原则多处使用,不想增加语言的学习成本。
typedef隐藏了一个非常重要的一点: 使用typedef 定义结构体类型的时候,如果本身类型不存在,本身的类型也会产生,这是什么意思呢?如下:

typedef struct A{
        int num;
}A_t;

除了使用这种方式定义
A_t temp;
还可以使用这种方式定义,struct A这种类型也产生了
struct A temp;

3.为什么struct支持省略类型定义?

前面说过 struct A 这两者是一体的,不知道出于什么心态,偏偏结构体的定义支持了省略,出现了以下的写法,这样就定义了一个不知道名字类型的结构体变量A

struct {
        int num
}A;

但是这种东西绝对不是为了只是定义一个两个变量而存在的,毕竟定义完变量后类型就匿名了,用不了了,区分度又不好; 其实,省略类型定义主要是为了使 typedef在声明一种结构体类型更加简单而出现的,而不是为了定义变量, 如下:

定义如下
typedef stuct{
      int num;
}A_t;
使用的时候,是没有问题的
A_t A={
    .num = 0,
};

4.结构体类型的前向声明

在解决头文件循环依赖的时候,常需要用到前向声明, 结构体的前向声明如下:

声明了一个结构体类型A
struct A;
定义一个变量
struct A temp;     error 错误, struct A 不完整
struct A *temp;    ok
补充结构体类型为A的定义
struct A{
        int num;
};

这种前向声明和c++的class不同,只能声明指针,声明变量会报错,让我很讶异,这种在同文件内容中扫描,在编译期就可以完成,不用等到跨文件链接阶段才做的事情居然不行?令人难以理解, 好消息是现在比较新的gcc都已经支持了,(笔者使用gcc 5.4),但是g++不行,所以尽量不要再g++中写struct?


最后, 由于经常会使用typedef定义struct,说一说这种类型的前向声明目前,如下:

对于下面的结构体类型,可以使用如下的前向声明
typedef struct A A_t;

typedef struct A{
      int num;
}A_t;

我们知道typedef的时候,不但产生了类型A_t,也产生了Struct A, 所以上面的typedef才合理没有报错,是因为它在typedef的时候先声明了 struct A, 相当于

struct A; 
typedef struct A A_t

以及, c语言对于struct类型和变量的区分做的比较好,对于struct A 和A是不同的东西在c中是不同的东西,c把struct A这两个合在一起看作一个东西, 所以经常也可以看到这么做结构体的声明,也是完全可以的

typedef struct A{
      int num;
}A;

strcut A A; 这样声明也可以
A A; 两者等价

相关文章

  • 一文理清c中的各种结构体定义和前向声明

    一直都是半c++半c,用惯了class,使用struct的时候比较少, 偏偏经常见到c有各种各样的结构体定义,让人...

  • 数据结构 -- 共用体Union

    在数据结构 -- 结构体Struct一文中详细介绍了结构体的定义以及内存对齐。在C语言中,还有另外一种和结构体非常...

  • 代码布局排版

    @class类声明 结构体定义 枚举 C函数定义 字符串常量声明 typedef重命名 协议

  • C++系列 --- 结构体、权限修饰符、类简介

    一、结构体 结构体:自定义的数据类型 C++ 中的结构和C中的结构有什么区别? C++中的结构除具备了C中的所有功...

  • 结构体的三种定义

    结构体变量的定义 1、先声明结构体类型,再定义变量 2、在声明类型的同时声明变量 3、直接定义结构体变量

  • 9.C语言(复合类型--结构体-共同体)

    结构体 1.结构体定义和初始化 2.定义结构体变量的方式 1.先声明结构体类型,再定义变量名 2.在声明类型的同时...

  • c语言中的结构体

    1、结构体的声明(1)结构体的关键词是struct第一种声明 第二种声明 第三种声明 2、结构体定义变量在C++语...

  • c结构体

    1.创建声明结构体 输出 2.声明结构体变量2 3.单独定义 structure.h structure.c 4....

  • 7.C语言复合类型(自定义类型)

    结构体 变量的定义和初始化 共三种方式 先声明结构体类型再定义变量名 在声明类型的同时定义变量 直接定义结构体类型...

  • C语言--结构体

    用户可以使用结构体自定义自己的数据类型。 结构体定义和变量声明 struct用来定义结构体,结构体一般定义如下,其...

网友评论

      本文标题:一文理清c中的各种结构体定义和前向声明

      本文链接:https://www.haomeiwen.com/subject/masfnqtx.html