C++字节存储方式和reinterpret_cast
数据存储方式和数据类型
变量
变量可以认为是一个内存块,该内存块中存放了变量的二进制表示格式。其实,汇编语言中,没有变量类型的概念,而在C等静态高级语言中,都有变量类型的概念。
1字节 = 1B = 8bit = 2^8 => 0-256
所以ASCII
标准字符有256个,sizeof(int) = 4
,因此int
最大是2(8×4−1)2^{(8 \times 4 - 1)}2(8×4−1),-1
是因为有符号位
可以这么理解,变量类型只是程序员告诉编译器变量的表示方式;而最终的汇编形式,仍然是没有数据类型的。我们的一些操作,需要变量类型,因为编译器需要根据变量的类型,完成与该类型有关的操作,比如int
赋值、加减乘除和比较大小等,都是4个字节的操作等。
可以这么理解,变量类型相当于一个操作协议,凡是同一种类型,都可以进行该类型协议的操作,保证操作的正确性。程序定义好类型之后,就可以按照类型,来执行符合类型的操作。
比如有结构体:
struct S {int a;char b;
};
该结构体的sizeof(S)
是8,因为int
有4个字节,char
有1个字节,但是编译器会有align
操作,以满足快速读取的需求,4 + 1 = 5,最接近8=2^3,因此是8字节。
因此,只要有一个足够内存,我们就可以直接序列化该结构体,然后写入即可。一般来说,连续的内存用char*
来表示。见下文序列化实例。
指针
指针用来表示一段地址,64位系统中,指针都是8字节长度,可以指向任意地方。同样的,指针的类型,意义仅仅是为了在语言级别限制操作等。指针可以类型转换,转换之后就可以指向不同的地址了。不过,这么做代表了操作的转变,还是谨慎些。void*
可以被任何指针指向。
函数
函数指针,仅仅表示一个代码段的执行起始地址。
测试代码实例
以下代码说明了数据格式转化的本质,注意字符串的内存布局。假设有字符串"abc",则内存的表示是:
a 97 b 98 c 99
01100001 | 01100010 | 01100011
而每个字符是从右往左计算,注意0补位
#include <cstdio>
#include <cstdlib>
#include <strings.h>template<typename T>
size_t serialize(const T& obj, char* buf, size_t len) {if (len < sizeof(obj)) {return -1;}*reinterpret_cast<T*>(buf) = obj;return sizeof(obj);
}template<typename T>
size_t deserialize(T& obj, char* buf, size_t len) {if (len < sizeof(obj)) {return -1;}obj = *reinterpret_cast<T*>(buf);return sizeof(obj);
}struct S {int a;char b;char str[100];int arr[10];
};void printS(const S& s) {printf("%d\n", s.a);printf("%d\n", s.b);printf("%s\n", s.str);for (int i = 0; i < sizeof(s.arr) / sizeof(int); i++) {printf("%d ", s.arr[i]);}printf("\n");
}int main() {printf("basic test =================\n");S s1;bzero(&s1, sizeof(s1));s1.a = 10;s1.b = 's';sprintf(s1.str, "hello world! This is a data type test");for (int i = 0; i < 10; ++i) {s1.arr[i] = i;}int N = 256;char buf[N];size_t ret = serialize(s1, buf, N);printf("serialize ret = %d\n", ret);S s2;ret = deserialize(s2, buf, N);printf("deserialize ret = ", ret);printS(s2);printf("\npointer test =================\n");int* a = (int*)malloc(sizeof(int));*a = 100;char* b = (char*)a;printf("%d %d\n", *a, *b);printf("%c\n", *a);bzero(buf, N);sprintf(buf, "aaaa");typedef long long LL;int* num;num = (int*)buf;printf("%d\n", *num);return 0;
}
最终输出:
basic test =================
serialize ret = 148
deserialize ret = 10
115
hello world! This is a data type test
0 1 2 3 4 5 6 7 8 9pointer test =================
100 100
d
1633771873
C++字节存储方式和reinterpret_cast相关推荐
- iOS开发系列--C语言之存储方式和作用域
概述 基本上每种语言都要讨论这个话题,C语言也不例外,因为只有你完全了解每个变量或函数存储方式.作用范围和销毁时间才可能正确的使用这门语言.今天将着重介绍C语言中变量作用范围.存储方式.生命周期.作用 ...
- 22.25在计算机中如何储存,浮点数在计算机中存储方式
C语言和C#语言中,对于浮点类型的数据采用单精度类型(float)和双精度类型(double)来存储,float数据占用32bit,double数据占用64bit,我们在声明一个变量float f= ...
- 《iOS取证实战:调查、分析与移动安全》一3.4 数据存储方式
3.4 数据存储方式 iPhone上的数据以很多方式进行存储.下面的小节涵盖了每一个数据存储的形式以供审查者了解潜在的证据如何定位或恢复. 内部存储: SQLite 数据库文件: 属性列表: 网络: ...
- 理解int的存储方式以及VS二进制编辑器的使用
此文先讲int数据的存储(大小端)问题,然后简单讲一下二进制编辑器的使用,针对像我一样的初学者,懂了的大神可以直接关掉 直接说结论,大家都知道一个int数据是4字节,一个字节是8个比特位,也就是一个i ...
- Redis简介、与memcached比较、存储方式、应用场景、生产经验教训、安全设置、key的建议、安装和常用数据类型介绍、ServiceStack.Redis使用(1)...
1.NOSQL简介 nosql的产生并不是要彻底的代替关系型数据库,而是作为传统关系型数据库的一个补充. Facebook和360使用Cassandra来存储海量社交数据 Twitter在其url抓取 ...
- 转载——C语言中float,double类型,在内存中的结构(存储方式)
最近在做一个数据格式分析和转换的项目,第一次接触底层的二进制代码存储,看的一头雾水,看到这个帖子后对于在Windows系统下数据的存储方式有了更多的了解,将原文分享一下: 原文地址为http://ww ...
- Oracle数据类型及存储方式——字符类型篇
注:这篇文章绝大部分都摘抄于袁光东先生的 <<oracle小组学习笔记>>. 下面会对各种字符类型作详细解释. 一. char 类型 oracle 可以定义1个char(n) ...
- 传统存储方式_分布式存储 vs 传统SAN、NAS 的优缺点分析
传统存储架构的局限性和分布式存储的优点 传统SAN存储设备一般采用双控制器架构,两者互为备份,配置两台交换机与前端的服务器进行连接,这种双控制器架构方式会有以下两个方面的缺点: 1. 网络带宽容易变成 ...
- int、unsigned int、float、double 和 char 在内存中存储方式
2017-12-28 创建人:Ruo_Xiao 实验环境:vs2010.Intel 邮箱:xclsoftware@163.com 2018-01-16 修改人:Ruo_Xiao添加对移位存储的说明. ...
最新文章
- 干货丨2017年含金量最高的机器学习技能或知识有哪些?
- 计算机视觉:让冰冷的机器看懂多彩的世界
- SPSS 26安装教程
- 程序员特有的9个坏习惯
- js sort方法根据数组中对象的某一个属性值进行排序(实用方法)
- 移动后端支持平台Parse将API由Ruby迁移到Go
- 牛客 牛牛做除法II
- mysql 数据迁移_CentOS7迁移Mysql数据库文件
- 信安教程第二版-第8章防火墙技术原理与应用
- mui封装的ajax请求
- python人脸识别库教程_OpenCV-最优秀的Python人脸识别库安装及入门教程
- MSSQL 读取本地文件数据
- Android SQLite实现query顺序、倒叙查询
- centos6.x系统内核升级的方法
- 第08课:GDB 实用调试技巧( 上)
- 小程序发送公众号模板消息+PHP后台
- 手机电源管理芯片一般在哪
- Backtrader系列教程⑦:可视化篇(重构)
- cisco anyConnect 不用每次输入密码的办法
- 51单片机程序存储器扩展
热门文章
- 网页防篡改技术_大数据让档案“活”起来:用区块链技术防篡改,用量子加密技术防盗窃...
- 数据结构 3-2-2 队列的顺序存储实现
- Scrapy 简介及初探
- Python中替换元素
- 实验3.2 定义一个简单的Computer类
- ROS2——南溪的ROS2使用手册
- matplotlib 绘图代码库(自用)
- LeetCode for SQL 176. 第二高的薪水 (ifnull limit order by)
- 字符串匹配问题 ----- KMP算法
- 《火星人敏捷开发手册》 2011-08-18版本发布