首先看看代码:
1 #ifndef STRCAT_H 2 #define STRCAT_H 3 4 /******************************************************************* 5 原型:extern char *strcat(char *dest,char *src); 6 7 strcat() 会将参数 src 字符串复制到参数 dest 所指的字符串尾部; 8 dest最后的结束字符NULL会被覆盖掉,并在连接后的字符串的尾部再增加一个 NULL。 9 10 返回指向dest的指针。 11 12 注意:dest 与 src 所指的内存空间不能重叠, 13 且 dest 要有足够的空间来容纳要复制的字符串。 14 15 ******************************************************************* 16 拓展: 17 * 有两个意思,理论上 18 作为 乘法 运算符,级别低于 ++(自增)。 19 作为 指针取值 运算符,级别同 ++(自增)一样。 20 21 *p++; 很令人混淆。它不是 *p = *p + 1; 而是 *p = *(p+1); 22 *******************************************************************/ 23 24 #include <stdio.h> 25 26 char *cat_stacat(char *dst, const char *src) { 27 if (NULL == dst && NULL == src) 28 return NULL; 29 30 char *addr = dst; 31 32 // 方法1: 33 // Notice: 注意方法1和2的区别!方法1的话,最后一次循环dst加了1,最终指向字符串结束符‘\0‘的下一字节 // 如果不--dst。则最后可能是“hello\0world”,遇到\0就结束,所以只会输出hello 34 /*while (*dst++) ; 35 --dst;*/ 36 37 // 方法2: 38 while (*dst) 39 ++dst; 40 41 while (*dst++ = *src++) ; 42 43 *dst = ‘\0‘; // 44 45 46 return addr; // 返回指向dst的指针 47 } 48 49 50 #endif
main:
1 #include "strcat.h" 2 3 void test_strcat(); 4 5 int main() { 6 7 test_strcat(); 8 9 return 0; 10 } 11 12 void test_strcat() { 13 char dst[64] = { "hello" }; // 保证dst有足够的空间 14 15 char *ret = cat_stacat(dst, " world!"); 16 17 printf("%s\n%s\n", ret, dst); 18 }
注意!!!
1 // 方法1: 2 // Notice: 注意方法1和2的区别!方法1的话,最后一次循环dst加了1,最终指向字符串结束符‘\0‘的下一字节 3 while (*dst++) ; 4 --dst; 5 6 // 方法2: 7 while (*dst) 8 ++dst;
注意这2种写法的区别!!!
让我看看while(*p++ !=‘\0’)的秘密。原以为跳出后,p指向‘\0‘,而实际上并非如此!这样子怎么拼接都实现不了。为了验证这个问题,我们先上个小程序吧:
1 #include<stdio.h> 2 3 void main() 4 5 { 6 7 char *p = "abcdefg"; 8 9 while(*p++ != ‘c‘); 10 11 printf("%c\n", *p); 12 13 }
您猜打印出来的是几? 结果是d。
为什么呢?
原来*和++的优先级是一样的,当优先级一样的时候,程序按自左至右的顺序执行。所以当*p = ‘c‘ 或者*p = ‘\0‘时,p仍然要往下移一位,即p指向满足条件后的下一个字节。(cat_strcat函数代码中的最后一次循环dst加了1,最终指向字符串结束符‘\0‘的下一字节)
由于‘\0‘ 结束符,if 、while当会把他判成0,因此程序写成while(*p++ );效果也一样,最终程序指向字符串结束符‘\0‘的下一字节。
如果这样写:
while(*p) p++;
当*p=‘\0‘时,进不到while里面的循环,因此这种写法跳出循环的时候,p指向的是‘\0‘。同志们注意了,这样写while后面是没有“;”号的。
//===========================================================//
最后,main函数输出的ret和dst的字符串是一样的!!
既然一样,为什么还需要返回那个值呢?岂不是多此一举?
原因其实很简单,我们写c代码的时候,常会用到链式调用。
即:通过返回首地址可以实现像strcat(strcat(dst, str1), str2);一样的用法!!!
在前面实现strcpy的博文中也说到了这点:http://www.cnblogs.com/lingshaohu/p/3961132.html
参考:http://blog.csdn.net/yanzi1225627/article/details/7843672