C语言---自定义类型:结构体,枚举,联合

news/2024/11/7 21:36:53/

在这里插入图片描述

🚀write in front🚀
📝个人主页:认真写博客的夏目浅石.
🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝
📣系列专栏:凡人修C传
💬总结:希望你看完之后,能对你有所帮助,不足请指正!共同学习交流 🖊
✉️如果无聊的话,就来逛逛我的博客栈吧stack-frame.cn

文章目录

  • 前言
  • 一、结构体
    • 1.1 结构的基础知识
    • 1.2 结构的声明
    • 1.3 特殊的声明
    • 1.4 结构的自引用
    • 1.5 结构体变量的定义和初始化
    • 1.6 结构体内存对齐
    • 1.7 修改默认对齐数
    • 1.8 结构体传参
    • 在这里插入图片描述
  • 总结


前言

今天夏目带你一起学习 结构体,枚举,联合,本篇博客除了结构体是我们以后要经常使用的外,枚举,联合却是比较少见的,但是就是因为少见我们就不学习了么?答案不是的,今天就带你学习这些知识。


一、结构体

1.1 结构的基础知识

结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量

1.2 结构的声明

描述一个学生:

struct Stu
{char name[20];//名字int age;//年龄char sex[5];//性别char id[20];//学号
}; //分号不能丢

1.3 特殊的声明

声明结构的时候可以不完全的声明。

//匿名结构体类型
struct
{i	nt a;char b;float c;
}x;
struct
{int a;char b;float c;
}a[20], *p;

那么问题来了?

//在上面代码的基础上,下面的代码合法吗?
p = &x;

在这里插入图片描述

警告:
编译器会把上面的两个声明当成完全不同的两个类型
所以是非法的

1.4 结构的自引用

在结构中包含一个类型为该结构本身的成员是否可以呢?

//代码1
struct Node
{int data;struct Node next;
};
//可行否?
如果可以,那sizeof(struct Node)是多少?

答案是不可以的,因为结构体无法形成树形结构因为这样会无穷递归下去,因此正确的写法是:

struct Node
{int data;struct Node* next;//写成指针形式
};typedef struct Node
{int data;struct Node* next;
}Node; //常用,因为方便更改名字和类型

这里后续的数据机构会继续深入学习结构体,这里要做到了解和理解。

1.5 结构体变量的定义和初始化

有了结构体类型,那如何定义变量,其实很简单,下面就来给大家讲解:
定义方式一:


#include<stdio.h>struct point
{int x;int y;
}p1;   //声明类型的同时定义变量p1

定义方式二:

struct Point p2; //定义结构体变量p2

定义方式三:

typedef struct Point 
{int data;struct Node* next;
}p3; //常用,因为方便更改名字和类型

初始化方式一:

struct Point p4 = {x, y};

初始化方式二:

struct Stu        //类型声明
{char name[15];//名字int age;      //年龄
};
struct Stu s = {"zhangsan", 20};//初始化

初始化方式三:

struct Node
{int data;struct Point p;struct Node* next; 
}n1 = {10, {4,5}, NULL}; //结构体嵌套初始化struct Node n2 = {20, {5, 6}, NULL};//结构体嵌套初始化

1.6 结构体内存对齐

我们已经掌握了结构体的基本使用了。
现在我们深入讨论一个问题:计算结构体的大小。
这也是一个特别热门的考点结构体内存对齐

学习之前,我想给大家看一张基础知识图片,这样有了基础再理解会事半功倍
在这里插入图片描述

  • 结构体的第一个成员,对齐到结构体在内存中存放位置的0偏移处。
  • 从第二个成员开始,每一个成员都要对齐到(一个对齐数)的整数倍处
  • 对齐数:结构体成员自身大小和默认对齐数的较小值
  • 结构体的总大小,必须是所有成员的对齐数中最大对齐数的整数倍
  • 如果结构体中嵌套了结构体成员,要将嵌套的结构体成员对齐到自己的成员中最大对齐数的整数倍处
  • 结构体的总大小必须是最大对齐数的整数倍,这里的最大对齐数:包括嵌套结构体成员中的对齐数,的所有对齐数中的最大值。

下面就配合例题来讲解知识:

32位系统环境,编译选项为4字节对齐,那么sizeof(A)sizeof(B)是( )
struct A
{int a;short b;int c;char d;
};
struct B
{int a;short b;char c;int d;
}

在这里插入图片描述
在这里插入图片描述
所以答案是:16,12;

