走进C标准库(7)——"string.h"中函数的实现memcmp,memcpy,memmove,memset

我的memcmp:


 1 int memcmp(void *buf1, void *buf2, unsigned int count){
2 int reval;
3 while(count && !(reval = (*(unsigned char *)buf1) - (*(unsigned char *)buf2)))
4 {
5 buf1 = (unsigned char *)buf1 + 1;
6 buf2 = (unsigned char *)buf2 + 1;
7 --count;
8 }
9 return reval;
10 }

MS VC:


int __cdecl memcmp (
const void * buf1,
const void * buf2,
size_t count
)
{
if (!count)
return(0);

while ( --count && *(char *)buf1 == *(char *)buf2 ) {
buf1 = (char *)buf1 + 1;
buf2 = (char *)buf2 + 1;
}

return( *((unsigned char *)buf1) - *((unsigned char *)buf2) );
}

应该使用const void *buf为宜,不改变该块内存的内容,最终使用unsigned char *进行运算,保证运算结果的符号正确。

我的memcpy:


1 void *memcpy(void *dest, const void *src, unsigned int count){
2 void *reval = dest;
3 while(count--){
4 (*(unsigned char *)dest++) = (*(unsigned char *)src++);
5 }
6 return reval;
7 }

MSVC:


 1 void * __cdecl memcpy (
2 void * dst,
3 const void * src,
4 size_t count
5 )
6 {
7 void * ret = dst;
8
9 #if defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC)
10 {
11 extern void RtlMoveMemory( void *, const void *, size_t count );
12
13 RtlMoveMemory( dst, src, count );
14 }
15 #else /* defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC) */
16 /*
17 * copy from lower addresses to higher addresses
18 */
19 while (count--) {
20 *(char *)dst = *(char *)src;
21 dst = (char *)dst + 1;
22 src = (char *)src + 1;
23 }
24 #endif /* defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC) */
25
26 return(ret);
27 }

我的memmove:


 1 void *memmove(void *dest, const void *src, unsigned int count){
2 void *reval = dest;
3 int overlap = ((unsigned char *)src < (unsigned char *)dest && ((unsigned char *)src + count) > dest);
4 while(count--){
5 if(overlap)//src is in front of dest and overlap. copy direction is from endIndex to beginIndex
6 (*((unsigned char *)dest + count)) = (*((unsigned char *)src + count));
7 else
8 (*(unsigned char *)dest++) = (*(unsigned char *)src++);
9 }
10 return reval;
11 }

MSVC:


 1 void * __cdecl memmove (
2 void * dst,
3 const void * src,
4 size_t count
5 )
6 {
7 void * ret = dst;
8
9 #if defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC)
10 {
11 extern void RtlMoveMemory( void *, const void *, size_t count );
12
13 RtlMoveMemory( dst, src, count );
14 }
15 #else /* defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC) */
16 if (dst <= src || (char *)dst >= ((char *)src + count)) {
17 /*
18 * Non-Overlapping Buffers
19 * copy from lower addresses to higher addresses
20 */
21 while (count--) {
22 *(char *)dst = *(char *)src;
23 dst = (char *)dst + 1;
24 src = (char *)src + 1;
25 }
26 }
27 else {
28 /*
29 * Overlapping Buffers
30 * copy from higher addresses to lower addresses
31 */
32 dst = (char *)dst + count - 1;
33 src = (char *)src + count - 1;
34
35 while (count--) {
36 *(char *)dst = *(char *)src;
37 dst = (char *)dst - 1;
38 src = (char *)src - 1;
39 }
40 }
41 #endif /* defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC) */
42
43 return(ret);
44 }

关于memcpy和memmove的区别,memcpy不考虑内存区域重叠的情况而memmove保证内存区域重叠也能正常复制成功。

有时候我们的memcpy也可能在内存重叠的情况下正常使用,这取决于它的实现,不具有普遍性,C语言标准中未对其有这种要求。

参考资料:

《关于memcpy和memmove两函数的区别》

http://blog.csdn.net/caowei840701/article/details/8491836

《memcpy() vs memmove()》

http://stackoverflow.com/questions/4415910/memcpy-vs-memmove

我的memset:


1 void *memset(void *buffer, int c, int count){
2 void *reval = buffer;
3 while(count--){
4 (*(unsigned char *)buffer++) = (unsigned char)c;
5 }
6 return reval;
7 }

