C语言结构体详解

news2024/11/17 13:42:46

邀请加入嵌入式社区,您可以在上面发布问题,博客链接,公众号分享,行业消息,招聘信息等。

目录

结构体有什么用?

结构体声明

正常的结构体声明

匿名结构体

匿名结构体只有在创建的时候可以建立变量

两个相同的匿名结构体,编译器会认为是不相同

结构体自引用

结构体自引用结构体

结构体自引用结构体指针

typedef与结构体

只创建一个名称

创建两个变量名 

注意事项

赋值

引用数据


结构体有什么用?

我们学习结构体之前需要知道结构体有什么用。举个例子,假如我现在需要将100个学生的信息录入教学系统。他们有年龄,性别,名字。我们进行编程的时候。不可能一一进行变量创建。那样太麻烦了。

那么我们就可以创建一个结构体,这个结构体类型里面包含年龄,性别,名字。这样,我们可以把小明,小红,小华都设置为这个类型的结构体。然后再对这个结构体赋值就可以了。

结构体声明

正常的结构体声明

结构体声明有两种方法

第一种是struct Stu s2。需要注意,struct一定要写上!

第二种方法就是在声明结构体的时候,}后面加上需要设置的结构体变量。

//现在我们建立了一个结构体类型,这个结构体类型名字叫做Stu
//s3,s4,s5,s6为全局变量,s1,s2是局部变量,但是他们都是同一种类型的结构体变量

struct Stu
{
  char name[20];//名字
  char tele[12];//电话
  char sex[10];//性别
  int age;
} s4,s5,s6;   //注意,这里的;不能少

struct Stu s3;//全局变量

int main()
{
  //创建的结构体变量
  struct Stu s1;//注意,这里的struct不能少
  struct Stu s2;

  return 0;
}

匿名结构体

匿名结构体只有在创建的时候可以建立变量

匿名结构体就是在创建结构体的时候,struct后面不加名字。个人不推荐使用匿名结构体,因为你创建了结构体之后,就不能再次创建该结构体的变量了

以下面这个为例子,我们struct后面没有增加名字。那么现在就只有sa这一个变量是属于该结构体类型变量。不能再次建立该类型的结构体变量了。

struct
{
  int a;
  char c;
}sa;  //这里一定要加sa,否则你接下来不能再次建立该结构体类型的变量了

int main()
{
    struct s1;   //这样是不可以的
    return 0;
}

两个相同的匿名结构体,编译器会认为是不相同

我们都知道,char型指针如果指向一个int型数据。编译器会报警告。

int main()
{
	int x;
	char* y = &x;  //警告

	return 0;
}

匿名结构体依旧如此,我们看起来长得一样的两个匿名结构体,编译器也会将他们看成是两个不同的类型。

struct
{
  int a;
  char c;
}sa;

struct
{
  int a;
  char c;
}* psa;

int main()
{
  psa = &sa;  //警告,编译器会把上面的两个声明当成完全不同的两个类型

  return 0;
}

结构体自引用

结构体自引用结构体

结构体创建变量的时候,创建的变量中有一个是自己,类似于递归。(但是不同!)

struct Node
{
  int data;//4
  struct Node n;  //这样是错误的
};

上面这一串代码明显是错误的。因为,假如他是正确的,那么他的大小sizeof(struct Node)是多少呢?很显然,无法确认。

结构体自引用结构体指针

(1)数据结构中有一个东西叫做链表。

(2)因为我们平常使用的数据都是依次按照顺序连接的,但是,如果我现在需要在这一堆数据arr的中间假如一个其他数据a。那么现在我就需要将arr中间的数据改为a,然后更改的数据都往后移动。这样明显很麻烦。

(3)那么我们可以利用链表的方式,比如说,现在我们有一个数据链arr1。每一个数据指向后面这个数字。那么,我现在需要在中间增加一个数据b,只需要将插入前面这个数据指向b,然后b指向插入后面这个数据即可。

(4)那么,方法如下

 

struct Node
{
 int data;
 struct Node* next;
};

此时sizeof(struct Node)为多少呢?如果是32位的系统下,是8个字节。因为int是4个字节,后面这个指针在32位系统下也是4个字节。

typedef与结构体

只创建一个名称

因为我们每次创建一个变量需要写成 struct Stu s1;很明显太麻烦了。于是我们可以使用typedef与结构体给结构体起一个别名。

typedef struct Node
{
  double d;
  int data;
}Node;

int main()
{
  //下面这两个等价
  struct Node n1;
  Node n2;

  return 0;
}

创建两个变量名 

有时候我们会看见typedef与结构体之后会有两个名字,这个是怎么会是呢?

这样就同时建立了两种类型,一种是Node型的结构体,一个是Node型的结构体指针。

// 在重命名结构体时,命名了两种:Node结构体类型,*pNode结构体指针类型
typedef struct Node
{
  double d;
  int data;
}Node,*pNode;


