wwpbjing
很高兴你能刨根问底,篇幅比较长,请耐心看完,先介绍下实验环境:C编译器:gcc6.1.0C调试器:gdb7.11.1为了讲明白,先来做个实验,见下图看到了吗?即便s1='Hello\0World',puts(s1)却只会显示Hello让我们用gdb debug一下,看看s1存成什么样看到了吗?s1确实是{'H','e','l','l','o','\0','W','o','r','l','d',9个'\0'}但puts(s1)却只显示Hello,原因是puts自动忽略了\0后面的'W','o','r','l','d',9个'\0',但它们是真实存在的再来看你提的问题:仔细看下图:上图告诉我们未执行strcat时s1{'H','e','l','l','o',15个'\0'}执行strcat(s1,s2)后s1{'H','e','l','l','o','W','o','r','l','d',10个'\0'}由实验一我们知道puts函数会把\0后截掉,最终只会显示HelloWorld那么Hello后面那15个'\0'去哪了?为什么不是Hello 15个\0 World呢?让我们读读strcat的源码:strcat源码节选:164 #ifndef __HAVE_ARCH_STRCAT
165 /**
166 * strcat - Append one %NUL-terminated string to another
167 * @dest: The string to be appended to
168 * @src: The string to append to it
169 */
170 #undef strcat
171 char *strcat(char *dest, const char *src)
172 {
173 char *tmp = dest;
174
// 上一行代码含义
// Hello\0\0\0\0\0...\0
// ^
// |
// *tmp,*dest
175 while (*dest)
176 dest++;
// 上两行代码含义
// Hello\0\0\0\0\0...\0
// ^ ^
// | |
// *tmp |
// *dest
177 while ((*dest++ = *src++) != '\0')
178 ;
// 上一行代码含义
// HelloW\0\0...\0
// ^ ^
// | |
// *tmp |
// *dest
// HelloWo\0\0...\0
// ^ ^
// | |
// *tmp |
// *dest
...
// 上一行代码含义
// HelloWold\0\0...\0
// ^ ^
// | |
// *tmp |
// *dest
179 return tmp;
180 }
181 EXPORT_SYMBOL(strcat);
182 #endif仔细读上面源码我添加的注释,可以看出函数strcat会从s1的第一个'\0'处拼接s2即:World,至此所有问题都解答了