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;
}
相关推荐
OpenApi.cc9 小时前
神经网络结构驱动+数据结构分析
数据结构·人工智能·神经网络
菜菜的顾清寒10 小时前
力扣HOT100(42)链表-随机链表的复制
算法·leetcode·链表
lqqjuly10 小时前
模型剪枝与稀疏化:理论、算法与可运行实现
人工智能·算法·剪枝
逻辑君10 小时前
Foresight研究报告【20260011】
人工智能·线性代数·算法·矩阵
珊瑚里的鱼10 小时前
【动态规划】不同路径Ⅱ
算法·动态规划
星恒随风10 小时前
C语言数据结构排序算法详解(下):冒泡排序、快速排序、归并排序和计数排序
c语言·数据结构·笔记·学习·排序算法
适应规律11 小时前
【无标题】
人工智能·python·算法
Rain50911 小时前
mini-cc 的 MCP 协议:给 AI 装个 USB-C 接口
c语言·开发语言·前端·人工智能·架构·node.js·ai编程
蒟蒻的贤11 小时前
关于文法G2算符优先分析的一个坑
算法
变量未定义~11 小时前
单调栈、单调队列(模板)、子矩阵、连通块中点的数量、堆箱子(4星)
算法