C语言两种strcat指针实现输出不同,是while还是指针问题?
问题原因分析
两个版本的核心差异是是否复制了字符串的终止符\0,第一个版本的错误就是没有给拼接后的目标字符串补终止符,导致输出异常。
第一个版本的执行逻辑问题
while ( (*(t+j)) != '\0'){ *(s+i) = *(t+j); i++; j++; }
这个循环的判断逻辑是:先检查t[j]是不是\0,只有不是的时候才进入循环执行赋值操作。
以你的测试用例为例:
- 初始
s = "Hola",第一个循环结束后i=4,刚好指向s末尾的\0位置 t = "lala"的有效字符是4个,j从0到3时t[j]都不是\0,所以会把l、a、l、a四个字符依次赋值到s[4]到s[7]的位置- 当
j=4时,t[j]是\0,循环直接终止,没有把这个\0赋值给s[8]
C语言的字符串以\0作为结束标志,此时s末尾没有\0,printf输出时会继续读取s后面的内存内容,直到碰到随机存储的\0才停止,你碰到的多输出一个a就是后面内存的残留值。
第二个版本正确的原因
while((*(s+i) = *(t+j)) != '\0'){ i++; j++; }
这个循环的执行顺序是:
- 先执行赋值操作:把
t[j]的值赋给s[i] - 再判断刚赋给
s[i]的值是不是\0,如果是就退出循环,不是就继续
也就是说哪怕t[j]是\0,也会先完成赋值再退出,这样拼接后的s末尾就有了正确的结束标志,printf输出时会在正确的位置停止,结果自然符合预期。
额外注意事项
你的测试代码其实存在数组越界风险:你定义的char s[] = "Hola"默认只分配了5字节的空间(4个字符+1个\0),拼接后总长度是8个字符加\0共需要9字节空间,你这里没崩溃属于栈内存布局的巧合,实际开发时必须保证目标字符串的空间足够容纳拼接后的完整内容。
内容的提问来源于stack exchange,提问作者Eduardo Salavarria
相关产品推荐
相关产品推荐

