strcat strcpy 深入研究(解决乱码等问题)

strcat是将一个字符串链接到另外一个字符串上的函数,具体形式如下:

char* strcat(char* dest,const char* src)

函数的具体流程如下:
1.先查找dest字符串的结尾(即'\0')
2.然后从dest字符串的结尾位置(即'\0'所在的位置)开始,复制src中的字符(包括结尾'\0')。产生的结果是dest的结尾'\0'会被覆盖掉,最后产生一个新的结尾。
3.将dest返回(一般用不到)
注意事项
1.dest必须被初始化,即包含一个'\0'结尾。用malloc分配字符串时,经常发生没有初始化的错误。有时候也会正常执行,是因为分配到的内存中,第一个单元的内容刚好为'\0'。但是不能保证每次都这么好运。所以初始化还是有必要的。
可以这样进行初始化
char* str=(char*) malloc(sizeof(100));
*str='\0';//注意这里是单引号,以为*str表示str所在地址存储的一个char
或者
*str=0;
也可以这样strcpy(str,"");
2.src也必须初始化,包含一个'\0'的结尾,不过这个一般发生错误的概率较小,因为很多时候直接使用一个字符串做参数strcat(dest,"hello world.")。
3.dest所指向内存的大小必须 >=strlen(dest)+strlen(src)+1,否则会发生 不可知的错误,比如 乱码。使用之前要先确认dest的空间足够大再使用strcat函数。
 
glibc中的源码 strcat.c
char *
strcat (dest, src)
     char *dest;
     const char *src;
{
  char *s1 = dest;
  const char *s2 = src;
  reg_char c;
 
  /* Find the end of the string.  */
  do
    c = *s1++;
  while (c != '\0');
 
  /* Make S1 point before the next character, so we can increment
     it while memory is read (wins on pipelined cpus).  */
  s1 -= 2;
 
  do
    {
      c = *s2++;
      *++s1 = c;
    }
  while (c != '\0');
 
  return dest;
}
 
strcpy是将一个字符串复制到另外一个字符串地址上的函数,函数形式如下:
char* strcpy(char* dest,char* src)
 
函数流程
1.将src中的字符(包括结尾'\0')一个个复制到dest中,dest原来的字符将被覆盖掉。
2.将dest指针返回
注意事项:
1.dest可以不初始化,比如
char *str=(char*) malloc(sizeof(char)*100);
strcat(str,"hellow world!");
2.利用这一特性,可以用来初始化字符串变量
strcat(str,"");将达到和
*str=0;一样的效果
 
glibc中strcpy.c的函数实现
char *
strcpy (dest, src)
     char *dest;
     const char *src;
{
  reg_char c;
  char *__unbounded s = (char *__unbounded) CHECK_BOUNDS_LOW (src);
  const ptrdiff_t off = CHECK_BOUNDS_LOW (dest) - s - 1;
  size_t n;
 
  do
    {
      c = *s++;
      s[off] = c;
    }
  while (c != '\0');
 
  n = s - src;
  (void) CHECK_BOUNDS_HIGH (src + n);
  (void) CHECK_BOUNDS_HIGH (dest + n);
 
  return dest;
}
 
有没有发现这个代码实现的很tricky,off是(dest的地址-src的地址-1)
c = *s++;
s[off] = c;
相当于
c = *s++;
dest++= c;
不过我感觉这样的代码格式不值得推荐,效率上一样,但是阅读性更差。让人很难看懂。下面就扯两句,代码写的让人看得懂,比少些几行,提高一点点效率更重要。更何况,很多时候经过编译器的优化,少些的那几行不见得更高效。具体的可以看看《重构 改善既有代码的设计》这本书。先声明一下,我不是卖书的,和这本书的作者没有一毛钱关系:-D。
本文由ladd原创,欢迎转载,但请注明出处:
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值