C遗漏知识(个人向)
之前C语言遗漏的一些。
数据在内存中的存储
原码、反码、补码
整数的2进制表⽰⽅法有三种,即 原码、反码和补码
正整数的原、反、补码都相同。
负整数的三种表⽰⽅法各不相同。
原码:直接将数值按照正负数的形式翻译成⼆进制得到的就是原码。
反码:将原码的符号位不变,其他位依次按位取反就可以得到反码。
补码:反码+1就得到补码。
对于整形来说:数据存放内存中其实存放的是补码。
⼤⼩端字节序和字节序判断
我们发现a是倒着存储的,这是为什么?
其实超过⼀个字节的数据在内存中存储的时候,就有存储顺序的问题,按照不同的存储顺序,我们分 为⼤端字节序存储和⼩端字节序存储,下⾯是具体的概念: ⼤端(存储)模式:是指数据的低位字节内容保存在内存的⾼地址处,⽽数据的⾼位字节内容,保存 在内存的低地址处。 ⼩端(存储)模式:是指数据的低位字节内容保存在内存的低地址处,⽽数据的⾼位字节内容,保存 在内存的⾼地址处。
为什么要有大小端呢?
这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着⼀个字节,⼀个字节为8 bit 位,但是在C语⾔中除了8 bit 的 char 之外,还有16 bit 的 short 型,32 bit 的 long 型(要看 具体的编译器),另外,对于位数⼤于8位的处理器,例如16位或者32位的处理器,由于寄存器宽度⼤ 于⼀个字节,那么必然存在着⼀个如何将多个字节安排的问题。因此就导致了⼤端存储模式和⼩端存 储模式。 例如:⼀个 16bit 的 short 型 x ,在内存中的地址为 0x0010 , x 的值为 0x1122 ,那么 0x11 为⾼字节, 0x22 为低字节。对于⼤端模式,就将 0x11 放在低地址中,即 0x0010 中, 0x22 放在⾼地址中,即 0x0011 中。⼩端模式,刚好相反。我们常⽤的 X86 结构是⼩端模式,⽽ KEIL C51 则为⼤端模式。很多的ARM,DSP都为⼩端模式。有些ARM处理器还可以由硬件来选择是 ⼤端模式还是⼩端模式。
判断大小端的两个程序
//代码1
#include <stdio.h>
int check_sys()
{int i = 1;return (*(char *)&i);
}
int main()
{int ret = check_sys();if(ret == 1){printf("⼩端\n");}else{printf("⼤端\n");}return 0;
}
//代码2
int check_sys()
{union{int i;char c;}un;un.i = 1;return un.c;
}
浮点数在内存中的存储
常⻅的浮点数:3.14159、1E10等,浮点数家族包括: float、double、long double 类型。 浮点数表⽰的范围: float.h 中定义
当然对于浮点数的表示规则比较多,比较繁琐,这里就不解释了。
文件操作
为什么用文件,文件是何,文件分类
如果没有⽂件,我们写的程序的数据是存储在电脑的内存中,如果程序退出,内存回收,数据就丢失 了,等再次运⾏程序,是看不到上次程序的数据的,如果要将数据进⾏持久化的保存,我们可以使⽤ ⽂件。
磁盘上的⽂件是⽂件。 但是在程序设计中,我们⼀般谈的⽂件有两种:程序⽂件、数据⽂件(从⽂件功能的⻆度来分类 的)。
程序⽂件
程序⽂件包括源程序⽂件(后缀为.c),⽬标⽂件(windows环境后缀为.obj),可执⾏程序(windows 环境后缀为.exe)。
数据⽂件 ⽂件的内容不⼀定是程序,⽽是程序运⾏时读写的数据,⽐如程序运⾏需要从中读取数据的⽂件,或 者输出内容的⽂件。
其实有时候我们会把信息输出到磁盘上,当需要的时候再从磁盘上把数据读取到内存中使⽤,这⾥处 理的就是磁盘上⽂件。
⼀个⽂件要有⼀个唯⼀的⽂件标识,以便⽤⼾识别和引⽤。 ⽂件名包含3部分:⽂件路径+⽂件名主⼲+⽂件后缀 例如: c:\code\test.txt 为了⽅便起⻅,⽂件标识常被称为⽂件名。
根据数据的组织形式,数据⽂件被称为⽂本⽂件或者⼆进制⽂件。 数据在内存中以⼆进制的形式存储,如果不加转换的输出到外存,就是⼆进制⽂件。 如果要求在外存上以ASCII码的形式存储,则需要在存储前转换。以ASCII字符的形式存储的⽂件就是⽂ 本⽂件。 ⼀个数据在内存中是怎么存储的呢? 字符⼀律以ASCII形式存储,数值型数据既可以⽤ASCII形式存储,也可以使⽤⼆进制形式存储。 如有整数10000,如果以ASCII码的形式输出到磁盘,则磁盘中占⽤5个字节(每个字符⼀个字节),⽽ ⼆进制形式输出,则在磁盘上只占4个字节 。
文件的打开和关闭
C程序针对⽂件、画⾯、键盘等的数据输⼊输出操作都是通过流操作的。 ⼀般情况下,我们要想向流⾥写数据,或者从流中读取数据,都是要打开流,然后操作 。
标准流:那为什么我们从键盘输⼊数据,向屏幕上输出数据,并没有打开流呢? 那是因为C语⾔程序在启动的时候,默认打开了3个流: • stdin - 标准输⼊流,在⼤多数的环境中从键盘输⼊,scanf函数就是从标准输⼊流中读取数据。 • stdout - 标准输出流,⼤多数的环境中输出⾄显⽰器界⾯,printf函数就是将信息输出到标准输出 流中。 • stderr - 标准错误流,⼤多数环境中输出到显⽰器界⾯。 这是默认打开了这三个流,我们使⽤scanf、printf等函数就可以直接进⾏输⼊输出操作的。 stdin、stdout、stderr 三个流的类型是: FILE* ,通常称为⽂件指针。 C语⾔中,就是通过 FILE* 的⽂件指针来维护流的各种操作的。
文件指针
缓冲⽂件系统中,关键的概念是“⽂件类型指针”,简称“⽂件指针”。 每个被使⽤的⽂件都在内存中开辟了⼀个相应的⽂件信息区,⽤来存放⽂件的相关信息(如⽂件的名 字,⽂件状态及⽂件当前的位置等)。这些信息是保存在⼀个结构体变量中的。该结构体类型是由系 统声明的,取名FILE.
文件类型申明
struct _iobuf {char *_ptr;int _cnt;char *_base;int _flag;int _file;int _charbuf;int _bufsiz;char *_tmpfname;};
typedef struct _iobuf FILE;
不同的C编译器的FILE类型包含的内容不完全相同,但是⼤同⼩异。 每当打开⼀个⽂件的时候,系统会根据⽂件的情况⾃动创建⼀个FILE结构的变量,并填充其中的信 息,使⽤者不必关⼼细节。 ⼀般都是通过⼀个FILE的指针来维护这个FILE结构的变量,这样使⽤起来更加⽅便。 下⾯我们可以创建⼀个FILE*的指针变量:
FILE* pf;//⽂件指针变量
定义pf是⼀个指向FILE类型数据的指针变量。可以使pf指向某个⽂件的⽂件信息区(是⼀个结构体变 量)。通过该⽂件信息区中的信息就能够访问该⽂件。也就是说,通过⽂件指针变量能够间接找到与 它关联的⽂件。
⽂件在读写之前应该先打开⽂件,在使⽤结束之后应该关闭⽂件。 在编写程序的时候,在打开⽂件的同时,都会返回⼀个FILE*的指针变量指向该⽂件,也相当于建⽴了 指针和⽂件的关系。 ANSIC 规定使⽤ fopen 函数来打开⽂件, fclose 来关闭⽂件。
//打开⽂件
FILE * fopen ( const char * filename, const char * mode );
//关闭⽂件
int fclose ( FILE * stream );
fopen文件打开模式
r代表read的简写,+代表可读可写,w代表write,b代表bit二进制位,t代表textr 打开只读文件,该文件必须存在
r+ 打开可读可写的文件,该文件必须存在(这里的写文件是指将之前的文件覆盖
rt 打开只读文本文件,该文本必须存在
rt+ 读写打开一个文本文件,允许读和写,该文件必须存在(这里的写文件是指将之前的文件覆盖
rb 只读打开一个二进制文件,,该文本必须存在
rb+ 读写打开一个文本文件,允许读和写,该文件必须存在(这里的写文件是指将之前的文件覆盖
w 打开只写文件,若文件存在,则文件长度清零,即文件内容会消失,若文件不存在则建立该文件
w+ 打开可读写文件,若文件存在,则文件长度清零,即文件内容会消失,若文件不存在则建立该文件(这里的读文件,同样需要使用rewind()函数)
wt 打开只写文本文件,若文件存在,则文件长度清零,即文件内容会消失,若文件不存在则建立该文件
wt+ 打开可读写文本文件,若文件存在,则文件长度清零,即文件内容会消失,若文件不存在则建立该文件
wb 打开只写二进制文件,若文件存在,则文件长度清零,即文件内容会消失,若文件不存在则建立该文件
wb+ 打开可读写文件,若文件存在,则文件长度清零,即文件内容会消失,若文件不存在则建立该文件
a以附加的方式打开只写文件,若文件不存在,则建立文件,存在则在文件尾部添加数据,即追加内容
a+以附加的方式打开可读写文件,不存在则建立文件,存在则写入数据到文件尾(这里的读文件,同样需要使用rewind()函数,但是写文件不需要rewind()函数,a是追加)
at二进制数据的追加,不存在则创建,只能写。
at+读写打开一个文本文件,允许读或在文本末追加数据(这里的读文件,同样需要使用rewind()函数,但是写文件不需要rewind()函数,a是追加)
ab二进制数据的追加,不存在则创建,只能写。
ab+读写打开一个二进制文件,不存在则创建,允许读或在文本末追加数据(这里的读文件,同样需要使用rewind()函数,但是写文件不需要rewind()函数,a是追加)
/* fopen fclose example */
#include <stdio.h>
int main ()
{FILE * pFile;//打开⽂件pFile = fopen ("myfile.txt","w");//⽂件操作if (pFile!=NULL){fputs ("fopen example",pFile);//关闭⽂件fclose (pFile);}return 0;
}
顺序函数读写函数
函数名 功能 适⽤于
fgetc 字符输⼊函数 所有输⼊流
fputc 字符输出函数 所有输出流
fgets ⽂本⾏输⼊函数 所有输⼊流
fputs ⽂本⾏输出函数 所有输出流
fscanf 格式化输⼊函数 所有输⼊流
fprintf 格式化输出函数 所有输出流
fread ⼆进制输⼊ ⽂件
fwrite ⼆进制输出 ⽂件
文件的随机读写
fseek 根据⽂件指针的位置和偏移量来定位⽂件指针。
ftell 返回⽂件指针相对于起始位置的偏移量
rewind 让⽂件指针的位置回到⽂件的起始位置
编译和链接
翻译环境和运⾏环境
在ANSI C的任何⼀种实现中,存在两个不同的环境。
第1种是翻译环境,在这个环境中源代码被转换为可执⾏的机器指令。
第2种是执⾏环境,它⽤于实际执⾏代码。
那翻译环境是怎么将源代码转换为可执⾏的机器指令的呢?这⾥我们就得展开开讲解⼀下翻译环境所 做的事情。 其实翻译环境是由编译和链接两个⼤的过程组成的,⽽编译⼜可以分解成:预处理(有些书也叫预编 译)、编译、汇编三个过程。
⼀个C语⾔的项⽬中可能有多个 .c ⽂件⼀起构建,那多个 .c ⽂件如何⽣成可执⾏程序呢? • 多个.c⽂件单独经过编译出编译处理⽣产对应的⽬标⽂件。 • 注:在Windows环境下的⽬标⽂件的后缀是 .obj ,Linux环境下⽬标⽂件的后缀是 .o • 多个⽬标⽂件和链接库⼀起经过链接器处理⽣成最终的可执⾏程序。 • 链接库是指运⾏时库(它是⽀持程序运⾏的基本函数集合)或者第三⽅库。
预处理
预定义符号
C语⾔设置了⼀些预定义符号,可以直接使⽤,预定义符号也是在预处理期间处理的。
__FILE__ //进⾏编译的源⽂件
__LINE__ //⽂件当前的⾏号
__DATE__ //⽂件被编译的⽇期
__TIME__ //⽂件被编译的时间
__STDC__ //如果编译器遵循ANSI C,其值为1,否则未定义
#define定义常量
#define MAX 1000
#define reg register //为 register这个关键字,创建⼀个简短的名字
#define do_forever for(;;) //⽤更形象的符号来替换⼀种实现
#define CASE break;case //在写case语句的时候⾃动把 break写上。
// 如果定义的 stuff过⻓,可以分成⼏⾏写,除了最后⼀⾏外,每⾏的后⾯都加⼀个反斜杠(续⾏符)。
#define DEBUG_PRINT printf("file:%s\tline:%d\t \date:%s\ttime:%s\n" ,\__FILE__,__LINE__ , \__DATE__,__TIME__ )
#define定义宏
#define 机制包括了⼀个规定,允许把参数替换到⽂本中,这种实现通常称为宏(macro)或定义宏 (define macro)。 下⾯是宏的申明⽅式:
#define name( parament-list ) stuff
其中的 parament-list 是⼀个由逗号隔开的符号表,它们可能出现在stuff中。 注意: 参数列表的左括号必须与name紧邻,如果两者之间有任何空⽩存在,参数列表就会被解释为stuff的 ⼀部分。
宏替换的规则
在程序中扩展#define定义符号和宏时,需要涉及⼏个步骤。 1. 在调⽤宏时,⾸先对参数进⾏检查,看看是否包含任何由#define定义的符号。如果是,它们⾸先 被替换。 2. 替换⽂本随后被插⼊到程序中原来⽂本的位置。对于宏,参数名被他们的值所替换。 3. 最后,再次对结果⽂件进⾏扫描,看看它是否包含任何由#define定义的符号。如果是,就重复上 述处理过程。 注意: 1. 宏参数和#define 定义中可以出现其他#define定义的符号。但是对于宏,不能出现递归。 2. 当预处理器搜索#define定义的符号的时候,字符串常量的内容并不被搜索。
相关文章:

C遗漏知识(个人向)
之前C语言遗漏的一些。 数据在内存中的存储 原码、反码、补码 整数的2进制表⽰⽅法有三种,即 原码、反码和补码 正整数的原、反、补码都相同。 负整数的三种表⽰⽅法各不相同。 原码:直接将数值按照正负数的形式翻译成⼆进制得到的就是原码。 反码&…...

ERR_SSL_VERSION_OR_CIPHER_MISMATCH
我在namesilo买的域名,coludflare做的解析,华为云的SSL,用宝塔部署的SSL,访问https报错,http却正常: 报错:此网站无法提供安全连接www.hongkong.ioyunxin.top 使用了不受支持的协议。 ERR_SSL_…...
2.5作业
一 、程序阅读题 1、给出下面程序输出结果。 #include <iostream.h> class example {int a; public: example(int b5){ab;} void print(){aa1;cout <<a<<"";} void print()const {cout<<a<<endl;} }; void main() {example x; const e…...
linux系统lvs命令的使用
Lvs命令 LVS ipvsadm 命令的使用LVS-server安装lvs管理软件命令选项 LVS ipvsadm 命令的使用 LVS-server安装lvs管理软件 yum -y install ipvsadm 程序包:ipvsadm(LVS管理工具) 主程序:/usr/sbin/ipvsadm 规则保存工具&#x…...
PoEAA笔记-7.分布策略
本文摘抄自PoEAA,详细信息请阅读本书 7.1 分布对象的诱惑 透明性非常有用,但虽然有很多东西在分布对象中可以是透明的,但性能却不在其中,尽管上面的架构师是为了提高性能而使用分布组件的,但他的设计只会影响性能&…...

Spring Boot 整合 Redis 使用教程
作为开发者,相信大家都知道 Redis 的重要性。Redis 是使用 C 语言开发的一个高性能键值对数据库,是互联网技术领域使用最为广泛的存储中间件,它是「Remote Dictionary Service」的首字母缩写,也就是「远程字典服务」。 Redis 以超…...

用友U8 Cloud ReportDetailDataQuery SQL注入漏洞复现(QVD-2023-47860)
0x01 产品简介 用友U8 Cloud 提供企业级云ERP整体解决方案,全面支持多组织业务协同,实现企业互联网资源连接。 U8 Cloud 亦是亚太地区成长型企业最广泛采用的云解决方案。 0x02 漏洞概述 用友U8 cloud ReportDetailDataQuery 接口处存在SQL注入漏洞,攻击者未经授权可以访…...

docker镜像命令
docker images 列表本机上的镜像 - REPOSITORY:表示镜像的仓库源 - TAG:镜像的标签 - IMAGE ID:镜像 - ID CREATED:镜像创建时间 - SIZE:镜像大小 同一仓库源可以有多个 TAG,代表这个仓库源的不同个版本&am…...

通义千问上线春节新应用,AI帮你免费拍全家福
2月5日,春节将至年味渐浓,阿里云通义千问APP上线多项免费新应用,涵盖全家福、拜新年、万物成龙等图像生成的新玩法,共提供超300套照片模板,用户上传照片即可生成全家福、团圆照、拜年照、千里江山主题照;此…...

RabbitMQ 安装
下载erlang语言: erlang语言 下载RabbitMQ rabbitmq 安装erlang 1.以管理员身份安装erlang 2.弹出框选择next 3.选择安装路径,亦可以安装在默认路径 4.接下来一路点击下一步,无需任何修改,直到 install安装为止ÿ…...
如何让MySQL从部署到稳定运行?
如何让MySQL从部署到稳定运行? 1. 安装MySQL 8保姆级教程 2. 《从菜鸟到大师之路 MySQL 篇》 3. 关于MySQL的66个问题 4. MySQL 的学习资源史上最全 5. 掌握 SQL 这些核心知识点,出去吹牛逼再也不担心了...
go 内存二进制数据操作
go 内存二进制数据操作 go 内存二进制数据直接操作 以数字类型为例 int(linux/macos 为int32,windows 为int64). 如果不清楚可以使用unsafe.Sizeof函数来查看(函数出来的值*8就是int位数) 若不使用内存二进制数据操作,你需要在每次获取数字内容时调用binary.Big…...

Antd+React+react-resizable实现表格拖拽功能
1、先看效果 2、环境准备 在package.json 引入相关的依赖 "dependencies": {"antd": "^5.4.0","react-resizable": "^3.0.4",},"devDependencies": {"types/react": "^18.0.33","types…...

StringBuilder类常用方法(Java)
StringBuilder类常用方法 StringBuilder 是 Java 中常用的字符串缓冲区类,适用于频繁修改字符串的场景。 1. append(): 将指定字符串、字符、布尔值或其他数据类型的表示追加到字符串缓冲区的末尾。 StringBuilder sb new StringBuilder("Hello"); sb.…...

Iceberg从入门到精通系列之二十一:Spark集成Iceberg
Iceberg从入门到精通系列之二十一:Spark集成Iceberg 一、在 Spark 3 中使用 Iceberg二、添加目录三、创建表四、写五、读六、Catalogs七、目录配置八、使用目录九、替换会话目录十、使用目录特定的 Hadoop 配置值十一、加载自定义目录十二、SQL 扩展十三、运行时配置…...

Linux的进程信号
注意:首先需要提醒一个事情,本节提及的进程信号和下节的信号量没有任何关系,请您区分对待。 1.信号概念 1.1.生活中的信号 我们在生活中通过体验现实,记忆了一些信号和对应的处理动作,这意味着信号有以下相关的特点&…...
svn常用命令及过滤文件 global ignore pattern
SVN常用命令详解和global ignore pattern Subversion(SVN)是一个版本控制系统,广泛用于软件开发项目中。它能够追踪文件的变更,并且允许多人在同一个项目中协同工作。以下是一些常用的SVN命令及其用法。 1. 检出代码 要从SVN服…...
【QT+QGIS跨平台编译】之二十九:【HDF5+Qt跨平台编译】(一套代码、一套框架,跨平台编译)
文章目录 一、HDF5介绍二、文件下载三、文件分析四、pro文件一、HDF5介绍 HDF5(层次数据格式第5版)是一种用于存储和组织大量数据的文件格式和技术集合。它由美国国家超级计算应用中心(NCSA)开发,旨在解决复杂数据的存储和分布问题。HDF5支持各种数据类型,能够有效地存储…...

React 中实现拖拽功能-插件 react-beautiful-dnd
拖拽功能在平时开发中是很常见的,这篇文章主要使用react-beautiful-dnd插件实现此功能。 非常好用,附上GitHub地址:https://github.com/atlassian/react-beautiful-dnd 安装及引入 // 1.引入 # yarn yarn add react-beautiful-dnd# npm npm…...

golang 引入swagger(iris、gin)
golang 引入swagger(iris、gin) 在开发过程中,我们不免需要调试我们的接口,但是有些接口测试工具无法根据我们的接口变化而动态变化。文档和代码是分离的。总是出现文档和代码不同步的情况。这个时候就可以在我们项目中引入swagge…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...

srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...
JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案
JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停 1. 安全点(Safepoint)阻塞 现象:JVM暂停但无GC日志,日志显示No GCs detected。原因:JVM等待所有线程进入安全点(如…...
SQL慢可能是触发了ring buffer
简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...
redis和redission的区别
Redis 和 Redisson 是两个密切相关但又本质不同的技术,它们扮演着完全不同的角色: Redis: 内存数据库/数据结构存储 本质: 它是一个开源的、高性能的、基于内存的 键值存储数据库。它也可以将数据持久化到磁盘。 核心功能: 提供丰…...
Python网页自动化Selenium中文文档
1. 安装 1.1. 安装 Selenium Python bindings 提供了一个简单的API,让你使用Selenium WebDriver来编写功能/校验测试。 通过Selenium Python的API,你可以非常直观的使用Selenium WebDriver的所有功能。 Selenium Python bindings 使用非常简洁方便的A…...

前端开发者常用网站
Can I use网站:一个查询网页技术兼容性的网站 一个查询网页技术兼容性的网站Can I use:Can I use... Support tables for HTML5, CSS3, etc (查询浏览器对HTML5的支持情况) 权威网站:MDN JavaScript权威网站:JavaScript | MDN...

基于江科大stm32屏幕驱动,实现OLED多级菜单(动画效果),结构体链表实现(独创源码)
引言 在嵌入式系统中,用户界面的设计往往直接影响到用户体验。本文将以STM32微控制器和OLED显示屏为例,介绍如何实现一个多级菜单系统。该系统支持用户通过按键导航菜单,执行相应操作,并提供平滑的滚动动画效果。 本文设计了一个…...