【C语言】数据的存储

news2025/8/3 0:07:34

☃️内容专栏:【C语言】进阶部分

☃️本文概括: C语言中的数据类型及其存储方式。

☃️本文作者:花香碟自来_ 

☃️发布时间:2023.2.24

 

目录

 一、数据类型详细介绍

1.1 基本的数据类型

1.2 整型家族

1.3 构造类型

1.4 指针类型

1.5 空类型

二、整型在内存中的存储

2.1 原码、反码、补码

三、大小端字节序

3.1概念 

3.2 笔试题

四、 练习——内存存储

4.1.

4.2.补充(char类型存放数值的范围)

1. signed char 范围划分

 2. unsigned char 范围划分

 4.3 

五、浮点型在内存中的存储

5.1浮点数存储的规则

5.2浮点数存储的例子


 一、数据类型详细介绍

1.1 基本的数据类型

以下为C语言的几种常见类型

char        字符数据类型
short短整型
int整型
long长整型
long long更长的整型
float                单精度浮点数   
double双精度浮点数

1.2 整型家族

char存储的是字符,但本质存储和表示的是其字符所对应的ASCII码值,ASCII码值属于整数,所以char也属于整数。

数据类型有符号无符号
charunsigned charsigned char
shortunsigned short(int)signed short(int)
intunsigned intsigned int
longunsigned long(int)

signed long (int) 

我们知道对于数值,如“10”、“-10”,数值有正负,数值是有符号的,比如说温度,是有正数也是有负数的,我们可以用unsigned int 来存储数值,比如说年龄,没有负数的概念,我们就可以用signed int来存储。

我们平时默认写的short 、int 、long,前面其实省略了signed,这个signed可添加可不添加,表示的都是有符号。需要注意的是,对于char类型来说,不一定省略的都是signed,需要根据编译器确定,一般情况下,属于signed的。

1.3 构造类型

也称自定义类型

数组类型int [],char [],float []……
结构体类型struct关键字构造的结构体
枚举类型enum
联合类型union

1.4 指针类型

整型指针int *
字符指针char *
浮点数指针float * / double *
空类型指针void *

1.5 空类型

void 表示空类型(无类型),通常应用于函数的返回类型、函数的参数、指针类型。

二、整型在内存中的存储

我们在初阶部分就已经知道,变量的创建是需要在内存中开辟空间的。空间的大小是根据不同的类型来决定的。内存中存放的数据是以二进制的形式表示。

那么整数在内存中是如何存储的,我们就需要引入原码、反码、补码的概念,

2.1 原码、反码、补码

计算机中的整数有三种2进制表示方法,即原码、反码和补码。
三种表示方法均有符号位和数值位两部分,符号位(最高位)都是用0表示“正”,用1表示“负”。其余位数均为数值位。
正数的原、反、补码都相同。负整数的三种表示方法各不相同。

  • 原码:直接将数值按照正负数的形式翻译成二进制就可以得到原码。
  • 反码:将原码的符号位不变,其他位依次按位取反就可以得到反码
  • 补码:反码+1就得到补码
#include<stdio.h>
int main()
{
	int a = 10;
	// 0000 0000 0000 0000 0000 0000 0000 1010 原码
	// 0000 0000 0000 0000 0000 0000 0000 1010 反码
	// 0000 0000 0000 0000 0000 0000 0000 1010 补码
	int b = -10;
	// 1000 0000 0000 0000 0000 0000 0000 1010 原码
	// 1111 1111 1111 1111 1111 1111 1111 0101 反码
	// 1111 1111 1111 1111 1111 1111 1111 0110 补码
	return 0;
}

那么整型存放在内存中是以什么码的形式进行存储的呢?

正数并不好观察,所以我们考虑观察一个负数,我们取出变量b的地址,观察是以小端字节序的形式显示,什么是小端,后面会讲到,这里暂且理解为倒着存放,即将补码化为十六进制后的数据ff ff ff f6与内存中的数据吻合,所以,我们有结论,整数数据在内存中存放的是补码。

 为什么呢?

在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;
同时,加法和减法也可以统一处理(CPU只有加法器)此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。

三、大小端字节序

