C语言复习笔记--自定义类型

        今天我们来复习一下自定义类型.自定义类型大概分为结构体,枚举,联合体,数组这几种.数组在之前就介绍过.今天我们来看下其他三种.

结构体

        首先来看结构体.

  结构体类型的声明

        之前在操作符的地方简单认识过结构体.下面我们回顾一下.

        结构体回顾

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

         结构的特殊声明--匿名结构体

        上⾯的两个结构在声明的时候省略掉了结构体标签(tag).

#include <stdio.h>struct
{int a;int b;
}x;
struct
{int a;int b;
}*p;
int main()
{x.a = 10;printf("%d", x.a);//x=*p;//err//不可以这样进行赋值,虽然两个结构体内部的结构相同,//但是匿名结构体只能用一次,所以编译器会把这两个看成不同类型//struct s;//err//并且无法用匿名结构体在之后创建变量return 0;
}

        如果想使用多次可以进行typedef重命名.具体见下.

typedef struct
{int a;int b;
}ST;
int main()
{ST st;st.a = 10;printf("%d", st.a);return 0;
}

        结构的自引用

        其实是不可以的,如果这样可以的 话,那么这个结构体的sizeof应该是多少呢?如果可以就没法解答这个问题了,因为会出现套娃现象,结构体大小会变为无穷大.那么链表的节点是如何实现的呢?其实我们可以用结构体指针来代替直接在结构体中创建一个一样的结构体.如下

        如果要用typedef使结构体的名字更加简单方便调用的话,在结构体内自引用使用指针时不要用typedef过的简单名字.

  结构体内存对齐

        我们已经了解了结构体的使用下面我们来了解一下结构体的大小.也就是结构体内存对齐.

        虽然是浪费空间去换取时间,但是空间也不能大肆浪费,所以如何既满⾜对⻬,⼜节省空间是需要学习的.

S1 和 S2 类型的成员⼀模⼀样,但是 S1 所占空间要大于 S2.

修改默认对齐数

        对于上述问题也可以通过修改默认对齐数来解决(一般修改的都是2的n次方的数).

#pragma pack(1)
struct S
{char a;int b;char c;
};
int main()
{struct S s;printf("%zd", sizeof(s));return 0;
}
//如果想还原
#pragma pack()
struct S
{char a;int b;char c;
};
int main()
{struct S s;printf("%zd", sizeof(s));return 0;
}

  结构体传参

typedef struct S
{char a;int b;char c;
}S;void test1(S s1)
{printf("%c %d %c\n", s1.a, s1.b, s1.c);
}
void test2(S* s2)
{printf("%c %d %c\n", s2->a, s2->b, s2->c);
}
int main()
{S s = {'y',10,'x'};test1(s);test2(&s);return 0;
}

        上面两个函数中test2要更好一点.

   结构体实现位段

        什么是位段

        位段的声明和结构是类似的,有两个不同

        1. 位段的成员必须是 int 、 unsigned int 或 signed int ,在C99中位段成员的类型也可以选择其他类型(char,一定要是整形大家庭中的).

        2. 位段的成员名后边有⼀个冒号和⼀个数字.(这个数字代表这个成员所占的比特位).

        如下,一个简单的例子

struct S
{
    int a : 2;
    int b : 3;
    char c : 5;
};

        既然知道了位段的大体结构,下面我们来看下大小 

struct S1
{char a : 2;char b : 3;char c : 5;
};
struct S2
{int a : 2;int b : 3;char c : 5;
};
int main()
{printf("%zd\n", sizeof(struct S1));printf("%zd\n", sizeof(struct S2));return 0;
}

        输出结果见下:

 

        位段的内存分配

        1. 位段的成员可以是 int unsigned int( signed int 或者是 char 等类型 int )

        2. 位段的空间上是按照需要以4个字节或者1个字节( char )的⽅式来开辟的。并且在计算大小时也要遵循内存对齐.(如上求大小例子中的S2所示).

        3. 位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使⽤位段。

        位段的跨平台问题

        位段的应用

        位段使用的注意事项 

        位段的⼏个成员共有同⼀个字节,这样有些成员的起始位置并不是某个字节的起始位置,那么这些位 置处是没有地址的。内存中每个字节分配⼀个地址,⼀个字节内部的bit位是没有地的。 所以不能对位段的成员使⽤&操作符,这样就不能使⽤scanf直接给位段的成员输⼊值,只能是先输⼊放在⼀个变量中,然后赋值给位段的成员.

