数据存储易错题

例题1 

#include<stdio.h>
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(补码存储)

原码:10000000    00000000   00000000   00000001

反码(原码取反):11111111    11111111    11111111    11111110

补码(反码+1):11111111    11111111    11111111    11111111

a是char类型

存储发生截断

a:    11111111

同理 

b:11111111

c:11111111

打印是以%d打印,因此需要整型提升

a是有符号的,提升后是

11111111 11111111 11111111 11111111

打印结果是-1

b与a一样结果也是-1

11111111 11111111 11111111 11111111

c是无符号类型,提升结果是

00000000 00000000 00000000 11111111

结果是255

例题2

#include <stdio.h>

int main()
{
	char a = -128;
	printf("%u\n", a);
	return 0;
}

signed  有符号的

unsigned   无符号的

signed char  a;a的取值范围-128~127

unsigned  char  b;b的取值范围0~255

-128存储形式

原:10000000   00000000    00000000    10000000 

补:11111111    11111111    11111111    10000000

存到a中:10000000

打印时发生整型提升

11111111    11111111    11111111    10000000        

%u是无符号整数直接打印十进制是4294967168

例题3

#include<stdio.h>
int main()
{
	char a = 128;
	printf("%u\n", a);
	return 0;
}

128存储形式

原(补)码:00000000   00000000    00000000    10000000 

存到a中:10000000

打印时发生整型提升,a是有符号字符,是负号,因此是:

11111111    11111111    11111111    10000000        

%u是无符号整数直接打印十进制是4294967168

例题4

#include<stdio.h>
int main()
{
	char a[1000];
	int i;
	for (i = 0; i < 1000; i++)
	{
		a[i] = -1 - i;
	}
	printf("%d", strlen(a));
	return 0;
}

数组a中只能存放-128~127的值

a中存放内容:

-1  -2  -3  ......-128  127  126......5  4  3  2  1  0  -1  -2  -3  ......-128  127  知道循环结束

求字符串长度找\0,\0的ASCII码是0,其实就是找0

0前共有255个元素

因此打印结果是255

例题5

#include<stdio.h>
unsigned char i = 0;
int main()
{
	for (i = 0; i <= 255; i++)
	{
		printf("hello world\n");
	}
	return 0;
}

i取值0~255,循环条件恒成立造成死循环,会一直打印hello world

例题6

#include<stdio.h>
int main()
{
	unsigned int i;
	for (i = 9; i >= 0; i--)
	{
		printf("%u\n", i);
	}
	return 0;
}

当i等于0的时候再减1,就是32个全1,无符号整型,因此转化成十进制就是非常大的正数,最终是死循环

例题7

在x86环境下,小端字节序

#include<stdio.h>
int main()
{
	int a[4] = { 1, 2, 3, 4 };
	int* ptr1 = (int*)(&a + 1);
	int* ptr2 = (int*)((int)a + 1);
	printf("%x,%x", ptr1[-1], *ptr2);
	return 0;
}

大小端字节序存储:

(注:两字节间的起始地址差1)

ptr1[-1]值是4,十六进制是0x00000004

ptr2是int*类型,*ptr2向后访问四个字节即00  00  00  02,十六进制还原0x02000000

打印结果是4,2000000

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值