为何叫字节序?是因为将内存的数据以字节为单位进行存储。

  • 大端字节序(Big-Endian)将数据的低位字节存放在内存的高位地址,高位字节存放在低位地址。这种排列方式与数据用字节表示时的书写顺序一致,符合人类的阅读习惯。
  • 小端字节序(Little-Endian),将一个多位数的低位放在较小的地址处,高位放在较大的地址处。小端字节序与人类的阅读习惯相反,但更符合计算机读取内存的方式,因为CPU读取内存中的数据时,是从低地址向高地址方向进行读取的。

3.1概念 

简单理解,

大端字节序(存储模式),是指数据的低位保存在内存的高地址处,而数据的高位保存在内存的低地址处;
小端字节序(存储模式),是指数据的低位保存在内存的低地址处,而数据的高位保存在内存的高地址处。

为什么会有大端小端呢?

为什么会有大小端模式之分呢?这是因为在计算机系统中,我们是以字节为单位的,每个地址单元
都对应着一个字节,一个字节为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处理器还可以由硬件来选择是大端模式
还是小端模式。

3.2 笔试题

百度2015年系统工程师笔试题
请简述大端字节序和小端字节序的概念,设计一个小程序来判断当前机器的字节序。(10分)
如何设计一段代码来判断机器的大小端呢?

思路:我们拿最简单的数字1进行判断,数字1存放在内存中转换为十六进制位0x000001,若在小端模式中,则以“01 00 00 00”的形式进行存储,若在大端模式中,则以“00 00 00 01”的形式进行存储通过观察,我们会发现,其区别是第一个字节为1还是0,我们就可以确定机器是大端存储还是小端存储。于是我们可以想到通过指针来访问,取地址访问的是四个字节,那么什么类型的指针可以访问1个字节的数据呢,当然是char*类型的指针,将拿到的地址强制转换成char*。再通过指针解引用结果是1那么断定是小端,结果是0就是大端了。

 代码1:

#include<stdio.h>
int main()
{
	int a = 1;
	char* p = (char*)&a;
	if (*p == 1)
	{
		printf("小端\n");
	}
	else
	{
		printf("大端\n");
	}
	return 0;
}

优化代码,封装成函数

#include <stdio.h>
//大端返回0
//小端返回1
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;
}

四、 练习——内存存储

4.1.

思考以下代码,输出什么?

#include <stdio.h>
int main()
{
	
	char a = -1;
	//写出-1的二进制形式
	// 1000 0000 0000 0000 0000 0000 0000 0001 原码
	// 1111 1111 1111 1111 1111 1111 1111 1110 反码
	// 1111 1111 1111 1111 1111 1111 1111 1111 补码
	// 1111 1111 (截断)
	signed char b = -1;
	// -1
	unsigned char c = -1;
	// 1000 0000 0000 0000 0000 0000 0000 0001 原码
	// 1111 1111 1111 1111 1111 1111 1111 1110 反码
	// 1111 1111 1111 1111 1111 1111 1111 1111 补码
	// 1111 1111 (截断,因为char里面只能存放8个bit位)

	printf("a=%d,b=%d,c=%d", a, b, c);// -1 -1 255
	//打印%d的a(%d为有符号整数)
	编译器默认写char 是有符号的char
	//  按符号位填充
	//  1111 1111 整型提升为
	//	1111 1111 1111 1111 1111 1111 1111 1111(补码)
	// %d为有符号的数,所以按内存的角度,高位为1,为负数
	//  ,所以需要转换为原码
	//  1111 1111 1111 1111 1111 1111 1111 1110 (反码)
	//  1000 0000 0000 0000 0000 0000 0000 0001 (原码)
	// a = -1

	//打印b同理 分析过程和a一样

	//打印%d的c
	//将无符号的char c打印,首先进行整型提升
	//无符号的char高位补充0
	//  1111 1111 整型提升为
	//	0000 0000 0000 0000 0000 0000 1111 1111(补码)
	// %d为有符号的数,所以按内存的角度,高位为0,为正数
	//正数的原码反码补码相同
	// c = 255

	return 0;
}

打印代码观察: 

4.2.补充(char类型存放数值的范围)

char类型数值的存储范围是按照有符号和无符号区分的。char类型的大小为1个字节,1个字节为8个bit位。 

1. signed char 范围划分

推断如下

需要注意的是,内存中 10000000 这个补码表示的是原码(十进制)-128这个值;

我们不妨先将 -128用二进制形式表示为110000000(原码),101111111(反码),110000000(补码),但是存放在char类型空间里,只有8bit的空间,也就是蓝色底纹的部分,剩余的部分将会被丢弃。故以上的 10000000 会被直接翻译成128

 2. unsigned char 范围划分