为什么存在内存对齐?

根据百度百科讲解:

平台原因(移植原因)

不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。

性能原因:

数据结构(尤其是栈)应该尽可能地在自然边界上对齐。
原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。

总体来说

结构体的内存对齐是拿空间来换取时间的做法。

1.7 修改默认对齐数

#include <stdio.h>
#pragma pack(8)//设置默认对齐数为8
struct S1
{char c1;int i;char c2;
};
#pragma pack()//取消设置的默认对齐数,还原为默认
#pragma pack(1)//设置默认对齐数为1
struct S2
{char c1;int i;char c2;
};
#pragma pack()//取消设置的默认对齐数,还原为默认
int main()
{//输出的结果是什么?printf("%d\n", sizeof(struct S1));printf("%d\n", sizeof(struct S2));return 0;
}

在这里插入图片描述

1.8 结构体传参

struct S
{int data[1000];int num;
};struct S s = {{1,2,3,4}, 1000};//结构体传参
void print1(struct S s)
{printf("%d\n", s.num);
}//结构体地址传参
void print2(struct S* ps)
{printf("%d\n", ps->num);
}int main()
{print1(s);  //传结构体print2(&s); //传地址return 0;
}

在这里插入图片描述

总结

今天夏目带你一起学习 结构体,枚举,联合,本篇博客除了结构体是我们以后要经常使用的外,枚举,联合却是比较少见的


http://www.ppmy.cn/news/297175.html

相关文章

分布式项目15 用户注册,单点登陆dubbo来实现

分析&#xff1a;当用户填写完成注册信息之后,将请求发送给前台服务器.之后前台消费者利用dubbo框架实现RPC调用。之后将用户信息传递给jt-sso服务提供者.之后完成数据的入库操作。 01.页面url分析 02.查看页面JS $.ajax({ type : "POST", url : "/user/doRe…

电脑重装系统后无法开机是什么原因导致的

电脑重装系统是一种常见的解决问题和提升性能的方法&#xff0c;但有时候重装系统后可能会遇到无法开机的问题。本文将介绍一些常见原因和解决方法&#xff0c;帮助您解决电脑重装系统后无法开机的困扰。 工具/原料&#xff1a; 系统版本&#xff1a;windows7系统 品牌型号&…

机器学习-12 卷积神经网络简介

卷积神经网络 引言深度学习发展历程深度应用领域深度学习vs传统机器学习深度神经网络vs浅层神经网络深度学习概述 卷积神经网络CNNBP神经网络CNN概述卷积神经网络大致结构卷积神经网络大致过程 局部连接权值共享非线性映射ReLU&#xff08;Rectified Linear Units&#xff09;池…

你的Postman为什么连不了数据库?

postman本身没有数据库连接功能&#xff0c;所以用到了node.js中的xmysql实现Rest API的生成&#xff0c;利用postman进行请求&#xff0c;获取需要的数据&#xff0c;来做数据准备或断言 1.安装 安装node.js&#xff1a;要求版本大于等于7.6 首先保证你的环境上有node.js&a…

DOTA数据集

https://captain-whu.github.io/DOTA/dataset.html https://github.com/search?qfaster_rcnn_for_DOTA 转载于:https://www.cnblogs.com/ivyharding/p/11155676.html

DOTA自走棋攻略

DOTA自走棋攻略 文章目录 DOTA自走棋攻略一、选择与走向-----全场节奏、圣物和嫖牌决定阵容走向二、前期运营三、牧师机制四、对手机制五、站位细节阵容 一、选择与走向-----全场节奏、圣物和嫖牌决定阵容走向 野怪 前3波小野怪 10波石头人 15波野狼 高人口阵容&#xff1a; …

软件测试金融项目,在测试的时候一定要避开的一些雷区

软件测试金融项目需要格外谨慎和专注&#xff0c;因为这些项目通常涉及大量的交易、用户隐私和其他敏感信息。以下是一些软件测试金融项目时需要关注的方面&#xff1a; 1. 数据保护 在测试金融项目时&#xff0c;必须确保用户数据和投资信息得到保护。测试人员必须确保测试环…

Dota数据集介绍

文章目录 前言DOTA数据集介绍DOTAV1.0DOTAV1.5DOTAV2.0标注方式Task1-- Detection with oriented bounding boxesTask2-- Detection with horizontal bounding boxes其他情况说明参考博客 前言 记录Dota数据集&#xff0c;时间2021.6.8 DOTA数据集介绍 DOTA数据集官网 https:…