news 2026/5/5 18:42:36

【C陷阱与缺陷】第1章:词法陷阱解析 | 避开C语言编程的初级坑

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【C陷阱与缺陷】第1章:词法陷阱解析 | 避开C语言编程的初级坑

【C陷阱与缺陷】第1章:词法陷阱解析 | 避开C语言编程的初级坑

在底层的角度下,一个程序就是一个由符号(token)或者记号组成的序列,就像一本书(程序)也只是一个单词(token)序列。还可以把程序看作语句和声明的序列,就像可以把书看作句子的序列一样。把程序分割成符号的过程叫做词法分析
写作本书的出发点不是要批判C语言,而是帮助C程序员绕过编程过程中的陷阱和障碍。全书分为8章,分别从词法分析、语法语义、连接、库函数、预处理器、可移植性缺陷等几个方面分析了C编程中可能遇到的问题。最后,作者用一章的篇幅给出了若干具有实用价值的建议。

(关注不迷路哈!!!)

文章目录

  • 【C陷阱与缺陷】第1章:词法陷阱解析 | 避开C语言编程的初级坑
    • 前言
    • 一、程序与符号(Token)的基本关系
    • 二、常见词法陷阱及实例分析
      • 1. 赋值`=`与判等`==`的混淆
      • 2. 按位运算符`&`、`|`与逻辑运算符`&&`、`||`的误用
      • 3. 词法分析的“贪心法”规则
      • 4. 整型常量的八进制陷阱
      • 5. 单引号与双引号的区别
    • 三、实战练习与思考
    • 四、总结与建议
    • 五、读后感

前言

  • 在C语言编程中,许多看似简单的错误往往源于对词法规则的误解。《C陷阱与缺陷》的第一章深入剖析了这些“词法陷阱”,帮助程序员从底层理解程序符号(token)的组成与解析逻辑。
  • 本文基于原书内容整理并扩展,结合实例分析常见问题,为C语言学习者提供实用参考。

一、程序与符号(Token)的基本关系

程序本质上是由符号(token)组成的序列,就像书籍由单词构成一样。词法分析(Lexical Analysis)是将程序拆分为符号的过程。每个符号是一个或多个字符的组合,例如if(x等。符号间的空格、换行等不影响解析,但符号本身的组合方式可能导致语义差异。考虑下面的语句:

if(x>big)big=x;// 这个语句中第一个token是if,一个关键字。// 第二个token是左括号,然后是标识符x、大于号、标识符big…// 我们可以在token间添加多余的空格(还有Tab、换行符)等。

二、常见词法陷阱及实例分析

1. 赋值=与判等==的混淆

  • 问题:C语言中=用于赋值,==用于比较。误用可能导致逻辑错误。

  • 示例

    while(c=' '||c=='\t'||c=='\n')// 错误:将比较写成了赋值c=getc(f);

    此处c = ' '实际是赋值操作,而非比较。由于=优先级低于||,整个表达式变为赋值语句,导致循环无法按预期跳过空白符。

  • 修正:明确使用==进行比较。

2. 按位运算符&|与逻辑运算符&&||的误用

  • 区别

    • &|是按位运算符,直接操作二进制位;
    • &&||是逻辑运算符,返回布尔值(0或1)。
  • 示例

    if(i&j)...// 可能误以为这是逻辑判断,实际是按位与

    ij非0或1时,结果可能与预期不符。

3. 词法分析的“贪心法”规则

  • 规则:编译器从左到右读取字符,尽可能组合最长的有效符号(如==优先于两个=)。
  • 示例
    • a---b被解析为(a--) - b,而非a - (--b)
    • /*被视为注释起始符,导致y = x/*p被误解析为注释(应写为y = x / *py = x/(*p))。
  • 注意:老版本C编译器可能支持=+等过时写法,需避免使用。

4. 整型常量的八进制陷阱

  • 规则:以0开头的数字会被解析为八进制数。

  • 示例

    010(八进制)等于十进制8,而非10

    0195是非法八进制数(数字9超出八进制范围),可能引发编译器警告。

5. 单引号与双引号的区别

  • 单引号:表示字符常量,实际是整数值(如'a'在ASCII中为97)。

  • 双引号:表示字符串,返回指向字符数组的指针(以\0结尾)。

  • 常见错误

    char*slash='/';// 错误:将整数赋给指针printf('\n');// 错误:参数应为字符串而非字符

    多字符常量(如'yes')的行为未定义,应避免使用。


三、实战练习与思考

  1. 练习1-1:测试编译器是否支持嵌套注释

    /*/**/"*/"/*"/**/
    • 支持嵌套注释时,输出等效于"/*"
    • 否则输出"*/"
  2. 练习1-3:为什么n-->0被解析为n-- > 0

    贪心法规则会优先将--视为一个符号。

  3. 练习1-4a+++++b无法通过编译

    因为a++返回的是右值(不可修改),无法再进行++操作。


四、总结与建议

第一章从词法角度揭示了C语言中看似简单却极易出错的细节。这些陷阱不仅是初学者的“拦路虎”,也是资深程序员需持续警惕的问题。通过理解底层规则,我们能更高效地编写可靠代码,避免低级错误。

  • 谨慎检查运算符:尤其是===&&&等易混淆符号。
  • 理解贪心法规则:避免因符号组合导致意外解析。
  • 规范常量写法:避免八进制误用,明确单引号与双引号的适用场景。
  • 编译器选择:使用现代编译器并开启警告选项(如-Wall),提前发现潜在问题。

五、读后感

C陷阱与缺陷》的第一章深入剖析了C语言中的词法陷阱

  1. 关于词法陷阱,作者先从区分token与字符开始讲起,进而讲述容易混淆程序员的符号,以便说明“=不同于==”和“& 和 | 不是 && 和 ||”。赋值运算符、比较运算符以及逻辑运算符,有些运算符虽然长得很相似但意义完全不同。
  2. 文中提到,把程序分割成符号的过程叫做词法分析。作者在第一章中讲述了C语言的词法规则,并且解释了每一个token的形成都是遵循贪心算法策略的。然而,正是由于C语言的词法规则,容易出现一些令人意想不到的问题,比如多个字符组合时哪个优先?字符嵌套如何处理?
  3. 当然,还有整型常量和单双引号问题,尽管编译后可能不会引发错误,但在运行时可能会产生奇奇怪怪的结果,这些陷阱可能导致的令人困惑的问题。
  4. 作为本书的阅读者,我深刻认识到C语言编程是一门值得不断学习和钻研的学问。在编程过程中,词法陷阱不仅是我们需要规避的陷阱,更是我们需要探索的宝藏。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/5 18:40:06

VisualCppRedist AIO:终极Windows运行库解决方案,告别DLL缺失烦恼

VisualCppRedist AIO:终极Windows运行库解决方案,告别DLL缺失烦恼 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist 你是否曾经遇到过打开软…

作者头像 李华
网站建设 2026/5/5 18:30:28

3分钟解锁B站缓存视频:m4s-converter终极转换指南

3分钟解锁B站缓存视频:m4s-converter终极转换指南 【免费下载链接】m4s-converter 一个跨平台小工具,将bilibili缓存的m4s格式音视频文件合并成mp4 项目地址: https://gitcode.com/gh_mirrors/m4/m4s-converter 你是否曾遇到过这样的困扰&#xf…

作者头像 李华