推断如下:

对于unsigned来说,就没有符号位的概念了,存在内存中的补码也是原码,数值均为正数,所以unsigned的取值范围是0~255

 4.3 

下列程序输出什么?

//2.
#include <stdio.h>
int main()
{
    char a = -128;
    //将-128转换成二进制 
    // 1000 0000 0000 0000 0000 0000 1000 0000 (-128的原码)
    // 1111 1111 1111 1111 1111 1111 0111 1111 (反码)
    // 1111 1111 1111 1111 1111 1111 1000 0000 (补码)
    // 1000 0000(截断)
    printf("%u\n", a);
    //整型提升
    // char为signed 高位按符号位补充
    // 1111 1111 1111 1111 1111 1111 1000 0000
    //%u打印无符号的数 站在内存的角度会视为无符号的数
    //所以为正数,直接打印
    //计算得到4,294,967,168
    return 0;
}

 

//3.
#include <stdio.h>
int main()
{
    char a = 128;
    //将128转换成二进制 
    // 0000 0000 0000 0000 0000 0000 1000 0000 (128的原码)
    // 1000 0000(截断)
    printf("%u\n", a);
    //整型提升
    // char为signed 高位按符号位补充
    // 1111 1111 1111 1111 1111 1111 1000 0000
    //%u打印无符号的数 站在内存的角度会视为无符号的数
    //所以为正数,直接打印
    //计算还是得到4,294,967,168

    return 0;
}

//4.
#include<stdio.h>
int main()
{
	int i = -20;
	// -20转换为二进制
	// 1000 0000 0000 0000 0000 0000 0001 0100 (原码)
	// 1111 1111 1111 1111 1111 1111 1110 1011 (反码)
	// 1111 1111 1111 1111 1111 1111 1110 1100 (补码)
	unsigned int j = 10;
	// 1000 0000 0000 0000 0000 0000 0000 1010 (补码)
	//i+j
	// 1111 1111 1111 1111 1111 1111 1111 0110(补码)
	//按照补码的形式进行运算,最后格式化成为有符号整数
	// 1111 1111 1111 1111 1111 1111 1111 0101(反码)
	// 1000 0000 0000 0000 0000 0000 0000 1010 (原码)  -> -10
	printf("%d\n", i + j); //发生了算术转换,但并不影响值的计算
	
    return 0;
}

该代码的结果是个死循环,因为i为unsigned的int类型,循环条件大于等于0是恒成立的。

       

 解释:当i == -1的时候,将-1转换为二进制1000 0000 0000 0000 0000 0000 0000 0001,

化为反码为1111 1111 1111 1111 1111 1111 1111 1110,

化为补码为1111 1111 1111 1111 1111 1111 1111 1111

%u的形式打印,直接将补码打印,结果就为4,294,967,295 

//6.
#include<stdio.h>
#include<string.h>
int main()
{
	char a[1000];
	int i;
	for (i = 0; i < 1000; i++)
	{
		a[i] = -1 - i;
	}
	//char a[1000]里面的值存放的是 -1 -2 -3 …… -999 -1000 ?
	//我们知道signed char类型的取值范围是 -128~127
	//具体怎么运算的呢,我们可以观察代码段以下图形
	//
	//其实是一个轮回的过程
	// -129不是真正意义上的-129了,而是站在char内存的角度,截断计算为127了
	//我们就知道 -1 -2 -3 … -127 -128 127 126 … 2 1 0 -1

	printf("%d", strlen(a));// 128 + 127 = 255
	//求字符串长度 找到'\0'(0)即为字符串的结束标志
	return 0;
}

 

该代码的运行结果是一个死循环,unsigned char 的范围是 0 ~ 255,当i++得到i = 256的时候,化为二进制序列为1000 0000 0000 0000 0000 0001 0000 0000,但是存放在char里面的时候,存储的是0000 0000,高位丢掉了。所以循环条件恒小于等于255。

五、浮点型在内存中的存储

常见的浮点数

 3.14159
 1E10(科学计数法)
 浮点数家族包括: float、double、long double 类型。
 浮点数表示的范围:float.h中定义

5.1浮点数存储的规则

将一个十进制的浮点数转换为一个二进制浮点数的规则如下:

根据国际标准IEEE 754 (电气和电子工程协会)规定,任意一个二进制浮点数V可以表示成下面的形式:

