C语言进阶————数据在内存中的存储1

2026年1月24日学习总结:

在之前已经结束了C语言初阶的学习,将进入C语言进阶的学习。在进入学习下一节之前补充一个知识点:

数组的越界访问代码的debug环境和release环境中运行的区别(X86环境下)

代码如下:

cs 复制代码
#include<stdio.h>
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int i = 0;
	for (i = 0; i <= 12; i++)
	{
		printf("hehe\n");
	}
	return 0;
}

在debug环境下为死循环(一直打印hehe),因为arr(低)的内存地址在i(高)地址后面,且包含一定间隔,就会出现地址冲突的情况。

而在release环境下只是打印了13个hehe,并没有陷入死循环。这是因为release环境下对该程序进行了优化,此时arr(高)的内存地址在i(低)地址的前面,从低到高进行访问时就不会出现地址冲突情况。

然后进入C语音进阶的学习,首先进入第一章的学习------数据在内存中的存储,本次学习主要分为以下两个部分:

1.数据类型介绍

基本数据类型:

char 字符数据类型 1字节

short 短整型 2字节

int 整型 4字节

long 长整型 32位机:4字节/64位机:8字节(C语音中:sizeof(long)>=sizeof(int))

long long 更长整型 8字节(C99中使用)

float 单精度浮点数 4字节

double 双精度浮点数 8字节

类型的意义:① 使用这个类型开辟空间的大小(大小决定使用范围);② 如何看待内存空间的视角。

1.1类型的基本归类

(1)整型家族:

char unsigned char signed char

short unsigned short [int] signed short [int]

int unsigned int signed int

long unsigned long [int] signed long [int]

long long unsigned long long [int] signed long long [int]

①为什么将char归纳到整型?

char本质是ASCLL码,是整型,所以划分到整型家族。

②char更详细的划分应该有3种类型:char,unsigned char,signed char。因为在使用cahr时并为定义是有符号还是无符号,这取决于编译器的实现。其余的都只有两种无符号和有符号,单独的类型相当于有符号(如int相当于signed int)

③可以根据实际情况判断使用的参数有符号还是无符号,一般最高位为符合位,0为正,1为负。

(2)浮点数家族:只要是表示小数就可以使用浮点数。

float 单精度 精度低 存储的数据范围小。

double 双精度 精度高 储存的数据范围大。

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

①数组类型(创建不同数据类型和不同个数的数组)

②结构体类型 struct

③枚举类型 enum

④联合类型 union

(4)指针类型 int* char* float* void*

(5)空类型 void 表示空类型(无类型)

通常用于函数的返回类型、函数的参数、指针类型。

例如: void teat(void) 第一个void表示函数不会返回值,第二个void表示函数不需要任何参数(只能起到提示作用,不能防止)

2.整型在内存中的存储

之前我们了解过数据有不同的表示形式,二进制、十进制、八进制、十六进制等。例如在十进制的21 二进制:10101 八进制:25 十六进制:15。

2.1整数的二进制也有三种表示形式:原码、反码、补码

三种表示形式的规则:①正数的原码、反码、补码相同;②负数需要通过计算得出。

计算规则:

原码:直接通过正正负形式写出二进制序列。

反码:原码符号位不变,其他按位取反得到的二进制序列。

补码:在反码的基础上加1。

以下面的代码为例:

cs 复制代码
#include<stdio.h>
int main()
{
	int a = 20;
	//原码、补码、反码:00000000 00000000 00000000 00010100
	//转为十六进制:  0x 00 00 00 14
	int b = -10;
	//原码:10000000 00000000 00000000 00001010
	//十六进制:0x 80 00 00 0a
	//反码:11111111 11111111 11111111 11110101
	//十六进制:0x ff ff ff f5
	//补码:11111111 11111111 11111111 11110110
	//十六进制:0x ff ff ff f6 
	return 0;
}

在调试下查看内存存储的信息:

变量a在内存中的存储:

变量b在内存中的存储:

根据上面可以看出,在计算机系统中,整型数值一律用补码来表示和存储。

原因:使用补码可以将符号位和数值域统一处理,这可以使加、减法可以统一处理(补码的加减分都可以统一使用加分完成,CPU只有加法器),此外,补码与原码互相转换,其运算过程是相同的,不需要额外的硬件电路(原码和补码之间的相互转换都可以通过取反加1得到)

数据存储的顺序不对劲,为什么?

2.2 大小端介绍(大小端取决于硬件)

大端(字节序)储存:是指数据的低位保存在内存的高地址中,而数据的高位保存在内存的低地址中(补码正着存)。

小端(字节序)存储:是指数据的低位保存在内存的低地址中,而数据的高位保存在内存的高地址中(补码倒着存,如上数据存储)。

相关试题:百度2015试题:解释大小端的区别,并用一个程序判断用的是大端还是小端存储?

版本一:将int*类型的指针强制转换成char*类型指针

cs 复制代码
#include<stdio.h>
int main()
{
	int a = 0;
	if (*(char*)&a == 1)
	{
		printf("小端\n");
	}
	else
	{
		printf("大端\n");
	}
	return 0;
}

版本二:封装成一个函数

cs 复制代码
#include<stdio.h>
int test_dxd(void)
{
	int a = 1;
	return *(char*)&a;
}
int main()
{
	int ret = test_dxd();
	if (ret == 1)
	{
		printf("小端\n");
	}
	else
	{
		printf("大端\n");
	}
	return 0;
}
相关推荐
飞机和胖和黄1 小时前
考研之C语言第二周作业
c语言·开发语言·考研
二年级程序员2 小时前
自定义类型:结构体
c语言
多米Domi0112 小时前
0x3f 第42天 复习 10:39-11:33
算法·leetcode
thubier(段新建)2 小时前
单招模考试卷模型思考(1)
算法·单招
议题一玩到2 小时前
#leetcode# 1984. Minimum Difference Between Highest and Lowest of K Scores
数据结构·算法·leetcode
czy87874752 小时前
LwIP 协议栈核心.c 文件依赖关系图
c语言·网络·单片机
是娇娇公主~2 小时前
算法——【最长回文子串】
c++·算法
你撅嘴真丑2 小时前
计算2的N次方 和 大整数的因子
数据结构·c++·算法
孞㐑¥2 小时前
算法—前缀和
c++·经验分享·笔记·算法