发布于 2014-10-27 06:37:58 | 178 次阅读 | 评论: 0 | 来源: 网友投递

这里有新鲜出炉的精品教程,程序狗速度看过来!

百度(Baidu)中文搜索引擎

百度(Nasdaq简称:BIDU)是全球最大的中文搜索引擎,2000年1月由李彦宏、徐勇两人创立于北京中关村,致力于向人们提供“简单,可依赖”的信息获取方式。“百度”二字源于中国宋朝词人辛弃疾的《青玉案·元夕》词句“众里寻他千百度”,象征着百度对中文信息检索技术的执著追求。


请编码实现memcpy函数:void *memcpy(void *dst,const void *src,unsigned int count)  显然是内存复制函数

下面是本人结合memcpy的源代码实现的一个测试用例,请大家指点

 
  1. #include <stdio.h>  
  2. void *memcpy(void *dst,const void *src,unsigned int count)  
  3. {  
  4.     char *p_dst = (char *)(dst);  
  5.     char *p_src = (char *)(src);  
  6.     unsigned int i;  
  7.     if(p_dst>p_src && p_dst<=(p_src+count-1))  
  8.     {  
  9.         while(count)  
  10.         {  
  11.             *(p_dst+count-1) = *(p_src+count-1);  
  12.             count--;  
  13.         }  
  14.     }  
  15.     else  
  16.     {  
  17.         for(i=0;i<count;i++)  
  18.         {  
  19.             *(p_dst+i) = *(p_src+i);  
  20.         }  
  21.     }  
  22.     return dst;  
  23. }  
  24. int main()  
  25. {  
  26.     int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};  
  27.     memcpy(arr+4,arr,sizeof(int)*6);// 这样的拷贝 src<dst && src+count-1>dst,也就是说已经产生了覆盖,  
  28.     //所以用从后往前的复制,进入if  
  29.     for(int i=0;i<10;i++)  
  30.         printf("%d\t",arr[i]);  
  31.     //    memcpy(arr,arr+4,sizeof(int)*6);// 这样的拷贝 src>dst && src<dst+count-1,  
  32.     //      这和正常的拷贝一样,进入else  
  33.     //    for(int i=0;i<10;i++)  
  34.     //        printf("%d\t",arr[i]);  
  35.     printf("\n");  
  36.     return 0;  
  37. }  


1  有人可能会问:你的算法保证了任何情况下都能够把数据正确的复制到目的地址,但是你有没有考虑过在复制的过程中,你有可能修改了原始数据呢?
修改了原始串这样的功能明确么?

回答:对,老兄你说的很对,的确会存在这个问题,举个例子吧,比如hello world,我们想把中间的空格去掉,滤掉空格就类似于操作系统中有一种内存分配方法,叫做可重地位分区分配,就是把小作业移动,去除中间的空隙,然后空出后面的一块大的内存地址,供其他程序使用。这样对原始数据不需要保存的情况下,可以应用这个函数。

2  可能你还有疑问:最后的dst+count = '\0' 假如传入的是char 型的数组,怎么办呢?你return dst如何判断空不空呢? ——  好吧,这也是我的问题,请大神们帮助解答????

