E33.【C语言】数据在内存中的存储练习集(未完)

1.

求下列代码的打印结果

cpp 复制代码
#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;
}

答案速查

分析

之前讲过,char在VS中默认为signed char,则a和b的打印结果应该是一样的

存储范围:

signed char -128~127

unsigned char 0~255

由于整数在内存中以补码形式存储,-1为0-1在计算器求出的结果为补码

这里如果没有位数的限制,由于不断向高位借位,会显示无数个1

在这里,无论是signed char类型还是unsigned char类型,其本质是限制在内存中的存储位数,从低位截断1 byte(8 bit),为1111 1111,因此a,b,c存储的均为1111 1111

回忆:15.75.【C语言】表达式求值

表达式中的字符和短整型操作数在++使用++ 之前被转换为普通整型 ,这种转换称为整型提升

到了printf("a=%d,b=%d,c=%d", a, b, c);时,由于a,b,c均为字符类型,因此在打印(即使用)之前会被提升为普通整型

对于1111 1111

signed char:有符号-->最高位为符号位

最高位为1,按最高位提升,x86下为11111111 11111111 11111111 11111111

unsigned char:无符号-->最高位不是符号位,以0填充

x86下为00000000 00000000 00000000 11111111

%d 打印有符号整数,%u 打印无符号整数

补码转换为原码

11111111 11111111 11111111 11111111最高位为1是符号位,不参与运算

取反+1后10000000 00000000 00000000 00000001,打印结果为-1

00000000 00000000 00000000 11111111

最高位为0是符号位,为正数,正数的原码=反码=补码,打印结果为255

总结

类型的作用:1.申请内存空间时的大小 2.决定看待内存中数据的视角

2.

求下列代码的打印结果

cpp 复制代码
#include <stdio.h>
int main()
{
	char a = -128;
	printf("a=%u", a);
	return 0;
}

答案速查

分析

-128==0-128

截断后8bit的补码10000000

char在VS中默认为signed char,整型提升11111111 11111111 11111111 10000000

%u打印,正数的原码=反码=补码

为FF FF FF 80-->

3.

把第2题的 char a = -128; 改为128,求打印的结果

结果和第二题一样

0-128截断后8bit的补码还是为10000000

4.

求下列代码的打印结果

cpp 复制代码
#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;
}

答案速查

分析

char类型的范围 -128~127

看循环时,从a[0]开始依次存储-1,-2,-3,...,-128,-129,-130,...,-1000

strlen找到/0(ASCII码为00)则停止,返回值

显然从-129开始存储会发生问题,char最多只能容纳8bit,计算机对于他们的处理采用"环绕溢出"机制

15.75.【C语言】表达式求值文中有一张图,很好地解释了这个机制

对于有符号(signed char)类型

8bit补码截断后存储:

0:0000 0000

1:0000 0001

2:0000 0010

......

126:0111 1110

127:0111 1111//不可再进位,否则影响符号位

-1:1111 1111

-2:1111 1110

-127:1000 0001

-128:1000 0000//被规定为-128

-129:0111 1111-->其实是127的结果

相当于:-1,-2,-3,-4,..,-128,127,126,...,1,0一共255bytes

5.

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

思想和第4题相同, unsigned char i = 0;(i范围0~255)定义全局变量

for循环中i<=255是恒成立的,死循环打印

6.(HARD★)

已知x86环境下是小端序存储,求下列代码的打印结果

cpp 复制代码
#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;
}

答案速查

分析

相关推荐
等等54319 分钟前
Java EE初阶——wait 和 notify
java·开发语言
低代码布道师26 分钟前
第五部分:第一节 - Node.js 简介与环境:让 JavaScript 走进厨房
开发语言·javascript·node.js
盛夏绽放43 分钟前
Python字符串常用方法详解
开发语言·python·c#
小狗祈祷诗1 小时前
day22-数据结构之 栈&&队列
c语言·数据结构
AI+程序员在路上2 小时前
XML介绍及常用c及c++库
xml·c语言·c++
好吃的肘子2 小时前
Elasticsearch架构原理
开发语言·算法·elasticsearch·架构·jenkins
nlog3n2 小时前
Go语言交替打印问题及多种实现方法
开发语言·算法·golang
kaixin_learn_qt_ing2 小时前
Golang
开发语言·后端·golang
ddd...e_bug2 小时前
Shell和Bash介绍
开发语言·bash
C4程序员3 小时前
Java百度身份证识别接口实现【配置即用】
java·开发语言