C语言_自定义类型详解

news2024/11/29 14:25:06

文章目录

  • 前言
  • 一.结构体的声明
    • 1.1结构体的基础知识
    • 1.2结构的声明
    • 1.3特殊声明
    • 1.4结构体的自引用
      • 在结构中包含一个类型为该结构本身的成员是否可以?
      • 正确的自引用方式
      • 匿名结构体类型和typedef的结合形式
    • 1.5 结构体变量的定义和初始化
      • 结构体定义与初始化
      • 结构体里嵌套结构体
    • 1.6 结构体内存对齐 -- 计算结构体大小
    • 1.7修改默认对齐数
    • 1.8 结构体传参
  • 二.位段
    • 2.1 什么是位段
    • 2.2 位段的内存分配
    • 2.3位段的跨平台问题
    • 2.4 位段的应用
  • 三.枚举
    • 3.1枚举类型的定义
    • 3.2 枚举优点
  • 四.联合(共用体)
    • 4.1 联合大小的计算


前言

提示:这里可以添加本文要记录的大概内容:

一.结构体的声明

1.1结构体的基础知识

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


1.2结构的声明


1.3特殊声明

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

//匿名结构体类型
//匿名结构体类型一般只能用一次
struct
{
    int a;
    char b;
    float c;
}x;
struct
{
    int a;
    char b;
    float c;
}*p ;
int main()
{
    p = &x;  //err
    return 0;
}

上面的两个结构体在声明的时候省略掉了结构体标签(tag)
那么在上面代码的基础上,下面的代码合法吗?

p=&x;

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

1.4结构体的自引用

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

代码如下:

//struct Node
//{
//    int data;
//    struct Node next;
//};
// 不可行,本质上是错误的 Node next ---  4/8
//                                ---  next
//                                --- 无穷                      

正确的自引用方式

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

匿名结构体类型和typedef的结合形式

错误样例:


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

解决方案:

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

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

结构体定义与初始化

struct SN
{
    char c; 
    int i;

}sn1 = { 'q',100 }, sn2 = {.i=200,.c='w'};//全局变量

int main()
{
    printf("%c %d\n", sn2.c, sn2.i);
    return 0;
}

结构体里嵌套结构体

struct SN
{
    char c; 
    int i;

}sn1 = { 'q',100 }, sn2 = {.i=200,.c='w'};//全局变量

struct S
{
    double d; 
    struct SN sn ;
    int arr[10];

};

int main()
{
    //printf("%c %d\n", sn2.c, sn2.i);
    struct S s = { 3.14,{'a',99},{1,2,3} };
    printf("%lf %c %d\n", s.d, s.sn.c, s.sn.c, s.sn.i);
    int i = 0;
    for (i = 0; i < 10; i++)
    {
        printf("%d ", s.arr[i]);
    }

    return 0;
}

运行结果:


1.6 结构体内存对齐 – 计算结构体大小

  • offsetof 宏 这个宏可以计算结构体成员相较于结构体其实位置的偏移量 ;头文件 #include<stddef.h>

上面的现象分析,我们发先结构体成员不是按照顺序在内存中连续存放的,而是有一定的对齐规则的。
结构体内存对齐的规则:

  • 1.结构体的第一个成员永远放在相较于结构体变量起始位置的偏移量为0的位置。
  • 2.从第二个成员开始,往后的每个成员都要对齐到某个对齐数的整数倍。
对齐数:结构体成员自身的大小和默认对齐数的较小值。 VS上默认对齐数是8; gcc没有默认对齐数,对齐数就是结构体成员的自身大小。
  • 3.结构体的总大小,必须是最大对齐数的整数倍.
    最大对奇数是:所有成员的对齐数中最大的值。
  • 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

1.7修改默认对齐数

#pragma 这个预处理指令,这里我们在次使用,可以改变我们的默认对齐数。


1.8 结构体传参

首选print2函数,函数传参的时候,参数需要压栈,会有时间和空间上的系统开销。
如果传递一个结构体对象的时候,结构体过大,参数压栈的系统开销比较大,所以会导致性能的下降。

二.位段

2.1 什么是位段

  • 1.位段的成员必须是 int、unsigned int 或 signed int 。
  • 2.位段的成员名后边有一个冒号和一个数字。

2.2 位段的内存分配

  • 1.位段的成员可以是 int unsigned int signed int 或者是char (属于整形家族)类型
  • 2.位段的空间上是按照需要以4个字节(int)或者1个字节(char)的方式来开辟的。
  • 3.位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段。

