结构体定义struct和typedef struct的区别(重新整理版)

2023-11-10

1 结构体的定义

允许用户自己建立由不同类型数据组成的组合型的数据结构,它称为结构体(实际上应称为 结构体类型)。

2 struct的用法

下面以一个结构体实例来说明一下:

struct os_tcb
{
	OS_STK *OSTCBStkPtr;
    OS_STK *OSTCBStkBottom;     
    INT32U OSTCBStkSize;     
    INT16U OSTCBOpt;         
    INT16U OSTCBId;           
};
名称 释义
Sturct 是声明结构体类型时所必须使用的关键字,不能省略。
os_tcb 是结构体名
花括号内 是该结构体所包括的子项,称为结构体成员。

前面只是建立了一个结构体类型,它相当于一个模型,并没有定义变量,其中并无具体数据,系统对之也不分配存储单元。为了能在程序中使用结构体类型的数据,应当定义结构体类型的变量,并在其中存放具体的数据。

可以采取以下3种方式定义结构体类型变量。

2.1 先声明结构体类型,再定义该类型的变量

定义上面的结构体类型后

struct os_tcb OS_TCB;	// 在定义了结构体变量后,系统会为之分配内存单元
名称 释义
struct os_tcb 结构体类型名
OS_TCB 结构体变量名
2.2 在声明类型的同时定义变量
struct os_tcb
{
	OS_STK *OSTCBStkPtr;
    OS_STK *OSTCBStkBottom;     
    INT32U OSTCBStkSize;     
    INT16U OSTCBOpt;         
    INT16U OSTCBId;            
} OS_TCB;     // OS_TCB 是一个结构体变量
2.3 不指定类型名而直接定义结构体类型变量
struct 
{
	OS_STK *OSTCBStkPtr;
    OS_STK *OSTCBStkBottom;     
    INT32U OSTCBStkSize;     
    INT16U OSTCBOpt;         
    INT16U OSTCBId;            
} OS_TCB;	// OS_TCB 是一个结构体变量

指定了一个无结构体名的结构体类型,显然不能再以此结构体类型去定义其他变量。

注:结构体类型与结构体变量是不同的概念,不要混同。只能对变量赋值、存取或运算,而不能对一个类型赋值、存取后运算。在编译时,对类型不分配空间,只对变量分配空间。

3 typedef struct的用法

下面再以一个结构体实例来说明一下:

一般有两种用 typedef struct 定义结构体的方法

3.1 typedef struct 定义结构体的方法一
typedef struct os_tcb
{
	OS_STK *OSTCBStkPtr;
    OS_STK *OSTCBStkBottom;     
    INT32U OSTCBStkSize;     
    INT16U OSTCBOpt;         
    INT16U OSTCBId;            
}OS_TCB;
3.2 typedef struct 定义结构体的方法二
typedef struct 
{
	OS_STK *OSTCBStkPtr;
    OS_STK *OSTCBStkBottom;     
    INT32U OSTCBStkSize;     
    INT16U OSTCBOpt;         
    INT16U OSTCBId;            
}OS_TCB;

可以看出,上面的区别在于 typedef struct 后面一个跟了标识符,另外一个没有跟标识符,这两个有什么区别呢?这里的os_tcb代表什么?OS_TCB的意义又是什么?

要搞清楚上面的问题,要从两方面入手。

第一 typedef的用法是什么?

typedef是在基本类型的基础上定义类型的同义字。注意typedef并不产生新的类型。例如 typedef int exam_score;这里的exam_score 就是一种基本类型,它的意义等同于 int,那么即可以用它来定义整型变量,例如:exam_score LIMING

第二 结构体的定义各个标志符的意义。

在结构体定义中,通常是这样的

struct exam_score
{
	chinese;
	english;
    math;
    physical;
    chemistry;
}LIMING;

这里的struct是结构体关键字,exam_score则是结构体类型名,LIMING则是结构体变量。

弄明白以上两个问题,回过头来看开始的那两个结构体。

typedef struct os_tcb
{
	OS_STK    *OSTCBStkPtr;
	OS_STK    *OSTCBStkBottom;     
    INT32U      OSTCBStkSize;     
    INT16U      OSTCBOpt;         
    INT16U      OSTCBId;            
}OS_TCB;	// OS_TCB是一个结构体类型 = struct os_tcb

这里声明一种结构体类型os_tcb,所以os_tcb就是结构体类型名;OS_TCBstruct os_tcb 的同义字,所以可以直接用OS_TCB来定义变量,同时也可以这样 struct os_tcb xxxOS_TCB xxx;都是合法的,因为OS_TCB 就等同于 struct os_tcb

来看第二种

