C语言笔记(数据的存储篇)

目录

1.数据类型的详细介绍

2.整型在内存中的存储:原码、反码、补码

3.大小端字节序介绍及判断

4.浮点型的内存中的存储解析


1.数据类型的详细介绍

下述是内置类型:

char      // 字符数据类型
short     //  短整型
int       //  整型
long      // 长整型
long long //  更长的整型
float     // 单精度浮点型
double    //双精度浮点型

        在这里就不说不同数据类型在内存中所占数据类型大小了。注意的是C语言中的没有字符串的数据类型

数据类型的意义

1.使用数据类型开辟内存空间的大小;

2.如何看待内存空间的视角。

整形家族:

char
unsigned char     //字符在存储的时候存储的是ASCLL码值A,ASCLL是整数,
signed char       //所以在归类的时候,字符属于整型家族short
unsigned short [int]
signed short [int]int
unsigned int
signed intlong
unsigned long [int]
signed long [int]      //[]中的数据类型是可以省略的

        注意, char是signed char还是unsigned char 是取决于编译器的。常见的编译器上char的类型就是signed char。

        数据元素个数和数组的名字发生变化,数组的类型也会发生变化。

        浮点数家族:

float
double

        构造类型

> 数组类型
> 结构体类型 struct
> 枚举类型 enum
> 联合类型 union

        指针类型

int *pi;
char *pc;
float* pf;
void* pv;

        void  表示空类型以为就是没有什么类型,可以用于函数的返回类型、函数的参数、指针类型。

2.整型在内存中的存储:原码、反码、补码

        正整型的原反补码都是相同的,但负整型数据的反码要符号位不变其他位置取反,加上1就会变成补码,如下 : 补码也可以先取反再+1得到原码。负整型补码转变成原码有两种方式。

-1//32位机器
原码 10000000 00000000 00000000 00000001
反码 11111111 11111111 11111111 11111110
补码 11111111 11111111 11111111 11111111补码转原码
//方式1
补码 11111111 11111111 11111111 11111111
反码 11111111 11111111 11111111 11111110 -1
原码 10000000 00000000 00000000 00000001 取反//方式2
补码 11111111 11111111 11111111 11111111
中间 10000000 00000000 00000000 00000000 取反
原码 10000000 00000000 00000000 00000001 +1

        整形数据在内存中是以二进制补码的形式来存放的。本例子列举的是32位机器中的存储。

int a = 20;// 20
// 00000000 00000000 00000000 00010100--原码
// 00000000 00000000 00000000 00010100--反码
// 00000000 00000000 00000000 00010100--补码
// 0x00 00 00 14   转换成16进制  在看看存储int b= -10;
//  -10
// 10000000 00000000 00000000 00001010--原码
// 11111111 11111111 11111111 11110101--反码
// 11111111 11111111 11111111 11110110--补码
// 0xff ff ff f6  转换成16进制

int a = 20;在VS2017下的存储方式

int b = -10;在VS2017下的存储方式

例题,下属例题都是判断输出什么的

1.  

#include <stdio.h>
int main()
{char a = -1;//10000000 00000000 00000000 00000001 原码//11111111 11111111 11111111 11111110 反码//11111111 11111111 11111111 11111111 补码//11111111 截断,将一个整型数值赋予一个字符变量的时候要截断//11111111 11111111 11111111 11111111 补码// 因为要输出的是整型,应该整型提升,有符号位置应该按照符号位来提升 1 补1 0补0//10000000 00000000 00000000 00000000  取反//10000000 00000000 00000000 00000001  原码signed char b = -1;//和上面相同//10000001 unsigned char c = -1;//10000000 00000000 00000000 00000001 原码//11111111 11111111 11111111 11111110 反码//11111111 11111111 11111111 11111111 补码//11111111                            截断//00000000 00000000 00000000 11111111 //整型提升 无符号为整型提升 补0//存储方式是一样的,但输出的方式是不一样的 printf("a=%d,b=%d,c=%d", a, b, c);  // -1 ,-1,255return 0;
}

2.