2.3位段的跨平台问题

  • 1.int 位段被当成有符号数还是无符号数是不确定的。
  • 2.位段中最大位的数目不能确定。(16位机器最大,32位机器最大,写成27,在16位机器会出现问题)。
  • 3.位段中的成员在内存中从左向右,还是从右向左分配标准尚未定义。
  • 4.当一个结构包含两个位段,第二个位段成员比较大,无法容纳于第一个位段剩余的位时,是舍弃剩余的位还是利用,这是不确定的。

总结:跟结构相比,位段可以达到同样的效果,并且可以很好的节省空间,但是跨平台的问题存在。


2.4 位段的应用


三.枚举

枚举顾名思义就是一一列举。
把我们的取值一一列举。

3.1枚举类型的定义

枚举,里面是枚举的可能取值,逗号。


3.2 枚举优点

四.联合(共用体)

联合也是一种特殊的自定义类型。
这种类型的定义的变量包含一系列的成员,特征是这些成员公用同一块空间(所以联合也叫共用体)

4.1 联合大小的计算

  • 联合的大小至少是最大成员的大小。
  • 当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。

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

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

相关文章

数据结构与算法:稀疏数组Java版

什么是稀疏数组 稀疏数组是一种特殊的数据结构&#xff0c;它仅在数组中保存了有效的数据元素&#xff0c;忽略掉了大部分未被使用或被零值占据的元素&#xff0c;从而节省了内存空间。 在稀疏数组中&#xff0c;只有非零元素会被保存&#xff0c;这些元素在原数组中的位置和…

姿态识别+康复训练矫正+代码+部署(AI 健身教练来分析深蹲等姿态)

姿态识别康复训练矫正&#xff08;AI 健身教练姿态分析&#xff09; 目录 本文旨在构建一个 AI 健身教练&#xff0c;帮助判断姿态标准与否&#xff0c;并且矫正姿态&#xff01;无论您是初学者还是专业人士&#xff0c;它都可以帮助您无缝地进行深蹲。为了完成这项任务&…

基于海洋捕食者算法的无人机航迹规划-附代码

基于海洋捕食者算法的无人机航迹规划 文章目录 基于海洋捕食者算法的无人机航迹规划1.海洋捕食者搜索算法2.无人机飞行环境建模3.无人机航迹规划建模4.实验结果4.1地图创建4.2 航迹规划 5.参考文献6.Matlab代码 摘要&#xff1a;本文主要介绍利用海洋捕食者算法来优化无人机航迹…

SANSAN每周新鲜事|到底哪一款物联网平台适合你?

假如您有对设备进行监控、控制、管理、维护的需求&#xff0c;或者您的业务系统涉及设备管控、设备数据可视化和分析&#xff0c;大概率上&#xff0c;您需要开发一套系统专门去做设备接入和管理&#xff0c;您会面临两种选择&#xff1a; 1、选择一款合适的物联网平台&#x…

“消费增值:绿色商业模式的创新之路“

随着消费者对绿色、环保生活方式的追求不断增加&#xff0c;一种名为消费增值的商业模式正逐渐受到人们的关注。通过鼓励绿色消费行为&#xff0c;消费增值模式引导消费者形成低碳环保的生活方式&#xff0c;并实现积分的增值和社会效益的提升。一种只涨不跌的模式&#xff0c;…

历年网规上午真题笔记(2015年)

解析: 变更控制为“问题识别”——“问题分析与变更描述”——“变更分析与成本计算”——“变更实现”——“修改后的需求” 自动化工具能够帮助变更控制过程更有效地运作,能有效收集、存储、管理变更,工具应该具备的特征如下: 可定义变更请求中的数据可定义变更请求生命…

以八数码问题为例实现A*算法的求解(未完结)

八数码&#xff1a; 在一个 33 的网格中&#xff0c;1∼8 这 8 个数字和一个 x 恰好不重不漏地分布在这 33 的网格中。 例如&#xff1a; 1 2 3 x 4 6 7 5 8在游戏过程中&#xff0c;可以把 x 与其上、下、左、右四个方向之一的数字交换&#xff08;如果存在&#xff09;。…

SQL server数据库端口访问法

最近数据库连接&#xff0c;也是无意中发现了这个问题&#xff0c;数据库可根据端口来连接 网址:yii666.com< 我用的是sql2014测试的&#xff0c;在安装其他程序是默认安装了sql(sql的tcp/ip端口为xxx)&#xff0c;服务也不相同&#xff0c;但是由于比较不全&#xff0c;我…

yum工具(介绍+常用指令)

目录 yum--软件包管理器 概念 引入 rpm安装 yum安装 指令 yum list yum install 包名 yum remove 包名 yum search 包名/关键字 yum update/upgrade yum makecache fast du命令 yum--软件包管理器 概念 引入 在linux中下载软件,可以下载源代码进行编译执行但是…