V = (-1)^S * M * 2^E

(-1)^S表示符号位,当S=0,V为正数;当S=1,V为负数。

M表示有效数字, 1≤M<2

2^E表示指数位。

举例来说: 十进制的5.0,写成二进制是 101.0 ,相当于 1.01×2^2 。 那么,按照上面V的格式,可以得出S=0,M=1.01,E=2。 十进制的-5.0,写成二进制是 -101.0 ,相当于 -1.01×2^2 。那么,S=1,M=1.01,E=2。

IEEE 754规定

对于32位的浮点数来说,最高的1位是符号位s,接着的8位是指数E,剩下的23位为有效数字M。

 

 对于64位的浮点数来说,最高的1位是符号位S,接着的11位是指数E,剩下的52位为有效数字M。

对于有效数字M,前面说过, 1≤M<2 ,也就是说,M可以写成 1.xxxxxx 的形式,其中xxxxxx表示小数部分。 IEEE 754规定,在计算机内部保存M时,默认这个数的第一位总是1,因此可以被舍去,只保存后面的 xxxxxx部分。比如保存1.01的时 候,只保存01,等到读取的时候,再把第一位的1加上去。这样做的目的,是节省1位有效数字。以32位浮点数为例,留给M只有23位, 将第一位的1舍去以后,等于可以保存24位有效数字。这样能够提高其精度性。

至于指数E,情况就比较复杂。 首先,E为一个无符号整数(unsigned int) 这意味着,如果E为8位,它的取值范围为0~255;如果E为11位,它的取值范围为0~2047。但是,我们知道,科学计数法中的E是可以出现负数的(比如说0.5),所以IEEE 754规定,存入内存时E的真实值必须再加上一个中间数,对于8位的E,这个中间数是127;对于11位的E,这个中间 数是1023。比如,2^10的E是10,所以保存成32位浮点数时,必须保存成10+127=137,即 10001001。

然后,指数E从内存中取出还可以分成三种情况:

第一种:E不全为0或不全为1

这时,浮点数就采用下面的规则表示,即指数E的计算值减去127(或1023),得到真实值,再将有效数字M前加上第一位的1。 比如: 0.5(1/2)的二进制形式为0.1,由于规定正数部分必须为1,即将小数点右移1位,则为 1.0*2^(-1),其阶码为-1+127=126,表示为01111110,而尾数1.0去掉整数部分为0,补齐0到23位00000000000000000000000,则其二进制表示形式为:0 01111110 00000000000000000000000

第二种:E为全0

这时,浮点数的指数E等于1-127(或者1-1023)即为真实值, 有效数字M不再加上第一位的1,而是还原为0.xxxxxx的小数。这样做是为了表示±0,以及接近于 0 的很小的数字。

第三种:E为全1 

这时,如果有效数字M全为0,表示±无穷大(正负取决于符号位s)

5.2浮点数存储的例子

观察以下代码:

int main()
{
     int n = 9;
     float *pFloat = (float *)&n;
     printf("n的值为:%d\n",n);  //code1
     printf("*pFloat的值为:%f\n",*pFloat); //code2
     *pFloat = 9.0;
     printf("num的值为:%d\n",n); //code3
     printf("*pFloat的值为:%f\n",*pFloat); //code4
     return 0;
}

将代码打印得到以下结果                

n的值为9   //code1

*pFloat的值为:0.000000   //code2

num的值为:1091567616  //code3

*pFloat的值为:9.000000   //code4

code1与code2我们能够表面地看出来,但是对于code2 和code3就需要对浮点数进行内存存储的计算了。

对于code2,为什么 0x00000009  还原成浮点数,就成了 0.000000 ? 首先,将 0x00000009 拆分,得到第一位符号位s=0,后面8位的指数 E=00000000 , 最后23位的有效数字M=000 0000 0000 0000 0000 1001

9 -> 0000 0000 0000 0000 0000 0000 0000 1001

由于指数E全为0,所以符合上一节的第二种情况。因此,浮点数V就写成:

 V=(-1)^0 × 0.00000000000000000001001×2^(-126)=1.001×2^(-146)

显然,V是一个很小的接近于0的正数,所以用十进制小数表示就是0.000000。

 再次观察code3

问浮点数9.0,如何用二进制表示?还原成十进制又是多少? 首先,浮点数9.0等于二进制的1001.0,即1.001×2^3。

 9.0 -> 1001.0 ->(-1)^0*1.001*2^3 -> s=0, M=1.001,E=3+127=130

