You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何在嵌套while循环中重复校验外层循环的终止条件?——基于字符串单词计数C代码的技术问询

为什么统计单词数的嵌套while循环要重复校验*ch != '\0'?

我写了一段用C语言统计字符串中单词数量的代码(单词以空格分隔),但搞不懂为什么嵌套的while循环里还要再检查外层循环的第一个条件(也就是*ch != '\0')。

int count_words(char *ch){
    int c = 0;
    while(*ch!='\0'){
        if(*ch==' '){
            ch++;
            continue;
        }
        c++;
        while(*ch && *ch !=' '){
            ch++;
        }
    }
    return c;
}

我的疑问:

  • 为什么嵌套while循环里要再次校验*ch != '\0'?
  • 是不是所有嵌套while循环都需要重复校验外层的条件?
  • 有没有我没理解到位的知识点?

核心原因:防止非法内存访问

咱们先拆解这段代码的逻辑:外层循环负责遍历整个字符串,嵌套循环的作用是跳过当前单词的所有非空格字符。那为什么嵌套循环要加*ch(等价于*ch != '\0')的检查?

举个极端场景:如果字符串的最后一个字符不是空格,比如"hello",外层循环进入后,因为第一个字符不是空格,c加1,然后进入嵌套循环。如果嵌套循环只写*ch != ' ',那当ch指向字符串末尾的'\0'时,*ch != ' '的判断是真(因为'\0'不等于空格),循环会继续执行,ch会继续往后移动,这就会访问到字符串内存之外的区域——这属于C语言里的未定义行为,程序可能崩溃、输出错误结果,或者看起来正常但埋下隐患。

所以嵌套循环里的*ch检查,是为了确保我们在跳过单词字符的时候,不会越过字符串的结束符'\0',避免非法内存访问。

是不是所有嵌套while都要重复校验外层条件?

当然不是,这得看嵌套循环的逻辑会不会修改外层循环的终止条件变量,以及会不会导致外层的终止条件失效。

比如如果嵌套循环只是处理当前元素,不会移动ch指针,那外层的*ch != '\0'已经能保证安全,就不需要重复检查。但在这个例子里,嵌套循环会持续移动ch指针,完全有可能让ch直接指向'\0',这时候如果没有内层的检查,循环就会“跑飞”。

简单总结:当嵌套循环会修改外层循环的终止条件变量,且可能提前触发外层的终止条件时,就需要在内层循环里也加上对应的检查。

补充知识点:C语言字符串的结束标记

C语言里的字符串是以'\0'(空字符,ASCII值为0)作为结束标记的,没有内置的长度信息。所以所有遍历字符串的代码,都必须时刻注意不要越过这个结束符——一旦访问了'\0'之后的内存,就是未定义行为,结果不可预测。

另外,代码里的*ch其实是*ch != '\0'的简写,因为在C的布尔判断里,0会被视为假,非0值视为真,所以*ch等价于*ch != '\0',写法更简洁。

内容的提问来源于stack exchange,提问作者Fang Yuan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 18:17:38