进阶C-数据的存储

就目前来看,C++JAVA的选择我选择了前者。

大家都说是Hard模式,但是自己不尝试,不努力又怎么知道能否成功呢!

所以再一次开始了C语言的进阶。这几部分总结完之后,我想就能开始C++的真正学习了!

C语言好学但又不好学。首先是因为C语言的语法比较固定,是可以很快理解的。但是C中有一个关键的地方,就是涉及到内存。因为C++追求的性能的极致。这就有了许多坑。

整型在内存中的存储

首先说到内存了,那么第一个需要考虑的还是在当前系统中,数据的存储模式。到底是大端还是小端。这里又要讨论到

大端模式:是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中

如:0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x0a 0a是低位,因为在16进制中表示10,应为00 00 00 0a这个样子。

低地址-----------------------------------------------------高地址

我们一般写数据也喜欢00 00 00 0a。

小端模式:是指数据的低位保存在内存低地址中,而数据的低位,保存在内存的高地址中

如:0x0a 0x00 0x00 0x00 0x00 0x00 0x00 0x00

低地址-----------------------------------------------------高地址

以上只是一个正整数在内存的表示方式。如果是负数呢?

这个时候就要考虑原码,补码,反码这三种的转换情况了

原码:直接将二进制按照正负数的形式翻译成二进制就可以。

反码:将原码的符号位不变,其他位依次按位取反就可以得到了。

补码:反码+1就得到补码。正数的原/反/补码都相同

在转换过程中,约定一个整数的最高位为符号位。正数为0,负数为1。

对于整型来说:数据存放内存中其实存放的是补码

但为什么我们需要搞一个补码?对人来说,原码不是更直观吗

这是为了方便计算机的计算来使用。计算机的内部表示都是用二进制来表示,那不管加减乘除都用补码,这样不就转换成了全是加法的运算吗。减法也只不过是加上一个负数

//检验大小端
#include<stdio.h>
#include<stdlib.h>
//如果是大端,返回0
//如果是小端,返回1
//非常重要!!校招总是爱考
int IsLittleEnd(){
	int a = 0x11223344;
	char* b = (char*)&a;
	if (*b == 0x11){
//检查低地址的内容是否是数字的高位
	return 0;
	}
	return 1;
}

int main(){
	int a = -10;
	printf("%d\n",a);
	//printf("%d\n",IsLittleEnd());              
	return 0;
}

数据在内存中具有一定的存储形式,存储同样的内容,可以按照不同的方式来理解

比如在unsigned char a = -1,这打印出来的即为255。因为-1在内存中表示为0xff,有时无符号此时就不管负号了。这之后0xff表示的就是255,所以打印出来不再是-1,就是255。

如果两个数据在内存中存储的形式是相同的,再按照相同的方式来理解,结果也肯定是相同的

char = 128和char = -128 在printf(“%u")打印下都是一样的

int i = -20;
unsigned j = 10;
printf("%d",i+j);

在这里又要碰到隐式转换。某个操作数属于不同的类型,那么除非其中一个操作数的转换为另一个操作数的类型,否则操作就无法进行。下面的层次体系为寻常算术转换

long double
double
float
unsigned long int
long int
unsigned int
int

如果某个操作数的类型在上面这个列表中排名较低,那么首先要转换为另一个操作数的类型后执行选择。比如int要转换成unsigned int,低类型要向高类型转换。

又因为打印为’%d’,是有符号的打印,所以我们最后为-10。

所以无符号整型在计算减法时很容易溢出。能不用无符号整数,就不用无符号,有符号整数来代替。

浮点型在内存中的存储

浮点型在内存中的分配中是根据国际标准IEEE754来定义的。

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

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

M表示有效数字,大于等于1,小于2。

2^E表示指数位。

举例来说:十进制的5.0,写成二进制是101.0,相当于1.01x2^2

那么,s=1,M=1.01,E=2

不能拿两个浮点数直接比较相等,浮点数的存储是存在误差的。因为在浮点数的存储中,如果是无限循环小数,数字超过了能存储的位数之后就不能在存储进去了。这样计算之后也无法得到准确的值

能不用浮点数,就不用浮点数。

猜你喜欢

转载自blog.csdn.net/skrskr66/article/details/86517171
C-