例题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