IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C语言进阶1. 数据在内存中的存储+指针数组解释 -> 正文阅读

[C++知识库]C语言进阶1. 数据在内存中的存储+指针数组解释

预备:局部变量存在栈区,且使用习惯:先高地址再低地址,且数组随着下标的增长,地址也由低到高
请添加图片描述
之前的死循环代码,Release版本下,代码会被直接一次性执行完,没有死循环要暂停,system(""pause),因为代码被优化了
因为在release版本下,代码中变量的存储顺序有改变,i先创建,但在更低的地址,而arr地址在i上面,所以没有死循环
请添加图片描述

所以release版本可能运行有BUG,但你在debug下测说没问题,因为可能版本不一样

数据在内存中的存储

  • 数据类型:内置类型、自定义类型
  1. 内置:
    float f = 0.0;
    int a = 0;
    不同类型的意义:开辟空间大小不一样、内存中看待这两个0的视角不一样(内存中所存不一样,不是全0)
  • 整型(分有符号和无符号):char(也算整型,一个字节,8bit)、short、int、long
    比如char:unsigned char(最高位是符号位)、signed char
    char到底是signed char还是unsigned char是不确定的取决于编译器的实现
    char大部分是signed char
    比如 short int a= 10; 中 int 可省略,short和int默认是有符号的int
    short是2字节
  • 浮点类型: float、double都是小数,没有符号区别
  • 自定义类型(构造类型):
    数组类型、结构体类型(struct)、枚举(enum)、联合(union)
    指针类型:** void* p (无类型指针)**
    空类型:void表示空类型(无类型),用于函数返回类型、函数参数、指针类型
    =====================================
    整型在内存中的存储

数据内存中存的是2进制,vs在展示内存为方便,显示的是16进制
且内存中是倒着存的
请添加图片描述

内存中数字存储有三种:原(正数没有反码)、反(负数反码不反符号位)、补(反最低+1),且都有符号位。负数的原、补不一样

必须知道,内存中所存为二进制形式
内存中做减法,其实是做(补码)正+(补码)负,如果用两个原码加,结果不对,于是发明了补码
做1+(-1)补码结果为1+032,会丢符号位 ->032,正好结果为0

用补码计算可以计算减法,且方便符号位(符号)计算,所以计算机内存中都用补码,使得数值域和符号可以统一处理,其实补码取反加1,也得到原码

  • 范围:要分有符号和无符号
    比如char有8位:如果是signed char :1+07 = 128(直接规定)
    -128~127,正数第一位必为0,因为需要一位标记符号,不存在说正数就比负数多一位去存储值了, 01111111(7)是最大正数,即:0+1
    7最大
    如果无符号(必然无负数,从0开始) 0~255
    unsigned short n = 0; // 0~65535
    signed short m = 0; //-32768~32767
解释数值在内存倒着存的原因

大小端字节序
大端字节序存储(看着正常):把一个数的低位字节序内容放在高地址处,高位字节序内容放在低地址处。
小端存储(逆序的): 把数的低位放在低,高位放在高
当前visual 用的是小端
请添加图片描述

有大端和小端的原因是因为在计算机系统中,以字节为单位,每个地址单元对于一个字节,因为存在多字节安排问题,所以需要大端存储模式和小端存储模式
00 00 00 01
大:00 00 00 01
小:01 00 00 00
经典百度面试题
简述大端字节序和小端字节序概念,设计小程序判断机器字节序:
思路:对比第一个字节
就用1来判断,大小端时的高位不同
00 00 00 01
大端:00 00 00 01
小端:01 00 00 00
要判断第一个字节的内容
拿char指针看这个第一位?
char 取低地址,从左向右从低到高,大端中低是00,小端中低是01
某类型的指针指向其它类型时候,右边需要强制转化
解引用大小为1字节

int a = 1;
char* p = (char*)&a; // int*
// *p本质是数字
// 因为p是char,解引用拿第一个字节地址,所以通过第一个字节地址判断
if(*p==1)
{
	printf("小端");
}

 判断机器是大端存储还是小端存储, 简单写法和普通写法
int check_sys()
{
	int a = 1;
	char* ret = (char*)&a;
	if (*ret == 1)
	{
		printf("小端");	//	*char第一个字节
	}
	else
	{
		printf("小端");
	}
	return 0;
}

// 简易版
int check_sys()
{
	int a = 1;
	return (* (char*)&a);
}

读代码题

char a = -128;
printf("%u", a);

char a = -128; 首先写-128原码
内存中读-128是个整型,用32位存
10000000 00000000 00000000 10000000 把它存入内存是补码
111111111 111111111 111111111 011111111(反)
111111111 111111111 111111111 10000000(+1得补码)
用char接收 只能存8位,存后8:10000000
而打印的时输出%u:无符号整型,是整型:所以有32位
整型提升:有符号就补符号位1,结果是无符号整型,直接计算
111111111 11111111 11111111 10000000 是最终结果
然后求它的值:
2^32 - 128

我错在了:输出上,转为无符号整型,要取32位,补最高位1

读代码题

char a = 128;
printf("%u", a);

128就是10000000。
放到char中时,a = 10000000
转无符号整型,而a是char,char默认有符号,补最高位:1
所以又成了上面的结果

读代码题

int i = -20;
unsigned int j = 10;
printf("%d\n", i + j);

