Chinaunix首页 | 论坛 | 博客
  • 博客访问: 11663
  • 博文数量: 2
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 10
  • 用 户 组: 普通用户
  • 注册时间: 2014-09-13 17:26
文章分类
文章存档

2014年(2)

我的朋友
最近访客

分类: 嵌入式

2014-09-13 17:29:21

1.strcpy函数的原型
    char *strcpy(char *dest, const char *src)
1.1 GNU官方解释
     The  strcpy()  function  copies the string pointed to by src, including the terminating null byte ('\0'), to the buffer  pointed  to  by  dest. The  strings  may  not overlap, and the destination string dest must be large enough to receive the copy.
1.2 注意要点
    (1)拷贝时,把src中包括'\0'的字符也一起拷贝到dest中
    (2)特别注意src和dest的地址千万不能重复
    (3)dest的空间大小至少要能够容纳src字符串所占的空间
1.3 自己实现的代码

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <assert.h>

  3. char *my_strcpy(char *dest,const char *src)
  4. {
  5.     //使用断言实现输入参数合法性的检查
  6.     assert(dest != NULL);
  7.     assert(src != NULL);

  8.     char *ret_dest = dest; //定义一个变量记录dest的首地址

  9.     while((*dest ++ = *src ++) != '\0'); //拷贝字符串src到dest,包括src中的'\0'

  10.     return ret_dest;
  11. }

  12. int main(int argc, const char *argv[])
  13. {
  14.     //说明:给my_strcpy(char *dest,const char *src)不能传递一个指针变量的地址,比如:
  15.     /* char *s1 = "abcdefgh"
  16.      * char *s2 = "abc"
  17.      * my_strcpy(s1,s2);
  18.      * 此时会发生段错误,原因从注意要点中的3点来分析:
  19.      * 首先:这样并不能保证,src的地址和dest的地址是不重复的,如果src和dest的字符串
  20.      * 是一样的,那么它们的首地址是一样的,这样程序就会出现死循环,直到出现非
  21.      * 法内存访问为止。
  22.      * 其次:这样做并没有保证dest指向的的空间至少要比src指向的空间要大。
  23.      * 总结:鉴于以上原因,利用字符数组就可以解决这个问题,具体如下所示:
  24.      */
  25.     
  26.     char dest[120] = "abcdefh";
  27.     char src[10] = "xxx";
  28.     
  29.     

  30.     my_strcpy(dest,src);
  31.     
  32.     printf("%s\n",dest);

  33.     return 0;
  34. }
运行测试结果:

点击(此处)折叠或打开

  1. ubuntu@ubuntu:~/interview/c_study$ gcc my_strcpy.c
  2. ubuntu@ubuntu:~/interview/c_study$ ./a.out
  3. xxx
2.memcpy函数的原型
    void *memcpy(void *dest, const void *src, size_t n);
2.1 GNU官方解释
    
The  memcpy()  function  copies  n bytes from memory area src to memory area dest.  The memory areas must not overlap.  Use memmove(3)  if  the memory areas do overlap.
2.2 注意要点
    (1)拷贝的src的前n个字符到src中,注意与strcpy的区别
    (2)特别注意src和dest的地址千万不能重复
    (3)如果dest中有100个字符,src有200个字符,但是n的值是10,拷贝也会成功,且只改变dest中的前10个字符,后面的字符不变
2.3 自己实现的代码

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <assert.h>
  3. #include <string.h>

  4. void *my_memcpy(void *dest,const void *src,size_t count)
  5. {
  6.     char *ret = dest;
  7.     char *s = src;

  8.     assert(dest != NULL && src != NULL);
  9.     
  10.     while(count --)
  11.     {
  12.         *ret++ = *s++;
  13.     }

  14.     return ret;
  15. }


  16. int main(int argc, const char *argv[])
  17. {
  18.     char buf[32] = "123456xyz";
  19.     char *str = "abcdef";

  20.     my_memcpy(buf,str,strlen(str) + 1);

  21.     printf("%s\n",buf);
  22.     
  23.     return 0;
  24. }
运行结果:

点击(此处)折叠或打开

  1. ubuntu@ubuntu:~/interview/c_study$ gcc my_memcpy.c
  2. ubuntu@ubuntu:~/interview/c_study$ ./a.out
  3. abcde6xyz
总结strcpy和memcpy的区别:
(1)各自的函数原型
    char *strcpy(char *dest, const char *src)
   void *memcpy(void *dest, const void *src, size_t n);
(2)具体区别:
strcpy和memcpy主要有以下3方面的区别。
1、复制的内容不同。strcpy只能复制字符串,而memcpy可以复制任意内容,例如字符数组、整型、结构体、类等。
2、复制的方法不同。,strcpy不需要指定长度,它遇到被复制字符的串结束符"\0"才结束所以容易溢出。memcpy则是根据其第3个参数决定复制的长度。
3、用途不同。通常在复制字符串时用strcpy,而需要复制其他类型数据时则一般用memcpy

3.memset函数的原型
     void *memset(void *s, int c, size_t n)
3.1 GNU官方解释
    
The  memset()  function  fills  the  first  n  bytes of the memory area pointed to by s with the constant byte c.
     将s指向的内存区域的前n个字节设置为int型的ASCII值,主要用于给新申请的内存做初始化的工作
3.2 注意要点
    (1)*s的类型是void类型,因此传递参数时可以传递任何类型,但是在函数内部具体实现时需要进行强制类型转换,然后进行操作
    (2)第二个参数是一个int型的ASCII值,
    (3)size_t的原型是:unsigned int