//struct S1
//{
//	char a : 2;
//	char b : 6;
//	char c : 5;
//};
//int main()
//{
//	struct S1 s;
//	char ch;
//	scanf("%c", &ch);
//	s.b = ch;
//	printf("%c", s.b);//在存进位段中时会发生截断,不要用char类型实验,这里打出来是截断之后的
//	return 0;
//}
// 
//换为int实验
struct S1
{int a : 2;int b : 18;int c : 5;
};
int main()
{struct S1 s;int ch = 0;scanf("%d%d",&s, &ch);s.b = ch;printf("%d %d\n", s.a, s.b);return 0;
}

联合体

  联合体类型的声明

        联合体也是由⼀个或者多个成员构成,这些成员可以不同的类型.但是编译器只为最⼤的成员分配⾜够的内存空间.联合体的特点是所有成员共⽤同⼀块内存空间。所以联合体也叫:共用体.给联合体其中⼀个成员赋值,其他成员的值也跟着变化.

        看一个简答的例子

union U
{char a;int b;
};
int main()
{union U u;u.b =0x11223348;printf("%c\n", u.a);//48对应的ASCII码表是Hreturn 0;
}

        输出结果见下 

  联合体的特点

        联合的成员是共⽤同⼀块内存空间的,这样⼀个联合变量的⼤⼩,⾄少是最⼤成员的⼤⼩(因为联合 ⾄少得有能⼒保存最⼤的那个成员).

        更加深入的理解一下

 

        所以联合体中所有元素的起始位置是相同的.

  联合体大小的计算 

        联合的⼤⼩⾄少是最⼤成员的⼤⼩

        当最大成员大小不是最大对⻬数的整数倍的时候,就要对⻬到最大对齐数的整数倍.

        在计算之前看好是联合体还是结构体,千万不要搞混了.

union Un1
{char c[5];//数组的对齐数按照数组的类型的对齐数算int i;
};
//因为有int所以最大对齐数为4
union Un2
{short c[7];int i;
};
int main()
{//下⾯输出的结果是什么?printf("%d\n", sizeof(union Un1));printf("%d\n", sizeof(union Un2));return 0;
}

        输出结果见下 

        使⽤联合体是可以节省空间的.

        既然了解了联合体那么我们来看下一个小练习吧.

写⼀个程序,判断当前机器是⼤端?还是⼩端(用到联合体的知识)

union U
{int a;char b;
};
int main()
{union U u;u.a = 1;if (1 == (int)(u.b)){printf("小端\n");}else{printf("大端\n");}return 0;
}

枚举类型

  枚举类型的声明

        举个例子:

enum Colour
{
    RED,
    GREEN,
    BLUE,
};

        验证一下

enum Colour
{RED,GREEN,BLUE,
};
int main()
{printf("%d %d %d", RED, GREEN, BLUE);return 0;
}

enum Colour
{RED=2,GREEN,BLUE=5,
};
int main()
{printf("%d %d %d", RED, GREEN, BLUE);return 0;
}

        如果一个给初始值后下面的没有给则下面的值为上面值+1.

  枚举类型的优点

        简单的注意一下第五点. 

  枚举类型的使用

        这里主要注意的是枚举常量的赋值.

enum Colour
{RED=2,GREEN,BLUE=5,
};
int main()
{printf("%d %d %d", RED, GREEN, BLUE);// enum Colour c = 0;//在VS中不报错,但是最好不要这样做,枚举类型就要用枚举类型赋值enum Colour c = RED;//要用枚举常量赋值return 0;
}

        那是否可以拿整数给枚举变量赋值呢?在C语⾔中是可以的,但是在C++是不⾏的,C++的类型检查⽐ 较严格

        以上就是自定义类型的复习了,我们下次复习见.

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

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

