【C语言入门级教学】内存函数

文章目录

1.memcpy使⽤和模拟实现

c 复制代码
void * memcpy ( void * destination, const void * source, size_t num );//可以拷贝许多类型的数据,所以数据地址类型是void*

功能

• 从源头指向的内存块拷贝固定字节数的数据到目标指向的内存块

• memcpy:memory copy(内存拷贝)

• 要包含头文件==<string.h>==

• 与strcpy函数不同的点:这个函数在遇到 '\0' 的时候并不会停下来,总是精确地拷贝参数传入的字节数

• 如果source和destination有任何的重叠,复制的结果都是未定义的。

参数

destination:指针,指向目标空间,拷贝的数据存放在这里

source:指针,指向源空间,要拷贝的数据从这里来

num:要拷贝的数据占据的字节数

返回值

函数运行结束后返回拷贝后的目的地内存块的起始地址

c 复制代码
#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;
 }
//或者
int main()
{
    float arr1[]={1.2f,2.2f,3.2f,4.2f,5.5f};
    float arr2[10]={0};
//  memcpy(arr2,arr1,20);
    memcpy(arr2,arr1,5*sizeof(float));//忘记浮点数的字节数可以这样做
    return 0;
}

有个题外话:float型无法精确保存数据

memcpy函数的模拟实现:

c 复制代码
void * memcpy ( void * dest, const void * src, size_t num) 
{ 
    void * ret = dest; 
    assert(dest); 
    assert(src); 
    while (num--) 
    { 
        *(char *)dest = *(char *)src;//转换成char*可以一个字节一个字节赋值,但是是临时转换
        //如果转换为整型,只能四个字节四个字节赋值
        src=(char*)src+1;//需要再重新转换成char*
        dest=(char*)dest+1;
        //不能写成
        //*(char*)dest++=*(char*)src++;
        //因为dest和src会先转换成char*,但是++操作会给dest和src++,而不是给(char*)dest和(char*)src进行++操作
    } 
    return ret; 
}

注意

void*不能进行++操作,因为void *是一个指向未知类型的指针类型,它的大小是不确定的。而++操作需要知道指针所指向的对象的大小,才能正确的进行指针运算。

如果出现下段这种代码:

c 复制代码
#include<stdio.h>  
#include<string.h> 
int main() 
{ 
    int arr1[] = { 1,2,3,4,5,6,7,8,9,10 }; 
    memcpy(arr1+2, arr1, 20); 
    int i = 0; for (i = 0; i < 10; i++) 
    { 
        printf("%d ", arr1[i]); 
    }
    return 0; 
}
//输出结果却是1 2 1 2 1 2 1

分析:因为目标空间和源头空间重复,给arr[4]拷贝时arr[2]已经被拷贝为1了,所以arr[4]会被拷贝现在arr[2]的值,那怎么解决这个问题呢,可以用memmove函数(但是vs编译器的memcpy可以拷贝重叠空间,属于超额完成任务)

2.memmove使⽤和模拟实现

c 复制代码
void * memmove ( void * destination, const void * source, size_t num );//和memcpy参数一样

功能

• memmove函数也是完成内存拷贝的

• memmove函数处理的源内存块和⽬标内存块是可以重叠,也可以不重叠。

• 需要包含头文件==<string.h>==

参数

destination:指针,指向目标空间,拷贝的数据存放在这里

source:指针,指向源空间,要拷贝的数据从这里来

num:要拷贝的数据占据的字节数

返回值

函数运行结束后,返回目标空间的起始地址

c 复制代码
#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; 
}

输出的结果: 1 2 1 2 3 4 5 8 9 10

memmove的模拟实现:

第二种方法

c 复制代码
#include<stdio.h>
#include<assert.h>
void* my_memmove ( void * dest, const void * src, size_t num) 
{ 
    assert(dest&&src);
    void* ret=dest;//先存起来
    if(dest>src)
    {
        while(num--)
       { 
            *(char*)dest=*(char*)src;
        	dest=(char*)dest+1;
        	src=(char*)src+1;
        }
    }
    else
    {
        while(num--)
        {
            *((char*)dest+num)=*((char*)src+num);
        }
    }
    return ret;//与memmove函数保持一致
}
int main() 
{ 
    int arr1[] = { 1,2,3,4,5,6,7,8,9,10 }; 
    my_memmove(arr1+2, arr1, 20); 
    int i = 0; 
    for (i = 0; i < 10; i++) 
    { 
        printf("%d ", arr1[i]); 
    }
    return 0; 
}