typedef struct 
{
	OS_STK    *OSTCBStkPtr;
    OS_STK    *OSTCBStkBottom;     
    INT32U      OSTCBStkSize;     
    INT16U      OSTCBOpt;         
    INT16U      OSTCBId;            
}OS_TCB;   // OS_TCB是一个结构体类型 = struct 

在结构体的定义中允许这样形式的定义:

struct
{
	xxx
	xxx
   	xxx
}var;

这里没有声明结构体变量名,直接定义了结构体变量varvar在这里是结构体变量。这样定义的结果是在程序不能再定义新的结构体变量。

这种形式加上typedef 之后情况就变了,这里的OS_TCB不是结构体变量,而是struct的同义字(结构体类型),这个同义仅限于上面定义的那种情况,可以用OS_TCB来定义结构体变量。

4 总结

有了以上叙述与理解,我们便可以很容易搞清楚一个易混淆的点:struct{}后面的到底是结构体变量名,还是结构体类型名

4.1 当只是定义结构体类型
struct 结构体名
{
	结构体成员名
}结构体变量名;

引用结构体成员方式应是:

结构体变量名. 结构体成员名	// 结构体变量直接引用结构体成员
4.2 当使用typedef定义时
typedef struct 结构体名
{
	结构体成员名
}结构体类型名;

引用结构体成员方式应是:

结构体类型名 xxx;	// 定义一个结构体变量

xxx.结构体成员名  // 引用结构体成员
4.3 使用typedef定义作用

对于typedef struct 结构体名{}结构体类型名,结构体类型名就相当于"struct 结构体名",只是使用typedef给其定义了一个别名。

我们都知道C中是不允许在定义结构体变量时省略struct关键字,当然C++中用不用的结果都是一样的,所以有时候为了平台的兼容性以及代码更好的可读性,我们使用typedef关键字,而且typedef的作用不止于此。

typedef只是给你的数据类型定义一个别名,不过使用typedef将能使你的代码更直观简洁,而且在代码跨平台移植时将提供极大的便利。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

结构体定义struct和typedef struct的区别(重新整理版) 的相关文章

  • 如何让 C# 设计器编辑我的结构属性?

    我正在使用 C 创建一个具有多个自定义属性的自定义 Windows 窗体控件 这些属性之一是一个带有几个整数字段的简单结构 public struct Test public int A B Test Test Category MyCat
  • 单个成员结构的对齐和大小保证

    给定一个 可能非 POD struct具有单个成员 没有继承 也没有虚方法 struct Foo Bar value Foo do something C 是否保证Foo将具有相同的对齐方式并且sizeof as Bar 如果不能 那么可以
  • 在 Go 中,如何将结构体转换为字节数组?

    我有一个我定义的结构实例 我想将其转换为字节数组 我尝试了 byte my struct 但这不起作用 另外 我还被指出二进制包 http golang org pkg encoding binary 但我不确定我应该使用哪个函数以及应该如
  • 如何将所有GET请求查询参数放入Go中的结构体中?

    你好 我想将 get 查询参数转换为 Go 中的结构 例如我有这样的结构 type Filter struct Offset int64 json offset Limit int64 json limit SortBy string js
  • SwiftUI - 使用“ObservableObject”和@EnvironmentObject 有条件地显示视图

    我想在我的应用程序中有条件地显示不同的视图 如果某个布尔值为 true 则将显示一个视图 如果为 false 将显示不同的视图 该布尔值位于 ObservableObject 类中 并根据将要显示的视图之一进行更改 PracticeStat
  • 访问结构向量

    我有一个结构 struct OutputStore int myINT string mySTRING 如果我创建一个 OutputStore 类型的数组 如下所示 OutputStore OutputFileData new Output
  • 寻找一种简单的方法来重新初始化结构

    我有一个名为 CoolStruct 的结构 struct CoolStruct int id uint32 type uint32 subtype String name 我也有这些结构的向量 std vector
  • std::bind2nd 和 std::bind 与二维数组和结构数组

    我知道 C 有 lambda 并且 std bind1st std bind2nd 和 std bind 已弃用 然而 从C 的基础开始 我们可以更好地理解新特性 所以 我从这个非常简单的代码开始 使用int 数组s 第一个例子 与std
  • typedef 有什么用?

    C语言中typedef关键字有什么用 什么时候需要 typedef http en wikipedia org wiki Typedef用于将某物定义为type 例如 typedef struct int a int b THINGY 定义
  • C 指针混乱

    我想在内存中存储一 个字符串并稍后读取它 gt desc constant gt base id char malloc 200 sprintf gt desc constant gt base id f 1 printf gt s n g
  • 在 open CL 中将结构数组传递给内核

    你好 我正在尝试在 open CL 中实现距离向量程序 基本上我在将结构数组作为参数传递到内核时遇到问题 我的结构定义是这样的 typedef struct int a nodes 4 node node srcA 为此分配内存后 我使用此
  • 解压以 ASCIIZ 字符串结尾的结构

    我正在尝试使用struct unpack 分解以 ASCII 字符串结尾的数据记录 该记录 恰好是 TomTom ov2 记录 具有以下格式 存储为小端 1 byte 4 字节 int 表示总记录大小 包括该字段 4字节整数 4字节整数 可
  • 从其对象获取结构体字段的名称和类型

    例如 我有一个类似这样的结构 struct Test int i float f char ch 10 我有一个该结构的对象 例如 Test obj 现在 我想以编程方式获取字段名称和类型obj 是否可以 顺便说一句 这是 C 你正在要求C
  • 仅导出嵌入结构实现的方法子集

    是否可以仅导出嵌入结构实现的方法的子集 这是一种与减少代码复制和粘贴非常不同的方法吗 还有更惯用的方法吗 type A struct func a A Hello fmt Println Hello func a A World fmt P
  • 如何自动为 Swift 类创建初始化程序?

    UPDATE 使用结构而不是类 struct 在很多方面都更好 它有自己的初始化器 这是我的模型课 是否有可能创建init自动方法 每次我都必须将所有变量一一初始化 这会花费很多时间 class Profile var id String
  • 如何在Python中正确声明ctype结构+联合?

    我正在制作一个二进制数据解析器 虽然我可以依靠 C 但我想看看是否可以使用 Python 来完成该任务 我对如何实现这一点有一些了解 我当前的实现如下所示 from ctypes import class sHeader Structure
  • 将原始结构内容(字节)写入 C 中的文件。对写入的实际大小感到困惑

    基本问题 但我预计这个结构占用 13 个字节的空间 1 个字节用于 char 12 个字节用于 3 个无符号整数 反而 sizeof ESPR REL HEADER 给我 16 个字节 typedef struct unsigned cha
  • 将 struct* 从 C# 传递到 C++ dll

    C dll中的结构体定义如下 struct WAVE INFO int channel num int audio type char wave data int wave length 调用方法如下 extern C STRUCTDLL
  • G++ 错误:“”的类型不完整

    我被迫使用第三方加密狗访问库 该库提供包含文件 sense4 h 其代码如下 if defined WINDOWS define WINAPI define CONST const typedef unsigned char UCHAR t
  • Golang 基础知识 struct 和 new() 关键字

    我正在学习 golang 当我阅读描述结构的章节时 我遇到了初始化结构的不同方法 p1 passport var p2 passport p3 passport Photo make byte 0 0 Name Scott Surname