#include <stdio.h>
int main()
{char a = -128;
//10000000 00000000 00000000 10000000  原码
//11111111 11111111 11111111 01111111  反码
//11111111 11111111 11111111 10000000  补码
//截取 10000000
//整型提升 看char是有符号的char 整型提升是看原来的数据类型来提升的
//11111111 11111111 11111111 10000000  //输出的是无符号数,可以直接输出,无符号数只有正的printf("%u\n", a);// 4294967168return 0; 
}

3.

int main()
{char a = 128;// 00000000 00000000 00000000 10000000// 10000000 截断// 11111111 11111111 11111111 10000000 整型提升printf("%u\n", a);return 0;
}

4.

int main()
{int i = -20;//10000000 00000000 00000000 00010100 原码//11111111 11111111 11111111 11101011 反码//11111111 11111111 11111111 11101100 补码unsigned  int  j = 10;//00000000 00000000 00000000 00001010 原码 补码//11111111 11111111 11111111 11110110//10000000 00000000 00000000 00001001//10000000 00000000 00000000 00001010 //-10printf("%d\n", i + j);//-10 //输出的形式有符号数 相加之后本来是无符号数的return 0;
}

5.

#include <stdio.h>
#include <windows.h>
int main()
{unsigned int i;for (i = 9; i >= 0; i--) //会无限制的循环,i不可能是负数的,因此会一直大于0{printf("%u\n", i);Sleep(100);} return 0;
} //可以执行一下 从零之后就是一个更大的数字了

6

#include <stdio.h>
int main()
{char a[1000];int i;for (i = 0; i < 1000; i++){a[i] = -1 - i; }//-1 -2 .......-128 127 126 3 2 1 0 128+127=255printf("%d", strlen(a)); //找到'\0' 其ASCLL码值为 0 找到0 return 0;
}

7.