第一种方法

c 复制代码
#include<stdio.h>
#include<assert.h>
void * memmove ( void * dest, const void * src, size_t count)
{
    assert(dest&&src);
 	void * ret = dst;
 	if (dest <= src || (char *)dest >= ((char *)src + count)) 
    {
         while (count--) 
         {
             *(char *)dest = *(char *)src;
             dest = (char *)dest + 1;
             src = (char *)src + 1;
         }
     }
     else 
     {
         dest = (char *)dest + count - 1;
         src = (char *)src + count - 1;
         while (count--) 
         {
             *(char *)dest = *(char *)src;
             dest = (char *)dest - 1;
             src = (char *)src - 1;
         }
     }
     return(ret);
}
int main() 
{ 
    int arr1[] = { 1,2,3,4,5,6,7,8,9,10 }; 
    my_memmove(arr1+2, arr1, 20); 
    int i = 0; 
    for (i = 0; i < 10; i++) 
    { 
        printf("%d ", arr1[i]); 
    }
    return 0; 
}

3.memset函数的使⽤和模拟实现

c 复制代码
void * memset ( void * ptr, int value, size_t num ); 

功能

• memset是⽤来设置内存的,将内存中的值以字节为单位设置成想要的内容。

• 需包含头文件==<string.h>==

参数

ptr:指针,指向要设置的内存空间,存放了要设置的内存空间的起始地址

value:要设置的值,函数将会把value值转换成unsigned char的数据进行设置的,也就是以字节为单位来设置内存块的

num:要设置的内存长度,单位是字节

返回值

函数运行完之后返回要设置的内存空间的起始位置

c 复制代码
#include<stdio.h>  
#include<string.h>
int main () 
{ 
    char str[] = "hello world"; 
    memset (str,'x',6); 
    printf(str); 
    return 0; 
}

输出的结果: xxxxxxworld

注意

memset函数对内存单元的设置是以字节为单位的

c 复制代码
int main()
{
    int arr[10]={0};
    memset(arr,1,40);
    return 0;
}

结果如下:发现每个字节都设置为1,而不是00 00 00 01

4.memcmp函数的使⽤和模拟实现

c 复制代码
int memcmp ( const void * ptr1, const void * ptr2, size_t num );

功能

• ⽐较从ptr1和ptr2指针指向的位置开始,向后的num个字节

• 需包含头文件==<string.h>==

参数

ptr1:指针,指向一块待比较的内存块

ptr2:指针,指向另外一块待比较的内存块

num:指定的比较长度,单位是字节

返回值

示例一:

c 复制代码
int main()
{
	int arr1[]={1,2,3,4,5,6,7,8,9,10};
	int arr2[]={1,2,3,4,8};
	int r=memcmp(arr1,arr2,17);
    if(r>0)
    	printf(">\n");
    else if(r<0)
        printf("<\n");
    else
        printf("=\n");
    return 0;
}

示例二:

c 复制代码
#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; 
}
相关推荐
-dzk-27 分钟前
【代码随想录】LC 59.螺旋矩阵 II
c++·线性代数·算法·矩阵·模拟
韩立学长34 分钟前
【开题答辩实录分享】以《基于Python的大学超市仓储信息管理系统的设计与实现》为例进行选题答辩实录分享
开发语言·python
风筝在晴天搁浅37 分钟前
hot100 78.子集
java·算法
Jasmine_llq40 分钟前
《P4587 [FJOI2016] 神秘数》
算法·倍增思想·稀疏表(st 表)·前缀和数组(解决静态区间和查询·st表核心实现高效预处理和查询·预处理优化(提前计算所需信息·快速io提升大规模数据读写效率
超级大只老咪1 小时前
快速进制转换
笔记·算法
froginwe111 小时前
Scala 循环
开发语言
m0_706653231 小时前
C++编译期数组操作
开发语言·c++·算法
故事和你911 小时前
sdut-Java面向对象-06 继承和多态、抽象类和接口(函数题:10-18题)
java·开发语言·算法·面向对象·基础语法·继承和多态·抽象类和接口
Bruk.Liu2 小时前
(LangChain实战2):LangChain消息(message)的使用
开发语言·langchain
qq_423233902 小时前
C++与Python混合编程实战
开发语言·c++·算法