C结构体的几种定义形式 + typedef结合使用的好处

struct 语句定义了一个包含多个成员的新的数据类型,struct 语句的格式如下:

        struct tag 
        {
                    member-list
                    member-list
                    member-list  
                    ...

        } variable-list ;

tag 是结构体标签。

member-list 是标准的变量定义,比如 int i; 或者 float f;,或者其他有效的变量定义。

variable-list 结构变量,定义在结构的末尾,最后一个分号之前,您可以指定一个或多个结构变量。

在一般情况下,tag、member-list、variable-list 这 3 部分至少要出现 2 个。以下为实例:

 C 结构体 | 菜鸟教程(<----摘抄了一部分菜鸟的C教程,这里链接给一下)

一、基本的结构体定义 (不使用 typedef)

1. 声明了 结构体标签;不声明结构体变量。(方式1)

struct  结构体标签  {数据类型  成员1;数据类型  成员2;// ... 更多成员
};

这种是结构体最常用也是最基本的定义方式。

struct: 关键字,表示定义一个结构体。

结构体标签: 给这个结构体类型起的名字 (类似于盒子的名字)。 你以后可以靠这个标签来声明这个类型的变量。

{ ... }: 花括号里定义一个个“成员”(类似于盒子里的每一个积木)。每个成员都有自己的数据类型(比如 intfloatchar)和名称。

//使用举例:
struct Point 
{ int x; int y; 
}; // 声明一个Point类型的变量(创建了一个盒子) 
struct Point p1; //每次声明变量的时候,都需要加上 struct 关键字。
p1.x = 10; // 访问成员 
p1.y = 20; // 访问成员 

特点: 每次声明变量的时候,都需要加上 struct 关键字。

2. 声明了 结构体变量;不声明 结构体标签。(方式2)

struct {数据类型  成员1;数据类型  成员2;// ...
} 变量名;

这种方式 没有结构体标签,它直接定义一个匿名结构体的变量。 创建一个盒子,并给这个盒子装上东西,但是没有给盒子起名字。

//使用举例:
struct {int x;int y;
} p5; // 定义了一个匿名的结构体变量 p5p5.x = 70;
p5.y = 80;// 再次定义会报错,因为结构体“长相”不同
// struct {
//   int x;
//   int y;
// } p6;  // 错误!

特点: 只能在定义的时候创建变量。 无法再创建同类型的其他变量,因为没有结构体标签来指示类型。 通常很少使用。

 

3. 同时声明了 结构体变量 和 结构体标签。(方式3)

struct 结构体标签 
{ 数据类型 成员1; 数据类型 成员2; // ... 更多成员 
}变量名;

解释: 同时定义了结构体标签P2和结构体变量S2。后续可以再通过结构体标签 P2,再定义S3,S4之类的结构体变量(struct P2 S3,S4;),可以理解其走了两步,第一步为:struct P2

{ int a; char b; double c; };  第二步为:struct P2 S2;

1. .h 文件中直接定义这种形式,在编译中不通过,这种形式同时完成了结构体声明和结构体定义,想象一下,如果你把 struct P2 S2; 放在一个 .h 文件里,并被多个 .c 文件 #include 了。 那么,每个包含这个 .h 文件的 .c 文件都会试图创建变量 S2。 这会导致 重复定义错误 (编译器会报错,因为同一个变量被多次定义了)。

2.可以放在某个.c文件中编译通过;

二、与 typedef联合使用

1.  使用 typedef 定义结构体 (带标签)(方式4)

typedef struct 结构体标签 {数据类型  成员1;数据类型  成员2;// ...
} 新的类型名;/*typedef 
struct 结构体标签 {数据类型  成员1;数据类型  成员2;// ...
} 
别名;*/

typedef: 关键字,用于给一个数据类型(包括结构体)起个别名。

新的类型名: 你给这个结构体类型新起的名字 (类似于给盒子起个外号)。 以后可以用这个新的名字来声明变量,而不需要写 struct 了。

typedef struct  Point  {  // 这个结构体叫 Point,并且起了一个"别名" MyPointint x;int y;
} MyPoint;// 声明一个Point类型的变量(创建了一个盒子)
MyPoint p2;  // 不需要写 "struct" 了!
p2.x = 30;
p2.y = 40;

特点:以后声明变量时,可以直接使用新起的类型名。更简洁,更方便。 推荐使用 typedef 来定义结构体。

2. 使用 typedef 定义匿名结构体 (无标签)(方式5)

typedef struct {数据类型  成员1;数据类型  成员2;// ...
}  新的类型名;

这种定义方式 没有结构体标签。 这样定义的结构体只能通过 typedef 赋的别名来使用。