那么,第一位的符号位s=0,有效数字M等于001后面再加20个0,凑满23位,指数E等于3+127=130, 即10000010。 所以,写成二进制形式,应该是S+E+M,即

0 10000010 001 0000 0000 0000 0000 0000

将其二进制换算成十进制打印就是 1091567616


😉❤💚💛 好啦,数据的存储内容到此为止,创作不易,还请多多三连支持我哦~

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

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

相关文章

压力传感器MPX5700D/MPX5700GP/MPX5700AP产品概述、特征

MPX5700系列压阻式换能器是最先进的单片硅压力传感器&#xff0c;可广泛用于各种应用&#xff0c;特别是采用A/D输入微控制器或微处理器的应用。这一获得专利的单元件传感器集合了高级微加工技术、薄膜金属化、双极工艺&#xff0c;能够提供精确的、与所施加压力成正比的高电平…

Java面向对象:继承特性的学习

本文介绍了面向对象的继承特性: 什么是继承 继承的概念 Java中继承的语法 在继承下父类成员的访问 super和this关键字 父类和子类构造方法 在继承下类中出现初始化代码的执行顺序 父类成员的访问权限对子类的可见性 Java的继承关系 final关键字 认识继承和组合关系 继承特性的学…

Pytorch学习笔记(7):优化器、学习率及调整策略、动量

目录 一、优化器 1.1 优化器的介绍 1.2 optimizer的属性 1.3 optimizer的方法 1.4 常用优化器 torch.optim.SGD 二、学习率 2.1 学习率介绍 2.2 为什么要调整学习率 2.3 pytorch的六种学习率调整策略 &#xff08;1&#xff09;StepLR &#xff08;2&#xff09;Mu…

linux:http服务器搭建及实验案例

目录准备工作http服务器各个配置文件大概说明实验1&#xff1a;访问不同ip获得不同网页实验2&#xff1a;同一ip访问不同端口获得不同网页准备工作 1&#xff0c;安装http服务 2&#xff0c;将 /etc/selinux/config 文件下面的 SELINUX值改为 disabled 或者 permissive 。 3&a…

如何基于无代码平台实现60个园区、3万台设备的管理?

产业园区的建设是经济发展的集中承载区域。数字化快速发展迭代趋势下&#xff0c;对于一个全国领先的园区综合建设、运营集团来说&#xff0c;对跨园区的监管服务压力也日益增大。特别是随着全国范围内化工、物流、生产等各业态园区快速建设和扩张&#xff0c;园区内消防、安全…

GSEAmining | 来看看你的GSEA结果是不是需要瘦身啦!~

1写在前面 最近真是累的不行&#xff0c;今天抽空写一下新的教程&#xff0c;关于人人都会做的GSEA&#xff08;Gene Set Enrichment Analysis&#xff09;。 但有时候我们做完GSEA后结果实在太多&#xff0c;无法确定其中重要的生物学意义&#xff0c;难以解释。&#x1f928;…

Servlet笔记(4):表单数据

1、Servlet表单数据的方法 GET方法 http://localhost/hello?key1value1&key2value2GET方法有大小限制&#xff1a;请求字符串中最多只能由【1024】个字符 这些信息通过QUERY_STRING头传递&#xff0c;并通过【QUERY_STRING】环境变量访问&#xff0c;Servlet通过【doGet(…

SpringCloud - Gateway网关路由

目录 网关初步介绍 搭建网关服务 路由断言工厂Route Predicate Factory 路由过滤器 GatewayFilter 全局过滤器 GlobalFilter 过滤器执行顺序 网关的cors跨域配置 网关初步介绍 不是所有的请求&#xff0c;都能访问服务&#xff0c;所以需要网关对来访问的请求进行提前判…

归并排序及其应用

归并排序算法基于分而治之的概念&#xff0c;具体来说就是遍历一棵树&#xff0c;归并的过程是一个后序执行的动作。 由于我们知道每个子部分在合并后都是有序的&#xff0c;我们可以利用这个特性来解决一些问题。 上图可视化了merge sort algorithm的过程&#xff0c;我们很容…

2023年:我成了半个外包

边线业务与主线角色被困外包&#xff1b; 012022年&#xff0c;最后一个工作日&#xff0c;裁员的小刀再次挥下&#xff1b; 商务区楼下又多了几个落寞的身影&#xff0c;办公室内又多了几头暴躁的灵魂&#xff1b; 随着裁员的结束&#xff0c;部门的人员结构简化到了极致&am…

