当前位置: 首页 > news >正文

并非从0开始的c++ day8

并非从0开始的c++ day8

  • 结构体
    • 结构体嵌套二级指针练习
    • 结构体偏移量
  • 内存对齐
    • 内存对齐的原因
    • 如何内存对齐
  • 文件操作
    • 文件的概念
    • 流的概念
      • 文本流
      • 二进制流
      • 文件缓冲区
      • 文件打开关闭
        • 文件关闭fclose
      • 文件读写函数回顾
      • 按格式化读写文件
      • 文件读写注意事项

结构体

结构体嵌套二级指针练习

需求:一个老师数组,老师设计一个结构体,需要有老师的名字和一个学生数组,学生数组可以有若干个学生

//结构体设计
struct Teacher
{//老师姓名char* name;//老师带的学生姓名数组char** students;
};void allocateSpace(struct Teacher *** teacherArray)
{if (teacherArray == NULL){return;}//堆区分配内存struct Teacher** ts = malloc(sizeof(struct Teacher*) * 3);//数据赋值//给老师分配内存for (int i = 0; i < 3; i++){//给老师分配内存ts[i] = malloc(sizeof(struct Teacher));//给老师姓名属性 分配内存ts[i]->name = malloc(sizeof(char) * 64);//给老师姓名赋值sprintf(ts[i]->name, "Teacher_%d", i+1);//给老师带领学生数组分配内存ts[i]->students = malloc(sizeof(char*) * 4);//给学生姓名分配内存 并且赋值for (int j = 0; j < 4; j++){ts[i]->students[j] = malloc(sizeof(char) * 64);sprintf(ts[i]->students[j], "%s_student_%d", ts[i]->name, j+1);}}//建立关系*teacherArray = ts;
}//打印操作
void printTeacherArray(struct Teacher ** teacherArray)
{for (int i = 0; i < 3; i++){//老师姓名printf("%s\n", teacherArray[i]->name);for(int j = 0;j<4;j++)//老师带领的学生printf("	%s\n", teacherArray[i]->students[j]);}
}//释放堆区数据
void freeSpace(struct Teacher** teacherArray)
{if (teacherArray == NULL){return;}for (int i = 0; i < 3; i++){//释放老师姓名if (teacherArray[i]->name != NULL){free(teacherArray[i]->name);teacherArray[i]->name = NULL;}//释放学生姓名for (int j = 0; j < 4; j++){if (teacherArray[i]->students[j] != NULL){free(teacherArray[i]->students[j]);teacherArray[i]->students[j] = NULL;}}//释放学生数组free(teacherArray[i]->students);teacherArray[i]->students = NULL;//释放老师free(teacherArray[i]);teacherArray[i] = NULL;}//释放老师数组free(teacherArray);teacherArray = NULL;
}void test01()
{//老师数组创建struct Teacher** teacherArray = NULL;//分配内存allocateSpace(&teacherArray);//打印所有老师和学生信息printTeacherArray(teacherArray);//释放堆区数据freeSpace(teacherArray);teacherArray = NULL;
}

牢记几个malloc对应几个free

结构体偏移量

printf(“b的偏移量:%d\n”, (int)&(p->b) - (int)p);
printf(“b的偏移量: %d\n”, offsetof(struct teacher, b));

struct  teacher
{char a;  //0 ~ 3int b;	 //4 ~ 7};void test01() 
{struct teacher t1;struct teacher* p = &t1;printf("b的偏移量:%d\n", (int)&(p->b) - (int)p);printf("b的偏移量: %d\n", offsetof(struct teacher, b));
}

通过偏移量获取数

void test02()
{struct teacher t1 = {'a',1000};struct teacher* p = &t1;printf("b的值为: %d\n", *(int*)((char*)p + offsetof(struct teacher, b)));printf("b的值为: %d\n", ((struct teacher *)((int*)p + 1))-> b);
}//结构体2
struct teacher2
{char a;int b;struct teacher c;
};void test03()
{struct teacher2  t = { 'a',10,'b',20 };int offset1 = offsetof(struct teacher2, c);int offset2 = offsetof(struct teacher, b);printf("属性c中的值为: %d\n", *(int *)((char*)&t + offset1 + offset2));printf("属性c中的值为: %d\n", *(int*)((char*)&t + offset1 + offset2));}

内存对齐

访问特定类型的变量只能在特定的地址访问,这就需要各个变量在空间上按一定的规则排列,而不是简单地顺序排列,这就是内存对齐

内存对齐的原因

我们知道内存的最小单元是一个字节,当CPU从内存中读取数据的时候,是一个一个字节读取

实际上cpu将内存当成多个块,每次从内存中读取一个块,这个块的大小可能是2、4、8、16等

内存对齐是操作系统为了提高访问内存的策略。操作系统在访问内存的时候,每次读取一定长度(这个长度是操作系统默认的对齐数,或者默认对齐数的整数倍)。如果没有对齐,为了访问一个变量可能产生二次访问

内存对齐优点:以空间换时间

如何内存对齐

  • 对于标准数据类型,它的地址只要是他的长度的整数倍
  • 对于非标准数据类型,比如结构体,要遵循一下对齐原则

内存对齐原则
第一个属性开始 从0开始计算偏移量
第二个属性 要放在该属性的大小 与 对齐模数比 取小的值的 整数倍上
当所有属性都计算完毕之后,整体做二次偏移,将上面计算的结构体
将上面计算的结果 扩充到 这个结构体中最大数据类型的整数倍 与对齐模数比 取小的值 的整数倍
对齐模数默认为8

#pragma pack (show)//查看对齐模数的值 默认为8
#pragma pack (1)typedef struct _STUDENT {int a;	// 0 ~ 3	//0~3char b; //4 ~ 7		//4double c;//8 ~ 15	//5~12float d;// 16 ~ 23	//13~16
}Student;void test01()
{printf("student sizeof = %d\n", sizeof(Student));
}

当嵌套结构体时,以子结构体最大数据类型的整数倍来取地址即可

typedef struct _STUDENT2 {char a;		//0 ~ 7Student b;	//8 ~ 31double c;	//32 ~ 39
}Student2;void test02()
{printf("student sizeof = %d\n", sizeof(Student2));
}

文件操作

文件的概念

通过fopen打开文件,中间还有一步open系统函数,open系统函数获取文件后,返回文件的指针FILE*给fopen

在这里插入图片描述

流的概念

C语言中,I/O操作可以简单地看做从程序移进或移出字节,这种搬运的过程称为流。I/O都是相对于程序来说,所以o输出为将字节输出到文件里,I输入为从文件读取

文本流

二进制流

我们程序中,经常看到的文本方式打开文件和二进制打开文件仅仅体现在换行符的处理上

输入/输出函数家族

家族名 目的 可用于所有流 只用于stdin和stdout
getchar 字符输入 fgetc、getc getchar
putchar 字符输出 fputc、putc putchar
gets 文本行输入 fgets gets
puts 文本行输出 fputs puts
scanf 格式化输入 fscanf scanf
printf 格式化输出 fprintf pirntf

文件缓冲区

有了缓冲区:提高硬盘寿命、提高运行效率
在这里插入图片描述
写文件时需要写fclose,因为可能有些数据留在写文件缓冲区,要是直接结束,可能会留这部分数据在里面没写进去,需要我们手动将其输出到文件

文件打开关闭

“r” 读
“w”写
“a”追加
“rb”二进制只读
“wb”二进制只写
“ab”二进制追加
“r+”允许读和写,文件必须已存在
“w+”允许读和写,如果文件不存在则创建,已存在则把文件长度截断为0字节再重新写
“a+”允许读和追加数据,如果文件不存在则创建
“rb+”以读或写方式打开一个二进制文件
“wb+”以读或写方式建立一个新的二进制文件
“ab+”以读或写方式打开一个二进制文件进行追加

文件关闭fclose

对打开文件进行写入时,若文件缓冲区的空间未被写入的内容填满,这些内容弄不会写到打开的文件中。只有对打开的文件进行关闭操作时,停留在文件缓冲区的内容才能写到改文件中,从而使文件完整。再者一旦关闭了文件,该文件对应的FILE结构将被释放,从而使关闭的文件受到保护,因为这时对该文件的存取操作将不会进行。文件的关闭也意味着释放了该文件的缓冲区

文件读写函数回顾

  • 按照字符读写文件:fgetc(),fputc()
  • 按照行读写文件:fputs(),fgets()
  • 按照块读写文件:fread(),fwrite()
  • 按照格式化读写文件:fprintf(),fscanf()
  • 按照随机位置读写文件:fseek(),ftell(),rewind()

while ((ch = fgetc(f_read)) != EOF)
判断是否是文件尾

//按字符方式读写
void test01()
{//写文件FILE * f_write = fopen("./test1.txt", "w+");if (f_write == NULL){return;}char buf[] = "hello world";for (int i = 0; i < strlen(buf); i++){fputc(buf[i], f_write);}fclose(f_write);//读文件FILE* f_read = fopen("./test1.txt", "r");if (f_read == NULL){return;}char ch;while ((ch = fgetc(f_read)) != EOF){printf("%c", ch);}printf("\n");fclose(f_read);
}

按格式化读写文件

//移动文件光标
void test05()
{//打开文件FILE* f_write = fopen("./test5.txt", "wb");if (f_write == NULL){return;}struct Hero heros[4] ={{"geats",19},{"revice",20},{"saber",21},{"zero one",22}};for (int i = 0; i < 4; i++)//参数1 写入数据的地址  参数2 块大小  参数3 快个数  参数4 文件指针fwrite(&heros[i], sizeof(struct Hero), 1, f_write);//关闭文件fclose(f_write);//读文件FILE* f_read = fopen("./test5.txt", "rb");struct Hero temp;if (f_read == NULL){perror("文件打开失败");//errno宏 全局变量return;}//移动文件光标//fseek(f_read, sizeof(struct Hero) , SEEK_SET);fseek(f_read, -(long)sizeof(struct Hero) * 2, SEEK_END);//将文件光标置首rewind(f_read);fread(&temp, sizeof(struct Hero), 1, f_read);printf("姓名: %s 年龄:%d\n", temp.name, temp.age);fclose(f_read);
}

//参数1 写入数据的地址 参数2 块大小 参数3 快个数 参数4 文件指针
fwrite(&heros[i], sizeof(struct Hero), 1, f_write);

//移动文件光标
//fseek(f_read, sizeof(struct Hero) , SEEK_SET);
fseek(f_read, -(long)sizeof(struct Hero) * 2, SEEK_END);
前者从前往后移,后者从后往前移,后者需要强制类型转换

//将文件光标置首
rewind(f_read);

  perror("文件打开失败");//errno宏 全局变量
对于每一个错误都会有一个相应的代码

文件读写注意事项

void test01()
{//按照字符读test文件FILE* file = fopen("test.txt", "r");if (file == NULL)return;#if 0char  ch;while (!feof(file)){ch = fgetc(file);if (feof(file)){break;}printf("%c", ch);}
#endifchar ch;while ((ch = fgetc(file)) != EOF){printf("%c", ch);}fclose(file);
}
  • EOF为结尾,在if内部的代码用feof有滞后性,在文件读取结束后,还会进一次循环后再退出,if下面的代码就可以解决

  • 如果结构体中属性,创建在堆区,保存数据到文件中的时候,要将指针放入到文件中

相关文章:

并非从0开始的c++ day8

并非从0开始的c day8结构体结构体嵌套二级指针练习结构体偏移量内存对齐内存对齐的原因如何内存对齐文件操作文件的概念流的概念文本流二进制流文件缓冲区文件打开关闭文件关闭fclose文件读写函数回顾按格式化读写文件文件读写注意事项结构体 结构体嵌套二级指针练习 需求&am…...

ubuntu下用i686-w64-mingw32交叉编译支持SDL、Openssl的ffmpeg库

前言 本篇博客是基于前两篇关于ffmpeg交叉编译下&#xff0c;进行再次编译操作。ubuntu下ffmpeg的交叉编译环境搭建可以参看以下我的这篇博客&#xff1a;https://blog.csdn.net/linyibin_123/article/details/108759367 &#xff1b; ubuntu下交叉编译openssl及交叉编译支持o…...

对IDEA中断点Suspend 属性理解

suspend的类型分为 1、ALL&#xff1a;有线程进入该断点时&#xff0c;暂停所有线程 2、Thread&#xff1a;有线程进入该断点时&#xff0c;只暂停该线程 讨论下不同线程在同一时间段都遇到断点时&#xff0c;idea的处理方法。假如在执行时间上&#xff0c;thread1会先进入断…...

IM即时通讯开发如何解决大量离线消息导致客户端卡顿的

大部分做后端开发的朋友&#xff0c;都在开发接口。客户端或浏览器h5通过HTTP请求到我们后端的Controller接口&#xff0c;后端查数据库等返回JSON给客户端。大家都知道&#xff0c;HTTP协议有短连接、无状态、三次握手四次挥手等特点。而像游戏、实时通信等业务反而很不适合用…...

【软件测试】测试老鸟的迷途,进军高级自动化测试测试......

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 很多从业几年的选手…...

HMM(隐马尔科夫模型)-理论补充2

目录 一.大数定理 二.监督学习方法 1.初始概率 2.转移概率 3.观测概率 三.Baum-Welch算法 1.EM算法整体框架 2. Baum-Welch算法 3.EM过程 4.极大化 5.初始状态概率 6.转移概率和观测概率 四.预测算法 1.预测的近似算法 2.Viterbi算法 1.定义 2. 递推&#xff1…...

【分布式系统】MinIO之Multi-Node Multi-Drive架构分析

文章目录架构分析节点资源硬盘资源服务安装安装步骤创建系统服务新建用户和用户组创建环境变量启动服务负载均衡代码集成注意最近打算使用MinIO替代原来使用的FastDFS&#xff0c;所以一直在学习MinIO的知识。这篇文章是基于MinIO多节点多驱动的部署进行研究。 架构分析 节点资…...

【无标题】(2019)NOC编程猫创新编程复赛小学组真题含参考

&#xff08;2019&#xff09;NOC编程猫创新编程复赛小学组最后6道大题。前10道是选择填空题 略。 这道题是绘图题&#xff0c;没什么难度&#xff0c;大家绘制这2个正十边形要注意&#xff1a;一是不要超出舞台&#xff1b;二是这2个正十边形不要相交。 这里就不给出具体程序了…...

【尚硅谷MySQL入门到高级-宋红康】数据库概述

1、为什么要使用数据库 数据的持久化 2、数据库与数据库管理系统 2.1 数据库的相关概念 2.2 数据库与数据库管理系统的关系 3、 MySQL介绍 MySQL从5.7版本直接跳跃发布了8.0版本 &#xff0c;可见这是一个令人兴奋的里程碑版本。MySQL 8版本在功能上做了显著的改进与增强&a…...

SpringBoot集成Redis并实现数据缓存

应用场景 存放Token、存放用户信息或字典等需要频繁访问数据库获取但不希望频繁访问增加数据库压力且变化不频繁的数据。 集成步骤 1. 新建 Maven 项目并引入 redis 依赖【部分框架有可能已经集成&#xff0c;会导致依赖文件有差异】 <dependency><groupId>org…...

SpringBoot配置文件(properties yml)

查看官网更多系统配置项&#xff1a;https://docs.spring.io/spring-boot/docs/current/reference/html/application-properties.html#application-properties 1.配置⽂件作⽤ 整个项⽬中所有重要的数据都是在配置⽂件中配置的&#xff0c;⽐如&#xff1a;数据库的连接信息&am…...

css 画图之质感盒子

前言 css 众所周知可以做很多的事情&#xff0c;比如&#xff1a;界面效果、特效、独特的样式等。今天给各位朋友带来的是以box-shadow来画一个很有质感效果的一个盒子。 之前在网上冲浪的时候&#xff0c;发现了这样的一个效果&#xff0c;所以来记录一下。 下面是实现后的…...

面了一个月,终于让我总结出了这份最详细的接口测试面试题

目录 1、你们公司是如何做接口测试的&#xff1f; 2、什么时候开展接⼝测试&#xff1f; 3、接⼝测试和UI测试的工作是否重复&#xff1f; 4、接口测试框架怎么搭建&#xff1f; 5、接⼝之间有依赖时怎么处理&#xff1f; 6、如何判断接⼝测试的结果&#xff08;成功或失败&a…...

{新}【java开发环境安装】完整工作环境安装配置

公司新发了一台红米笔记本&#xff0c;打算用新的笔记本&#xff0c;开启自己新的工作旅程&#xff0c;其中把做个的事都记录一边&#xff0c;以便实现&#xff0c;听、读、视频图像、讨论、实践、教人的一个学习过程。 一、Java开发环境安装 找到安装包下载&#xff1b;在官…...

Python|每日一练|数组|数学|图算法|字符串|动态规划|单选记录:加一|迷宫问题|扰乱字符串

1、加一&#xff08;数组&#xff0c;数学&#xff09; 给定一个由 整数 组成的 非空 数组所表示的非负整数&#xff0c;在该数的基础上加一。 最高位数字存放在数组的首位&#xff0c; 数组中每个元素只存储单个数字。 你可以假设除了整数 0 之外&#xff0c;这个整数不会以…...

MySQL 使用IF判断

mysql判断语句 1、IF 和IFNULL IF(表达式1&#xff0c;表达式2&#xff0c;表达式3); 含义&#xff1a;如果表达式1为true&#xff0c;则返回表达式2的值&#xff0c;否则返回表达式3的值&#xff0c;表达式的值类型可以为数字或字符串 例&#xff1a;判断对错 SELECT IF(TRUE…...

C++类与对象(上)【详析】

目录1.面向过程和面向对象初步认识2.类的引入3.类的定义4.类的访问限定符及封装4.1访问限定符4.2封装5.类的作用域6.类的实例化7.类对象模型7.1 如何计算类对象的大小8.this关键字如果说我们对C的初步认识&#xff0c;是觉得C是对C语言不足之处的进行修补&#xff0c;在认识完类…...

AIR系列|板载LED|gpio引脚选择|GPIO|流水灯|LuatOS-SOC接口|官方demo|学习(20-1):GPIO库基础

AIR系列各型号开发板板载LED对应管脚及GPIO控制代码 AIR103&#xff1a; rtos_bsp "AIR103" then -- Air103开发板LED引脚编号--return pin.PB26, pin.PB25, pin.PB24return 42,41,40 AIR105&#xff1a; rtos_bsp "AIR105" then -- Air105开发板LED引…...

MySQL数据库中的函数怎样使用?

函数 是指一段可以直接被另一段程序调用的程序或代码。 也就意味着&#xff0c;这一段程序或代码在MySQL中已经给我们提供了&#xff0c;我们要做的就是在合适的业务场景调用对应的函数完成对应的业务需求即可。 那么&#xff0c;函数到底在哪儿使用呢?我们先来看两个场景&…...

命名空间的使用大全

概述 在C中&#xff0c;我们会使用变量、常量、函数、类、对象、结构体等各种元素。随着工程越来越庞大&#xff0c;代表这些元素的标识符冲突的概率也越来越大。为了解决标识符命名冲突的问题&#xff0c;C标准在1995年引入了关键字namespace&#xff0c;也叫做命名空间。使用…...

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

页面渲染流程与性能优化

页面渲染流程与性能优化详解&#xff08;完整版&#xff09; 一、现代浏览器渲染流程&#xff08;详细说明&#xff09; 1. 构建DOM树 浏览器接收到HTML文档后&#xff0c;会逐步解析并构建DOM&#xff08;Document Object Model&#xff09;树。具体过程如下&#xff1a; (…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级

在互联网的快速发展中&#xff0c;高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司&#xff0c;近期做出了一个重大技术决策&#xff1a;弃用长期使用的 Nginx&#xff0c;转而采用其内部开发…...

【JavaSE】绘图与事件入门学习笔记

-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角&#xff0c;以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向&#xff0c;距离坐标原点x个像素;第二个是y坐标&#xff0c;表示当前位置为垂直方向&#xff0c;距离坐标原点y个像素。 坐标体系-像素 …...

第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词

Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵&#xff0c;其中每行&#xff0c;每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid&#xff0c;其中有多少个 3 3 的 “幻方” 子矩阵&am…...

佰力博科技与您探讨热释电测量的几种方法

热释电的测量主要涉及热释电系数的测定&#xff0c;这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中&#xff0c;积分电荷法最为常用&#xff0c;其原理是通过测量在电容器上积累的热释电电荷&#xff0c;从而确定热释电系数…...

招商蛇口 | 执笔CID,启幕低密生活新境

作为中国城市生长的力量&#xff0c;招商蛇口以“美好生活承载者”为使命&#xff0c;深耕全球111座城市&#xff0c;以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子&#xff0c;招商蛇口始终与城市发展同频共振&#xff0c;以建筑诠释对土地与生活的…...

【LeetCode】3309. 连接二进制表示可形成的最大数值(递归|回溯|位运算)

LeetCode 3309. 连接二进制表示可形成的最大数值&#xff08;中等&#xff09; 题目描述解题思路Java代码 题目描述 题目链接&#xff1a;LeetCode 3309. 连接二进制表示可形成的最大数值&#xff08;中等&#xff09; 给你一个长度为 3 的整数数组 nums。 现以某种顺序 连接…...

Python 实现 Web 静态服务器(HTTP 协议)

目录 一、在本地启动 HTTP 服务器1. Windows 下安装 node.js1&#xff09;下载安装包2&#xff09;配置环境变量3&#xff09;安装镜像4&#xff09;node.js 的常用命令 2. 安装 http-server 服务3. 使用 http-server 开启服务1&#xff09;使用 http-server2&#xff09;详解 …...

TSN交换机正在重构工业网络,PROFINET和EtherCAT会被取代吗?

在工业自动化持续演进的今天&#xff0c;通信网络的角色正变得愈发关键。 2025年6月6日&#xff0c;为期三天的华南国际工业博览会在深圳国际会展中心&#xff08;宝安&#xff09;圆满落幕。作为国内工业通信领域的技术型企业&#xff0c;光路科技&#xff08;Fiberroad&…...