#include <stdio.h>
unsigned char i = 0;
int main()
{for (i = 0; i <= 255; i++){printf("hello world\n");//死循环}return 0;
}

循环限制条件是无符号数,是一定要注意,设置的限制条件一定要大于0。

3.大小端字节序介绍及判断

        大端(存储)模式,是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中;
        小端(存储)模式,是指数据的低位保存在内存的低地址中,而数据的高位,,保存在内存的高地址中。

        为什么会存在大端存储和小端存储呢?

        其思想源于格列夫游记,两个国家由于鸡蛋应该是先从大头剥还是从小头处开始剥皮的问题开始了战争。   

        小端存储,举一个例子,下面是一个数

int a = 0x11223344;

     下面就是数据在VS2017的存储方式。

        数据的低位应该是这样理解的,123 3就是这个数据的低位。看数据的低位放在了低地址上,数据的高位放在了高地址上。

做个表格详细了解一下

地址0x007EFBFC0x007EFBFD0x007EFBFE0x007EFBFE
小端存储44332211
大端存储11223344
低地址高地址

        我们再写一个小程序来判断一个编辑器是大端存储还是小端存储。

#include <stdio.h>
int main()
{int a = 1;//存储方式是 0x00 00 00 01  如果只取一个字节就比较好判断了char *pa = (char *)&a;//()括号中的强制类型转化if (*pa == 1){printf("小端存储\n");}else{printf("大端存储\n");}return 0;
}

        还可以将这个逻辑封装到一个函数中,大家可以练习一下,在以后的时候中好的函数是经常调用的。

封装函数

void  check_byte()
{int a = 1;if ((char *)&a)printf("小端存储\n");elseprintf("大端存储\n");
}

4.浮点型的内存中的存储解析

        大家想一下 3.14159, 1E10.在内存中是如何存储的?当然和整型是不一样的。先看下面的例子。

int main()
{
int n = 9;
//00000000 00000000 00000000 00001001
float *pFloat = (float *)&n;
printf("n的值为:%d\n",n);
printf("*pFloat的值为:%f\n",*pFloat);
//以浮点数的存储方式取出是不正常值,两者存储的方式是不一样的,*pFloat = 9.0;
printf("num的值为:%d\n",n);
printf("*pFloat的值为:%f\n",*pFloat);
return 0;
}

        以下是上述代码的值,可以往后看看浮点型是如何存储的就理解了,在文章的最后会有解析的。

       浮点数的存储规则

        根据国际标准IEEE(电气和电子工程协会) 754,任意一个二进制浮点数V可以表示成下面的形式:

>. (-1)^S * M * 2^E
>. (-1)^s表示符号位,当s=0,V为正数;当s=1,V为负数。
>. M表示有效数字,大于等于1,小于2。
>. 2^E表示指数位

        举个例子就明白了,

将十进制的 5.0   1> 转换成二级制101.1,相当都1.01×2^2

按上述的格式就是 S=0,表示正数;M=1.01,E=2。如果是-5的话那就是S=-1了。

 再来一个 5.5= 101.1二进制  , 转换成科学计数法 1.011*2^2    (-1)^0*1.011*2^2

S=0, M=1.011, E=2。 0.5 大家思考一下  注意一下(浮点数中没有原反补的概念)

单精度浮点数存储模型(4byte)

双精度浮点型(8byte)

特殊规定

      1. M值的存储方式

        前面说过, 1≤M<2 ,也就是说,M可以写成 1.xxxxxx 的形式,其中xxxxxx表示小数部分。IEEE 754规定,在计算机内部保存M时,默认这个数的第一位总是1,因此可以被舍去,只保存后面的xxxxxx部分。 (此种方式可以提升精度)

        比如保存1.01的时候,只保存01,等到读取的时候,再把第一位的1加上去。这样做的目的,是节省1位有效数字。以32位浮点数为例,留给M只有23位,将第一位的1舍去以后,等于可以保存24位有效数字。

        2. E的存储方式      

        E为一个无符号整数是无法判读E是正负的。如果E为8位,它的取值范围为0~255;如果E为11位,它的取值范围为0~2047。但是科学计数法中的E是可以出现负数的,所以IEEE 754规定,存入内存时E的真实值必须再加上一个中间数,对于8位的E,这个中间数是127;对于11位的E,这个中间数是1023。比如,2^10的E是10,所以保存成32位浮点数时,必须保存成10+127=137,即10001001。

        指数E从内存中中取出还可以再分为三种情况

        1.E不全为0或者不全为1

这时,浮点数就采用下面的规则表示,即指数E的计算值减去127(或1023),得到真实值,再有效数字M前加上第一位的1。 比如: 0.5(1/2)的二进制形式为0.1,由于规定正数部分必须为1,即将小数点右移1位,则为1.0*2^(-1),其阶码为-1+127=126,表示为01111110,而尾数1.0去掉整数部分为0,补齐0到23位00000000000000000000000,则其二进制表示形式为:

0 01111110 00000000000000000000000

        2.E全为0

        这时,浮点数的指数E等于1-127(或者1-1023)即为真实值, 有效数字M不再加上第一位的1,而是还原为0.xxxxxx的小数。这样做是为了表示±0,以及接近于0的很小的数字。

        3.E全为1

        这时,如果有效数字M全为0,表示±无穷大(正负取决于符号位s).

实际的例子 

5.5

float f = 5.5f;// 转换成SME的形式 (-1)^0 * 1.011 * 2^2//S = 0;M = 1.011; E = 2; 2+127=129//0 10000001 01100000000000000000000//0100 0000 1011 0000 0000 0000 0000 0000// 4    0    b    0    0    0    0    0

4.小节开始的例题

#include <stdio.h>
int main()
{int n = 9;float *pFloat = (float *)&n;//00000000 00000000 00000000 00001001//0 00000000 0000000 00000000 00001001//(-1)^0 * 0.00000000000000000001001 * 2^-126 相当于0了printf("n的值为:%d\n", n);printf("*pFloat的值为:%f\n", *pFloat);*pFloat = 9.0;//9.0的存储方式//1001二级制 1.001^3 3+127=130//0 1000 0010 00100000000000000000000//01000001000100000000000000000000 存储方式printf("num的值为:%d\n", n);printf("*pFloat的值为:%f\n", *pFloat);//1,091,567,616return 0;
}

        由于存储方式的不同和访问方式的不同,会造成数据错误。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/56670.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL-事务Transaction详解

文章目录 事务概述事务基本概念事务四大特性(ACID)演示MySQL事务手动开启事务MySQL默认事务机制 事务的隔离级别隔离级别基本概述三种现象脏读不可重复读幻读 查看和设置隔离级别四种隔离级别及演示读未提交(read uncommitted)读提交(read committed)可重复读(repeatable read)…

sql-labs靶场第十八关测试报告

目录 一、测试环境 1、系统环境 2、使用工具/软件 二、测试目的 三、操作过程 1、寻找注入点 2、注入数据库 ①寻找注入方法 ②爆库&#xff0c;查看数据库名称 ③爆表&#xff0c;查看security库的所有表 ④爆列&#xff0c;查看users表的所有列 ⑤成功获取用户名…

用Spring AI 做智能客服,基于私有知识库和RAG技术

Java智能客服系统运用RAG技术提升答疑精准度 基于Spring ai 的 RAG&#xff08;检索增强生成&#xff09;技术&#xff0c;Java智能客服系统能够利用私有知识库中的信息提供更准确的答疑服务。 它的核心思路是&#xff1a; 首先&#xff0c;将客服QA以Word形式导入到系统中&…

基于FreeRTOS的LWIP移植

目录 前言一、移植准备工作二、以太网固件库与驱动2.1 固件库文件添加2.2 库文件修改2.3 添加网卡驱动 三、LWIP 数据包和网络接口管理3.1 添加LWIP源文件3.2 Lwip文件修改3.2.1 修改cc.h3.2.2 修改lwipopts.h3.2.3 修改icmp.c3.2.4 修改sys_arch.h和sys_arch.c3.2.5 修改ether…

量子门电路开销——T门、clifford门、toffoli门、fredkin门

在量子计算中&#xff0c;T门的成本比Clifford门高出很多倍的原因与量子计算中纠错的实现、物理门操作的复杂性以及容错量子计算架构中的成本评估有关。以下是几个关键原因&#xff0c;解释了为什么 T 门的成本在量子计算中远远高于 Clifford 门&#xff1a; 1. T 门和 Cliffo…

录微课专用提词器,不会被录进视频中的提词器,还能显示PPT中备注的内容

不坑提词器&#xff0c;全称&#xff1a;不坑隐形提词器。是一款能够在截图、录屏、直播过程中隐藏界面的提词器软件。 系统要求&#xff1a;Win10 1024 以上&#xff08;特别提醒&#xff1a;Win7状态下不可隐身&#xff09; ⏬下载 提词器默认放在不坑盒子的安装目录下&…

百易云资产管理运营系统 ufile.api.php SQL注入漏洞复现

0x01 产品描述&#xff1a; 百易云资产管理运营系统&#xff0c;是专门针对企业不动产资产管理和运营需求而设计的一套综合解决方案。该系统能够覆盖资产的全生命周期管理&#xff0c;包括资产的登记、盘点、评估、处置等多个环节&#xff0c;同时提供强大的运营分析功能&#…

SQL Injection | MySQL 手工注入全流程

0x01&#xff1a;MySQL 手工注入 —— 理论篇 手工注入 MySQL 数据库&#xff0c;一般分为以下五个阶段&#xff0c;如下图所示&#xff1a; 第一阶段 - 判断注入点&#xff1a; 在本阶段中&#xff0c;我们需要判断注入点的数据类型&#xff08;数字型、字符型、搜索型、XX 型…

【星闪技术】WS63E模块的WiFi客户端测试

引言 我所计划的WS63E测试要实现MQTT联网&#xff0c;所以首先需要确保开发板连接WiFi。今天来测试一下WiFi功能。 程序分析 WiFi客户端的例子在src/application/samples/wifi/sta_sample目录下。这个例子看上去和hi3861的例子差不多。 这段程序是一个用于嵌入式设备的Wi-F…

国产AI逆袭!零一万物新模型Yi-Lightning超越 GPT-4o

近日&#xff0c;由全球千万用户盲测投票产生的 AI 模型排行榜公布&#xff0c;国产 AI 模型“Yi-Lightning”逆袭&#xff0c;超越了此前长期占据榜首的 GPT-4。 “Yi-Lightning”模型由国内知名 AI 公司零一万物研发&#xff0c;在多个分榜中均名列前茅&#xff0c;其中数学…

HDU RSA

翻译成中文后&#xff1a; 思路&#xff1a;由题易得&#xff0c;d * e y * f ( n ) 1 ,且gcd ( e , f ( n ) ) 1,所以用扩展欧几里得求出 d &#xff0c;但要保证 d 是非负的&#xff0c;最有用快速幂求出每个字符即可。 #include<bits/stdc.h> using namespace std;…

HTML5教程(二)- HTML语法及基本结构

1. 介绍 HTML 超文本标记语言&#xff08;HyperText Markup Language&#xff09;浏览器能够识别和解析的语言&#xff0c;通过标签的形式构建页面结构和填充内容&#xff08;用来描述网页的语言&#xff09;。HTML 不是一种编程语言&#xff0c;而是一种标记语言&#xff08;是…

基于SpringBoot+Vue+uniapp微信小程序的教学质量评价系统的详细设计和实现

项目运行截图 技术框架 后端采用SpringBoot框架 Spring Boot 是一个用于快速开发基于 Spring 框架的应用程序的开源框架。它采用约定大于配置的理念&#xff0c;提供了一套默认的配置&#xff0c;让开发者可以更专注于业务逻辑而不是配置文件。Spring Boot 通过自动化配置和约…

决策树(1)

原理 基础概念 决策树属于判别模型。 决策树算法属于监督学习方法。 决策树是一种树状结构&#xff0c;通过做出一系列决策&#xff08;选择&#xff09;来对数据进行划分&#xff0c;这类似于针对一系列问题进行选择。 决策树的决策过程就是从根节点开始&#xff0c;测试待分…

UNION 联合查询

1.UNION ALL联合查询 同样为了演示方便&#xff0c;先向 teacher 表插入多条测试数据&#xff1a; INSERT INTO teacher (name,age,id_number,email) VALUES (姓名一,17,42011720200604077X,NULL), (姓名二,18,42011720200604099X,123qq.com), (姓名三,19,42011720200604020X…

007、链表的回文结构

0、题目描述 链表回文结构 1、法1 一个复杂的问题可以拆解成几个简单的问题&#xff0c;找中间节点和逆置链表&#xff08;翻转链表&#xff09;之前都做过。 class PalindromeList { public://1、找中间节点ListNode* FindMid(ListNode* A){if (A nullptr || A->next …

流程图 LogicFlow

流程图 LogicFlow 官方文档&#xff1a;https://site.logic-flow.cn/tutorial/get-started <script setup> import { onMounted, ref } from vue import { forEach, map, has } from lodash-es import LogicFlow, { ElementState, LogicFlowUtil } from logicflow/core …

Jmeter监控服务器性能

目录 ServerAgent 安装 打开Jmeter ServerAgent 在Jmeter上监控服务器的性能比如CPU&#xff0c;内存等我们需要用到ServerAgent&#xff0c;这里可以下载我分享 ServerAgent-2.2.3.zip 链接: https://pan.baidu.com/s/1oZKsJGnrZx3iyt15DP1IYA?pwdedhs 提取码: edhs 安装…

FPGA图像处理之均值滤波

文章目录 一、什么是图像滤波&#xff1f;1.1 噪声类型1.2 滤波类型 二、均值滤波原理2.1 3*3窗口滑动过程2.2 图像扩展 三、Matlab实现均值滤波四、FPGA实现均值滤波4.1 生成 3*3 矩阵4.2 仿真3*3矩阵4.3 计算均值4.4 仿真均值滤波 一、什么是图像滤波&#xff1f; 图像滤波是…

得物App3D创新应用引关注,世界设计之都大会启幕

近日&#xff0c;2024世界设计之都大会&#xff08;WDCC&#xff09;在上海盛大启幕。此次大会以“设计无界 新质生长”为主题&#xff0c;汇聚了全球设计领域的精英与前沿成果&#xff0c;展现了设计作为新质生产力的巨大潜力。主场展览占据了整整3个楼面&#xff0c;总面积达…