浙江职业能力建设网站知乎 wordpress 博客
news/
2025/10/3 5:02:53/
文章来源:
浙江职业能力建设网站,知乎 wordpress 博客,易店无忧官网,南昌新建网站建设个人主页#xff1a;PingdiGuo_guo 收录转栏#xff1a;C干货专栏 前言 本篇博客是讲解关于C内存的一些知识点的。 文章目录
前言
1.内存函数
1.1memcpy函数
1.2memmove函数
1.3 memset函数
2.各数据类型占用
2.1bool类型
2.2char类型
2.3short、int、long类型及整数… 个人主页PingdiGuo_guo 收录转栏C干货专栏 前言 本篇博客是讲解关于C内存的一些知识点的。 文章目录
前言
1.内存函数
1.1memcpy函数
1.2memmove函数
1.3 memset函数
2.各数据类型占用
2.1bool类型
2.2char类型
2.3short、int、long类型及整数
2.4float类型及double类型及浮点数
3.学习内存有什么用
总结 1.内存函数
内存函数是在计算机程序中用来操作内存的一类函数。内存函数可以用于分配和释放内存读取和写入内存中的数据以及进行内存的复制和移动等操作。
在这里我们主要介绍几种可以复制的内存函数。
1.1memcpy函数
memcpy函数是C中的一个标准库函数用来实现内存拷贝操作。它的原型如下
void *memcpy(void *dest, const void *src, size_t n);
在C中也可以使用内存拷贝操作来复制数组元素。C提供了memcpy函数它与C的memcpy函数功能相同但被包含在std命名空间中。
下面是使用memcpy实现数组元素拷贝的示例代码
#include iostream
#include cstringusing namespace std;int main() {int srcArray[] {1, 2, 3, 4, 5};int destArray[5];// 使用memcpy函数拷贝数组元素memcpy(destArray, srcArray, sizeof(srcArray));// 思考sizeof(srcArray)是什么这个函数拷贝拷贝了多少元素memcpy(destArray, srcArray,20);//思考这里可以拷贝多少元素//思考这里是谁拷贝的谁// 打印目标数组的元素for (int i 0; i sizeof(destArray) / sizeof(destArray[0]); i) {cout destArray[i] ;}return 0;
} 1.sizeof(srcArray)是srcArray数组的字节大小即sizeof(int) * 5所以sizeof(srcArray)是20。 2.这个函数拷贝了5个元素。因为memcpy函数根据参数指定的字节数进行拷贝sizeof(srcArray)指定了srcArray数组的字节大小所以拷贝了整个srcArray数组的元素。 3.第二个memcpy函数使用了20作为拷贝的字节数。因为是5每个int占4个字节所以这个函数可以拷贝5个元素。 4.这里是destArray拷贝了srcArray数组。 memcpy函数在处理内存重叠问题时是未定义行为。也就是说如果源内存块和目标内存块重叠memcpy函数可能会导致不可预测的结果。 输出结果
1.2memmove函数
memmove与memcpy类似但不同的地方是memmove是可以处理内存块的重叠的。它的函数原型为
void *memmove(void *dest, const void *src, size_t count);拷贝数组
#include bits/stdc.h
using namespace std;
int main()
{int arr1[] { 1,2,3,4,5,6,7,8,9,10};memmove(arr12, arr1, 20);for (int i 0; i 10; i){coutarr1[i] ;}return 0;
}
输出结果 这里出现了一个问题那就是内存重叠了。 那么我们如何处理这个内存重叠问题呢 我们可以检查它们的内存是否重叠。 如果是那我们就直接从后往前拷贝否则我们就从前往后拷贝。 图示 srcsrc 是 memory source 的缩写表示源地址即需要被复制的内存块的起始位置。 destdest 是 destination 的缩写表示目标地址即复制后的内存块的起始位置。 代码
// 自定义 memmove 函数解决内存重叠问题
void* me(void* d, const void* sr, size_t n) {void* ret d;if (d sr || (char*)d ((char*)sr n)) {// 从前往后while (n--) {*(char*)d *(char*)sr;d (char*)d 1;sr (char*)sr 1;}} else {// 从后往前d (char*)d n - 1;sr (char*)sr n - 1;while (n--) {*(char*)d *(char*)sr;d (char*)d - 1;sr (char*)sr - 1;}}return ret;
}1.3 memset函数
memset函数式将指定大小的内存块设置为给定的值。它的函数原型为
void * memset ( void * ptr, int value, size_t num);
使用
#include iostream
#include cstring
using namespace std;
int main() {char str[10];// 将str的前5个字节设置为字符 Amemset(str, A, 5);cout str endl; // 输出 AAAAAreturn 0;
}运行结果 2.各数据类型占用
我们可以用sizeof(数据类型)格式来计算个数据类型的占用内存大小。这里我们要了解一个知识点 字节是计算机中的最小存储单位通常用来表示一个字母、一个数字或者一个符号。一个字节等于8个二进制位即8个0或1。字节是计算机中信息存储和传输的基本单位用来表示各种数据类型和文件大小。 二进制位是计算机中的最小计数单位用于表示数字的最基本形式。二进制位只能是0或1两种状态用于表示八进制、十进制、十六进制等不同进制数系统的数值。计算机中的所有数据都是以二进制位的形式存储和处理的二进制位的组合可以表示各种不同的数值和字符。8个二进制位组合在一起形成一个字节即8位二进制位表示一个字节的数据。 2.1bool类型
代码
coutsizeof(bool)endl;
占用一字节。
解释 bool类型占用内存是一个字节。虽然大家可能觉得bool类型的取值范围只有true和false两种占用内存应该很小但是为了在内存中存储和处理bool类型的值需要用一个字节来表示。这是因为计算机在内存中最小的存储单元就是一个字节无法将一个布尔值存储在更小的存储单元中。因此无论bool类型的值占用的实际位数是多少它始终会占用1个字节的内存空间。 2.2char类型
代码
coutsizeof(char)endl;
占用一个字节及八位二进制位图表
1/01/01/01/01/01/01/01/0
其中每一个二进制位的变化都可以表示一个不同的值也就是2^8256个值只是当有符号和无符号时表示的范围并不相同我们平时的所用的每一个字符在内存中都由8位2进制位来表示。
比如字符A在ASCLL码中对应65在内存则表示为
01000001
2.3short、int、long类型及整数
short、int、long类型都是储存整数的所以放到一块讲了。
short类型
coutsizeof(short)endl;
占用二字节也就是十六位二进制位可以表示2^1665536个值。
int类型
coutsizeof(int)endl;
占用四字节三十二位二进制位可以表示2^324294967296个值。
long类型
coutsizeof(long)endl;
也是占用四字节表示三十二位二进制位可以表示2^324294967296个值和int类型一样。
整数
整数的存储都是由原码、反码、补码来表示的 对于整数 1. 原码只要通过正负数判断即可获得原码正数1负数0 2. 反码在原码的基础上对负数的各位取反。 3. 补码在反码的基础上对负数的最低有效位加1。即将反码符号位除外加1得到补码。 注正整数的原、反、补码是相同的。 在计算机内存中整数通常用二进制补码的形式来储存。为什么呢 因为计算机中通过补码运算可以实现加法、减法、乘法和除法等操作。在进行运算时计算机会自动进行补码的转换和处理。 2.4float类型及double类型及浮点数
因为float和double都是储存浮点数的所以归为一类了。
float类型
代码
coutsizeof(float)endl;
占用四字节三十二位二进制位。
这里需要了解一个表示方式就是二进制的科学表示法
± mantissa × 2 exponent
mantissa尾数exponent指数均使用二进制表示
它的储存采用了IEEE 754单精度浮点格式存储方式如下 1 bit符号位 8 bit指数位 23 bit尾数位 00 1 1 1 1 1 0 0 00 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 03031 2322 0
这里的bit也是二进制位是二进制位的缩写。如上图所示该格式最高一位是符号位0位正1位负后面8位为无符号整型数表示范围为0~265后面23位小数为索引从22到0分别对应2^-1到2^-23。
double类型
代码
coutsizeof(double)endl;
double型在内存中有八个字节储存的数据较大六十四位二进制位bit。他和float类型一样都是采用的二进制的科学计数法。
它的储存采用了IEEE 754双精度浮点格式储存方式如下 1 bit符号位 11 bit指数位 52 bit尾数位 第一位为63倒数第一位为52 倒数第一位为0
如上图所示该格式最高位也为符号位0位正1位负后面11位为无符号整型数表示范围为0~2^11-1后面52位小数为索引从51到0分别对应2^-1到2^-52。
浮点数
浮点数的储存方式可看上面的两张图表接下来讲一下浮点数如何转化为二进制。
步骤 1. 将浮点数分为整数部分和小数部分。例如考虑浮点数12.375整数部分为12小数部分为0.375。 2. 将整数部分转化为二进制。对于整数部分可以使用短除法将其转化为二进制。例如12转化为二进制是1100。对于短除法这里就不过多讲述了大家可以去查一查。 3. 将小数部分转化为二进制。对于小数部分可以使用乘2取整法将其转化为二进制。将小数部分乘以2取整数部分然后将小数部分的整数部分再乘以2依此类推直到小数部分为0或达到所需的精度。例如0.375转化为二进制的过程如下 0.375 x 2 0.75 - 0//整数部分为0继续乘20.75 x 2 1.5 - 1//整数部分为1舍弃整数部分继续乘20.5 x 2 1.0 - 1//乘得积为1停止运算 所以0.375转化为二进制是0.011。 4. 合并整数部分和小数部分的二进制。将步骤2和步骤3得到的二进制合并在一起注意小数点的位置。对于上述例子合并后的二进制是1100.011。 5. 二进制小数转化为十进制验算。比如二进制小数1100.0111*2^20*2^21*2^2(0 * 2^-1) (1 * 2^-2) (1 * 2^-3) 12.375正确。 3.学习内存有什么用
大家可能会有一些疑问学内存知识有什么用呢学内存有以下几个方面的作用 1. 内存管理C是一种低级语言需要手动管理内存分配和释放。了解C内存知识可以帮助我们正确地分配和释放内存避免内存泄漏和野指针等问题提高程序的健壮性和效率。 2. 优化性能理解C内存模型和内存使用方式可以帮助我们优化程序性能。例如了解内存对齐和缓存行的概念可以避免访问内存的延迟提高程序的运行速度。 3. 安全性和稳定性内存相关的错误往往是导致程序崩溃和漏洞的主要原因之一。学习C内存知识可以帮助我们避免常见的内存错误提高程序的安全性和稳定性。 4. 调试和错误排查当程序出现内存相关的问题时了解C内存知识可以帮助我们更快地定位和修复问题提高调试的效率。 总的来说学习C内存知识对于使用和开发C程序非常重要可以帮助我们进行内存管理、优化性能、提高安全性和稳定性深入理解语言特性以及进行调试和错误排查。
总结 本篇博客到这里就结束了感谢大家的支持与观看有好的建议欢迎留言如果这篇博客对您有帮助那请给PingdiGuo_guo一个免费的赞谢谢大家啦
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/925545.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!