3.3 自己实现的代码

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <assert.h>

  3. typedef unsigned int size_t;

  4. char *my_memset(void *dest,int ch,size_t count)
  5. {
  6.     char *tmp = dest;
  7.     char *ret = tmp;

  8.     while(count --)
  9.     {
  10.         *tmp++ = ch;
  11.     }

  12.     return ret;
  13. }

  14. int main(int argc, const char *argv[])
  15. {
  16.     char buf[] = "abcdef";
  17.     char *str = NULL;

  18.     str = my_memset(buf,'x',4);

  19.     printf("%s\n",str);
  20.     

  21.     return 0;
  22. }
运行结果:

点击(此处)折叠或打开

  1. ubuntu@ubuntu:~/interview/c_study$ vi my_memset.c
  2. ubuntu@ubuntu:~/interview/c_study$ gcc my_memset.c
  3. ubuntu@ubuntu:~/interview/c_study$ ./a.out
  4. xxxxef

4.strlen函数的原型
     size_t strlen(const char *s);
4.1 GNU官方解释
   The  strlen() function calculates the length of the string s, excluding the terminating null byte ('\0')

4.2 注意要点
    (1)size_t 的类型是unsigned int 类型,char *s是用const修饰的,所求长度不包括'\0',比如“abc”,求出的长度是3
4.3 自己实现的代码

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <assert.h>

  3. int my_strlen(char *src)
  4. {
  5.     int ret = 0;

  6.     assert(src != NULL);
  7.     
  8.     while(*src++ != '\0')
  9.     {
  10.         ret ++;
  11.     }

  12.     return ret;
  13. }


  14. int main(int argc, const char *argv[])
  15. {
  16.     int ret;
  17.     char *str = "abcdef";

  18.     ret = my_strlen(str);
  19.     
  20.     printf("%d\n",ret);

  21.     return 0;
  22. }
运行结果:

点击(此处)折叠或打开

  1. ubuntu@ubuntu:~/interview/c_study$ gcc my_strlen.c
  2. ubuntu@ubuntu:~/interview/c_study$ ./a.out
  3. 6

5.strcat函数的原型
      char *strcat(char *dest, const char *src);
5.1 GNU官方解释
    The  strcat() function appends the src string to the dest string, over‐writing the terminating null byte ('\0') at the end of dest,  and  then adds  a  terminating  null  byte.  The strings may not overlap, and the dest string must have enough space for the result.
5.2 注意要点
    (1)把src的字符串接在dest字符串的后面,并且在新的dest末尾添加一个'\0'
    (2)特别注意src和dest的地址千万不能重复,否则会出现死循环,发生段错误
    (3)特别注意必须把原来的dest末尾的'\0'应该替换掉
    (4)其中dest指向的内存区域必须能够容纳下src所指向的字符串
5.3 自己实现的代码

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <assert.h>

  3. char *my_strcat(char *dest,char *src)
  4. {
  5.     char *tmp = dest;

  6.     while(*dest != '\0')
  7.     {
  8.         dest++;
  9.     }

  10.     while((*dest ++ = *src ++) != '\0');

  11.     return tmp;
  12. }

  13. int main(int argc, const char *argv[])
  14. {
  15.     char dest[20] = "abc";
  16.     char src[] = "def";

  17.     my_strcat(dest,src);

  18.     printf("%s\n",dest);
  19.     
  20.     return 0;
  21. }
运行结果:

点击(此处)折叠或打开

  1. ubuntu@ubuntu:~/interview/c_study$ gcc my_strcat.c
  2. ubuntu@ubuntu:~/interview/c_study$ ./a.out
  3. abcdef

6.strcmp函数的原型
      int strcmp(const char *s1, const char *s2);
6.1 GNU官方解释
     The  strcmp()  function compares the two strings s1 and s2.  It returns an integer less than(*s1<*s2), equal to(*s1++ == *s2++), or greater than(*s1>*s2) zero if  s1  is  found, respectively, to be less than, to match, or be greater than s2.
6.2 注意要点
    (1)实现了两个字符串的比较,并且是逐个比较,*s1 == *s2 ? *(s1 + 1) == *(s2 + 1) ……直到两个字符串都结尾或者任意一个结尾
    (2)碰到第一个不相等的字符时就立即返回,且如果*s1 > *s2则返回正数1,如果*s1 < *s2则返回负数-1,如果两个字符串完全相同,
       则直接返回0
6.3 自己实现的代码

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <assert.h>

  3. int my_strcmp(const char *dest,const char *src)
  4. {
  5.     unsigned char c1,c2;

  6.     assert(dest != NULL);
  7.     assert(src != NULL);

  8.     while(1)
  9.     {
  10.         if(*dest != *src)
  11.         {
  12.             return *dest > *src ? 1 : -1;
  13.         }
  14.         else
  15.         {
  16.             dest ++;
  17.             src ++;
  18.         }
  19.         if(*dest == '\0' && *src == '\0')
  20.         {
  21.             break;
  22.         }
  23.     }

  24.     return 0;
  25. }

  26. int main(int argc, const char *argv[])
  27. {
  28.     int ret;
  29.     char dest[] = "aa";
  30.     char src[] = "aa";

  31.     ret = my_strcmp(dest,src);

  32.     printf("%d\n",ret);

  33.     return 0;
  34. }
运行结果:

点击(此处)折叠或打开

  1. ubuntu@ubuntu:~/interview/c_study$ gcc my_strcmp.c
  2. ubuntu@ubuntu:~/interview/c_study$ ./a.out
  3. 0
     以上总结了常见的字符串处理函数,自己写的代码实现部分不能完全保证没有问题,希望大家多多指正,多交流,共同学习!
阅读(1586) | 评论(0) | 转发(0) |
0

上一篇:没有了

下一篇:C++的精髓——虚函数

给主人留下些什么吧!~~