MSVC:


 1 void * __cdecl memset (
2 void *dst,
3 int val,
4 size_t count
5 )
6 {
7 void *start = dst;
8
9 #if defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC)
10 {
11 extern void RtlFillMemory( void *, size_t count, char );
12
13 RtlFillMemory( dst, count, (char)val );
14 }
15 #else /* defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC) */
16 while (count--) {
17 *(char *)dst = (char)val;
18 dst = (char *)dst + 1;
19 }
20 #endif /* defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC) */
21
22 return(start);
23 }

走进C标准库(7)——"string.h"中函数的实现memcmp,memcpy,memmove,memset,码迷,mamicode.com

时间: 2024-10-11 22:50:38

走进C标准库(7)——"string.h"中函数的实现memcmp,memcpy,memmove,memset的相关文章

走进C标准库(8)——"string.h"中函数的实现相关字符串操作函数

我的strcat: 1 char *strcat(char *dest,char *src) 2 { 3 char * reval = dest; 4 while(*dest) 5 dest++; 6 while(*src) 7 *dest++ = *src++ ; 8 *dest = *src; 9 return reval; 10 } MSVC: 1 char * __cdecl strcat ( 2 char * dst, 3 const char * src 4 ) 5 { 6 char

走进C标准库(6)——"string.h"中函数的实现memchr

我写的memchr: 1 void *memchr(const void *buf, char ch, unsigned count){ 2 unsigned int cnt = 0; 3 while(*(buf++) != ch && cnt <= count){cnt++;} 4 if(cnt > count) 5 return NULL; 6 else 7 return buf; 8 } 红色部分报错. 该错误为为ANSIC中认定的错误,是因为它坚持:进行算法操作的指针必

【C 标准库】&lt;string.h&gt;

参考链接:C 标准库 - <string.h> string.h中主要有两类函数: memxxx 和 strxxx,其中memxxx是针对内存操作的函数,在遇到'\0'的时候并不会停下来,而通常是设置一个size_t类型(其实是unsigned int)的参数来表示字节大小: 而strxxx是针对字符串操作的函数,遇到'\0'停下来.strxxx函数中,有一些函数是strnxxx的,这些函数可以通过传入一个size_t类型的参数来表示字节大小,所以遇到'\0'或到达字节大小都会停下来,相对安全

谈谈两种标准库类型---string和vector

两种最重要的标准库---string和vector string和vector是两种最重要的标准库类型,string表示可变长的字符序列,vector存放的是某种给定类型对象的可变长序列. 一.标准库类型string   1.定义和初始化string对象:初始化string对象的方式有 string s1   默认初始化,s1是一个空串   string s2(s1)   s2是s1的副本 string s2=s1   等价于s2(s1),s2是s1的副本 string s3("value&qu

C++标准库类型string

string类表示可变长字符序列,包含在头文件string中,作为标准库的一部分string定义在std命名空间中 1.初始化string对象 std::string s1;//默认初始化s1是个空字符 std::string s2 = s1;//s2是s1的副本 std::string s3 = "hello";//s3是该字符串字面值的副本 std::string s4(10,'h');s4的内容是hhhhhhhhhh 直接初始化和拷贝初始化 初始化时用到=号的就是拷贝初始化,其在

3.2 标准库类型string(上)

#include <string> #include <iostream> using std::string; using std::cin; using std::cout; using std::endl; //string定义在命名空间std中 int main() { /**************3.2.1 定义和初始化string*****************/ string s1; //默认初始化,S1是一个空字符串 string S2 = s1; //S2时S

C语言:自定义一个查找字串的功能函数,类似于&lt;string.h&gt;中的strstr()

//自定义一个字符串字串查找标准库函数strstr() #include<stdio.h> #include<string.h> char* myStrstr(char *str1,char *str2); int main() { char *str1 = "hello worl world ld"; char *str2 = " world "; puts(myStrstr(str1,str2)); return 0; } char *m

string.h中常用函数

string.h文件中函数的详细用法 下面为string.h文件中函数的详细用法,附加实例: 1.strcpy 函数名: strcpy 功 能: 拷贝一个字符串到另一个 用 法: char *strcpy(char *destin, char *source); 程序例: #include <stdio.h> #include <string.h> int main(void) { char string[10]; char *str1 = "abcdefghi"

基于标准库的string类实现简单的字符串替换

感觉基本功还是不扎实,虽然能做些程序但是现在看来我还是个初学者(primer),试着完成习题结果还得修修改改. 废话不多说,实现功能很简单,<C++ Primer>9.5.2节习题. // 将s中所有oldVal替换成newVal void replace(string& s, const string& oldVal, const string& newVal); 对字符串进行替换,实际上是先找到字符串s中的匹配部分,将匹配部分(oldVal)删除,然后插入要替换的字