相关文章

python jupyter notebook

什么是Jupyter Notebook Jupyter Notebook是一个开源的Web应用程序&#xff0c;允许用户创建和共享包含实时代码、方程、可视化和解释性文本的文档。它最初由IPython团队开发&#xff0c;现在已经成为一个独立的项目&#xff0c;并广泛用于数据清理和转换、数值模拟、统计建模…

Linux——https基础理论

1. 初步认识https协议 • 属于应用层 • 相较于http协议&#xff0c;https在应用层多了一层加密层&#xff0c;为了保证数据安全 • 简单理解&#xff1a;https就是对http的加密和解密 2. 中间人攻击 • 数据在传输过程中&#xff0c;遭第三方篡改。 3. 加密方式 • 对称加密&a…

在 C++ 中对类型进行排序

0.前言 在 C 中&#xff0c;我编写了一个 tuple-like 模板&#xff0c;这个模板能容纳任意多且可重复的类型&#xff1a; template<typename... Ts> struct TypeList {};// usage: using List1 TypeList<int, double, char, double>; using List2 TypeList<…

Unity-Socket通信实例详解

今天我们来讲解socket通信。 首先我们需要知道什么是socket通信&#xff1a; Socket本质上就是一个个进程之间网络通信的基础&#xff0c;每一个Socket由IP端口组成&#xff0c;熟悉计网的同学应该知道IP主要是应用于IP协议而端口主要应用于TCP协议&#xff0c;这也证明了Sock…

使用Go语言对接全球股票数据源API实践指南

使用Go语言对接全球股票数据API实践指南 概述 本文介绍如何通过Go语言对接支持多国股票数据的API服务。我们将基于提供的API文档&#xff0c;实现包括市场行情、K线数据、实时推送等核心功能的对接。 一、准备工作 1. 获取API Key 联系服务提供商获取访问密钥&#xff08;替…

LeetCode 热题 100 17. 电话号码的字母组合

LeetCode 热题 100 | 17. 电话号码的字母组合 大家好&#xff0c;今天我们来解决一道经典的算法题——电话号码的字母组合。这道题在 LeetCode 上被标记为中等难度&#xff0c;要求给定一个仅包含数字 2-9 的字符串&#xff0c;返回所有它能表示的字母组合。下面我将详细讲解解…

OpenCV计算机视觉实战(3)——计算机图像处理基础

OpenCV计算机视觉实战&#xff08;3&#xff09;——计算机图像处理基础 0. 前言1. 像素和图像表示1.1 像素 2. 色彩空间2.1 原色2.2 色彩空间2.3 像素和色彩空间 3. 文件类型3.1 图像文件类型3.2 视频文件3.3 图像与视频 4. 计算机图像编程简史5. OpenCV 概述小结系列链接 0. …

Vite 的工作流程

Vite 的工作流程基于其创新的 “预构建 按需加载” 机制&#xff0c;通过利用现代浏览器对原生 ES 模块的支持&#xff0c;显著提升了开发效率和构建速度。以下是其核心工作流程的详细分析&#xff1a; 一、开发环境工作流程 1. 启动开发服务器 冷启动&#xff1a;通过 npm …

线性DP(动态规划)

线性DP的概念&#xff08;视频&#xff09; 学习线性DP之前&#xff0c;请确保已经对递推有所了解。 一、概念 1、动态规划 不要去看网上的各种概念&#xff0c;什么无后效性&#xff0c;什么空间换时间&#xff0c;会越看越晕。从做题的角度去理解就好了&#xff0c;动态规划…

MySQL中sql_mode的设置

■ 57版本原来配置 show variables like %sql_mode%; STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION ■ 修改配置文件 注释掉sql_mode&#xff0c;并重启&#xff0c;查看57版本的默认设置 ONL…

