赞
踩
目录
字符(串)函数可以专门对字符或字符串操作,同时,若要对其他类型数据进行这些操作,就可以借助内存函数直接对内存操作,接下来介绍的几个内存函数就是极其常用的。
- void* memcpy( void* destination , const void* source, size_t num);
- 从source的位置开始拷贝numge个字节的数据到destination的内存位置;
- 所有类型的数据都可以拷贝,所以返回值是void* 类型;
- 遇到 ' \0 ' 的时候不会停下来;
- 对自己内容的一部分拷贝给自己是无效的;
- #include<stdio.h>
- #include<string.h>
-
- int main()
- {
- int source[10] = { 1,2,3,4,5,6,7,8,9,10 };
- int destination[5] = { 0 };
-
- memcpy(destination, source, 5 * sizeof(int));
-
- return 0;
- }
关键思路:
既然返回类型和形参类型都是void* ,那对于不同的类型数据怎么保证全部拷贝呢?
可以强转为char*型,这样就可以不放过每个字节对应的数据了;
- #include<stdio.h>
- #include<string.h>
- #include<assert.h>
-
- void* my_memcpy(void* destination, const void* source, size_t num)
- {
- assert(destination && source);
- void* start = destination;
- while (num--)
- {
- *((char*)destination)++ = *((char*)source)++;
- }
- //warning C4716 : “my_memcpy”: 必须返回一个值
- return start;
- }
- int main()
- {
- int source[10] = { 1,2,3,4,5,6,7,8,9,10 };
- int destination[5] = { 0 };
-
- my_memcpy(destination, source, 5 * sizeof(int));
-
- for (int i = 0; i < 5; i++)
- {
- printf("%d ", destination[i]);
- }
-
- return 0;
- }
注意点:
- void * memmove ( void * destination, const void * source, size_t num );
和 memcpy 的差别就是 memmove 函数处理的源内存块和目标内存块是可以重叠的; 如果源空间和目标空间出现重叠,就得使用 memmove 函数处理。
对于上述第二点:
关于该函数的模拟实现也就有的研究了。
比如:对于数组arr自身要实现移动:必须考虑数据覆盖问题
如果要移动的数据的起始位置在目标位置之前:就应该依次先移动最后面的数据(从后往前);
如果要移动的数据的起始位置在目标位置之后:就应该依次先移动前面的数据(从前往后);
秘诀:其实就是从它们相交的位置开始移动
- #include<stdio.h>
- #include<string.h>
- #include<assert.h>
-
- void* my_memmove(void* destination, const void* source, size_t num)
- {
- assert(destination && source);
- void* ret = destination;
- //前 -> 后
- //dest < src
- if (destination < source)
- {
- while (num--)
- {
- *(char*)destination = *(char*)source;
- destination = (char*)destination + 1;
- source = (char*)source + 1;
- }
- }
- //后 -> 前
- //dest > src
- else
- {
- while (num--)
- {
- *((char*)destination + num) = *((char*)source + num);
- }
- }
-
- return ret;
- }
- int main()
- {
- int source[10] = { 1,2,3,4,5,6,7,8,9,10 };
-
- my_memmove(source, source + 5, 5 * sizeof(int));
-
- return 0;
- }
- int memcmp ( const void * ptr1, const void * ptr2, size_t num );
- 比较ptr1和ptr2各自后面num个字节的数据是否相同;
- 先遇到谁的小谁的就小;
- 特点:可以作用于任何类型的数据;
- 返回值:
- #include<stdio.h>
- #include<string.h>
-
- int main()
- {
- int arr1[5] = { 1,2,3,4,5 };
- int arr2[5] = { 1,2,3,3,5 };
-
- int ret = memcmp(arr1, arr2, 5 * sizeof(int));
-
- printf("%d\n", ret);
-
- return 0;
- }
- #include<stdio.h>
- #include<string.h>
- #include<assert.h>
-
- int my_memcmp(const void* ptr1, const void* ptr2, size_t num)
- {
- assert(ptr1 && ptr2);
- int ret = 0;
- while (num--)
- {
- ret = *((char*)ptr1) - *((char*)ptr2);
- ptr1 = (char*)ptr1 + 1;
- ptr2 = (char*)ptr2 + 1;
- if (ret != 0)
- {
- return ret;
- }
- }
-
- return 0;
- }
- int main()
- {
- int arr1[5] = { 1,2,3,4,5 };
- int arr2[5] = { 1,2,3,3,5 };
-
- int ret = my_memcmp(arr1, arr2, 5 * sizeof(int));
-
- printf("%d\n", ret);
-
- return 0;
- }
- Sets buffers to a specified character.
- void *memset( void *dest, int value, size_t count );
Return Value :memset returns the value of dest.
- #include<stdio.h>
- #include<string.h>
-
- int main()
- {
- char arr[20] = { "hello world" };
- memset(arr + 6, 'x', 6 * sizeof(char));
-
- return 0;
- }
注意:
memset函数的赋值是按照字节为单位的(见下图4),赋值1,实则是在内存中全部放了0x010101010101....... 这个数刚好是10进制的16843009
因此:该函数不能对整形数组赋除 0 和 -1 之外的数;
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。