int main()
{
  pNode = &Node;

  return 0;
}

注意事项

虽然我们有typedef,但是如果需要链表那种形式的创建,还是有讲究的地方。我们看下面这一段代码。

因为在我typedef之前,你就已经使用了Node了。那么编译器就不会认识Node*。

/***** 错误写法 *****/
typedef struct 
{
  double d;
  int data;//4
  Node* next;//4/8
}Node;

/***** 正确写法 *****/

typedef struct Node
{
  double d;
  int data;//4
  struct Node* next;//4/8
}Node;

赋值

对于结构体只能在定义的时候初始化才能全部赋值,之后就不能再全体赋值了,只能单个赋值

/******这样是可以的,在定义变量的时候就初始化了*******/

    struct book s1={ "guojiajiaoyun", "yuwen",22.5};

/******这种就不行了,在定义变量之后,若再要对变量的成员赋值,那么只能单个赋值了*******/

    struct book s1;
    //这样就是不行的,只能在定义的时候初始化才能全部赋值,之后就不能再全体赋值了,只能单个赋值
    s1={"guojiajiaoyun","yuwen",22.5  };
    s1.title = "yuwen";//只能单个赋值;

引用数据

我们直接写上'.'进行数据引用

struct T
{
  double weight;
  short age;
};

struct S
{
  char c;
  struct T st;
  int a;
  double d;
  char arr[20];
};

int main()
{
  struct S s = { 'c', {55.6, 30}, 100, 3.14, "hello bit" };

  printf("%c %d %lf %s\n", s.c, s.a, s.d, s.arr);
  printf("%lf\n", s.st.weight);

  return 0;
}

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

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

相关文章

vuex通过Mutations来修改状态的原理及devtools插件的下载

状态修改: 通过Mutations来修改状态,并配合devtools调试工具会记录这个状态何时被修改过; 好处是因为所有组件都可以访问和修改状态,通过Mutations配合调试工具能知道状态被哪个组件什么时候被修改过,方便追溯&#…

如何让 ChatGPT 写短篇小说?

故事一 请根据下面内容续写故事,要求800字。 在一个晴朗的秋日下午,男主人 Jack 抱着他的妻子 Rose,两人坐在沙发上看着电视。 这是,Jack对Rose说:”亲爱的,我们来玩一个游戏吧。” ChatGPT回答&#xff1a…

华为机试 - 端口合并

目录 题目描述 输入描述 输出描述 用例 题目解析 算法源码 题目描述 有M(1<M<10)个端口组&#xff0c; 每个端口组是长度为N(1<N<100)的整数数组&#xff0c; 如果端口组间存在2个及以上不同端口相同&#xff0c;则认为这2个端口组互相关联&#xff0c;可以…

CentOS部署主从DNS服务器

几个概念&#xff1a; 域名解析为IP地址&#xff1a;正向解析 IP地址解析为域名&#xff1a;反向解析 主DNS服务器&#xff1a;在特定区域内具有唯一性&#xff0c;负责维护该区域内的域名和IP地址之间的对应关系。 从DNS服务器&#xff1a;从服务器中获得域名和IP地址对应关系…

PCIE2PCI104载板转接卡

功能型号 PCIE2PCI104 此无源扩展卡允许开发人员将PCI104或PC/104plus卡安装到通用PCI总线系统中。适配器配备了一个堆栈式连接器。 功能描述 规格 适用于标准&#xff1a;Universal.3.3V或5V PCI插槽 工业温度工作范围&#xff1a;-40至85 C 连接器/接口&#xff1a;包括一个带…

干货 | 肖特基二极管4大特性

前言 肖特基二极管是重要的电子元器件&#xff0c;因为其承载着保护电路的重要作用&#xff0c;所以显得格外的不可或缺&#xff0c;我们都知道在选择肖特基二极管时&#xff0c;主要看它的正向导通压降、反向耐压、反向漏电流等。 但我们却很少知道其在不同电流、不同反向电压…

固定支撑约束在ANSYS有限元计算中的三大注意事项

固定支撑是在结构有限元中&#xff0c;大家最常用的一种约束条件了。如图1所示给出了设置固定支撑操作的方法。 图1 设置固定支撑操作方法 固定支撑约束&#xff0c;可以应用在点&#xff0c;线和面特征上。固定支撑表示被约束为位置为刚性&#xff0c;但是在现实工程结构中&a…

解决“Vector Hardware Manager无法连接This Computer”(能够独立解决问题,体现一个人的综合能力)

1. 引子 Vector Hardware Manager是先前配置工具Vector Hardware Config的继承者,是Vector Hardware Config工具的升级版或替代产品 什么是Vector Hardware Config? CANoe里打开: 界面: 而Vector Hardware Manager其实就是把Vector Hardware Config里的功能搬到了这里实…

