C语言程序while语句中*p操作数的作用与存在必要性
原
while语句中前置*p判空的必要性 你用标准输入Lloyd Fosdick测试时两个版本结果一致,是因为这个输入完全符合程序预期的格式:没有前导空格、名和姓之间用单个空格分隔、末尾带fgets读入的换行符,属于理想场景下的规范输入。这部分*p判空本质是边界安全兜底逻辑,不是为规范输入准备的,核心作用是防止非规范输入触发内存越界的未定义行为,三个循环的判空分别对应不同的异常场景:
- 第一个循环(跳过前导空格):如果去掉
*p判空,当用户输入全是空格、没有任何有效字符时,指针p会一直向后自增,越过name数组的内存边界,直到扫到内存中某个不是空格的随机字节才会停止,属于典型的野指针读越界。加了*p判断后,遇到字符串结束符\0就会立刻终止循环,不会越界。 - 第二个循环(跳过名字段找分隔空格):如果去掉
*p判空,当用户只输入了名字、没有输入空格和姓(比如只输入Lloyd就回车),指针p会一直向后扫,越过字符串结尾、越过数组边界,直到内存中碰巧碰到值为空格的字节才会停,同样是越界访问。 - 第三个循环(输出姓氏直到换行):如果去掉
*p判空,两种场景会出问题:一是前面的循环已经发生越界,根本碰不到换行符,会持续输出内存里的随机垃圾值;二是当用户输入长度超过MAX_LEN时,fgets会读满缓冲区直接加\0结尾,不会存下换行符,这时候没有判空的话循环会一直越界读,直到碰巧碰到值为\n的字节才停止。
写C语言遍历字符串时加*p判空是基本的安全习惯,相当于给循环加了个硬终止条件:只要走到字符串末尾就立刻停,不能无限制往后扫内存。只测理想输入当然看不出区别,但实际运行时的输入永远不会全按预期来,缺了这层兜底就是埋随时可能触发崩溃、泄露内存数据的隐患。
内容的提问来源于stack exchange,提问作者Fary
相关产品推荐
相关产品推荐

