C语言_自定义类型详解

文章目录

  • 前言
  • 一.结构体的声明
    • 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;  //errreturn 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.hqwc.cn/news/157019.html

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

相关文章

探求flutter全栈开发

显示一种网络图片 import package:flutter/material.dart; main(){runApp(MaterialApp(theme: ThemeData.dark(),home:Home(),));}class Home extends StatelessWidget{overrideWidget build(BuildContext context) {// TODO: implement buildreturn Scaffold(appBar:AppBar(t…

图像二值化阈值调整——OTSU算法(大津法/最大类间方差法)

大津算法&#xff08;OTSU算法&#xff09;是一种常用的图像二值化方法&#xff0c;用于将灰度图像转化为二值图像。该算法由日本学者大津展之于1979年提出&#xff0c;因此得名。 大津算法的核心思想是通过寻找一个阈值&#xff0c;将图像的像素分为两个类别&#xff1a;前景…

LangChain介绍及代码实践

一、简介 LangChian 作为一个大语言模型开发框架&#xff0c;是 LLM 应用架构的重要一环。那什么是 LLM 应用架构呢&#xff1f;其实就是指基于语言模型的应用程序设计和开发的架构。 LangChian 可以将 LLM 模型、向量数据库、交互层 Prompt、外部知识、外部工具整合到一起&a…

与云栖的浪漫邂逅:记一段寻找云端之美的旅程

云端之旅 2023 年的云栖大会如约而至&#xff0c;这次云栖大会也是阿里新任掌门蔡老板当任阿里巴巴董事局主席以来的第一次。大会与以往有很多不一样的地方&#xff0c;其中 AIGC 更是本届大会的重点议题&#xff01;你会感叹&#xff0c;阿里还是猛啊&#xff01; 我逛了下展…

高校教务系统登录页面JS分析——天津大学

高校教务系统密码加密逻辑及JS逆向 本文将介绍天津大学教务系统的密码加密逻辑以及使用JavaScript进行逆向分析的过程。通过本文&#xff0c;你将了解到密码加密的基本概念、常用加密算法以及如何通过逆向分析来破解密码。 本文仅供交流学习&#xff0c;勿用于非法用途。 一、密…

优先队列----数据结构

概念 不知道你玩过英雄联盟吗&#xff1f;英雄联盟里面的防御塔会攻击离自己最近的小兵&#xff0c;但是如果有炮车兵在塔内&#xff0c;防御塔会优先攻击炮车&#xff08;因为炮车的威胁性更大&#xff09;&#xff0c;只有没有兵线在塔内时&#xff0c;防御塔才会攻击英雄。…

Azure机器学习 - 在 Azure 机器学习中上传、访问和浏览数据

目录 一、环境准备二、设置内核三、下载使用的数据四、创建工作区的句柄五、将数据上传到云存储空间六、访问笔记本中的数据七、创建新版本的数据资产八、清理资源 机器学习项目的开始阶段通常涉及到探索性数据分析 (EDA)、数据预处理&#xff08;清理、特征工程&#xff09;以…

Android 10.0 framework关于systemUI定制之导航栏透明背景的功能实现

1.概述 在10.0的系统产品定制化开发中,在对于系统原生SystemUI的导航栏背景在沉浸式导航栏的 情况下默认是会随着背景颜色的变化而改变的,在一些特定背景下导航栏的背景也是会改变的,所以由于产品开发需要 要求需要设置导航栏背景为透明的,所以就需要在Activity创建的时候…

【贝叶斯回归】【第 1 部分】--pyro库应用

Bayesian Regression - Introduction (Part 1) — Pyro Tutorials 1.8.6 documentation 一、说明 我们很熟悉线性回归的问题&#xff0c;然而&#xff0c;一些问题看似不似线性问题&#xff0c;但是&#xff0c;用贝叶斯回归却可以解决。本文使用土地平整度和国家GDP的关系数据…

10.30寄存器,寄存器堆

寄存器 8位环形移位寄存器 module shift_regist (input wire clk,input wire rstn,input wire [7:0]D,output reg [7:0]Q ); always (posedge clk or negedge rstn) beginif(!rstn)Q<8b000000;elseQ<{D[6:0],D[7]} ; end endmodule //shift_regist 输入有时钟…

gRPC源码剖析-Builder模式

一、Builder模式 1、定义 将一个复杂对象的构建与表示分离&#xff0c;使得同样的构建过程可以创建不同的的表示。 2、适用场景 当创建复杂对象的算法应独立于该对象的组成部分以及它们的装配方式时。 当构造过程必须允许被构造的对象有不同的表示时。 说人话&#xff1a…

Ubuntu 使用 nginx 搭建 https 文件服务器

Ubuntu 使用 nginx 搭建 https 文件服务器 搭建步骤安装 nginx生成证书修改 config重启 nginx 搭建步骤 安装 nginx生成证书修改 config重启 nginx 安装 nginx apt 安装&#xff1a; sudo apt-get install nginx生成证书 使用 openssl 生成证书&#xff1a; 到对应的路径…