void * memcpy ( void * destination, const void * source, size_t num );函数memcpy从source的位置开始向后复制num个字节的数据到destination指向的内存位置
这个函数在遇到 '\0' 的时候并不会停下来
如果source和destination有任何的重叠,复制的结果都是未定义的
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[10] = { 0 };
memcpy(arr2, arr1, 20);
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d ", arr2[i]);
}
return 0;
}使用内存拷贝函数memcpy,将整型数组arr1中前5个元素(对应20字节)的数据,复制到整型数组arr2中,最终遍历输出arr2的所有元素,对于重叠的内存,交给memmove来处理

void * memmove ( void * destination, const void * source, size_t num );和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的,如果源空间和目标空间出现重叠,就得使用memmove函数处理
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
memmove(arr1 + 2, arr1, 20);
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d ", arr1[i]);
}
return 0;
}使用memmove函数,将整型数组arr1开头的5个元素(对应20字节),复制到数组自身从第3个元素开始的位置。由于源内存和目标内存存在“重叠”,memmove会安全处理避免数据覆盖,最终输出修改后的数组

void * memset ( void * ptr, int value, size_t num );memset是用来设置内存的,将内存中的值以字节为单位设置成想要的内容
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main()
{
char str[] = "hello world";
memset(str, 'x', 6);
printf(str);
return 0;
}使用内存填充函数 memset,将字符串 str 中前 6 个字符(对应 6 字节)统一填充为字符 'x',然后输出修改后的字符串

int memcmp ( const void * ptr1, const void * ptr2, size_t num );比较从ptr1和ptr2指针指向的位置开始,向后的num个字节
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main()
{
char buffer1[] = "DWgaOtP12df0";
char buffer2[] = "DWGAOTP12DF0";
int n;
n = memcmp(buffer1, buffer2, sizeof(buffer1));
if (n > 0)
printf("'%s' is greater than '%s'.\n", buffer1, buffer2);
else if (n < 0)
printf("'%s' is less than '%s'.\n", buffer1, buffer2);
else
printf("'%s' is the same as '%s'.\n", buffer1, buffer2);
return 0;
}使用通用内存比较函数memcmp,按字节逐一对两个字符串数组buffer1和buffer2的全部内容(包括字符串结束符 '\0')进行比较

整数的2进制表示方法有三种,即原码、反码和补码 有符号的整数,三种表示方法均有符号位和数值位两部分,符号位都是用0表示“正”,用1表示“负”,最高位的⼀位是被当做符号位,剩余的都是数值位
正整数的原、反、补码都相同
负整数的三种表示方法各不相同
原码:直接将数值按照正负数的形式翻译成⼆进制得到的就是原码
反码:将原码的符号位不变,其他位依次按位取反就可以得到反码
补码:反码+1就得到补码
对于整形来说:数据存放内存中其实存放的是补码(为什么呢?)
在计算机系统中,数值⼀律用补码来表示和存储,原因在于使用补码,可以将符号位和数值域统⼀处理; 同时,加法和减法也可以统⼀处理(CPU只有加法器)此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main()
{
int a = 0x11223344;
return 0;
}这就是a这个临时变量在内存中的地址和数据存储的情况,那为什么是倒序存储的?
1.因为数据在内存中存储的是二进制的补码
2.在调试去昂口中观察内存的时候,为了方便显示,显示的是十六进制的值
3.存储的顺序好像是倒过来的,这里就牵扯到大小端存储,只要把存储的数据能按需求拿出来就可以了,中间这么存储的不重要

一般一个数据有低位和高位(个十百千万……位),而内存中的数据是从低到高存储,所以把低位的数据存储到高地址处叫做“大端字节序存储”,把高地址数据存储到高地址处叫做“小端字节序存储”

11是高位,44是低位,高位存储在高地址处叫“小端存储”(但并不代表在VS中所有数据都是小段存储)
这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着⼀个字节,⼀个字节为8 bit 位,但是在C语言中除了8bit的 char 之外,还有16bit的 short 型,32bit的 long 型(要看具体的编译器),另外,对于位数大于8位的处理器,例如16位或者32位的处理器,由于寄存器宽度大于⼀个字节,那么必然存在着⼀个如何将多个字节安排的问题。因此就导致了大端存储模式和小端存储模式。 例如:⼀个 16bit 的 short 型 x ,在内存中的地址为 0x11 为高字节, 0x0010 , x 的值为 0x22 为低字节。对于大端模式,就将 0x22 放在高地址中,即 0x1122 ,那么 0x11 放在低地址中,即 0x0011 中。小端模式,刚好相反。我们常用的 0x0010 中, X86 结构是小端模式,而KEILC51 则为大端模式,很多的ARM,DSP都为小端模式,有些ARM处理器还可以由硬件来选择是大端模式还是小端模式
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int check_sys()
{
int i = 1;
return (*(char*)&i);
}
int main()
{
int ret = check_sys();
if (ret == 1)
{
printf("小端\n");
}
else
{
printf("⼤端\n");
}
return 0;
}这里是把整型类型的数据转化为字符指针类型,因为存储的时候是存储字节,就是4个字节,一个字节占八位,两个十六进制数占八位
