C语言:数值(int)在char类型下的存储

本文详细解释了C语言中char,signedchar和unsignedchar类型的内存存储机制,以及它们在数值范围、运算和打印时的行为,特别强调了负数的补码表示和无符号类型对整数处理的影响。
摘要由CSDN通过智能技术生成
int main()
{
	char a = -1;
	signed char b = -1;
	unsigned char c = -1;
	printf("a=%d,b=%d,c=%d", a, b, c);
	return 0;
}
//运行结果:a=-1,b=-1,c=255

首先,我们要了解到:在C语言中,char类型变量在内存中存储占1个字节=8个比特位;int类型占4个字节=32个比特位。而数值是以二进制补码的形式在内存中存储(其中,正数:原码=反码=补码;负数: 反码=原码除符号位按位取反、补码=反码+1)。数值有正数和负数之分,存储类型也有有符号(signed 【一般省略】)和无符号(unsigned)之分。

以char类型变量为例探索数值在内存中的存储:

(1)signed char类型的范围是-128~127;(最高位是符号位:0表示正数、1表示负数)

原码反码补码十进制注释
0000 00000000 00000000 00000最小的正数
0111 11110111 11110111 1111127最大的正数
1000 00011111 11101111 1111-1最大的负数
1111 11111000 00001000 0001-127
1000 000001111 11111000 0000-128最小的负数

(2)unsigned char类型的范围是0~255;(无符号位,每一位都表示数值)

原码反码补码十进制注释
0000 00000000 00000000 00000最小的正数
1111 11111111 11111111 1111255最大的正数

char a = -1;
signed char b=-1;
//两者相等(signed可省略)

unsigned char c = -1;
printf("a=%d,b=%d,c=%d", a, b, c);

 运算及打印过程:

-1signed charunsigned char
原码(int)1000 0000 0000 0000 0000 0000 0000 00011000 0000 0000 0000 0000 0000 0000 0001
反码(int) 1111 1111 1111 1111 1111 1111 1111 1110 1111 1111 1111 1111 1111 1111 1111 1110
补码(int) 1111 1111 1111 1111 1111 1111 1111 11111111 1111 1111 1111 1111 1111 1111 1111

截断存入

char类型变量

 取后8个比特位: 1111 1111取后8个比特位: 1111 1111

 %d打印

整型提升

按符号位全补1:

 1111 1111 1111 1111 1111 1111 1111 1111

无符号直接补0:

0000 0000 0000 0000 0000 0000 1111 1111

转成原码输出1000 0000 0000 0000 0000 0000 0000 0001    【-1】0000 0000 0000 0000 0000 0000 1111 1111  【255】
char a = -128;
printf("%u\n", a);
//4294967168
char a = 128;
printf("%u\n", a);
//4294967168
char-128128
原码(int)1000 0000 0000 0000 0000 0000 1000 00000000 0000 0000 0000 0000 0000 1000 0000
反码(int) 1111 1111 1111 1111 1111 1111 0111 1111 0000 0000 0000 0000 0000 0000 1000 0000
补码(int) 1111 1111 1111 1111 1111 1111 1000 00000000 0000 0000 0000 0000 0000 1000 0000

截断存入

char类型变量

 取后8个比特位: 1000 0000取后8个比特位: 1000 0000

 %d打印

整型提升

按符号位全补1:

 1111 1111 1111 1111 1111 1111 1000 0000

按符号补1:

1111 1111 1111 1111 1111 1111 1000 0000

转成原码输出1111 1111 1111 1111 1111 1111 1000 0000【%u无符号】1111 1111 1111 1111 1111 1111 1000 0000【%u无符号】

unsigned int 类型例(经典):

#include<Windows.h>
int main()
{
	unsigned int i;
	//0000...0000 0000
	//1111...1111 1111
	//-1、-2、-3...的补码正常存到内存中
	//但按照无符号打印,直接将其当作原码打印
	//i是无符号数,在进行运算时,也将补码直接当作原码运算
	for (i = 9; i >= 0; i--)
		//控制循环 一直将补码视为无符号的原码,一直循环
	{
		printf("%u\n", i);
		//将补码视为无符号的原码一直打印
		printf("%d\n", i);
		//将补码转换成原码打印
		Sleep(1000);
	}
	return 0;
}

int main()
{
	char a[1000];
	int i;
	for (i = 0; i < 1000; i++)
	{
		a[i] = -1 - i;
		//-1 -2 -3 -4...-128 127 126...3 2 1 0 -1 -2...
	}
	printf("%d", strlen(a));
	//strlen是求字符串长度,计算字符串中
	// ‘\0’(ASCII为0)之前出现多少字符
	return 0;
}

char类型变量循环做减法或循环做加法时,会循环-127~128,因为数值是int类型,64比特位;char类型始终截断其后8位。此代码会一直循环下去,但strlen取长度到0为止。

  • 7
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值