10000000 00000000 00000000 0001 0100
111111111 111111111 111111111 1110 1011 (反码)
111111111 111111111 111111111 1110 1100(补码)
00000000 00000000 00000000 0000 1010 (10的补码即原码)
111111111 111111111 111111111 1111 0110 (补码转回去)

111111111 111111111 111111111 1111 0101
10000000 00000000 00000000 0000 1010

我犯的错:对于10,明明是正数,求出原码即是补码,我又多做了两步
结果:10

内存中的数据理解
  • 整型:
    unsigned int i;
    无符号整型数据永远不会小于0,拿它做循环变量,不可以,因为减到0,以后,它再减,又会变得很大。0的补码是0,而减去1是2的32次-1。
    请添加图片描述
    -128:1000 0000 1+0*7
    -129放不下
    char类型取值范围:-128~127
    -128:1000 0000,减1 -> 0111 1111,成了127,继续减成了126…1…0
    128+127=253

unsignedchar只有8位,无符号最大为255,加到255为1111 1111
此时再加1,会成为0
i永远在0~255范围,所以死循环

在这里插入图片描述

  • 浮点数在内存的存储
    整型家族的范围定义都在->limits.h中
  • float.h中定义范围:float.h

请添加图片描述
分析:
n是整型,地址是int*,所以把地址给float需要强制转化
float解引用,float也是4字节,解引用能拿到4字节
X: n:9, pf:9, n9 , pf:9.0
正确结果:
请添加图片描述
显然,float和int类型在内存中不一样,
前两行:以整型存到float中,以%d拿出来本身n,还不变,但以float拿出来,结果不一样,说明内存中不一样。
后两行:正常float读、取

============
内存中存float
5.5存float:先转2进制
1 0 1 . 1 1 1
2^2 2^1 2^0 2^-1 2^-2 2^-3
小数点后第n位是2的负n次
2^-1 = 0.5
=> 101.1 => 1.0112^2
请添加图片描述
解读第一行: -1^S
… 正数让这里为1,负数为-
float实际存储: 按规定存,最后分别拿出求最终
请添加图片描述
请添加图片描述

float存时(double也类似),都是1.几,因为都化为1.几,所以不存1.,有效数m只存小数点后面,读取时再加1.,而指数e:它是无符号整数,但是科学计数法规定e可以是负数,所以存入内存E必须加一个中间数,而读取取出时,再减去中间数
请添加图片描述
比如5.5f:
101.1
1.011*2^2
(-1)^0 * 1.011 *2 ^2
最高位符号位:0,幂e存e+127 即129(可以用8位),存m,省略整数1.,存 011 ,后面全补0
0 (1000 0001) (011 000000000)
0100 0000 1011 0000 0000 0000 0000 0000
40 0b 00 00
小端模式:逆着存,如下图右侧
请添加图片描述
当e不全为0或不全为1,就按上面
当e全为0:e=1-127,有效位不加第一位的1,还原为0.xxx,这样表示非常接近0的数字
当e全为1:下图
请添加图片描述

=再分析开始问题==
请添加图片描述
把int型的n的补码0 0000000 000000000000001001放入float中,解引用float,会认为这串是浮点数按浮点数的规则解析,高位0 (s),e中全0(第二种特殊情况)指数等于1-127 再加后面的0.000000000001001,后面本来就很小,再乘以2^-126,接近0。
而第三行*pf=9.0就按float规则存,按整型的二进制读出来,得到很大的值,第四行以float读,当然是本身9.0
请添加图片描述
short是两个字节
回忆:每当用不同类型指针接收其它类型地址时,需要先强制转换,且这样之后的引用因为步长大小可能不一致,会造成不能修改或访问到全部原始地址中数据

=====================================

分析:
因为是小端,char *pc 拿到低地址的44
*pc = 0,44位置为0
最后输出%x(c语言以16进制输出) : 0x11223300
请添加图片描述
指针数组

请添加图片描述

A. int* arr是个指针,加了[]就是指针数组,所以对
数组创建不给大小说明有初始化,但是B都没初始化
C是二级指针
D是数组指针,*和arr结合是数组,这是指向数组的指针

char初始化、接收
int main()
{
// char数组用0来初始化
char arr[100] = {0};
scanf(“%s”, arr);
strlen(); // strlen()字符串数组求长度在函数内可以,需要传入指针,而整型数组需要传长度
//
return 0;
}

回调函数

qsort():
第1个参数 void* p,无类型指针,不能解引用,所以在函数写的时候,一般要把它强制转换
第4个参数解释:不同类型的比较方法不一样,所以需要自己手动定义

void *用法:可以接收任何类型,作用就是为了接收任意类型地址
不能±指针,因为不知道指针所存数据大小

结构体指针,解引用, p->name
字符串比较字典序:strcmp();

=写一个回调函数=
参数中有函数指针,初始时候,要用什么函数,这个回调函数的参数:函数指针处传什么函数。
冒泡排序:

智力题:

  1. 烧香:
    两根香,一根点一端,另一根点两端,两端燃完30分,另一根差30分,这时把它两端都点着
  2. 坐电梯
    电梯有人和下雨天坐到32,没人坐到10楼,爬上去?
  3. 下水道井盖是圆的
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-05-24 17:55:54  更:2022-05-24 17:58:21 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/13 16:41:09-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码