UE5 + VS2022和UE4 + VS2019 编译踩坑

1&#xff0c;卡住且没有cl.exe进程 &#xff08;1&#xff09;&#xff0c;卸载Incredibuild&#xff0c;Incredibuild也是利用进程虚拟化技术&#xff0c;加速包括编译的方法&#xff0c;和firstbuild是一样的&#xff0c;所以优先选择了Incredibuild的方式&#xff0c;但是2…

PDF文件添加水印怎么添加?只需要两步轻松添加水印

PDF文件添加水印怎么添加&#xff1f;我们在处理工作文件时&#xff0c;都非常在意文件的隐私性&#xff0c;我们经常会使用一些方法来确保我们文件的内容不被别人窃取&#xff0c;其中一种方法就是给PDF文件添加水印&#xff0c;这样文件的内容就不会轻易被窃取了&#xff01;…

ControllerAdvice统一异常处理失效

问题描述 在common模块增加统一异常处理代码&#xff0c;如下。在service业务处理类中抛出异常&#xff0c; 但是接口返回的为spring统一的500错误。 package com.tea.common.exception; import com.tea.common.entity.ResponseResult; import com.tea.common.entity.Status…

基于java springboot的小说阅读微信小程序含后台管理系统源码

系统运行环境 开发工具 eclipse(idea)&#xff0c;mysql5.7&#xff08;大于5.5&#xff09;&#xff0c;navicat&#xff0c;小程序开发工具 硬件要求 windows操作系统 cpu&#xff1a;2.4GHz 内存&#xff1a;4G 硬盘&#xff1a;100G 开发及运行环境 windows10操作…

ArcGIS基础:栅格数据中的NoData数值(空值)的处理

先看下实验操作数据&#xff0c;也是原始数据&#xff0c;如下所示&#xff1a; 是一个非常普通的DEM栅格数据&#xff0c;中间空了一大块&#xff0c;也就是nodata&#xff0c;那么如果进行数据运算处理时&#xff0c;nodata值的像元是不参与&#xff0c;因此&#xff0c;需要…

Google Earth Engine(GEE)——将每小时降水量转化为逐日的降水量

很多时候我们获取影像的时间分辨率为逐小时,但是如何获取影像的累积降水量?这里的整体思路就是获取不同时间影像的时间序列,然后分别获取每天的降水量,最后同一秋累计值,如果要进行时序图片展示的情况,我们就可以再秋累计值的时候就可以建立一个时间属性,这样可以建立时…

【WebGL-iTwin.js】先导篇:用bentley-iTwin.js搭建模型在线可视化平台

一、先导篇说明 本篇博客为先导篇&#xff0c;方便快速搭建可视化平台。后面会慢慢补充WebGL相关的知识&#xff0c;理论原理和代码实战都会涉及&#xff0c;采用的技术是iTwin.js&#xff0c;它是由bentley推出的基于Cesium的开源图形框架&#xff0c;主要用于工程数字化BIM应…

<论文阅读>FLIRT:二维激光数据的兴趣区域及其在机器人导航中的应用

摘要&#xff1a;在这篇文章中&#xff0c;我们提出了FLIRT&#xff08;快速激光兴趣区域变换&#xff09;&#xff0c;用于 2D 激光数据的多尺度兴趣区域算子。FLIRT结合了基于大地线&#xff08;是指地球椭球面上两点间的最短程曲线&#xff09;的曲线近似范围信号的探测器和…

SpringMVC的作用,在Spring家族体系中功能角色?

一、 什么叫 MVC 模型-视图-控制器&#xff08;MVC&#xff09; 是一个众所周知的以设计界面应用程序为基础的设计思想。 它主要通过分离模型、 视图及控制器在应用程序中的角色将业务逻辑从界面中解耦。 通常&#xff0c; 模型负责封装应用程序数据在视图层展示。 视图仅仅只…

【蓝桥杯国赛真题08】python约分 蓝桥杯青少年组python编程 蓝桥杯国赛真题解析

目录 python约分 一、题目要求 1、编程实现 2、评分标准 二、解题思路 1、案例分析

C# mvc控制器向视图传递值

1.新建ASP.NET MVC应用程序&#xff0c;选择“空”模板&#xff0c;添加HomeController控制器和Index.cshtml视图页面。 2.选中Models文件夹&#xff0c;添加右键“添加—新建项”&#xff0c;弹出添加新项对话框&#xff0c;如图所示&#xff1a; 3.选择“数据”菜单&#xff…

(三)Redis的其他小功能

一 慢查询分析 所谓慢查询日志就是系统在命令执行前后计算每条命令的执行时间&#xff0c;当超过预设阈值&#xff0c;就将这条命令的相关信息&#xff08;例如&#xff1a;发生时间、耗时、命令的详细信息&#xff09;记录下来。 1.1 生命周期 发送命令-> 命令排队 ->…