使用Ansible中的playbook

目录 1.Playbook的功能 2.YAML 3.YAML列表 4.YAML的字典 5.playbook执行命令 6.playbook的核心组件 7.vim 设定技巧 示例 1.Playbook的功能 playbook 是由一个或多个play组成的列表 Playboot 文件使用YAML来写的 2.YAML #简介# 是一种表达资料序列的格式,类似XML #特…

GB28181学习(十四)——语音广播与语音对讲

语音对讲 定义 用户端向设备通过视音频点播请求音频数据&#xff1b;用户端接收音频数据并通过特定的播放设备&#xff08;如音响&#xff09;播放&#xff1b;用户端向设备发送广播请求&#xff1b;设备解析广播成功后通过INVITE方法向用户请求音频数据&#xff1b;用户通过音…

大长案例 - 经典长连接可水平扩容高可用架构

文章目录 需求设计 需求 支撑百万充电桩充电业务的长连接可水平扩容高可用架构需求如下&#xff1a; 可扩展性&#xff1a;系统应该具备高度可扩展性&#xff0c;能够轻松应对新增充电桩的需求。任何时候都应该容易添加更多的充电桩&#xff0c;而不会影响整体性能。 负载均衡…

Linux C语言进阶-D7~D8指针与数组

一维数组 一维数组的数组名&#xff1a;就是一维数组的指针&#xff08;起始地址&#xff09; 如果int *px x;则&#xff1a; x[i]、*(pxi)、*(xi)、px[i]具有完全相同的功能&#xff1a;访问数组第i1个数组元素 注意&#xff1a;1、指针变量和数组在访问数组元素时&#x…

筛网孔径测量方法,您了解多少?

筛网是一种表面有均匀而稳定的透气孔、具有筛选和过滤作用的工业用品&#xff0c;常见的有金属丝编织网和冲孔板筛网&#xff0c;广泛用于新能源汽车、太阳能光伏、冶金、煤炭、橡胶、石油、化工、制药、建材、粮油等行业。 筛网有着严格的网孔尺寸规范&#xff0c;需要符合标…

141. 环形链表、Leetcode的Python实现

博客主页&#xff1a;&#x1f3c6;看看是李XX还是李歘歘 &#x1f3c6; &#x1f33a;每天分享一些包括但不限于计算机基础、算法等相关的知识点&#x1f33a; &#x1f497;点关注不迷路&#xff0c;总有一些&#x1f4d6;知识点&#x1f4d6;是你想要的&#x1f497; ⛽️今…

安装opensips

1. 安装opensips ubuntu下安装&#xff1a; 1&#xff09;执行以下的脚本 openSIPS | APT Repository 2&#xff09;apt-get install opensips 安装完毕后&#xff0c;再选择需要的module继续安装&#xff0c;不需要编译 如果只是用作load balancer&#xff0c;那么只需要…

剑指JUC原理-8.Java内存模型

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱吃芝士的土豆倪&#xff0c;24届校招生Java选手&#xff0c;很高兴认识大家&#x1f4d5;系列专栏&#xff1a;Spring源码、JUC源码&#x1f525;如果感觉博主的文章还不错的话&#xff0c;请&#x1f44d;三连支持&…

Windows安装tensorflow-gpu=1.14.0CUDA=10.0cuDNN=7.4 (多版本CUDA共存)

文章目录 0. 前置说明1. 查看版本对应关系2. 安装 cuda3. 安装 cudnn4. 添加环境变量5. 安装 tensorflow 0. 前置说明 本机&#xff08;Windows 11&#xff09;已安装CUDA 11.7 使用命令查看显卡驱动&#xff1a; nvidia-smi这里显示的CUDA Version: 11.7说明支持安装11.7版本…

小说网站源码带管理后台手机端和采集

搭建教程&#xff0c;安装宝塔 php7.2&#xff0c;绑定域名&#xff0c;上传源码到根目录解压 源码获取请自行百度&#xff1a;一生相随博客 一生相随博客致力于分享全网优质资源&#xff0c;包括网站源码、游戏源码、主题模板、插件、电脑软件、手机软件、技术教程等等&#…

2.Docker的安装

1.认识Docker的基本架构 下面这张图是docker官网上的&#xff0c;介绍了整个Docker的基础架构&#xff0c;我们根据这张图来学习一下docker的涉及到的一些相关概念。 1.1 Docker的架构组成 Docker架构是由Client(客户端)、Docker Host(服务端)、Registry(远程仓库)组成。 …