数据在内存中的存储(c数据类型)

本文介绍了C语言中数据类型的存储,包括整型、浮点型、构造类型和指针类型。重点讲解了整型在内存中以补码形式存储,以及大小端字节序的概念。还探讨了隐式类型转换,如整形提升和算术转换,并给出了相关例题解释计算过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、数据类型:

整形家族:

  1. char:unsigned char / signed char
  2. short:unsigned short [int] / signed short [int]
  3. int:unsigned int / signed [int]
  4. long:unsigned long [int] / signed long [int]
  5. long long:unsigned long long [int] / signed long long [int]

tips:字符类型在内存中的存储,是存储的字符类型对应的ASCII码,所以字符类型算作整形。

浮点型家族:

  1. float:
  2. double:

构造类型(自定义类型):

  1. 数组:
  2. 结构体:
  3. 枚举:
  4. 联合体:

指针类型:

空类型:

二、整形在内存中的存储:

        计算机中的整数有三种二进制表示方法,即:原码、反码、补码。

        三种表示方法均有符号位和数值位,符号位用0表示“正”,用1表示“负”。正数的原、反、补相同,负数的原、反、补不同。而整形在内存中存储的就是整数的二进制补码,这样的作用是可以将符号位和数值位统一计算,省去硬件中多余的逻辑电路。

整形在内存中占4个字节,下面举例整形的二进制表示:

255的原码、反码、补码:

00000000 00000000 00000000 11111111 ——  原码

00000000 00000000 00000000 11111111 ——  反码

00000000 00000000 00000000 11111111 ——  补码

-1的原码、反码、补码:

10000000 00000000 00000000 00000001 ——  原码

11111111 11111111 11111111 11111110     ——  反码:符号位不变,其余位按位取反

11111111 11111111 11111111 11111111     ——  补码:反码+1

        虽然整数在内存中以补码存储,但是读取时还是要转换回原码。补码转换为原码有两种方式:1. 补码 - 1,符号位不变,其余位按位取反;2. 符号位不变,其余位按位取反得到的二进制再 + 1

三、大小端字节序存储模式:

        什么是大小端字节序存储模式?

        大端(存储)模式:数据的低位字节存放在内存的高地址处,数据的高位字节存放在内存的低地址处。

        小端(存储)模式:数据的高位字节存放在内存的高地址处,数据的低位字节存放在内存的高地址处。

        

         如图:num  = 0x11223344,在内存低地址处存放的是num的低位字节44,高地址处存放的num的高位字节11,可见此系统是以小端模式进行数据的存储的。

四、隐式类型转换:

        这部分内容不算是数据在内存中存储的范畴,但是部分计算需要理解数据怎么在内存中进行存储的,才能知道结果是怎么得出的。

        整形提升:

        C语言中的整形运算符总是至少以缺省整形类型的精度来进行计算的,为了获得这个精度,表达式中的字符和短整形操作数在使用之前要被转换为普通整形,这种转换被成为整形提升。

        如何进行整形提升?

        整形提升是按照变量自身的数据类型的符号位来操作的,如果是有符号数:补齐符号位;如果是无符号数:补齐0。

        算术转换:

        如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数转换为另一个操作数的类型,否则操作就无法进行。下面的层次体系称为寻常算术转换:当处于列表下方的操作数类型较低时,需向上转换。

long double

double

float

unsigned long int

long int

unsigned int

int

五、一些例题:

        1.如何判断当前系统为大端存储模式还是小端存储模式,请写程序判断:

#include <stdio.h>

int judge_sys(int *value) {
	return *(char*)value;
}

int main() {
	int num = 1;
	if (judge_sys(&num)) {
		printf("小端\n");
	}
	else {
		printf("大端\n");
	}

	return 0;
}

        2.请写出下列程序的输出:

#include <stdio.h>

int main() {
    char x = -128;
    printf("%u\n", x);

    return 0;
}

        上面程序结果为:4294967168,计算过程如下:

(1)-128的补码:

10000000 00000000 00000000 10000000 —— 原码

11111111 11111111 11111111 01111111     —— 反码

10000000 00000000 00000000 10000000 —— 补码

(2)x为字符类型,只能访问一个字节的内存空间,所以x的值为:10000000。这过程也叫整形截断。

(3)以%u也就是无符号整形形式打印,x需要整形提升,x自身为有符号数,所以补齐符号位。

11111111 11111111 11111111 10000000 —— 补码

11111111 11111111 11111111 01111111  —— 反码

10000000 00000000 00000000 10000000 —— 原码

(4)以无符号形式打印原码,最后得到4294967168

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

石Ww.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值