随机推荐

  • 付出行动加入刷脸支付感受刷脸带来的红利

    无现金时代已陪伴我们许久 扫码支付给消费者带去诸多便利 但在两年后 我们或将引来无手机支付时代 刷脸支付将赋予消费者更加高效便捷的支付新习惯 据数据显示 2019年是我国刷脸支付的元年 届时将取代扫码支付成为主要支付方式 而在扫码支付盛行以
  • angular-cli中引入ng-zorro-antd(蚂蚁框架)

    首先你要确保angular cli环境搭建成功 第一步 进入项目文件夹 执行以下命令后将自动完成 ng zorro antd 的初始化配置 包括引入国际化文件 导入模块 引入样式文件等工作 ng add ng zorro antd 安装完成
  • 谷歌chrome编辑css样式不显示

    最近在用vscode编辑css代码的时候使用 在IE浏览器 qq浏览器 等其他浏览器上都可以显示 但是用谷歌浏览器没有显示任何效果 这里我在网上找到的原因是 谷歌浏览器会缓存页面的原css 要用Ctrl F5才可以重新加载修改后的css样式
  • 分区索引笔记(三)--全局分区索引

    全局分区索引在一个索引分区中包含来自多个表分区的键 一个全局分区索引的分区键是分区表中不同的或指定一个范围的值 在创建全局分区索引时 必须定义分区键的范围和值 全局索引只能是B树索引 Oracle在默认情况下不会维护全局分区索引 如果一个分
  • MPU6050使用心得(简单分享一下)

    前言 选用MPU6050做 倾斜检测 功能 前期准备 开发板 正点原子STM32F103 精英版 STM32F103ZET6 模块 GY 521 MPU6050 其他 杜邦线若干 烧录线 FlyMcu Keil5 正点原子开发板配套的套件
  • 镜头景深计算公式的推导

    景深是指成像画面中最近清晰点到最远的清晰点之间的范围 由于传感器或胶片的分辨率限制 或者照片冲洗放大后在一定距离观看时 受到人眼的分辨率极限限制 通常会将清晰这一概念与底片上一定尺寸的弥散斑大小相关联 按照传统的景深定义 物距为u1的点光源
  • IDEA 卡死的几种解决方案

    idea最为最为流行的Java开发工具其智能化提示对于开发人员非常友好 大大提高开发效率 不过我们在平时开发的时候不可避免的遇到idea卡死的情况 以下是我在平时遇到卡死的情况下的解决方法 1 调大idea内存配置参数 修改完后保存重启 X
  • 常用距离算法 (原理、使用场景、Python实现代码)

    距离度量是有监督和无监督学习算法的基础 包括k近邻 支持向量机和k均值聚类等 距离度量的选择影响我们的机器学习结果 因此考虑哪种度量最适合这个问题是很重要的 因此 我们在决定使用哪种测量方法时应该谨慎 但在做出决定之前 我们需要了解距离测量
  • 天拓分享:关于S7-1200和S7-300之间的通信

    1 S7 1200 的PROFINET 通信口 S7 1200 CPU 本体上集成了一个 PROFINET 通信口 支持以太网和基于 TCP IP 的通信标准 使用这个通信口可以实现 S7 1200 CPU 与编程设备的通信 与hmi触摸屏
  • 如何在 Debian 11 上设置一个静态 IP 地址

    当你在电脑上安装一个新的操作系统时 DHCP服务器会给你分配一个动态IP地址 然而 在各种情况下 你可能需要在你的机器上设置一个静态IP地址 例如 当你正在托管一个网络服务器 或者任何服务需要一个IP地址而不是域名 或者在你即将授予某人远程
  • LayoutParams布局

    AbsoluteLayout LayoutParams可以重新设置坐标 然后调用setLayoutParamsLinearLayout LayoutParams可以调用setMargins 来移动控件位置比如在调用rootLayout ad
  • VSCode的C/C++环境初始化(2022版)

    提前说明 如果中间 VSCode 提示要装插件 直接点击安装推荐的第一个即可 下拉框有 g 编译 gdb 调试 可以盲选 第一步 下载MinGW64 下载地址 https sourceforge net projects mingw w64
  • (十五)Mybatis当中一级二级缓存用法详解

    学习Mybatis一级二级缓存看这一篇足够了 写的非常详细 用法及代码示例都写出来了 对大家的学习或者工作具有一定的参考学习价值 需要的朋友们下面随着小编来一起学习学习吧 目录 一级缓存 一级缓存使用示例 一级缓存失效示例 1 sqlSes
  • mariadb之半同步

    补充说明 做的时候楼主没看清楚版本号 10 2以前是my conf 以后是my conf d server conf 楼主本人是写到了server这个文件里 请大家注意 可能不显示模式的原因可能就是写错配置文件了 等我明天重新做一遍 看看有
  • java版4人过桥问题

    夜晚 桥头有 4个人在一起准备过桥 这些人中只有一个人有手电筒 从桥头走到桥尾一次最多只能俩个人同时行进 每个人单独过桥的时间可能不一样 如果两个人在一起走 则这次的花费时间是走的最慢的那个人 假如现在四个人单独过桥的时间分别是 1 2 5
  • 管理员后台页面html代码,HTML5技术实现的管理员后台模板界面

    实例简介 一套采用了CSS3和HTML5技术实现的后台管理界面 不具备具体的管理功能 只是一个界面 但使用了最新的HTML5技术 网页上有超多你见不到的新效果 新形式 包括图表等 是下一个WEB技术的革命创新 有兴趣的可不要错过哦 学习HT
  • 安装某些工具不能用时,可能环境变量出现问题

    安装某些工具不能用时 可能环境变量出现问题 尝试使用 echo PATH 查看在环境中的变量 如果环境中没有该变量 退出重进 还是没有就或者手动添加
  • 事件内核对象 CreateEvent

    事件内核对象是在线程同步时比较常用的内核对象 一个事件内核对象的触发表示一个操作已经完成 有两种类型的事件内核对象 手动重置事件和自动重置事件 当一个手动重置对象被触发的时候 正在等待该事件的所有线程都将变成可调度状态 而当一个自动重置事件
  • 互联网+国家战略-整理

    互联网 国家战略 前言 互联网 普惠经济 跨界 融合 连接一切 互联网 的密码 第一篇 互联网 纳入国家计划 什么是互联网 怎么理解 加什么 互联网 与国家影响力 互联网 融合共识 协同行动 互联网 六大特征 跨界融合 创新驱动 重塑结构
  • 结构体定义struct和typedef struct的区别(重新整理版)

    1 结构体的定义 允许用户自己建立由不同类型数据组成的组合型的数据结构 它称为结构体 实际上应称为 结构体类型 2 struct的用法 下面以一个结构体实例来说明一下 struct os tcb OS STK OSTCBStkPtr OS