Fiddler在ios内的app中抓取https的解决方法

1、安装&设置Fiddler 查看链接---->Fiddler对PC浏览器&安卓App抓包的使用和配置 2、配置完后重启fiddler 3、ios安装证书 3.1、在fiddler右上角这里悬浮鼠标&#xff0c;查看自己电脑IP 或者通过&#xff1a; window键R&#xff0c;输入cmd&#xff0c;在命令行…

java Spring JdbcTemplate 准备工作

查看本文之前 您需要先看我 java Spring的IOC和AOP操作作为基础 如果并不掌握 可以找一下我之前的文章 都有讲到过 接下来的 我们将通过 JdbcTemplate 来做一些数据库操作 那我们就需要对 JdbcTemplate 有个基本的概念 首先 JdbcTemplate 是 Spring对 JDBC的一个很好的封装 通…

哪款蓝牙耳机延迟最低?打游戏零延迟的蓝牙耳机

我知道很多朋友会很在意声音延迟问题&#xff0c;虽然现如今蓝牙5.2甚至5.3已经可以几乎做到零延迟&#xff0c;但毕竟无线传输到现在依然存在或多或少延迟的情况出现&#xff0c;尤其是在这种蓝牙设备密集的地方&#xff0c;信号的干扰是不可避免的&#xff0c;由于技术的迭代…

【数据结构】空间复杂度

&#x1f680;write in front&#x1f680; &#x1f4dc;所属专栏&#xff1a;初阶数据结构 &#x1f6f0;️博客主页&#xff1a;睿睿的博客主页 &#x1f6f0;️代码仓库&#xff1a;&#x1f389;VS2022_C语言仓库 &#x1f3a1;您的点赞、关注、收藏、评论&#xff0c;是对…

免去打包烦恼,自动构建你的GitHub Pages|玩转GitHub Pages三部曲(二)

本文讲述了如何利用 GitHub Actions 来自动构建 GitHub Pages 项目&#xff0c;免去繁琐的手动构建再提交过程&#xff0c;让你专注于写作。大家的点赞和互动是我更文的动力 /(ㄒoㄒ)/ 所以我决定发起一项活动&#xff0c;到三月三十一日统计&#xff0c;留言次数和赞赏次数最多…

CSDN新星计划/原力计划来喽,对此你有何期待

文章目录&#x1f31f; 写在前面&#x1f31f; 新星计划&#x1f31f; 独自开&#x1f31f; 原力计划&#x1f31f; 横穿全年的计划&#x1f31f; 写在最后&#x1f31f; 写在前面 哈喽&#xff0c;大家好&#xff0c;我是几何心凉&#xff0c;这是一份全新的专栏&#xff0c;…

辛普森悖论

感谢原作者&#xff01;原文传送门 以下是摘录&#xff1a; 1、什么是辛普森悖论&#xff1f; 辛普森悖论是 1951 年由 E.H. 辛普森提出的&#xff0c;简单来讲就是在分组比较中都占优势的一方&#xff0c;有的时候在总评中反而是失势的一方。指局部的结论和整体的结论完全相…

HashMap~

HashMap&#xff1a; HashMap是面试中经常被问到的一个内容&#xff0c;以下两个经常被问到的问题&#xff0c; Question1&#xff1a;底层数据结构&#xff0c;1.7和1.8有何不同&#xff1f; 答&#xff1a;1.7数组&#xff0b;链表&#xff0c;1.8数组&#xff0b;(链表|红…

k8s使用外部ca证书

PKI证书和要求Kubernetes 需要 PKI 证书才能进行基于 TLS 的身份验证。如果你是使用 kubeadm 安装的 Kubernetes&#xff0c; 则会自动生成集群所需的证书。你还可以生成自己的证书。 例如&#xff0c;不将私钥存储在 API 服务器上&#xff0c;可以让私钥更加安全。此页面说明了…

C++ 模板

1. 泛型编程实现一个通用的交换函数&#xff0c;使用函数重载虽然可以实现&#xff0c;但是有以 下几个不好的地方&#xff1a;1. 重载的函数仅仅是类型不同&#xff0c;代码复用率比较低&#xff0c;只要有新类型出现时&#xff0c;就需要用户自己增加对应的函数2. 代码的可维…