//使用举例:
typedef struct {  // 没有 "结构体标签"int x;int y;
} MyPoint;  // 定义结构体的时候同时定义了别名MyPoint p3;
p3.x = 50;
p3.y = 60;// 错误,因为没有定义结构体名称
// struct { int x; int y; } p4;  // 错误!

    特点: 只能使用 typedef 定义的别名来声明变量。 因为没有结构体标签,所以无法再用 struct { ... } 变量名; 这种方式定义变量。

    3.在结构体定义时就进行初始化 (配合 typedef 与否均可)

    解释: 在定义结构体变量的同时,给它的成员赋值。

    3.1使用 typedef

    typedef struct Point {int x;int y;
    } MyPoint;MyPoint p1 = {100, 200};  // 直接初始化
    

    3.2不使用 typedef

    struct Point {int x;int y;
    };struct Point p2 = {300, 400};
    

    总结:
    • 推荐: 使用 typedef 结合结构体标签。 这样既可以给结构体起别名,又方便以后阅读和维护代码。

    • 一般避免: 直接定义匿名结构体变量(方式2)。 因为你很难重复使用这个类型。

    • 匿名结构体: 适合在定义后立即使用,并且不希望再定义同类型结构体的情况。 比较少见。

    本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
    如若转载,请注明出处:http://www.pswp.cn/pingmian/92186.shtml
    繁体地址,请注明出处:http://hk.pswp.cn/pingmian/92186.shtml

    如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

    相关文章

    SPICE电容矩阵

    SPICE电容矩阵: 如果有许多条传输线,就可以用下标来标记每一条线。例如,如果有5条线,就用1~5分别标记,依惯例把返回路径导体标记为导线0。图10.6给出了5条导线和一个公共返回平面的横截面图。首先研究电容器元件,下一节再讨论电感器元件。 在这个线的集合中,每对导线之间…

    【Java】栈和队列

    文章目录1.栈1.1 栈的定义1.2 栈的使用1.3 栈的模拟实现2.队列2.1 队列的定义2.2 队列的使用2.3 队列的模拟实现3.循环队列3.1 循环队列的概念3.2 循环队列判断空和满4.双端队列Deque1.栈 1.1 栈的定义 栈是一种特殊的线性表&#xff0c;其只允许在固定的一段进行数据的插入或…

    【性能测试】---测试工具篇(jmeter)

    目录 1、安装并启动jemeter 2、重点组件 2.1、线程组&#xff1a; 2.2、HTTP取样器​编辑 2.3、查看结果树 2.4、HTTP请求默认值 2.5、HTTP信息头管理器 2.6、JSON提取器 2.7、JSON断言 2.8、同步定时器 2.9、CSV数据文件设置 2.10、HTTP Cookie管理器 3、测试报告…

    机器学习(12):拉索回归Lasso

    - 拉索回归可以将一些权重压缩到零&#xff0c;从而实现特征选择。这意味着模型最终可能只包含一部分特征。 - 适用于特征数量远大于样本数量的情况&#xff0c;或者当特征间存在相关性时&#xff0c;可以从中选择最相关的特征。 - 拉索回归产生的模型可能更简单&#xff0c;因…

    Redis持久化存储

    Redis持久化存储详解 一、核心持久化机制 Redis提供两种主要持久化方式&#xff1a;RDB&#xff08;快照&#xff09; 和 AOF&#xff08;追加文件&#xff09;&#xff0c;以及两者的混合模式。 RDB&#xff08;Redis Database&#xff09;快照持久化 工作原理 RDB通过创建数据…

    python学智能算法(三十四)|SVM-KKT条件回顾

    【1】引言 前序学习进程中&#xff0c;对软边界拉格朗日方程进行了初步构建。 其中约定了两个拉格朗日乘子要非负&#xff0c;其本质是要满足KKT条件。 今天就乘此次机会&#xff0c;在回顾一下KKT条件。 【2】定义 当问题无约束的时候&#xff0c;只要让函数梯度为零&#…

    【网络基础】计算机网络发展背景及传输数据过程介绍

    本文旨在帮助初学者建立起计算机网络的基础认知&#xff0c;从网络的发展背景到网络协议的分层模型&#xff0c;再到IP与MAC地址的基本概念&#xff0c;全面覆盖第一阶段学习重点。 &#x1f4cc; 本节重点 了解计算机网络的发展背景&#xff0c;掌握局域网&#xff08;LAN&am…

    阿里云-通义灵码:解锁云原生智能开发新能力,让云开发更“灵”~

    免责声明&#xff1a;此篇文章所有内容皆是本人实验&#xff0c;并非广告推广&#xff0c;并非抄袭&#xff0c;如有侵权&#xff0c;请联系笔者。 每日一句 信念其实就是相信未来&#xff0c; 相信内在&#xff0c; 以及坦然美好的心境。 目录 每日一句 一. 引言 二.通义…

    lesson33:Python协程详解:从原理到实战的异步编程指南

    目录 一、协程核心概念&#xff1a;轻量级并发的本质 1.1 什么是协程&#xff1f; 1.2 协程与线程/进程的对比 二、协程工作原理&#xff1a;事件循环与协作式调度 2.1 事件循环&#xff08;Event Loop&#xff09;&#xff1a;协程的"调度中心" 2.2 协作式调度…

    深入理解C++模板进阶:非类型参数、特化与分离编译

    前言C模板是泛型编程的核心&#xff0c;它允许我们编写与类型无关的代码。在掌握了模板的基础知识后&#xff0c;我们需要进一步了解模板的高级特性&#xff0c;以便更灵活地使用它们。本文将深入探讨三个重要的模板进阶主题&#xff1a;非类型模板参数、模板特化以及模板的分离…

    使用winsw把SpringBoot项目注册成window服务

    目录 一、使用winsw注册 1.1、项目打jar包 1.2、下载winsw 1.3、把 WinSW.NET4.exe 重新命名 1.4、编写m配置文件用于配置注册信息 1.5、创建文件夹存放你的文件 1.6、安装服务 1.7、启动服务 1.8、卸载服务 1.8、停止服务 一、使用winsw注册 1.1、项目打jar包 例如项目jar包名…

    进阶向:Python开发简易QQ聊天机器人

    数字化时代的聊天机器人应用在当今数字化时代&#xff0c;聊天机器人已经成为日常生活和商业活动中不可或缺的一部分。根据市场研究数据显示&#xff0c;全球聊天机器人市场规模预计将在2026年达到102亿美元&#xff0c;年复合增长率达到34.75%。这些智能助手正广泛应用于以下场…

    基于开源链动2+1模式AI智能名片S2B2C商城小程序的用户留存策略研究

    摘要&#xff1a;在数字化商业竞争白热化的当下&#xff0c;用户留存成为企业可持续发展的核心命题。本文聚焦开源链动21模式AI智能名片S2B2C商城小程序这一创新技术组合&#xff0c;通过分析其技术架构、模式创新与生态闭环的协同效应&#xff0c;揭示其在降低用户决策成本、提…

    单词的划分(动态规划)

    题目描述有一个很长的由小写字母组成字符串。为了便于对这个字符串进行分析&#xff0c;需要将它划分成若干个部分&#xff0c;每个部分称为一个单词。出于减少分析量的目的&#xff0c;我们希望划分出的单词数越少越好。你就是来完成这一划分工作的。输入第一行&#xff0c;一…

    C语言学习笔记——文件

    目录1 文件的概念2 程序文件和数据文件3 二进制文件和文本文件4 流4.1 流的概念4.2 标准流5 文件信息区和文件指针6 处理文件的库函数6.1 fopen6.2 fclose6.3 fgetc6.4 fputc6.5 fgets6.6 fputs6.7 fscanf6.8 fprintf6.9 fread6.10 fwrite6.11 fseek6.12 ftell6.13 rewind6.14 …

    C++语法与面向对象特性(2)

    一.inline函数1.inline的基本特性被inline修饰的函数被称为内联函数。inline函数设计的初衷是为了优化宏的功能&#xff0c;编译器会在编译阶段对inline函数进行展开。然而需要注意的是&#xff0c;inline对于编译器而言是一种建议&#xff0c;它通常会展开一些简短的&#xff…

    Linux中grep命令

    Linux 中的 grep 用法详解grep 是 Linux 中强大的文本搜索工具&#xff0c;用于在文件或输入流中查找匹配指定模式的行。其基本语法为&#xff1a;grep [选项] "模式" [文件]核心功能基础搜索在文件中查找包含特定字符串的行&#xff1a;grep "error" log.…

    【遥感图像入门】遥感中的“景”是什么意思?

    在遥感成像中,“3景城市影像”和“5景城市影像”中的“景”是遥感数据的基本单位,通常指一次成像过程中获取的独立遥感影像块。这一概念的具体含义需结合技术背景和应用场景理解: 一、“景”的技术定义 单次成像的独立覆盖区域 遥感平台(如卫星、飞机)在特定时间和位置对…

    Pytorch-07 如何快速把已经有的视觉模型权重扒拉过来为己所用

    下载&#xff0c;保存&#xff0c;加载&#xff0c;使用模型权重 在这一节里面我们会过一遍对模型权重的常用操作&#xff0c;比如&#xff1a; 如何下载常用模型的预训练权重如何下载常用模型的无训练权重&#xff08;只下载网络结构&#xff09;如何加载模型权重如何保存权…

    C语言零基础第9讲:指针基础

    目录 1.内存和地址 2.指针变量和地址 2.1 取地址操作符&#xff08;&&#xff09; 2.2 指针变量 2.3 解引用操作符&#xff08;*&#xff09; 2.4 指针变量的大小 3.指针变量类型的意义 3.1 指针的解引用 3.2 指针 - 整数 3.3 void*指针 4.指针运算 4.1 指针…