c语言学习笔记-整型数据的储存

目录

一、char

1.截断存取

2.有符号与无符号的处理

3.整型提升

 二、大小端字节序


一、char

众所周知,在c语言里面,char也是属于整型里面的。这是为何呢?因为char调用字符的时候是用的ascii码值储存的。

在c语言中,整型数据里面给int分配的四个字节内存,而给char类型分配的是一个字节,应为如果用其表示英语的话一个字节完全足矣。

那么,现在从下面这个程序引入今天我想分享的学习点里面吧:

#include<stdio.h>
int main()
{

	char a = -1;
	unsigned char b = -1;
	printf("a = %d, b = %d\n", a, b);
	return 0;
}

这个代码里面首先要了解整型字面值里面是以int类型默认的,按理说以大容量类型到小类型转换需要强制转化类型,但是对于char类型是不需要的。现在上面的代码需要 截断存取有符号与无符号类型的处理,最后,整型提升

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(补码)。注意到的是上述变化只是在负数的时候需要这样变换,但是对于正数来说的话,原码反码补码一致哦。

随后,对于char类型的来说,只有八个bite的内存显然存不下32bite的数据,自然就会发生截断,只把后面的8个bite的数据存到a和b变量里面即可,即 1111 1111。

2.有符号与无符号的处理

虽然此时ab变量里面存的补码一致,但是你以为他们输出的是一样的吗?当然不一样,造成这种差异的正是有符号与无符号的处理,在printf函数的处理时,将它们取出,需要进行整型提升,但是整型提升要按什么要求来提升呢?就是以这个处理来进行提升的。

正如从char型数据取出数据,只有八个bite,现在就要往前补齐至32个bite,有符号的就补符号位,而没有符号的就补0,c语言统一规定的。

3.整型提升

正如2里面所说,那么a就是正常的进行提升,由 1111 1111,是负数,就提升1,那么:

1111 1111 1111 1111 1111 1111 1111 1111;和原来存进去的方式一模一样,所以可以确定a输出来的结果也是一致了,那么b的话是无符号,就提升0:

0000 0000 0000 0000 0000 0000 1111 1111 ,这个时候需要转化为反码和原码吗?不,此时补零后打印%d,看首位是0,所以被认成了正数,所以就直接转化为十进制得255啦!

 二、大小端字节序

大小端字节序指的是数据在电脑上存储的字节顺序。

这是怎么一回事呢?

比如储存1:

int a = 1;

调试后在内存块找到&a即可会看到这样的情况:

 按理说的话应该是(上面内存块是以十六进制存的)

高位 00 00 00 01 低位,是反起存的,当然这就是小端储存。,那么大小端字节序究竟是怎么储存的呢?

大端字节序:高位的字节存在低地址上,低位的字节存在高地址上。

小端字节序:高位的字节存在高地址上,低位的字节存在低地址上。

当然,大端字节序的话就符合我们的观看情况了:

 那么,我们如何分析或者说设计一个函数来区别当前环境下是什么字节序呢?

当然可以,我们可以直接在主函数里面去写:

int main()
{
	int a = 1;
	char* b = (char*)&a;
	if (*b == 0)
		printf("大端");
	else
		printf("小端");
	return 0;
}

想一想,我们可以拿最简单的1来进行实验,其在内存里面的存储情况应该是 00 00 00 01(十六进制),那么我们能否从低地址里面去出一个字节的数据即一个 00或者01来判断是否大小端呢?上述代码就实现啦,但是,我们是要制作一个函数,万一转换环境了,还要把main函数带过去吗?所以,我们可以打包成函数:

void Byte_order()
{
	int a = 1;
	char* b = (char*)&a;
	if (*b == 0)
		printf("大端");
	else
		printf("小端");

}
int main()
{
	Byte_order();
	return 0;
}

但是,在函数里面打印的话效率不高,不适用,我们不妨将这个函数的类型改为int型的,使其返回1和0来表示判断:

int Byte_order()
{
	int a = 1;
	char* b = (char*)&a;
	if (*b == 0)
		return 0;
	return 1;

}
int main()
{
	if (Byte_order() == 1)
		printf("小端");
	else
		printf("大端");
	return 0;
}

既然都返回0和1了,那么我们为何不直接返回呢?并且,在函数里面还重新创建了一个指针变量,我们是否可以不用创建呢?

int Byte_order()
{
	int a = 1;
	return *(char*)&a;

}
int main()
{
	if (Byte_order() == 1)
		printf("小端");
	else
		printf("大端");
	return 0;
}

显然,最后一个代码已经让我沦陷。。。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值