MCAL学习(1)——AutoSAR

1.了解AutoSAR及一些概念 AutoSAR是Automotive Open System Architecture ,汽车开放系统架构。 针对汽车ECU的软件开发架构。已经是汽车电子软件开发的标准。 OS服务&#xff1a;Freertos 整车厂&#xff08;OEM&#xff09;主要负责应用层算法 一级供应商&#xff1a;生产制…

Vue报错:Cannot read properties of null (reading ‘xxx‘)

一、报错问题 Cannot read properties of null (reading style)at patchStyle (runtime-dom.esm-bundler.js:104:22)二、错误排查 这类报错一般是在已经开发好后&#xff0c;后面测试时突然发现的&#xff0c;所以不好排查错误原因。 三、可能原因及解决方案 v-if 导致 在 …

25G 80km双纤BIDI光模块:远距传输的创新标杆

目录 一、产品优势&#xff1a;双纤与BIDI的独特价值 易天光通信25G SFP28 ZR 80KM 易天光通信25G SFP28 BIDI ZR 80KM 二、权威认证与技术突破 三、双纤与BIDI的核心差异解析 四、应用场景&#xff1a;驱动多领域高效互联 总结 在5G、云计算与数字化转型的推动下&#xff0c;光…

2025-05-06 学习记录--Python-注释 + 打印变量 + input输入

合抱之木&#xff0c;生于毫末&#xff1b;九层之台&#xff0c;起于累土&#xff1b;千里之行&#xff0c;始于足下。&#x1f4aa;&#x1f3fb; 一、注释 ⭐️ &#xff08;一&#xff09;、块注释 &#x1f36d; 举例&#xff1a; &#x1f330; # 打印数字 print(2025) …

基于mediapipe深度学习的眨眼检测和计数系统python源码

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 (完整程序运行后无水印) 2.算法运行软件版本 人工智能算法python程序运行环境安装步骤整理_本地ai 运行 python-CSDN博客 3.部分核心程序 &…

怎样通过API 实现python调用Chatgpt,gemini

怎样通过API 实现python调用Chatgpt,gemini 以下为你详细介绍如何设置和调用这些参数,以创建一个类似的 ChatCompletion 请求: 1. 安装依赖库 如果你使用的是 OpenAI 的 API 客户端,需要先安装 openai 库。可以使用以下命令进行安装: pip install openai2. 代码示例 …

Linux 下MySql主从数据库的环境搭建

测试环境&#xff1a;两台服务器&#xff0c;Mysql版本 8.0&#xff0c;linux版本&#xff1a;Ubuntu 20.04.3&#xff1b; 1.在两台服务器上安装MySql&#xff1b; 2.选一台作为主服务器&#xff0c;在主服务器上以root用户进入Mysql&#xff0c;执行以下语句&#xff1a; …

力扣1812题解

记录 2025.5.7 题目&#xff1a; 思路&#xff1a; 从左下角开始&#xff0c;棋盘的行数和列数&#xff08;均从 1 开始计数&#xff09;之和如果为奇数&#xff0c;则为白色格子&#xff0c;如果和为偶数&#xff0c;则为黑色格子。 代码&#xff1a; class Solution {pu…

适合java程序员的Kafka消息中间件实战

创作的初心&#xff1a; 我们在学习kafka时&#xff0c;都是基于大数据的开发而进行的讲解&#xff0c;这篇文章为java程序员为核心&#xff0c;助力大家掌握kafka实现。 什么是kafka: 历史&#xff1a; 诞生与开源&#xff08;2010 - 2011 年&#xff09; 2010 年&#xf…

PDF智能解析与知识挖掘:基于pdfminer.six的全栈实现

前言 在数字化信息爆炸的时代&#xff0c;PDF&#xff08;便携式文档格式&#xff09;作为一种通用的电子文档标准&#xff0c;承载着海量的结构化与非结构化知识。然而&#xff0c;PDF格式的设计初衷是用于展示而非数据提取&#xff0c;这使得从PDF中挖掘有价值的信息成为数据…