3memcpy() 和 普通 strncpy() 复制函数的区别,看代码吧,不多说了:

 

  1. #include <iostream>  
  2. #include <cstring> // for c style string manipulation  
  3.   
  4. using namespace std;  
  5.   
  6. int main ()  
  7. {  
  8.     char str1[]= "To be or not to be";//  18 个字符(含空格)+ '\0' = 19 个字符,因为默认结尾有 '\0'  
  9.     cout << sizeof(str1) << endl;  
  10.     char str2[40];  
  11.     cout << str1 << endl;  
  12.     // copy to sized buffer (overflow safe):  
  13.     strncpy ( str2, str1, sizeof(str2) );  
  14.     cout << str2 << endl;  
  15.     // partial copy (only 5 chars):  
  16.     strncpy ( str2, str1, 5 );  
  17.     cout << str2 << endl;  
  18.     str2[5] = '\0';   // null character manually added  
  19.     cout << sizeof(str2) << " " << str2 << endl;  
  20.   
  21.     strncpy(str1 + 3, str1, 6); // 出现内存覆盖问题  
  22.     cout << str1 ;  
  23.   
  24.     return 0;  
  25. }  
 
  1. 总结:strcpy   
  2.   源字串全部拷贝到目标字串中,包括'\0',但是程序员必须保证目标串长度足够,且不与源串重叠。  
  3.   strncpy   
  4.   如果目标长>=指定长>源长,则将源串全部拷贝到目标串,连同'\0'   
  5.   如果指定长<源长,则将截取源串中按指定长度拷贝到目标字符串,不包括'\0',手动添加‘\0’,建议对于前两种都手动添加就可以了  
  6.   如果指定长>目标长,错误!  
 
  1. #include <iostream>  
  2. #include <cstring> // for c style string manipulation  
  3. using namespace std;  
  4. const int maxn = 8;  
  5. int main ()  
  6. {  
  7.     int i;  
  8.     char dest[]="Hell99iam!";// 10个字符,占了11个空间,最后一个'\0'  
  9.     char src[]="abc\0def";  
  10.     strncpy(dest,src,maxn);  
  11.     dest[maxn] = '\0';  
  12.     for(i=0;i<sizeof(dest);i++)  
  13.     {  
  14.         if(*(dest+i) == '\0')  
  15.             cout << "* ";  
  16.         else  
  17.             cout << *(dest+i) << " ";  
  18.     }  
  19.     cout << endl << dest << endl;  
  20.     char str[maxn];  
  21.     strncpy(str,src,1);  
  22.     for(i=0;i<sizeof(str);i++)  
  23.     {  
  24.         if(*(str+i) == '\0')  
  25.             cout << "* ";  
  26.         else  
  27.             cout << *(str+i) << " ";  
  28.     }  
  29.     //str[1] = '\0'; 如果没有这句话,就是下图的结果了  
  30.     cout << endl << str << endl;  
  31.     return 0;  
  32. }  
  33. /* 
  34.     (c/c++)复制字符串src中的内容(字符,数字、汉字....)到字符串dest中,复制多少由size_t的 
  35.     值决定,返回指向dest的指针。如果遇到空字符('\0')[1] ,则空字符后面全部为空(字符),maxn 决定有多少个空格 
  36.  
  37. */  
 

3 中第一个函数的结果:

3 中第二个函数的结果:

4  void * memset ( void * ptr, int ch, size_t num );

函数的作用是: fill the first num bytes(注意不是element) of block of memory(由空指针ptr指向) with value. 最后我们会解释这句话的含义。在C++中,设计 size_t 就是为了适应多个平台的 。size_t的引入增强了程序在不同平台上的可移植性。size_t是针对系统定制的一种数据类型,一般是整型(int),因为C/C++标准只定义一最低的位数,而不是必需的固定位数。

 

  1. /* memset example */  
  2. #include <iostream>  
  3. #include <cstring>  
  4. using namespace std;  
  5. const int maxn = 11;  
  6. int main ()  
  7. {  
  8.     int arr[maxn], i;  
  9.     char str[] = "almost every programmer should know memset!";  
  10.   
  11.     memset(str, '-', 6);  
  12.     cout << str << endl;  
  13.   
  14.     memset(arr,10,maxn*sizeof(int));  
  15.     for(i=0; i<maxn; i++) {  
  16.        cout << arr[i] << " ";  
  17.     }  
  18.     cout << endl;  
  19.   
  20.     memset(arr,-1,maxn*sizeof(int));  
  21.     for(i=0; i<maxn; i++) {  
  22.        cout << arr[i] << " ";  
  23.     }  
  24.     cout << endl;  
  25.   
  26.     return 0;  
  27. }  

问题来了: 对于上例子中, 对char 型数组的初始化, 输出符合预期。 但是对于整型数组却不符合预期, 为什么呢。 答案就是memset 是对于memory block  是一个字节一个字节的赋值。 由于int 型数组一个int元素就有4个bytes, 当然不符合预期了。 相信改为0后就可以了, 另外改为-1 也可以:

结果如下:


 

 



最新网友评论  共有(0)条评论 发布评论 返回顶部

Copyright © 2007-2017 PHPERZ.COM All Rights Reserved   冀ICP备14009818号  版权声明  广告服务