<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <id>https://firefly.cuteleaf.cn/</id>
  <title type="text">Dream Blog</title>
  <subtitle type="text">Demo site</subtitle>
  <updated>2026-09-26T00:00:00.000Z</updated>
  <author><name>Dream</name></author>
  <link rel="alternate" href="https://firefly.cuteleaf.cn/"/>
  <link rel="self" href="https://firefly.cuteleaf.cn/atom.xml"/>
  <generator uri="https://github.com/CuteLeaf/Firefly">Firefly v6.16.8</generator>
    <entry>
      <id>https://firefly.cuteleaf.cn/posts/language/c/10c%E8%AF%AD%E8%A8%80%E4%BB%8B%E7%BB%8D/10c%E8%AF%AD%E8%A8%80%E5%8F%91%E5%B1%95%E5%8F%B2/</id>
      <title type="text">C 语言发展史</title>
      <published>2026-09-26T00:00:00.000Z</published>
      <updated>2026-09-26T00:00:00.000Z</updated>
      <author><name>Dream</name></author>
      <link rel="alternate" href="https://firefly.cuteleaf.cn/posts/language/c/10c%E8%AF%AD%E8%A8%80%E4%BB%8B%E7%BB%8D/10c%E8%AF%AD%E8%A8%80%E5%8F%91%E5%B1%95%E5%8F%B2/"/>
      <summary type="text">了解 C 语言从 BCPL、B 语言到现代标准 C 的发展历程、核心特点与应用领域。</summary>
      <content type="html"><![CDATA[<section><h1>C 语言发展史<a href="#c-语言发展史"><span>#</span></a></h1><blockquote><p>C 语言由丹尼斯·里奇（Dennis Ritchie）于 20 世纪 70 年代初在贝尔实验室主持设计。它最初服务于 UNIX 操作系统开发，核心目标是在运行效率、底层控制能力和源代码可移植性之间取得平衡。</p></blockquote></section>
<section><h1>【一】C 语言诞生的背景<a href="#一c-语言诞生的背景"><span>#</span></a></h1><p>早期操作系统主要使用汇编语言编写。汇编语言执行效率高，也能直接控制硬件，但它与具体处理器紧密相关：更换硬件平台后，程序往往需要大幅重写。</p><p>高级语言虽然更容易编写和移植，当时却难以同时满足系统软件对运行效率和底层操作的要求。C 语言正是在这一矛盾中逐步形成的。</p><p>其演进关系可以概括为：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>BCPL（1967）</span></div></div><div><div><div>2</div></div><div><span><span>    </span></span><span>↓</span></div></div><div><div><div>3</div></div><div><span>B 语言（1969）</span></div></div><div><div><div>4</div></div><div><span><span>    </span></span><span>↓</span></div></div><div><div><div>5</div></div><div><span>C 语言（约 1972）</span></div></div></code></pre><div><div></div><div></div></div></figure></div><section><h2>【1】BCPL 语言<a href="#1bcpl-语言"><span>#</span></a></h2><p>1967 年，马丁·理查兹（Martin Richards）设计了 BCPL。它是一种结构简单、便于编写编译器的无类型语言，对后来的 B 语言产生了直接影响。</p></section><section><h2>【2】B 语言<a href="#2b-语言"><span>#</span></a></h2><p>1969 年前后，肯·汤普森（Ken Thompson）在贝尔实验室以 BCPL 为基础设计了 B 语言，并将其用于早期 UNIX 系统的开发。</p><p>B 语言采用“无类型”的设计，适合当时字长固定的计算机，但在 PDP-11 等新硬件上逐渐暴露出数据类型不足、运行效率不高等问题。</p></section><section><h2>【3】C 语言诞生<a href="#3c-语言诞生"><span>#</span></a></h2><p>1971—1973 年间，丹尼斯·里奇对 B 语言进行改进，逐步加入字符、整数、指针、数组和结构体等机制。改进后的语言最初被称为“New B”，后来正式命名为 C。</p><p>1973 年，UNIX 内核的大部分代码被改用 C 语言编写。这一实践证明：操作系统并非只能使用汇编语言开发，也使 UNIX 更容易被移植到不同的计算机平台。</p></section></section>
<section><h1>【二】重要发展时间线<a href="#二重要发展时间线"><span>#</span></a></h1>

<table><thead><tr><th>时间</th><th>事件</th><th>意义</th></tr></thead><tbody><tr><td>1967 年</td><td>BCPL 语言诞生</td><td>为 B 语言提供设计基础</td></tr><tr><td>1969 年</td><td>肯·汤普森设计 B 语言</td><td>用于早期 UNIX 开发</td></tr><tr><td>1972 年前后</td><td>丹尼斯·里奇设计 C 语言</td><td>加入数据类型等重要机制</td></tr><tr><td>1973 年</td><td>UNIX 内核大部分改用 C 编写</td><td>验证了 C 语言的系统编程能力和可移植性</td></tr><tr><td>1978 年</td><td>《The C Programming Language》第一版出版</td><td>K&amp;R C 成为事实上的语言规范</td></tr><tr><td>1983 年</td><td>ANSI 成立 X3J11 委员会</td><td>C 语言标准化工作正式展开</td></tr><tr><td>1989 年</td><td>ANSI 发布 C89</td><td>C 语言的第一个正式标准</td></tr><tr><td>1990 年</td><td>ISO 发布 C90</td><td>将 C89 纳入国际标准体系</td></tr><tr><td>1995 年</td><td>发布 C95 修订案</td><td>增强宽字符和多字节字符支持</td></tr><tr><td>1999 年</td><td>发布 C99</td><td>语言功能和标准库得到大幅扩展</td></tr><tr><td>2011 年</td><td>发布 C11</td><td>引入原子操作、线程和泛型选择等功能</td></tr><tr><td>2018 年</td><td>发布 C17</td><td>主要修正和澄清 C11</td></tr><tr><td>2024 年</td><td>ISO/IEC 9899&lt;2024&gt; 正式发布</td><td>通常称为 C23，是当前主要标准版本</td></tr></tbody></table></section>
<section><h1>【三】K&amp;R C 与标准化<a href="#三kr-c-与标准化"><span>#</span></a></h1><p>1978 年，布莱恩·柯林汉（Brian Kernighan）和丹尼斯·里奇合著的《C 程序设计语言》（<em>The C Programming Language</em>）第一版出版。</p><p></p><figure><img src="https://oss.silentdream.top/2026/09/26/19-48-35-f7d58bb0-s28292981-1789996115038-8-e0d035.jpg" alt="《C 程序设计语言》封面" /><figcaption>《C 程序设计语言》封面</figcaption></figure><p></p><p>书中描述的 C 语言后来被称为 <strong>K&amp;R C</strong>。它不是由标准化组织发布的正式标准，但在 C89 出现以前长期被视为事实上的规范。</p><p>随着 C 语言不断普及，不同编译器对语言的实现逐渐产生差异。为了提高程序的兼容性和可移植性，美国国家标准协会（ANSI）于 1983 年成立 X3J11 委员会，并在 1989 年发布第一个正式标准 C89。</p></section>
<section><h1>【四】C 语言标准演进<a href="#四c-语言标准演进"><span>#</span></a></h1><section><h2>【1】C89 与 C90<a href="#1c89-与-c90"><span>#</span></a></h2><ul>
<li><strong>C89</strong>：ANSI X3.159-1989。</li>
<li><strong>C90</strong>：ISO/IEC 9899&lt;1990&gt;。</li>
<li>两者在技术内容上基本相同，通常合称为 <strong>ANSI C</strong> 或 <strong>C89/C90</strong>。</li>
<li>引入函数原型，完善类型检查。</li>
<li>标准化 <code>void</code>、<code>const</code>、<code>volatile</code> 等类型和限定符。</li>
<li>系统定义标准头文件和标准库。</li>
<li>明确预处理、类型转换和程序行为规则。</li>
</ul></section><section><h2>【2】C95<a href="#2c95"><span>#</span></a></h2><p>C95 并不是一次完整重写的语言标准，而是对 C90 的修订，正式形式为 C90 的 Amendment 1。</p><p>主要变化包括：</p><ul>
<li>加强宽字符和多字节字符支持。</li>
<li>增加 <code>&lt;wchar.h&gt;</code> 和 <code>&lt;wctype.h&gt;</code>。</li>
<li>增加用于替代部分特殊字符的双字符组（digraph）。</li>
</ul></section><section><h2>【3】C99<a href="#3c99"><span>#</span></a></h2><p>C99 是 C 语言历史上一次重要更新，代表性变化包括：</p><ul>
<li>允许使用 <code>//</code> 单行注释。</li>
<li>允许在语句之间声明变量。</li>
<li>允许在 <code>for</code> 初始化部分声明变量。</li>
<li>增加 <code>long long</code>、<code>_Bool</code> 和复数类型。</li>
<li>引入 <code>inline</code> 和 <code>restrict</code>。</li>
<li>支持可变长度数组（VLA）。</li>
<li>支持指定初始化器、复合字面量和柔性数组成员。</li>
<li>增加 <code>&lt;stdint.h&gt;</code> 等标准头文件。</li>
</ul><blockquote><p>从 C11 开始，可变长度数组变为实现可选功能，并不是所有编译器都完整支持。</p></blockquote></section><section><h2>【4】C11<a href="#4c11"><span>#</span></a></h2><p>C11 更关注并发编程、类型安全和现代硬件支持，代表性变化包括：</p><ul>
<li>引入 <code>_Atomic</code> 和原子操作。</li>
<li>增加 <code>&lt;threads.h&gt;</code> 线程库。</li>
<li>引入 <code>_Generic</code> 泛型选择。</li>
<li>引入 <code>_Static_assert</code> 静态断言。</li>
<li>支持匿名结构体和匿名联合体。</li>
<li>增加对齐控制功能。</li>
<li>改进 Unicode 字符支持。</li>
</ul><p>线程和原子操作在部分实现中属于可选功能，实际使用时需要检查编译器及标准库支持情况。</p></section><section><h2>【5】C17（C18）<a href="#5c17c18"><span>#</span></a></h2><p>C17 的正式标准编号为 <strong>ISO/IEC 9899&lt;2018&gt;</strong>，因此也经常被称为 C18。</p><p>它没有加入重要的新语言特性，主要用于修正 C11 中的缺陷、歧义和规范表述问题，是对 C11 的维护性更新。</p></section><section><h2>【6】C23<a href="#6c23"><span>#</span></a></h2><p>C23 在开发阶段曾被称为 <strong>C2X</strong>，最终标准文件为 <strong>ISO/IEC 9899&lt;2024&gt;</strong>。虽然正式文件于 2024 年发布，业界通常仍将这一版本称为 C23。</p><p>代表性变化包括：</p><ul>
<li>增加 <code>nullptr</code> 和 <code>nullptr_t</code>。</li>
<li>增加 <code>typeof</code> 和 <code>typeof_unqual</code>。</li>
<li>支持 <code>constexpr</code> 对象。</li>
<li>支持二进制整数字面量和数字分隔符。</li>
<li>增加 <code>_BitInt</code> 位精确整数类型。</li>
<li>引入 <code>#embed</code> 预处理指令。</li>
<li>改进枚举、属性和类型推导能力。</li>
<li>将 <code>bool</code>、<code>true</code>、<code>false</code> 纳入语言本身。</li>
<li>删除部分过时的旧式语法。</li>
</ul><blockquote><p>C23 较新，不同编译器对各项特性的支持程度可能不同。使用前应查看具体编译器版本的说明。</p></blockquote></section></section>
<section><h1>【五】各版本对比<a href="#五各版本对比"><span>#</span></a></h1>

<table><thead><tr><th>版本</th><th>发布时间</th><th>定位</th><th>代表性变化</th></tr></thead><tbody><tr><td>K&amp;R C</td><td>1978 年</td><td>事实规范</td><td>描述标准化以前的经典 C 语言</td></tr><tr><td>C89/C90</td><td>1989/1990 年</td><td>首个正式标准</td><td>函数原型、类型限定符、标准库</td></tr><tr><td>C95</td><td>1995 年</td><td>C90 修订案</td><td>宽字符、多字节字符</td></tr><tr><td>C99</td><td>1999 年</td><td>大规模功能扩展</td><td><code>//</code>、<code>inline</code>、VLA、<code>stdint.h</code></td></tr><tr><td>C11</td><td>2011 年</td><td>现代化更新</td><td>原子操作、线程、泛型选择、静态断言</td></tr><tr><td>C17</td><td>2018 年</td><td>维护性版本</td><td>修正和澄清 C11</td></tr><tr><td>C23</td><td>2024 年正式发布</td><td>当前主要标准版本</td><td><code>nullptr</code>、<code>typeof</code>、<code>constexpr</code>、<code>#embed</code></td></tr></tbody></table></section>
<section><h1>【六】C 语言的主要特点<a href="#六c-语言的主要特点"><span>#</span></a></h1><section><h2>【1】运行效率高<a href="#1运行效率高"><span>#</span></a></h2><p>C 语言提供较少的运行时抽象，程序通常可以被编译成高效的机器代码，因此适合对性能和资源占用要求较高的场景。</p></section><section><h2>【2】具备底层控制能力<a href="#2具备底层控制能力"><span>#</span></a></h2><p>指针、位运算和内存操作使 C 语言能够直接处理内存地址、寄存器及硬件资源。</p></section><section><h2>【3】源代码可移植性较好<a href="#3源代码可移植性较好"><span>#</span></a></h2><p>符合标准且避免依赖平台特性的 C 程序，通常只需少量修改或重新编译，就能运行在不同平台上。</p><p>“可移植”并不意味着所有 C 程序在任何平台上都会得到完全相同的结果。数据类型长度、字节序及实现定义行为等仍可能存在差异。</p></section><section><h2>【4】语言核心精简<a href="#4语言核心精简"><span>#</span></a></h2><p>C 语言的语法和核心机制相对精简，许多功能通过标准库或第三方库提供。这种设计带来了灵活性，也要求程序员主动管理资源。</p></section><section><h2>【5】需要关注内存安全<a href="#5需要关注内存安全"><span>#</span></a></h2><p>C 语言允许直接操作内存，但不会自动进行边界检查或垃圾回收。数组越界、空指针、悬空指针和内存泄漏都是常见风险。</p></section></section>
<section><h1>【七】主要应用领域<a href="#七主要应用领域"><span>#</span></a></h1><ul>
<li><strong>操作系统与内核</strong>：UNIX、Linux 内核及部分 Windows 系统组件。</li>
<li><strong>嵌入式系统</strong>：单片机、汽车电子、工业控制和物联网设备。</li>
<li><strong>驱动程序与固件</strong>：需要直接操作硬件和寄存器的程序。</li>
<li><strong>编译器与运行时</strong>：编译器、解释器及语言运行库。</li>
<li><strong>数据库与基础软件</strong>：数据库、网络服务和高性能基础组件。</li>
<li><strong>跨语言接口</strong>：C ABI 简单而稳定，许多语言通过 C 接口调用系统库。</li>
</ul></section>
<section><h1>【八】C 语言的影响<a href="#八c-语言的影响"><span>#</span></a></h1><p>C 语言对后来的编程语言产生了深远影响。C++ 和 Objective-C 直接建立在 C 的基础上；Java、C#、JavaScript 等语言也借鉴了大量 C 风格语法。</p><p>更重要的是，C 语言及其 ABI 已成为操作系统、硬件和高级编程语言之间的重要接口。即使应用程序并不直接使用 C 编写，其底层往往仍依赖 C 标准库、系统调用或由 C 实现的运行时组件。</p></section>
<section><h1>【九】常见认识误区<a href="#九常见认识误区"><span>#</span></a></h1><ol>
<li>
<p><strong>C 语言不是在 1972 年某一天突然完成的。</strong><br />
它是在 1971—1973 年间逐步设计和完善的。</p>
</li>
<li>
<p><strong>K&amp;R C 不是正式标准。</strong><br />
它是 C89 出现以前被广泛采用的事实规范。</p>
</li>
<li>
<p><strong>C89 和 C90 不是两个差异明显的版本。</strong><br />
二者技术内容基本相同，只是发布组织和年份不同。</p>
</li>
<li>
<p><strong>C17 和 C18 通常指同一代标准。</strong><br />
C17 是常用名称，正式标准文件发布于 2018 年。</p>
</li>
<li>
<p><strong>C2X 已经不再是“计划中的标准”。</strong><br />
它最终发展为 C23，并以 ISO/IEC 9899&lt;2024&gt; 的形式正式发布。</p>
</li>
<li>
<p><strong>可移植性不等于完全与平台无关。</strong><br />
编写可移植程序仍需避免未定义行为和平台相关假设。</p>
</li>
</ol></section>
<section><h1>【十】总结<a href="#十总结"><span>#</span></a></h1><p>C 语言的发展可以概括为：</p><blockquote><p>使用接近高级语言的结构化表达方式，获得接近底层硬件的控制能力。</p></blockquote><p>它诞生于 UNIX 操作系统的开发需求，经过 K&amp;R C、C89/C90、C99、C11、C17 和 C23 等阶段不断完善。虽然现代编程语言不断涌现，C 语言仍然是操作系统、嵌入式开发、编译器和高性能基础软件领域的重要工具。</p><p>学习 C 语言不仅是学习一种语法，更是在理解内存、数据表示、编译过程及计算机系统的基本工作方式。</p></section>
<section><h1>【十一】延伸阅读<a href="#十一延伸阅读"><span>#</span></a></h1><ul>
<li><a href="https://www.bell-labs.com/usr/dmr/www/chist.html" target="_blank">The Development of the C Language</a></li>
<li><a href="https://www.open-std.org/jtc1/sc22/wg14/" target="_blank">ISO/IEC JTC 1/SC 22/WG 14（C 语言标准工作组）</a></li>
<li><a href="https://www.iso.org/standard/82075.html" target="_blank">ISO/IEC 9899&lt;2024&gt;</a></li>
</ul></section>]]></content>
    </entry>
    <entry>
      <id>https://firefly.cuteleaf.cn/posts/language/c/10c%E8%AF%AD%E8%A8%80%E4%BB%8B%E7%BB%8D/20c%E7%8E%AF%E5%A2%83%E5%AE%89%E8%A3%85/</id>
      <title type="text">C 语言开发环境的安装与配置</title>
      <published>2026-09-26T00:00:00.000Z</published>
      <updated>2026-09-26T00:00:00.000Z</updated>
      <author><name>Dream</name></author>
      <link rel="alternate" href="https://firefly.cuteleaf.cn/posts/language/c/10c%E8%AF%AD%E8%A8%80%E4%BB%8B%E7%BB%8D/20c%E7%8E%AF%E5%A2%83%E5%AE%89%E8%A3%85/"/>
      <summary type="text">在 Windows、Linux 与 macOS 上安装 C 工具链，配置编辑器，并编译运行第一个 C 程序。</summary>
      <content type="html"><![CDATA[<section><h1>C 语言开发环境的安装与配置<a href="#c-语言开发环境的安装与配置"><span>#</span></a></h1><p>编写并运行一个 C 程序，至少需要以下两类工具：</p><ol>
<li><strong>代码编辑器或集成开发环境（IDE）</strong>：用于编写和管理源代码。</li>
<li><strong>C 工具链</strong>：通常包含编译器、链接器、调试器和构建工具。</li>
</ol><blockquote><p><strong>注意：</strong> Visual Studio Code 只是代码编辑器。安装 C/C++ 扩展后，还需要单独安装 GCC、Clang 或 MSVC 等编译器，才能编译和运行 C 程序。</p></blockquote></section>
<section><h1>【一】开发工具的组成<a href="#一开发工具的组成"><span>#</span></a></h1>

<table><thead><tr><th>工具</th><th>作用</th><th>常见选择</th></tr></thead><tbody><tr><td>编辑器 / IDE</td><td>编写代码、管理文件、提供代码提示</td><td>Visual Studio Code、Visual Studio、CLion、Vim</td></tr><tr><td>编译器</td><td>将 C 源代码翻译为目标代码</td><td>GCC、Clang、MSVC</td></tr><tr><td>链接器</td><td>将目标文件和库组合成可执行程序</td><td>GNU <code>ld</code>、LLVM <code>lld</code>、MSVC LINK</td></tr><tr><td>调试器</td><td>单步执行、查看变量和调用栈</td><td>GDB、LLDB、Visual Studio Debugger</td></tr><tr><td>构建工具</td><td>自动执行多文件编译和链接</td><td>Make、CMake、Ninja</td></tr></tbody></table><p>C 源文件通常使用 <code>.c</code> 扩展名，头文件通常使用 <code>.h</code> 扩展名。例如：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>hello.c       C 源文件</span></div></div><div><div><div>2</div></div><div><span>student.h     头文件</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
<section><h1>【二】编辑器的选择<a href="#二编辑器的选择"><span>#</span></a></h1><section><h2>【1】Visual Studio Code<a href="#1visual-studio-code"><span>#</span></a></h2><p>Visual Studio Code（简称 VS Code）体积较小、跨平台且扩展丰富，适合初学者使用。</p><ul>
<li>下载地址：<a href="https://code.visualstudio.com/" target="_blank">Visual Studio Code 官网</a></li>
<li>C/C++ 扩展：<a href="https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools" target="_blank">Microsoft C/C++</a></li>
</ul><p>安装 VS Code 后，在扩展面板中搜索并安装 Microsoft 发布的 <strong>C/C++</strong> 扩展。该扩展提供代码补全、语法检查和调试支持，但编译器仍需单独安装。</p><blockquote><p>初学阶段建议先在终端中手动执行编译命令。这样可以清楚理解“源文件 → 编译 → 可执行文件 → 运行”的过程。</p></blockquote></section><section><h2>【2】其他选择<a href="#2其他选择"><span>#</span></a></h2><ul>
<li><strong>Visual Studio</strong>：适合 Windows，内置 MSVC 工具链和图形化调试器。</li>
<li><strong>CLion</strong>：跨平台商业 IDE，学生和符合条件的开源开发者可申请免费许可。</li>
<li><strong>Vim / Neovim / Emacs</strong>：高度可定制，适合熟悉命令行的用户。</li>
<li><strong>Sublime Text</strong>：轻量、启动快，但编译和调试通常需要自行配置。</li>
</ul><blockquote><p>Atom 已于 2022 年停止官方维护，不建议再作为新的 C 语言学习环境。</p></blockquote></section></section>
<section><h1>【三】Windows 环境安装（推荐）<a href="#三windows-环境安装推荐"><span>#</span></a></h1><p>Windows 上可以选择 GCC、MSVC 或 WSL 等开发方案。本文采用以下组合搭建 C 语言开发环境：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>VS Code + MinGW-w64 工具链（GCC + GDB）</span></div></div></code></pre><div><div></div><div></div></div></figure></div><section><h2>【1】安装 MinGW-w64<a href="#1安装-mingw-w64"><span>#</span></a></h2><ul>
<li>为了在 Windows 上使用 GCC，可以安装 MinGW-w64。</li>
<li>MinGW-w64 是一个开源项目，为 Windows 系统提供 GCC 工具链及相关运行库，支持生成 32 位和 64 位 Windows 应用程序。</li>
<li>访问 <a href="https://www.mingw-w64.org/" target="_blank">MinGW-w64 官网</a>，进入其<a href="https://www.mingw-w64.org/downloads/" target="_blank">下载页面</a>，选择合适的 MinGW-w64 发行包。</li>
<li>MinGW-w64 的下载页面列出了多个发行包及相关工具：</li>
</ul><p></p><figure><img src="https://oss.silentdream.top/2026/09/26/19-49-34-11125fa0-598e5e491cc2e43fd2b008111e8cb92e-1789999682807-1-d07c7a.png" alt="img" /><figcaption>img</figcaption></figure><p></p><ul>
<li>本文采用 MinGW-w64。单击图中红框标出的“SourceForge”超链接，即可进入 SourceForge 上的 MinGW-w64 下载页面。</li>
<li>SourceForge 下载地址：<a href="https://sourceforge.net/projects/mingw-w64/files/" target="_blank">MinGW-w64 Files</a></li>
<li>GitHub 上也提供了编译完成的二进制包：<a href="https://github.com/niXman/mingw-builds-binaries/releases" target="_blank">MinGW-Builds</a></li>
</ul><p></p><figure><img src="https://oss.silentdream.top/2026/09/26/19-49-34-948360d2-5c80d450eb6bd2930f011df68fe935c3-1789999693704-4-f9f974.png" alt="img" /><figcaption>img</figcaption></figure><p></p><p>进入下载页面后，可以根据 Windows 系统架构选择对应的安装包：</p><p></p><figure><img src="https://oss.silentdream.top/2026/09/26/19-49-34-f3ff59e5-6576bba5be6352d1268c7769704a537e44-3066be.png" alt="img" /><figcaption>img</figcaption></figure><p></p><p>使用在线安装程序时，可能会遇到网络连接错误，因此也可以直接下载 SJLJ 版本的压缩包（提供 32 位和 64 位版本）：</p><ul>
<li>[下载 32 位 sjlj](<a href="https://sourceforge.net/projects/mingw-w64/files/Toolchains" target="_blank">https://sourceforge.net/projects/mingw-w64/files/Toolchains</a> targetting Win32/Personal Builds/mingw-builds/8.1.0/threads-posix/sjlj/)</li>
<li>[下载 64 位 sjlj](<a href="https://sourceforge.net/projects/mingw-w64/files/Toolchains" target="_blank">https://sourceforge.net/projects/mingw-w64/files/Toolchains</a> targetting Win64/Personal Builds/mingw-builds/8.1.0/threads-posix/sjlj/)</li>
</ul><p>下载完成后，将压缩包解压到合适的位置。在其 <code>bin</code> 目录中可以找到 <code>gcc.exe</code>、<code>g++.exe</code> 等程序：</p><p></p><figure><img src="https://oss.silentdream.top/2026/09/26/19-49-34-b5387ce9-0c7bc6a0115ffa879f01885c9bbe6e75-1789999736200-9-a51be2.png" alt="img" /><figcaption>img</figcaption></figure><p></p><ul>
<li>安装 MinGW-w64 时，需要确保所选工具包中包含 GCC、G++、Binutils 和运行库等基本组件。</li>
<li>将 MinGW-w64 安装目录下的 <code>bin</code> 子目录添加到 <strong>Path</strong> 环境变量中。完成配置后，即可在命令行中直接调用这些工具。</li>
</ul><p></p><figure><img src="https://oss.silentdream.top/2026/09/26/19-49-34-17214cea-c3452d2b6a990b107498381ccfef5bd4-1789999750065-12-2f8eaa.png" alt="img" /><figcaption>img</figcaption></figure><p></p><ul>
<li>安装并配置完成后，可以在 Windows 命令行中运行 <code>gcc</code>、<code>g++</code>、<code>ar</code>、<code>ranlib</code>、<code>dlltool</code> 等 GNU 工具。</li>
</ul></section><section><h2>【2】安装 VS Code<a href="#2安装-vs-code"><span>#</span></a></h2><section><h3>（1）下载安装包<a href="#1下载安装包"><span>#</span></a></h3><ul>
<li>从 <a href="https://code.visualstudio.com/" target="_blank">VS Code 官网</a>下载安装程序。</li>
</ul><p></p><figure><img src="https://oss.silentdream.top/2026/09/26/19-49-34-644cd4b0-image-20260921220124456-fd98f2.png" alt="image-20260921220124456" /><figcaption>image-20260921220124456</figcaption></figure><p></p></section><section><h3>（2）安装<a href="#2安装"><span>#</span></a></h3><ul>
<li>双击下载的安装程序，开始安装。图中使用的安装包名称为 <code>VSCodeUserSetup-x64-1.83.1.exe</code>；实际文件名会随版本更新而变化。</li>
</ul><p></p><figure><img src="https://oss.silentdream.top/2026/09/26/19-49-34-3bc8e7f9-image-20260921220218339-46e29c.png" alt="image-20260921220218339" /><figcaption>image-20260921220218339</figcaption></figure><p></p><ul>
<li>选择安装位置，然后单击“下一步”。</li>
</ul><p></p><figure><img src="https://oss.silentdream.top/2026/09/26/19-49-34-5db8d5d0-image-20260921220229486-74f4d3.png" alt="image-20260921220229486" /><figcaption>image-20260921220229486</figcaption></figure><p></p><ul>
<li>选择开始菜单文件夹。这里采用默认选项，直接单击“下一步”。</li>
</ul><p></p><figure><img src="https://oss.silentdream.top/2026/09/26/19-49-34-ab9a6e91-image-20260921220241479-60fd4b.png" alt="image-20260921220241479" /><figcaption>image-20260921220241479</figcaption></figure><p></p><ul>
<li>选择附加任务。为了方便后续使用，这里勾选图中所示的全部选项。</li>
</ul><p></p><figure><img src="https://oss.silentdream.top/2026/09/26/19-49-34-4be52887-image-20260921220258127-5e40cb.png" alt="image-20260921220258127" /><figcaption>image-20260921220258127</figcaption></figure><p></p><ul>
<li>确认安装设置后，单击“安装”。</li>
</ul><p></p><figure><img src="https://oss.silentdream.top/2026/09/26/19-49-34-dfa0a193-image-20260921220308116-8b6316.png" alt="image-20260921220308116" /><figcaption>image-20260921220308116</figcaption></figure><p></p><ul>
<li>安装完成后，勾选“启动 Visual Studio Code”，然后单击“完成”。</li>
</ul><p></p><figure><img src="https://oss.silentdream.top/2026/09/26/19-49-34-bbbfef00-image-20260921220320533-b275c0.png" alt="image-20260921220320533" /><figcaption>image-20260921220320533</figcaption></figure><p></p></section><section><h3>（3）选择颜色主题风格<a href="#3选择颜色主题风格"><span>#</span></a></h3><ul>
<li>VS Code 首次启动时会打开欢迎页面，可以在其中选择颜色主题。默认主题为深色模式，本文选择浅色模式；后续也可以在设置中随时更换主题。</li>
</ul><p></p><figure><img src="https://oss.silentdream.top/2026/09/26/19-49-34-639f01d2-image-20260921220358709-b42189.png" alt="image-20260921220358709" /><figcaption>image-20260921220358709</figcaption></figure><p></p></section><section><h3>（4）配置 VS Code<a href="#4配置-vs-code"><span>#</span></a></h3><section><h4>[1] 安装中文语言包<a href="#1-安装中文语言包"><span>#</span></a></h4><ul>
<li>单击左侧活动栏中的“扩展”按钮，在搜索框中输入 <code>Chinese</code>，找到并安装 <strong>Chinese (Simplified) (简体中文) Language Pack for Visual Studio Code</strong>。</li>
</ul><p></p><figure><img src="https://oss.silentdream.top/2026/09/26/19-49-34-22090bd1-image-20260921220449049-a0b61b.png" alt="image-20260921220449049" /><figcaption>image-20260921220449049</figcaption></figure><p></p><ul>
<li>语言包安装完成后需要重启 VS Code。正常情况下，界面会显示重启按钮；如果没有显示，也可以手动关闭并重新启动 VS Code。</li>
</ul><p></p><figure><img src="https://oss.silentdream.top/2026/09/26/19-49-34-3151e989-image-20260921220501215-5e5970.png" alt="image-20260921220501215" /><figcaption>image-20260921220501215</figcaption></figure><p></p></section><section><h4>[2] 安装 C 语言扩展<a href="#2-安装-c-语言扩展"><span>#</span></a></h4><ul>
<li>单击左侧活动栏中的“扩展”按钮，搜索 <code>C/C++</code>，选择并安装 <strong>C/C++ Extension Pack</strong>。该扩展包集成了 C/C++ 开发中常用的多个扩展。</li>
</ul><p></p><figure><img src="https://oss.silentdream.top/2026/09/26/19-49-34-94dbf436-image-20260921220543673-d8fbce.png" alt="image-20260921220543673" /><figcaption>image-20260921220543673</figcaption></figure><p></p></section></section></section><section><h2>【3】验证安装<a href="#3验证安装"><span>#</span></a></h2><p>完全关闭并重新打开 VS Code，然后新建一个 PowerShell 终端，依次执行：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span><span>gcc </span><span>--</span><span>version</span></span></div></div><div><div><div>2</div></div><div><span><span>gdb </span><span>--</span><span>version</span></span></div></div><div><div><div>3</div></div><div><span>Get-Command</span><span> gcc</span></div></div><div><div><div>4</div></div><div><span><span>gcc </span><span>-</span><span>dumpmachine</span></span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>如果安装正确：</p><ul>
<li><code>gcc --version</code> 会显示 GCC 版本信息；</li>
<li><code>gdb --version</code> 会显示 GDB 版本信息；</li>
<li><code>Get-Command gcc</code> 会显示 <code>gcc.exe</code> 的实际路径；</li>
<li>对于 64 位 MinGW-w64，<code>gcc -dumpmachine</code> 的结果通常包含 <code>x86_64-w64-mingw32</code>。</li>
</ul></section></section>
<section><h1>【四】编写并运行第一个 C 程序<a href="#四编写并运行第一个-c-程序"><span>#</span></a></h1><section><h2>【1】创建项目目录<a href="#1创建项目目录"><span>#</span></a></h2><p>建议为每个项目单独建立文件夹。例如：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>C:\Code\c-study\hello</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>使用 VS Code 打开该文件夹，然后新建 <code>hello.c</code>：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>#include</span><span> </span><span>&lt;stdio.h&gt;</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>int</span><span> </span><span>main</span><span>(</span><span>void</span><span>)</span></div></div><div><div><div>4</div></div><div><span>{</span></div></div><div><div><div>5</div></div><div><span>    </span><span>printf</span><span>(</span><span>"Hello, C!</span><span>\n</span><span>"</span><span>);</span></div></div><div><div><div>6</div></div><div><span>    </span><span>return</span><span> </span><span>0</span><span>;</span></div></div><div><div><div>7</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div></section><section><h2>【2】编译程序<a href="#2编译程序"><span>#</span></a></h2><p>在 VS Code 中选择“终端 → 新建终端”，执行：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span><span>gcc </span><span>-</span><span>std</span><span>=</span><span>c17 </span><span>-</span><span>Wall </span><span>-</span><span>Wextra </span><span>-</span><span>Wpedantic </span><span>-</span><span>g hello.c </span><span>-</span><span>o </span></span><span>hello.exe</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>各参数含义：</p>

<table><thead><tr><th>参数</th><th>作用</th></tr></thead><tbody><tr><td><code>-std=c17</code></td><td>按 C17 标准编译</td></tr><tr><td><code>-Wall -Wextra -Wpedantic</code></td><td>开启常用警告，帮助发现潜在问题</td></tr><tr><td><code>-g</code></td><td>写入调试信息，供 GDB 使用</td></tr><tr><td><code>hello.c</code></td><td>输入的 C 源文件</td></tr><tr><td><code>-o hello.exe</code></td><td>指定生成的可执行文件名</td></tr></tbody></table><blockquote><p>编译成功时，GCC 通常不会输出任何信息。没有消息往往表示没有发现错误。</p></blockquote></section><section><h2>【3】运行程序<a href="#3运行程序"><span>#</span></a></h2><p>在 PowerShell 中执行：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>.\</span><span>hello.exe</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>预期输出：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>Hello, C!</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>PowerShell 默认不会直接从当前目录查找程序，因此需要使用 <code>.</code> 表示当前目录，即写成 <code>.\hello.exe</code>。</p></section></section>
<section><h1>【五】Windows 上的其他方案<a href="#五windows-上的其他方案"><span>#</span></a></h1><section><h2>【1】Visual Studio + MSVC<a href="#1visual-studio--msvc"><span>#</span></a></h2><p>如果希望使用完整 IDE，可以安装 <a href="https://visualstudio.microsoft.com/vs/community/" target="_blank">Visual Studio Community</a>。在安装器中选择：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>使用 C++ 的桌面开发（Desktop development with C++）</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>虽然工作负载名称包含“C++”，其中的 MSVC 编译器同样可以编译 C 程序。在 “Developer PowerShell for VS” 中可以这样编译：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span><span>cl </span><span>/</span><span>W4 </span><span>/</span><span>Zi hello.c</span></span></div></div><div><div><div>2</div></div><div><span>.\</span><span>hello.exe</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>MSVC 与 GCC 的命令行参数不同，不能直接照搬 GCC 的参数。</p></section><section><h2>【2】WSL（适合学习 Linux 开发）<a href="#2wsl适合学习-linux-开发"><span>#</span></a></h2><p>WSL 可以在 Windows 中提供 Linux 环境。管理员 PowerShell 中执行：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span><span>wsl </span><span>--</span><span>install</span></span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>进入 Ubuntu 后安装工具链：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>sudo</span><span> </span><span>apt</span><span> </span><span>update</span></div></div><div><div><div>2</div></div><div><span>sudo</span><span> </span><span>apt</span><span> </span><span>install</span><span> </span><span>build-essential</span><span> </span><span>gdb</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><p>WSL 中生成的是 Linux 可执行文件，应在 WSL 内使用 <code>./hello</code> 运行，而不是在 Windows 中运行。</p></section></section>
<section><h1>【六】Linux 环境安装<a href="#六linux-环境安装"><span>#</span></a></h1><p>先检查编译器是否已经安装：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>gcc</span><span> </span><span>--version</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><p>如果未安装，可以根据发行版执行相应命令。</p><section><h2>【1】Debian / Ubuntu<a href="#1debian--ubuntu"><span>#</span></a></h2><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>sudo</span><span> </span><span>apt</span><span> </span><span>update</span></div></div><div><div><div>2</div></div><div><span>sudo</span><span> </span><span>apt</span><span> </span><span>install</span><span> </span><span>build-essential</span><span> </span><span>gdb</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div></section><section><h2>【2】Fedora<a href="#2fedora"><span>#</span></a></h2><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>sudo</span><span> </span><span>dnf</span><span> </span><span>install</span><span> </span><span>gcc</span><span> </span><span>gdb</span><span> </span><span>make</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div></section><section><h2>【3】Arch Linux<a href="#3arch-linux"><span>#</span></a></h2><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>sudo</span><span> </span><span>pacman</span><span> </span><span>-S</span><span> </span><span>base-devel</span><span> </span><span>gdb</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><p>编译并运行：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>gcc</span><span> </span><span>-std=c17</span><span> </span><span>-Wall</span><span> </span><span>-Wextra</span><span> </span><span>-Wpedantic</span><span> </span><span>-g</span><span> </span><span>hello.c</span><span> </span><span>-o</span><span> </span><span>hello</span></div></div><div><div><div>2</div></div><div><span>./hello</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div></section></section>
<section><h1>【七】macOS 环境安装<a href="#七macos-环境安装"><span>#</span></a></h1><p>macOS 推荐安装 Apple Command Line Tools：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>xcode-select</span><span> </span><span>--install</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><p>安装后验证：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cc</span><span> </span><span>--version</span></div></div><div><div><div>2</div></div><div><span>clang</span><span> </span><span>--version</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><p>macOS 默认提供的是 <strong>Apple Clang</strong>。系统中的 <code>gcc</code> 命令通常也会调用 Clang，并不代表安装了 GNU GCC。</p><p>编译并运行：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cc</span><span> </span><span>-std=c17</span><span> </span><span>-Wall</span><span> </span><span>-Wextra</span><span> </span><span>-Wpedantic</span><span> </span><span>-g</span><span> </span><span>hello.c</span><span> </span><span>-o</span><span> </span><span>hello</span></div></div><div><div><div>2</div></div><div><span>./hello</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div></section>
<section><h1>【八】常见问题排查<a href="#八常见问题排查"><span>#</span></a></h1><section><h2>【1】提示“无法识别 gcc”或“gcc 不是内部或外部命令”<a href="#1提示无法识别-gcc或gcc-不是内部或外部命令"><span>#</span></a></h2><p>可能原因：</p><ul>
<li>工具链尚未安装；</li>
<li>MinGW-w64 安装目录下的 <code>bin</code> 文件夹没有加入 <code>Path</code>；</li>
<li>修改 <code>Path</code> 后没有重启终端或 VS Code；</li>
<li><code>Path</code> 中存在其他旧版 GCC，导致工具冲突。</li>
</ul><p>在 PowerShell 中检查：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>Get-Command</span><span><span> gcc </span><span>-</span><span>All</span></span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h2>【2】安装了 VS Code 扩展却不能编译<a href="#2安装了-vs-code-扩展却不能编译"><span>#</span></a></h2><p>C/C++ 扩展只提供代码编辑、代码提示和调试集成，不包含编译器。按照本文的技术路线，还需要单独安装 MinGW-w64 工具链。</p></section><section><h2>【3】出现 <code>No such file or directory</code><a href="#3出现-no-such-file-or-directory"><span>#</span></a></h2><p>先确认终端所在目录和文件名：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>Get-Location</span></div></div><div><div><div>2</div></div><div><span>Get-ChildItem</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后确认当前目录中确实存在 <code>hello.c</code>。文件扩展名也可能被 Windows 隐藏，应避免将文件误命名为 <code>hello.c.txt</code>。</p></section><section><h2>【4】双击程序后窗口一闪而过<a href="#4双击程序后窗口一闪而过"><span>#</span></a></h2><p>不要通过双击运行控制台程序。应在 PowerShell、Windows Terminal 或 VS Code 终端中执行：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>.\</span><span>hello.exe</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h2>【5】中文输出乱码<a href="#5中文输出乱码"><span>#</span></a></h2><p>初学阶段可先使用英文路径、英文文件名和英文输出，减少编码问题。需要输出中文时，应确保源文件、终端和程序使用兼容的字符编码；在现代 Windows Terminal 中通常建议统一使用 UTF-8。</p></section><section><h2>【6】<code>gcc</code> 和 <code>g++</code> 有什么区别<a href="#6gcc-和-g-有什么区别"><span>#</span></a></h2><ul>
<li><code>gcc</code>：用于编译 C 程序；</li>
<li><code>g++</code>：用于编译 C++ 程序，并自动链接 C++ 标准库。</li>
</ul><p>学习 C 语言时，源文件应使用 <code>.c</code> 扩展名，并使用 <code>gcc</code> 编译。</p></section></section>
<section><h1>【九】推荐的学习配置<a href="#九推荐的学习配置"><span>#</span></a></h1><p>对于 Windows 初学者，建议统一使用以下组合：</p>

<table><thead><tr><th>项目</th><th>推荐选择</th></tr></thead><tbody><tr><td>编辑器</td><td>Visual Studio Code</td></tr><tr><td>编辑扩展</td><td>Microsoft C/C++</td></tr><tr><td>工具链</td><td>MinGW-w64 GCC</td></tr><tr><td>调试器</td><td>GDB</td></tr><tr><td>语言标准</td><td>C17（兼容性较好）</td></tr><tr><td>编译警告</td><td><code>-Wall -Wextra -Wpedantic</code></td></tr></tbody></table><p>C23 已正式发布，但不同编译器对其特性的支持程度不一致。基础学习阶段使用 C17 更稳定；学习 C23 新特性时，再根据编译器版本选择 <code>-std=c23</code> 或旧版 GCC 使用的 <code>-std=c2x</code>。</p></section>
<section><h1>【十】延伸阅读<a href="#十延伸阅读"><span>#</span></a></h1><ul>
<li><a href="https://code.visualstudio.com/docs/languages/cpp" target="_blank">VS Code：C++ programming with Visual Studio Code</a></li>
<li><a href="https://www.mingw-w64.org/" target="_blank">MinGW-w64 官方网站</a></li>
<li><a href="https://gcc.gnu.org/onlinedocs/" target="_blank">GCC 官方文档</a></li>
<li><a href="https://clang.llvm.org/docs/" target="_blank">Clang 官方文档</a></li>
<li><a href="https://learn.microsoft.com/cpp/" target="_blank">Microsoft C/C++ 文档</a></li>
</ul></section>]]></content>
    </entry>
    <entry>
      <id>https://firefly.cuteleaf.cn/posts/language/c/10c%E8%AF%AD%E8%A8%80%E4%BB%8B%E7%BB%8D/30c%E8%AF%AD%E8%A8%80%E5%88%9D%E8%AF%86/</id>
      <title type="text">C 语言初识：程序运行机制与基本结构</title>
      <published>2026-09-26T00:00:00.000Z</published>
      <updated>2026-09-26T00:00:00.000Z</updated>
      <author><name>Dream</name></author>
      <link rel="alternate" href="https://firefly.cuteleaf.cn/posts/language/c/10c%E8%AF%AD%E8%A8%80%E4%BB%8B%E7%BB%8D/30c%E8%AF%AD%E8%A8%80%E5%88%9D%E8%AF%86/"/>
      <summary type="text">认识 C 程序从源代码到运行的完整流程，以及基础语法和程序的基本结构。</summary>
      <content type="html"><![CDATA[<section><h1>【一】C 程序的运行机制<a href="#一c-程序的运行机制"><span>#</span></a></h1><p>从源代码到程序运行，通常会经历编写、预处理、编译、汇编、链接和运行等阶段。开发者平时执行一条编译命令时，这些阶段大多由编译器工具链自动完成，因此中间文件不一定会被保留下来。</p><p></p><figure><img src="https://oss.silentdream.top/2026/09/26/19-50-04-e1f7e1b7-u%3D1362887596%2C68938054-fm%3D253-app%3D138-f%3DJPEG-5d4f0e.jpeg" alt="img" /><figcaption>img</figcaption></figure><p></p><blockquote><p>图中展示的是 Windows 下的 MSVC 工具链：<code>cl.exe</code> 负责处理和编译源文件，<code>link.exe</code> 负责链接，目标文件扩展名为 <code>.obj</code>。本文安装的是 MinGW-w64 GCC 工具链，目标文件通常使用 <code>.o</code> 扩展名。二者生成的文件名称和使用的命令有所不同，但整体处理过程基本一致。</p></blockquote><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>1. 编写代码：使用编辑器编写 C 源代码，并保存为 xx.c 文件。</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>2. 预处理：处理 #include、#define、条件编译等预处理指令，并处理源代码中的注释，通常得到 xx.i 文件。</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>3. 编译：对预处理后的代码进行词法分析、语法分析、语义分析和优化，再转换为汇编代码，通常得到 xx.s 文件。</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>4. 汇编：汇编器将汇编代码转换成机器指令，生成可重定位目标文件；GCC 通常生成 xx.o，MSVC 通常生成 xx.obj。</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span>5. 链接：链接器把一个或多个目标文件、启动代码和所需的库组合起来，解析函数与变量的引用，最终生成可执行文件。Windows 下通常为 xx.exe。</span></div></div><div><div><div>10</div></div><div>
</div></div><div><div><div>11</div></div><div><span>6. 运行：操作系统加载可执行文件及其依赖的动态库，完成运行环境初始化后开始执行程序，并得到运行结果。</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>这里需要区分“编译”的两种常见含义：</p><ul>
<li><strong>广义的编译</strong>：泛指从源文件生成可执行文件的整个构建过程，包括预处理、狭义编译、汇编和链接。</li>
<li><strong>狭义的编译</strong>：特指把预处理后的 C 代码转换为汇编代码的阶段。</li>
</ul><p>目标文件虽然已经包含机器指令，但通常还存在尚未确定地址的符号引用，因此不能直接运行。例如，程序调用 <code>printf</code> 时，目标文件只记录了对该函数的引用；链接器还需要从相应的库中找到它，并建立正确的关联。</p><p>使用 MinGW-w64 GCC 时，可以通过下面的命令分别观察各个阶段：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 1. 预处理：hello.c -&gt; hello.i</span></div></div><div><div><div>2</div></div><div><span><span>gcc </span><span>-</span><span>E hello.c </span><span>-</span><span>o hello.i</span></span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 2. 编译：hello.i -&gt; hello.s</span></div></div><div><div><div>5</div></div><div><span><span>gcc </span><span>-</span><span>S hello.i </span><span>-</span><span>o hello.s</span></span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># 3. 汇编：hello.s -&gt; hello.o</span></div></div><div><div><div>8</div></div><div><span><span>gcc </span><span>-</span><span>c hello.s </span><span>-</span><span>o hello.o</span></span></div></div><div><div><div>9</div></div><div>
</div></div><div><div><div>10</div></div><div><span># 4. 链接：hello.o -&gt; hello.exe</span></div></div><div><div><div>11</div></div><div><span><span>gcc hello.o </span><span>-</span><span>o </span></span><span>hello.exe</span></div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span># 5. 运行（PowerShell）</span></div></div><div><div><div>14</div></div><div><span>.\</span><span>hello.exe</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>实际开发时通常不需要手动执行每个阶段。一条命令即可让 GCC 依次完成预处理、编译、汇编和链接：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span><span>gcc hello.c </span><span>-</span><span>o </span></span><span>hello.exe</span></div></div><div><div><div>2</div></div><div><span>.\</span><span>hello.exe</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p><code>gcc</code> 不只是狭义上的编译器命令，它还充当工具链的驱动程序，会根据参数自动调用预处理器、编译器、汇编器和链接器。</p></blockquote></section>
<section><h1>【二】C 基础语法<a href="#二c-基础语法"><span>#</span></a></h1><p>C 语言是一种通用编程语言，广泛应用于系统编程、嵌入式开发和高性能计算等领域。</p><p>C 语言具有高效、灵活、可移植性强等特点，是许多其他编程语言（如 C++、Java、Go）的基础，至今仍是操作系统、驱动程序和底层库开发的主流选择。</p><p>在 C 语言中，令牌（Token）是程序的基本组成单位。编译器通过词法分析，将源代码识别为一个个具有特定含义的令牌。了解令牌的类别，有助于看懂程序的语法结构。</p><p>C 语言的令牌主要包括以下几种类型：</p><ul>
<li><strong>关键字（Keywords）</strong>：语言预留的具有特殊含义的单词，如 <code>int</code>、<code>if</code>、<code>return</code>。</li>
<li><strong>标识符（Identifiers）</strong>：程序员自定义的名称，用于变量、函数、数组等。</li>
<li><strong>常量（Constants）</strong>：程序中固定不变的值，如整数 <code>42</code>、浮点数 <code>3.14</code>。</li>
<li><strong>字符串字面量（String Literals）</strong>：由双引号括起来的字符序列，如 <code>"Hello"</code>。</li>
<li><strong>运算符（Operators）</strong>：用于执行运算的符号，如 <code>+</code>、<code>==</code>、<code>&amp;&amp;</code>。</li>
<li><strong>分隔符（Separators）</strong>：用于分隔语句和代码块的符号，如 <code>;</code>、<code>{}</code>。</li>
</ul><p>阅读代码时，可以先找出标识符、字面量和运算符，再观察分号、括号与花括号如何组织语句。C 语言区分大小写，例如 <code>count</code> 和 <code>Count</code> 是两个不同的标识符。</p></section>
<section><h1>【三】C 程序的基本结构<a href="#三c-程序的基本结构"><span>#</span></a></h1><section><h2>【1】简单的 C 语言程序<a href="#1简单的-c-语言程序"><span>#</span></a></h2><p>先从一个输出文字的 C 程序开始，观察头文件、<code>main</code> 函数与 <code>return</code> 语句的位置：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>#include</span><span> </span><span>&lt;stdio.h&gt;</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>int</span><span> </span><span>main</span><span>() {</span></div></div><div><div><div>4</div></div><div><span>  </span><span>printf</span><span>(</span><span>"Hello, World!</span><span>\n</span><span>"</span><span>);</span></div></div><div><div><div>5</div></div><div><span>  </span><span>return</span><span> </span><span>0</span><span>;</span></div></div><div><div><div>6</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><p>上面的代码可以从以下几个组成部分理解；变量声明和其他函数定义则会出现在后续示例中：</p><ul>
<li><strong>预处理器指令</strong>：如 <code>#include</code> 和 <code>#define</code>，在编译前由预处理器处理。</li>
<li><strong>主函数</strong>：每个 C 程序都有且只有一个 <code>main()</code> 函数，是程序的执行入口。</li>
<li><strong>变量声明</strong>：声明程序中使用的变量，C89 要求声明必须在代码块最开头。</li>
<li><strong>函数定义</strong>：定义程序中使用的函数，描述函数的具体实现逻辑。</li>
</ul></section><section><h2>【2】复杂一点的 C 程序结构<a href="#2复杂一点的-c-程序结构"><span>#</span></a></h2><p>再看一个稍完整的 C 程序：它从标准输入读取两个整数，调用 <code>add</code> 函数计算结果，并输出求和结果。下面先认识整体结构，各知识点会在后续章节展开说明。</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>#include</span><span> </span><span>&lt;stdio.h&gt;</span><span>   </span><span>// 头文件包含</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>#define</span><span> </span><span>PI</span><span> </span><span>3.14159</span><span>    // 宏定义</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>// 函数声明</span></div></div><div><div><div>6</div></div><div><span>int</span><span> </span><span>add</span><span>(</span><span>int</span><span><span> </span><span>a</span><span>,</span><span> </span></span><span>int</span><span><span> </span><span>b</span><span>);</span></span></div></div><div><div><div>7</div></div><div>
</div></div><div><div><div>8</div></div><div><span>int</span><span> </span><span>main</span><span>() {</span><span>         // 主函数</span></div></div><div><div><div>9</div></div><div><span>    </span><span>// 变量声明</span></div></div><div><div><div>10</div></div><div><span>    </span><span>int</span><span> num1, num2, sum;</span></div></div><div><div><div>11</div></div><div>
</div></div><div><div><div>12</div></div><div><span>    </span><span>// 用户输入</span></div></div><div><div><div>13</div></div><div><span>    </span><span>printf</span><span>(</span><span>"Enter two integers: "</span><span>);</span></div></div><div><div><div>14</div></div><div><span>    </span><span>if</span><span> (</span><span>scanf</span><span>(</span><span>"</span><span>%d</span><span> </span><span>%d</span><span>"</span><span>, </span><span>&amp;</span><span>num1, </span><span>&amp;</span><span>num2) </span><span>!=</span><span> </span><span>2</span><span>) {</span></div></div><div><div><div>15</div></div><div><span>        </span><span>printf</span><span>(</span><span>"Invalid input.</span><span>\n</span><span>"</span><span>);</span></div></div><div><div><div>16</div></div><div><span>        </span><span>return</span><span> </span><span>1</span><span>;</span></div></div><div><div><div>17</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>18</div></div><div>
</div></div><div><div><div>19</div></div><div><span>    </span><span>// 函数调用</span></div></div><div><div><div>20</div></div><div><span><span>    </span></span><span>sum </span><span>=</span><span> </span><span>add</span><span>(num1, num2);</span></div></div><div><div><div>21</div></div><div>
</div></div><div><div><div>22</div></div><div><span>    </span><span>// 输出结果</span></div></div><div><div><div>23</div></div><div><span>    </span><span>printf</span><span>(</span><span>"Sum: </span><span>%d</span><span>\n</span><span>"</span><span>, sum);</span></div></div><div><div><div>24</div></div><div>
</div></div><div><div><div>25</div></div><div><span>    </span><span>return</span><span> </span><span>0</span><span>;</span><span>        // 返回 0 表示程序成功执行</span></div></div><div><div><div>26</div></div><div><span>}</span></div></div><div><div><div>27</div></div><div>
</div></div><div><div><div>28</div></div><div><span>// 函数定义</span></div></div><div><div><div>29</div></div><div><span>int</span><span> </span><span>add</span><span>(</span><span>int</span><span><span> </span><span>a</span><span>,</span><span> </span></span><span>int</span><span><span> </span><span>b</span><span>) {</span></span></div></div><div><div><div>30</div></div><div><span>    </span><span>return</span><span> a </span><span>+</span><span> b;</span></div></div><div><div><div>31</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p><code>scanf</code> 会返回成功读取并转换的数据项数量。本例需要读取两个整数，因此返回值应为 <code>2</code>；如果返回值不等于 <code>2</code>，程序会提示输入无效并提前结束，从而避免继续使用未正确赋值的变量。</p><p><strong>头文件包含</strong></p><ul>
<li>头文件通常在程序开头通过 <code>#include</code> 指令引入。例如，<code>&lt;stdio.h&gt;</code> 声明了标准输入输出函数，<code>&lt;stdlib.h&gt;</code> 提供了常用的通用工具声明。包含相应头文件后，编译器才能获得所用函数和宏的相关信息。</li>
<li>标准库头文件通常使用尖括号 <code>&lt; &gt;</code>，项目自定义头文件通常使用双引号 <code>" "</code>；两种写法的头文件搜索方式不同。</li>
<li>示例：<code>#include &lt;stdio.h&gt;</code>（标准库头文件）、<code>#include "myheader.h"</code>（自定义头文件）。</li>
</ul><p><strong>宏定义</strong></p><ul>
<li>宏通过 <code>#define</code> 指令定义，可表示符号常量或代码片段。预处理器会在编译前展开宏；宏常用于定义常量或简短的可复用表达式。</li>
<li>宏本身不进行类型检查，使用时需谨慎；需要类型约束时，可以考虑使用 <code>const</code> 变量。</li>
<li>示例：<code>#define PI 3.14159</code>、<code>#define MAX(a, b) ((a) &gt; (b) ? (a) : (b))</code></li>
</ul><p><strong>函数声明</strong></p><ul>
<li>函数声明（也称函数原型）提供返回类型、函数名和参数信息，使编译器能在调用处检查参数与返回类型。本例在调用 <code>add</code> 之前先写出声明，再在 <code>main</code> 之后给出定义。</li>
<li>多个源文件需要调用同一个函数时，可以将其声明放在头文件中共享。</li>
<li>示例：<code>int add(int a, int b);</code></li>
</ul><p><strong>主函数</strong></p><ul>
<li><code>main()</code> 函数是 C 程序的入口点，每个 C 程序都必须包含一个 <code>main()</code> 函数。程序从 <code>main()</code> 开始执行，返回值通常为 <code>0</code> 表示程序成功执行，非零值表示出现了错误。</li>
<li><code>main()</code> 函数也可以接收命令行参数：<code>int main(int argc, char *argv[])</code>，其中 <code>argc</code> 是参数个数，<code>argv</code> 是参数字符串数组。</li>
<li>示例：<code>int main() { ... }</code></li>
</ul><p><strong>变量声明</strong></p><ul>
<li>在 C 程序中，变量使用前需要声明其类型。变量既可以在函数内部声明为局部变量，也可以在函数外部声明为全局变量。</li>
<li>声明变量时可同时进行初始化，未初始化的局部变量包含不确定值（垃圾值），而全局变量和静态变量会被自动初始化为 <code>0</code>。</li>
<li>示例：<code>int count = 0;</code>、<code>float price = 9.99;</code>、<code>char grade = 'A';</code></li>
</ul><p><strong>语句和表达式</strong></p><ul>
<li>语句用于组织程序中的操作，例如函数调用、赋值或控制流。表达式则可以由变量、运算符和常量等构成，并参与求值。</li>
<li>C 语言中，赋值本身也是一个表达式，具有值（即被赋的值），因此可以写出 <code>a = b = c = 0;</code> 这样的链式赋值。</li>
<li>示例：</li>
</ul><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>printf</span><span>(</span><span>"Enter two integers: "</span><span>);</span></div></div><div><div><div>2</div></div><div><span>sum </span><span>=</span><span> </span><span>add</span><span><span>(</span><span>num1</span><span>,</span><span> num2</span><span>);</span></span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><p><strong>控制流语句</strong></p><ul>
<li>控制流语句决定程序的执行顺序，包括条件判断（<code>if</code>/<code>else</code>、<code>switch</code>）、循环（<code>for</code>、<code>while</code>、<code>do-while</code>），以及 <code>break</code>、<code>continue</code>、<code>goto</code> 和 <code>return</code> 等跳转语句。</li>
<li>合理使用控制流语句有助于让程序逻辑更清晰；为了保持代码可读性，应避免滥用 <code>goto</code>。</li>
<li>示例：</li>
</ul><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>if</span><span> (num1 </span><span>&gt;</span><span> num2) {</span></div></div><div><div><div>2</div></div><div><span>    </span><span>printf</span><span>(</span><span>"num1 is greater than num2"</span><span>);</span></div></div><div><div><div>3</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><p><strong>函数定义</strong></p><ul>
<li>函数定义包含完整的函数体，描述函数的具体实现。一个函数通常由返回类型、函数名、参数列表和函数体组成。设计函数时，可以尽量让每个函数专注于一项明确的任务。</li>
<li>C 语言的函数不支持重载，每个函数名在同一作用域中必须唯一。函数可以递归调用自身。</li>
<li>示例：</li>
</ul><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>int</span><span> </span><span>add</span><span>(</span><span>int</span><span><span> </span><span>a</span><span>,</span><span> </span></span><span>int</span><span><span> </span><span>b</span><span>) {</span></span></div></div><div><div><div>2</div></div><div><span>    </span><span>return</span><span> a </span><span>+</span><span> b;</span></div></div><div><div><div>3</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><p><strong>返回语句</strong></p><ul>
<li><code>return</code> 语句用于终止函数的执行，并将控制权连同返回值一起交还给调用者。<code>void</code> 类型的函数可以使用不带值的 <code>return;</code> 提前退出，也可以省略 <code>return</code> 语句。</li>
<li><code>main()</code> 函数的返回值会传递给操作系统，<code>0</code> 通常表示成功，可使用标准宏 <code>EXIT_SUCCESS</code> 和 <code>EXIT_FAILURE</code>（定义在 <code>&lt;stdlib.h&gt;</code>）。</li>
<li>示例：<code>return 0;</code>、<code>return EXIT_SUCCESS;</code></li>
</ul></section></section>]]></content>
    </entry>
    <entry>
      <id>https://firefly.cuteleaf.cn/posts/language/c/10c%E8%AF%AD%E8%A8%80%E4%BB%8B%E7%BB%8D/40c%E8%AF%AD%E8%A8%80%E5%9F%BA%E7%A1%80/</id>
      <title type="text">C 语言基础：注释、关键字、变量与数据类型</title>
      <published>2026-09-26T00:00:00.000Z</published>
      <updated>2026-09-26T00:00:00.000Z</updated>
      <author><name>Dream</name></author>
      <link rel="alternate" href="https://firefly.cuteleaf.cn/posts/language/c/10c%E8%AF%AD%E8%A8%80%E4%BB%8B%E7%BB%8D/40c%E8%AF%AD%E8%A8%80%E5%9F%BA%E7%A1%80/"/>
      <summary type="text">学习 C 语言的注释、关键字、标识符、常量、变量和基本数据类型等基础知识。</summary>
      <content type="html"><![CDATA[<section><h1>【一】注释<a href="#一注释"><span>#</span></a></h1><p>注释用于补充代码的设计意图、使用条件和注意事项，不参与程序运行。C 语言支持 <code>//</code> 单行注释和 <code>/* ... */</code> 块注释，其中 <code>//</code> 从 C99 开始被正式纳入标准。</p><section><h2>【1】单行注释<a href="#1单行注释"><span>#</span></a></h2><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>// 单行注释</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><ul>
<li>单行注释以 <code>//</code> 开始，到当前行末尾结束。它既可以单独占一行，也可以写在代码行末尾。</li>
</ul></section><section><h2>【2】多行注释<a href="#2多行注释"><span>#</span></a></h2><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>/* 单行注释 */</span></div></div><div><div><div>2</div></div><div><span>/*</span></div></div><div><div><div>3</div></div><div><span><span> </span></span><span>多行注释</span></div></div><div><div><div>4</div></div><div><span><span> </span></span><span>多行注释</span></div></div><div><div><div>5</div></div><div><span><span> </span></span><span>多行注释</span></div></div><div><div><div>6</div></div><div><span><span> </span></span><span>*/</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><ul>
<li>块注释以 <code>/*</code> 开始、以 <code>*/</code> 结束，可以写成一行或跨越多行，适合补充较长的说明。</li>
</ul><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>#include</span><span> </span><span>&lt;stdio.h&gt;</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>// 这是单行注释</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>/*</span></div></div><div><div><div>6</div></div><div><span>这是多行注释</span></div></div><div><div><div>7</div></div><div><span>它可以跨越多行</span></div></div><div><div><div>8</div></div><div><span>*/</span></div></div><div><div><div>9</div></div><div>
</div></div><div><div><div>10</div></div><div><span>int</span><span> </span><span>main</span><span>(</span><span>void</span><span>) {</span></div></div><div><div><div>11</div></div><div><span>    </span><span>// 打印一条消息</span></div></div><div><div><div>12</div></div><div><span>    </span><span>printf</span><span>(</span><span>"Hello, World!</span><span>\n</span><span>"</span><span>);</span></div></div><div><div><div>13</div></div><div><span>    </span><span>return</span><span> </span><span>0</span><span>;</span></div></div><div><div><div>14</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div></section><section><h2>【3】文档注释（文本注释）<a href="#3文档注释文本注释"><span>#</span></a></h2><p>文档注释本质上仍是块注释，C 语言标准并没有单独规定“文档注释”语法。Doxygen 等文档生成工具会识别 <code>/** ... */</code> 中的特定标记，并据此生成接口文档。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>/**</span></div></div><div><div><div>2</div></div><div><span><span>    </span></span><span>本质是多行注释</span></div></div><div><div><div>3</div></div><div><span><span>    </span></span><span>文档注释的功能 : 添加批注</span></div></div><div><div><div>4</div></div><div><span>*/</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>#include</span><span> </span><span>&lt;stddef.h&gt;</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>/**</span></div></div><div><div><div>4</div></div><div><span>* </span><span>@brief</span><span> 计算字符串的长度</span></div></div><div><div><div>5</div></div><div><span>*</span></div></div><div><div><div>6</div></div><div><span>* </span><span>@param</span><span> </span><span>str</span><span> 指向以空字符结尾的字符串</span></div></div><div><div><div>7</div></div><div><span>* </span><span>@return</span><span> 字符串的长度</span></div></div><div><div><div>8</div></div><div><span>*/</span></div></div><div><div><div>9</div></div><div><span>size_t</span><span> </span><span>string_length</span><span>(</span><span>const</span><span> </span><span>char</span><span> </span><span>*</span><span><span>str</span><span>);</span></span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><p>上例只展示函数声明及其文档说明。<code>@brief</code>、<code>@param</code> 和 <code>@return</code> 是 Doxygen 常用标记，不是 C 语言关键字。</p></section><section><h2>【4】注意<a href="#4注意"><span>#</span></a></h2><ul>
<li>
<p>块注释不能嵌套。例如，<code>/* 外层 /* 内层 */ 外层 */</code> 会在遇到第一个 <code>*/</code> 时结束，后续内容可能引发编译错误。</p>
</li>
<li>
<p>字符串字面量和字符常量中的 <code>//</code>、<code>/*</code>、<code>*/</code> 只是普通字符，不会被识别为注释。例如，<code>"https://example.com"</code> 中的 <code>//</code> 不会开始一段注释。</p>
</li>
<li>
<p>注释是写给人看的，应简洁明了，重点解释“为什么这样做”、约束条件和容易忽略的问题，而不是机械重复代码已经表达的内容。</p>
</li>
<li>
<p>良好的注释习惯是专业编程的重要组成部分，有助于代码维护和团队协作。</p>
</li>
</ul></section></section>
<section><h1>【二】关键字<a href="#二关键字"><span>#</span></a></h1><p>关键字是由 C 语言标准预先赋予特殊含义的单词，不能用作变量名、函数名或其他标识符。不同 C 标准引入的关键字有所不同，下表首先列出 C90 的 32 个经典关键字。</p>

<table><thead><tr><th>关键字</th><th>说明</th></tr></thead><tbody><tr><td>auto</td><td>声明自动变量（局部变量默认存储类型，现代 C 中很少显式使用）</td></tr><tr><td>break</td><td>跳出当前循环或 switch 语句</td></tr><tr><td>case</td><td>switch 语句中的分支标签</td></tr><tr><td>char</td><td>声明字符类型；<code>sizeof(char)</code> 始终等于 1，但 1 字节不一定等于 8 位</td></tr><tr><td>const</td><td>添加只读限定，表示不能通过该左值修改对象</td></tr><tr><td>continue</td><td>结束本次循环迭代，直接开始下一轮循环</td></tr><tr><td>default</td><td>switch 语句中的默认分支（所有 case 均不匹配时执行）</td></tr><tr><td>do</td><td>do-while 循环的循环体，循环体至少执行一次</td></tr><tr><td>double</td><td>声明双精度浮点型变量或函数返回值类型（通常占 8 字节）</td></tr><tr><td>else</td><td>条件语句的否定分支（与 if 连用）</td></tr><tr><td>enum</td><td>声明枚举类型，用于定义一组命名的整型常量</td></tr><tr><td>extern</td><td>声明变量或函数在其它文件或本文件的其他位置定义</td></tr><tr><td>float</td><td>声明单精度浮点型变量或函数返回值类型（通常占 4 字节）</td></tr><tr><td>for</td><td>for 循环语句，适合已知循环次数的场景</td></tr><tr><td>goto</td><td>无条件跳转语句（应谨慎使用，可能降低代码可读性）</td></tr><tr><td>if</td><td>条件判断语句</td></tr><tr><td>int</td><td>声明整型变量或函数返回值类型（通常占 4 字节）</td></tr><tr><td>long</td><td>声明长整型变量或函数返回值类型</td></tr><tr><td>register</td><td>建议编译器将变量存入寄存器以提高访问速度（现代编译器通常自动优化）</td></tr><tr><td>return</td><td>函数返回语句，可带返回值，也可不带（void 函数）</td></tr><tr><td>short</td><td>声明短整型变量或函数返回值类型（通常占 2 字节）</td></tr><tr><td>signed</td><td>声明有符号类型变量（可表示负数，整型默认有符号）</td></tr><tr><td>sizeof</td><td>获取类型或表达式结果类型所占的字节数；涉及 VLA 时可能在运行期求值</td></tr><tr><td>static</td><td>使局部变量具有静态存储期，或使文件作用域名称具有内部链接</td></tr><tr><td>struct</td><td>声明结构体类型，将不同类型的数据组合成一个整体</td></tr><tr><td>switch</td><td>多分支选择语句，根据表达式的值跳转到对应 case</td></tr><tr><td>typedef</td><td>为已有数据类型定义新的别名，提高代码可读性</td></tr><tr><td>unsigned</td><td>声明无符号类型变量（只能表示非负数，范围更大）</td></tr><tr><td>union</td><td>声明共用体类型，所有成员共享同一块内存空间</td></tr><tr><td>void</td><td>表示无值类型；可声明无返回值函数、无参数函数或通用对象指针 <code>void *</code></td></tr><tr><td>volatile</td><td>表示对象可能以编译器无法预知的方式变化，要求相关访问按抽象机规则发生</td></tr><tr><td>while</td><td>while 循环语句，适合循环次数未知但终止条件明确的场景</td></tr></tbody></table><section><h2>【1】C99 新增关键字<a href="#1c99-新增关键字"><span>#</span></a></h2>

<table><thead><tr><th><code>_Bool</code></th><th><code>_Complex</code></th><th><code>_Imaginary</code></th><th><code>inline</code></th><th><code>restrict</code></th></tr></thead><tbody><tr><td></td><td></td><td></td><td></td><td></td></tr></tbody></table><p>C99 新增的关键字主要用于：布尔类型支持（<code>_Bool</code>）、复数支持（<code>_Complex</code>、<code>_Imaginary</code>）、内联函数优化（<code>inline</code>）、指针别名限制优化（<code>restrict</code>）。</p><blockquote><p><code>_Imaginary</code> 与虚数类型属于实现可选功能，并非所有编译器都提供支持。</p></blockquote></section><section><h2>【2】C11 新增关键字<a href="#2c11-新增关键字"><span>#</span></a></h2>

<table><thead><tr><th><code>_Alignas</code></th><th><code>_Alignof</code></th><th><code>_Atomic</code></th><th><code>_Generic</code></th><th><code>_Noreturn</code></th></tr></thead><tbody><tr><td><code>_Static_assert</code></td><td><code>_Thread_local</code></td><td></td><td></td><td></td></tr></tbody></table><p>C11 新增的关键字主要用于：内存对齐控制（<code>_Alignas</code>、<code>_Alignof</code>）、原子操作与多线程支持（<code>_Atomic</code>、<code>_Thread_local</code>）、泛型选择（<code>_Generic</code>）、静态断言（<code>_Static_assert</code>）和标记无返回值函数（<code>_Noreturn</code>）。</p></section><section><h2>【3】C23 新增的常用关键字<a href="#3c23-新增的常用关键字"><span>#</span></a></h2>

<table><thead><tr><th><code>alignas</code></th><th><code>alignof</code></th><th><code>bool</code></th><th><code>constexpr</code></th><th><code>false</code></th><th><code>nullptr</code></th></tr></thead><tbody><tr><td><code>static_assert</code></td><td><code>thread_local</code></td><td><code>true</code></td><td><code>typeof</code></td><td><code>typeof_unqual</code></td><td><code>_BitInt</code></td></tr></tbody></table><p>C23 为部分以下划线开头的旧写法提供了更自然的拼写，并加入 <code>constexpr</code>、<code>nullptr</code>、<code>typeof</code>、<code>typeof_unqual</code> 和 <code>_BitInt</code> 等功能。C23 较新，实际使用前应确认编译器版本及其支持情况。</p></section></section>
<section><h1>【三】标识符<a href="#三标识符"><span>#</span></a></h1><p>标识符是变量、函数、数组、类型等程序实体的名称，通常由程序员定义。对于基础学习，可以将规则概括为：标识符由英文字母、数字和下划线组成，但不能以数字开头。</p><p>一个常见的标识符以字母 <code>A-Z</code>、<code>a-z</code> 或下划线 <code>_</code> 开始，后面可以跟零个或多个字母、下划线或数字 <code>0-9</code>。</p><p>C 标识符中不能随意使用 <code>@</code>、<code>$</code>、<code>%</code>、空格和连字符等字符。C 语言<strong>区分大小写</strong>，因此 <code>Manpower</code> 和 <code>manpower</code> 是两个不同的标识符。下面列出几个有效的标识符：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>mohd       zara    abc   move_name  a_123</span></div></div><div><div><div>2</div></div><div><span>myname50   _temp   j     a23b9      retVal</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><p>以下是一些无效的标识符示例及原因：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>2abc</span><span>        // 错误：以数字开头</span></div></div><div><div><div>2</div></div><div><span>my</span><span>-</span><span>name</span><span>     // 错误：包含连字符 -</span></div></div><div><div><div>3</div></div><div><span>float</span><span>       // 错误：与关键字重名</span></div></div><div><div><div>4</div></div><div><span>my name</span><span>     // 错误：包含空格</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><p>命名建议：标识符应具有描述性，能清晰表达其用途。常见的命名风格有下划线命名法（<code>my_variable</code>）和小驼峰命名法（<code>myVariable</code>），在同一项目中保持一致即可。</p><p>以下划线开头的名称还涉及标准保留规则：</p><ul>
<li>任何位置都不要自定义以双下划线 <code>__</code> 开头的标识符。</li>
<li>任何位置都不要自定义以下划线加大写字母开头的标识符，如 <code>_Value</code>。</li>
<li>文件作用域中，应避免定义任何以下划线开头的标识符。</li>
</ul><p>这些名称通常保留给编译器、标准库和具体实现使用。</p></section>
<section><h1>【四】常量<a href="#四常量"><span>#</span></a></h1><p>常量可以理解为程序中直接使用的固定值，或在程序中不允许通过某个名称修改的对象。学习时需要区分<strong>字面量</strong>、<code>const</code> 限定对象和宏常量，它们虽然都常被称作“常量”，但语言机制并不相同。</p><p>常量可以是整型常量、浮点型常量、字符常量、枚举常量等：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>const</span><span> </span><span>int</span><span> MAX </span><span>=</span><span> </span><span>100</span><span>;</span><span>            // const 限定的整型对象</span></div></div><div><div><div>2</div></div><div><span>const</span><span> </span><span>double</span><span> PI </span><span>=</span><span> </span><span>3.1415926</span><span>;</span><span>    // const 限定的浮点型对象</span></div></div><div><div><div>3</div></div><div><span>const</span><span> </span><span>char</span><span> NEWLINE </span><span>=</span><span> </span><span>'</span><span>\n</span><span>'</span><span>;</span><span>      // const 限定的字符型对象</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><p>其中，<code>100</code>、<code>3.1415926</code> 和 <code>'\n'</code> 是字面量；<code>MAX</code>、<code>PI</code> 和 <code>NEWLINE</code> 是具有类型的 <code>const</code> 限定对象。<code>const</code> 表示不能通过这些名称修改对应对象，但它并不等同于预处理宏。</p><p>字符常量中常用的转义字符包括：</p><ul>
<li><code>\n</code>：换行</li>
<li><code>\t</code>：水平制表符</li>
<li><code>\\</code>：反斜杠</li>
<li><code>\'</code>：单引号</li>
<li><code>\0</code>：空字符，数值为 0，常用作 C 字符串的结束标志</li>
</ul><p>与 <code>#define</code> 宏相比，<code>const</code> 限定对象具有明确类型，编译器可以进行类型检查，也能在调试器中观察它。二者用途并不完全相同，应根据使用场景选择。</p><p>常见的字面量可以分为以下几类：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>42</span><span>                    // 整数字面量</span></div></div><div><div><div>2</div></div><div><span>3.14</span><span>                  // 浮点数字面量，默认类型为 double</span></div></div><div><div><div>3</div></div><div><span><span>3.14</span><span>f</span></span><span>                 // float 类型的浮点数字面量</span></div></div><div><div><div>4</div></div><div><span>'A'</span><span>                   // 字符常量</span></div></div><div><div><div>5</div></div><div><span>"Hello"</span><span>               // 字符串字面量</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><p>C99 引入 <code>_Bool</code> 类型；包含 <code>&lt;stdbool.h&gt;</code> 后，在 C17 及更早标准中通常可以使用 <code>bool</code>、<code>true</code> 和 <code>false</code> 宏。C23 将 <code>bool</code>、<code>true</code> 和 <code>false</code> 纳入语言本身。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>#include</span><span> </span><span>&lt;stdbool.h&gt;</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>bool</span><span> is_ready </span><span>=</span><span> </span><span>true</span><span>;</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><blockquote><p>C 语言不存在名为 <code>null</code> 的通用“空常量”。表示空指针时，传统写法使用 <code>NULL</code> 或整数常量 <code>0</code>；C23 还引入了 <code>nullptr</code>。空指针与表示字符串结尾的空字符 <code>'\0'</code> 是两个不同概念。</p></blockquote><section><h2>【1】字符串字面量<a href="#1字符串字面量"><span>#</span></a></h2><p>字符串字面量是由双引号括起来的字符序列，用于表示文本数据。</p><p>字符串字面量在内存中以字符数组形式表示，末尾会自动添加空字符 <code>\0</code>（null character），用于标记字符串结束。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>char</span><span> greeting</span><span>[]</span><span> </span><span>=</span><span> </span><span>"Hello, World!"</span><span>;</span><span>  // 编译器自动计算长度（包含 \0）</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><p>以下是关于字符串字面量的几点重要说明：</p><ul>
<li>“Hello” 在内存中实际占 6 个字节：<code>'H'、'e'、'l'、'l'、'o'、'\0'</code>。</li>
<li>修改字符串字面量会产生未定义行为，因此不应通过指针修改它；若需要可修改的字符串，应使用字符数组保存其副本。</li>
<li>两个相邻的字符串字面量会被编译器自动拼接：<code>"Hello, " "World!"</code> 等同于 <code>"Hello, World!"</code>。</li>
<li>字符 <code>'A'</code>（字符常量）和字符串 <code>"A"</code>（字符串字面量）是不同的，后者包含 <code>'A'</code> 和 <code>'\0'</code> 两个字符。</li>
</ul><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>1.</span><span> 整数字面量：</span><span>10</span><span>、</span><span>20</span><span>、</span><span><span>0x</span><span>FF</span></span><span>、</span><span><span>0</span><span>77</span></span></div></div><div><div><div>2</div></div><div><span>2.</span><span> 浮点数字面量：</span><span>3.14</span><span>、</span><span>-</span><span>0.5</span><span>、</span><span><span>1.0</span><span>e</span><span>3</span></span><span>、</span><span><span>2.5</span><span>f</span></span></div></div><div><div><div>3</div></div><div><span>3.</span><span> 字符常量：</span><span>'a'</span><span>、</span><span>'A'</span><span>、</span><span>'0'</span><span>、</span><span>' '</span><span>、</span><span>'!'</span><span>、</span><span>'</span><span>\0</span><span>'</span><span>、</span><span>'</span><span>\n</span><span>'</span></div></div><div><div><div>4</div></div><div><span>4.</span><span> 字符串字面量：</span><span>"任意内容"</span><span>、</span><span>""</span><span>（空字符串）</span></div></div><div><div><div>5</div></div><div><span>5.</span><span> 布尔值：</span><span>false</span><span> 和 </span><span>true</span><span>（具体用法取决于采用的 C 标准）</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>主要用途：</span></div></div><div><div><div>8</div></div><div><span>1.</span><span> 参与表达式计算或通过 printf 输出，此时应使用与类型相匹配的格式说明符。</span></div></div><div><div><div>9</div></div><div><span>2.</span><span> 为变量提供初始值，例如：</span><span>int</span><span> a </span><span>=</span><span> </span><span>10</span><span>; </span><span>char</span><span> ch </span><span>=</span><span> </span><span>'a'</span><span>;</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><p>普通字符常量通常使用单引号，例如 <code>'A'</code>。源代码中的中文字符涉及源文件编码、执行字符集和实现支持，不能简单假设 <code>'我'</code> 能像普通单字节字符一样存入 <code>char</code>。处理中文文本时通常使用字符串及明确的字符编码方案，相关内容会在字符串章节中进一步说明。</p></section><section><h2>【2】自定义常量<a href="#2自定义常量"><span>#</span></a></h2><p>自定义常量常见有三种方式：<code>const</code> 限定对象、对象式宏和枚举常量。</p><section><h3>（1）使用 <code>const</code><a href="#1使用-const"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>const</span><span> </span><span>int</span><span> MAX_STUDENTS </span><span>=</span><span> </span><span>50</span><span>;</span></div></div><div><div><div>2</div></div><div><span>const</span><span> </span><span>double</span><span> TAX_RATE </span><span>=</span><span> </span><span>0.13</span><span>;</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><p>这种写法具有明确的数据类型，适合定义在运行过程中不应被修改的值。</p></section><section><h3>（2）使用 <code>#define</code><a href="#2使用-define"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>#define</span><span> </span><span>BUFFER_SIZE</span><span> </span><span>1024</span></div></div><div><div><div>2</div></div><div><span>#define</span><span> </span><span>PI</span><span> </span><span>3.1415926</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><p><code>#define</code> 由预处理器执行文本替换，没有变量类型，也不会为宏名称本身分配存储空间。为了便于识别，宏名称通常使用全大写字母和下划线。</p><p>宏定义末尾通常不写分号，否则分号也会成为替换内容的一部分：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>#define</span><span> </span><span>MAX_COUNT</span><span> </span><span>100</span><span>    // 正确</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div></section><section><h3>（3）使用枚举常量<a href="#3使用枚举常量"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>enum</span><span> Weekday {</span></div></div><div><div><div>2</div></div><div><span><span>    </span></span><span>MONDAY </span><span>=</span><span> </span><span>1</span><span>,</span></div></div><div><div><div>3</div></div><div><span><span>    </span></span><span>TUESDAY,</span></div></div><div><div><div>4</div></div><div><span><span>    </span></span><span>WEDNESDAY</span></div></div><div><div><div>5</div></div><div><span>};</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><p>枚举常量适合表示一组相互关联的命名整数值。在上例中，<code>MONDAY</code> 为 <code>1</code>，后续未显式赋值的成员依次递增，因此 <code>TUESDAY</code> 为 <code>2</code>、<code>WEDNESDAY</code> 为 <code>3</code>。</p></section></section></section>
<section><h1>【五】变量<a href="#五变量"><span>#</span></a></h1><p>变量是具有名称、类型和值的程序对象，其保存的值可以在允许的范围内发生变化。“可以变化”表示变量具备修改能力，并不意味着它在程序运行期间一定会被修改。</p><p>例如，鸡蛋的单价可能随时间改变，因此可以使用变量保存；某一时刻赋给该变量的 <code>1.0</code> 则是一个固定的字面量。</p><p>从入门角度看，可以把变量理解为一块用于存放数据的存储区域：</p><ul>
<li><strong>变量类型</strong>决定数据的表示方式、允许执行的操作及通常需要的存储空间。</li>
<li><strong>变量名</strong>用于在源代码中标识这个对象。</li>
<li><strong>变量值</strong>是当前保存在对象中的数据。</li>
<li><strong>变量地址</strong>表示对象在存储空间中的位置，可以使用取地址运算符 <code>&amp;</code> 获取可寻址对象的地址。</li>
</ul><blockquote><p>“变量一定真实占用一块独立内存”是便于入门的理解。经过优化后，编译器可能把变量保存在寄存器中，甚至完全消除不必要的变量；程序应依据 C 语言规则使用变量，而不应依赖编译器具体如何存储它。</p></blockquote><section><h2>【1】变量的声明、定义与初始化<a href="#1变量的声明定义与初始化"><span>#</span></a></h2><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>int</span><span> age;</span><span>              // 定义变量，但没有显式初始化</span></div></div><div><div><div>2</div></div><div><span>int</span><span> score </span><span>=</span><span> </span><span>100</span><span>;</span><span>      // 定义变量并初始化</span></div></div><div><div><div>3</div></div><div><span>double</span><span> price </span><span>=</span><span> </span><span>1.0</span><span>;</span><span>   // 定义并初始化 double 变量</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>score </span><span>=</span><span> </span><span>95</span><span>;</span><span>           // 赋值：修改变量已有的值</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><p>基本格式如下：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>数据类型 变量名 = 初始值;</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ul>
<li><strong>数据类型</strong>：规定数据的表示方式、取值范围和可执行的操作。</li>
<li><strong>变量名</strong>：在程序中访问变量时使用的标识符。</li>
<li><strong><code>=</code></strong>：在定义中表示初始化，在普通语句中表示赋值。</li>
<li><strong>初始值</strong>：变量创建时获得的第一个值。</li>
</ul><p>初始化与赋值看起来都使用 <code>=</code>，但发生时机不同：初始化发生在对象创建时，而赋值用于修改已经存在的对象。</p><p><strong>声明</strong>用于向编译器说明名称及其类型，<strong>定义</strong>还会真正创建对应的对象。变量定义本身也是一种声明；使用 <code>extern</code> 且不带初始化器的写法通常只进行声明：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>extern</span><span> </span><span>int</span><span> shared_count;</span><span>    // 声明：定义位于其他位置</span></div></div><div><div><div>2</div></div><div><span>int</span><span> shared_count </span><span>=</span><span> </span><span>0</span><span>;</span><span>       // 定义：创建对象并初始化</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><p>同一个作用域中可以存在相互兼容的重复声明，但一个对象通常只能有一个定义。</p></section><section><h2>【2】未初始化变量<a href="#2未初始化变量"><span>#</span></a></h2><p>函数内部的普通局部变量如果没有显式初始化，其值通常是不确定的。读取这种不确定值通常会导致未定义行为，因此应遵循“先初始化，再使用”的原则。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>int</span><span> count;</span></div></div><div><div><div>2</div></div><div><span>printf</span><span>(</span><span>"</span><span>%d</span><span>\n</span><span>"</span><span><span>,</span><span> count</span><span>);</span></span><span>    // 错误示例：count 尚未初始化</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><p>可以在定义时给出初始值：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>int</span><span> count </span><span>=</span><span> </span><span>0</span><span>;</span></div></div><div><div><div>2</div></div><div><span>printf</span><span>(</span><span>"</span><span>%d</span><span>\n</span><span>"</span><span><span>,</span><span> count</span><span>);</span></span><span>    // 正确：输出 0</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><p>文件作用域变量以及使用 <code>static</code> 声明的对象，如果没有显式初始化，会按规则进行零初始化：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>static</span><span> </span><span>int</span><span> total;</span><span>    // 自动初始化为 0</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><blockquote><p>“垃圾值”是日常教学中的形象说法，但不够严谨。标准术语是<strong>不确定值</strong>；问题也不只是输出不可预测，读取它还可能导致未定义行为。</p></blockquote></section><section><h2>【3】作用域与生命周期<a href="#3作用域与生命周期"><span>#</span></a></h2><ul>
<li><strong>作用域</strong>决定变量名可以在源代码的哪些位置被访问。</li>
<li>**生命周期（存储期）**决定变量对应的对象从何时存在到何时结束。</li>
</ul><p>函数内部定义的普通局部变量通常只能在所在代码块中访问，并在进入代码块时创建、离开代码块时结束。文件作用域变量和静态局部变量通常在整个程序运行期间存在。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>int</span><span> global_count </span><span>=</span><span> </span><span>0</span><span>;</span><span>      // 文件作用域变量</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>void</span><span> </span><span>increase</span><span>(</span><span>void</span><span>)</span></div></div><div><div><div>4</div></div><div><span>{</span></div></div><div><div><div>5</div></div><div><span>    </span><span>static</span><span> </span><span>int</span><span> calls </span><span>=</span><span> </span><span>0</span><span>;</span><span>  // 仅在本函数中可见，但值会跨调用保留</span></div></div><div><div><div>6</div></div><div><span>    </span><span>int</span><span> step </span><span>=</span><span> </span><span>1</span><span>;</span><span>          // 普通局部变量</span></div></div><div><div><div>7</div></div><div>
</div></div><div><div><div>8</div></div><div><span><span>    </span></span><span>calls </span><span>+=</span><span> </span><span>1</span><span>;</span></div></div><div><div><div>9</div></div><div><span><span>    </span></span><span>global_count </span><span>+=</span><span> step;</span></div></div><div><div><div>10</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div></section></section>
<section><h1>【六】数据类型<a href="#六数据类型"><span>#</span></a></h1><p>数据类型规定一组数据的表示方式、取值范围以及可以对其执行的操作。C 语言是静态类型语言，变量和函数的类型在编译阶段就需要确定。</p><blockquote><p>C 语言没有“引用数据类型”这一类别。引用是 C++ 等语言中的概念；C 语言通过指针间接访问对象。</p></blockquote><p>从入门角度，可以将常见类型整理如下：</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>1. 基本类型</span></div></div><div><div><div>2</div></div><div><span><span>   </span></span><span>a. 字符类型：char、signed char、unsigned char</span></div></div><div><div><div>3</div></div><div><span><span>   </span></span><span>b. 整数类型：short、int、long、long long 及其 signed/unsigned 形式</span></div></div><div><div><div>4</div></div><div><span><span>   </span></span><span>c. 布尔类型：_Bool（C99）；bool 是常用写法</span></div></div><div><div><div>5</div></div><div><span><span>   </span></span><span>d. 浮点类型：float、double、long double</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>2. 枚举类型</span></div></div><div><div><div>8</div></div><div><span><span>   </span></span><span>enum</span></div></div><div><div><div>9</div></div><div>
</div></div><div><div><div>10</div></div><div><span>3. void 类型</span></div></div><div><div><div>11</div></div><div><span><span>   </span></span><span>表示“无值”，常用于无返回值函数和通用对象指针 void *</span></div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span>4. 派生类型</span></div></div><div><div><div>14</div></div><div><span><span>   </span></span><span>指针、数组和函数类型</span></div></div><div><div><div>15</div></div><div>
</div></div><div><div><div>16</div></div><div><span>5. 结构与联合类型</span></div></div><div><div><div>17</div></div><div><span><span>   </span></span><span>struct、union</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><section><h2>【1】整数类型<a href="#1整数类型"><span>#</span></a></h2><p>整数类型用于表示没有小数部分的数值。<code>signed</code> 类型可表示负数、零和正数，<code>unsigned</code> 类型只表示非负数。</p>

<table><thead><tr><th>类型</th><th>常见含义</th><th>说明</th></tr></thead><tbody><tr><td><code>char</code></td><td>字符或小整数</td><td>大小始终为 1 字节；是否有符号由实现决定</td></tr><tr><td><code>short</code></td><td>短整型</td><td>至少 16 位</td></tr><tr><td><code>int</code></td><td>基本整型</td><td>通常是平台上运算较自然的整数类型，至少 16 位</td></tr><tr><td><code>long</code></td><td>长整型</td><td>至少 32 位</td></tr><tr><td><code>long long</code></td><td>长长整型</td><td>至少 64 位</td></tr></tbody></table><p>C 标准只规定各类型的最小表示范围和相对等级，并不保证 <code>int</code> 永远是 4 字节。实际大小取决于编译器和目标平台，可用 <code>sizeof</code> 运算符查看。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>#include</span><span> </span><span>&lt;stdio.h&gt;</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>int</span><span> </span><span>main</span><span>(</span><span>void</span><span>)</span></div></div><div><div><div>4</div></div><div><span>{</span></div></div><div><div><div>5</div></div><div><span>    </span><span>printf</span><span>(</span><span>"sizeof(char)      = </span><span>%zu</span><span>\n</span><span>"</span><span>, </span><span>sizeof</span><span>(</span><span>char</span><span>));</span></div></div><div><div><div>6</div></div><div><span>    </span><span>printf</span><span>(</span><span>"sizeof(short)     = </span><span>%zu</span><span>\n</span><span>"</span><span>, </span><span>sizeof</span><span>(</span><span>short</span><span>));</span></div></div><div><div><div>7</div></div><div><span>    </span><span>printf</span><span>(</span><span>"sizeof(int)       = </span><span>%zu</span><span>\n</span><span>"</span><span>, </span><span>sizeof</span><span>(</span><span>int</span><span>));</span></div></div><div><div><div>8</div></div><div><span>    </span><span>printf</span><span>(</span><span>"sizeof(long)      = </span><span>%zu</span><span>\n</span><span>"</span><span>, </span><span>sizeof</span><span>(</span><span>long</span><span>));</span></div></div><div><div><div>9</div></div><div><span>    </span><span>printf</span><span>(</span><span>"sizeof(long long) = </span><span>%zu</span><span>\n</span><span>"</span><span>, </span><span>sizeof</span><span>(</span><span>long</span><span> </span><span>long</span><span>));</span></div></div><div><div><div>10</div></div><div><span>    </span><span>return</span><span> </span><span>0</span><span>;</span></div></div><div><div><div>11</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><p><code>sizeof</code> 的结果类型是 <code>size_t</code>，使用 <code>printf</code> 输出时应采用 <code>%zu</code> 格式说明符。</p></section><section><h2>【2】浮点类型<a href="#2浮点类型"><span>#</span></a></h2><p>浮点类型用于表示带小数部分或范围很大的近似数值：</p>

<table><thead><tr><th>类型</th><th>常见精度</th><th>说明</th></tr></thead><tbody><tr><td><code>float</code></td><td>约 6～9 位十进制有效数字</td><td>单精度浮点类型</td></tr><tr><td><code>double</code></td><td>约 15～17 位十进制有效数字</td><td>双精度浮点类型</td></tr><tr><td><code>long double</code></td><td>不低于 <code>double</code></td><td>具体精度由实现决定</td></tr></tbody></table><p>浮点数采用有限位数表示，很多十进制小数无法被精确存储，因此不应简单使用 <code>==</code> 判断两个计算所得的浮点数是否相等。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>double</span><span> result </span><span>=</span><span> </span><span>0.1</span><span> </span><span>+</span><span> </span><span>0.2</span><span>;</span></div></div><div><div><div>2</div></div><div><span>printf</span><span>(</span><span>"</span><span>%.17f</span><span>\n</span><span>"</span><span><span>,</span><span> result</span><span>);</span></span><span>  // 结果可能不是精确的 0.3</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div></section><section><h2>【3】布尔类型<a href="#3布尔类型"><span>#</span></a></h2><p>C99 引入 <code>_Bool</code> 类型，其值会归一化为 <code>0</code> 或 <code>1</code>。在 C17 及更早标准中，通常包含 <code>&lt;stdbool.h&gt;</code> 后使用更易读的 <code>bool</code>、<code>true</code> 和 <code>false</code>：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>#include</span><span> </span><span>&lt;stdbool.h&gt;</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>bool</span><span> is_valid </span><span>=</span><span> </span><span>true</span><span>;</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><p>在条件判断中，数值 <code>0</code> 表示假，任何非零值都表示真。C23 已将 <code>bool</code>、<code>true</code> 和 <code>false</code> 纳入语言本身。</p></section><section><h2>【4】字符类型与字符编码<a href="#4字符类型与字符编码"><span>#</span></a></h2><p><code>char</code> 本质上属于整数类型，也常用于保存字符编码单元。字符常量使用单引号，字符串字面量使用双引号：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>char</span><span> grade </span><span>=</span><span> </span><span>'A'</span><span>;</span></div></div><div><div><div>2</div></div><div><span>char</span><span> message</span><span>[]</span><span> </span><span>=</span><span> </span><span>"Hello"</span><span>;</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><p><code>sizeof(char)</code> 永远等于 <code>1</code>，但 C 标准规定的“字节”不一定是 8 位。可以通过 <code>&lt;limits.h&gt;</code> 中的 <code>CHAR_BIT</code> 查看每字节的位数；在现代通用平台上通常为 8。</p></section><section><h2>【5】固定宽度整数类型<a href="#5固定宽度整数类型"><span>#</span></a></h2><p>当程序确实需要宽度明确的整数时，可以使用 <code>&lt;stdint.h&gt;</code> 提供的类型，例如 <code>int8_t</code>、<code>uint32_t</code> 和 <code>int64_t</code>。这些类型只有在实现能够提供对应宽度时才会定义。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>#include</span><span> </span><span>&lt;stdint.h&gt;</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>uint32_t</span><span> color </span><span>=</span><span> </span><span><span>0x</span><span>FF3366</span><span>U</span></span><span>;</span></div></div><div><div><div>4</div></div><div><span>int64_t</span><span> distance </span><span>=</span><span> </span><span><span>9000000000</span><span>LL</span></span><span>;</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><p>普通业务代码优先使用 <code>int</code> 等基本类型；处理文件格式、网络协议、硬件寄存器等对位宽有明确要求的场景时，再考虑固定宽度类型。</p></section></section>]]></content>
    </entry>
    <entry>
      <id>https://firefly.cuteleaf.cn/posts/language/c/20c%E8%AF%AD%E8%A8%80%E5%9F%BA%E7%A1%80/10%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B/</id>
      <title type="text">C 语言数据类型</title>
      <published>2026-09-26T00:00:00.000Z</published>
      <updated>2026-09-26T00:00:00.000Z</updated>
      <author><name>Dream</name></author>
      <link rel="alternate" href="https://firefly.cuteleaf.cn/posts/language/c/20c%E8%AF%AD%E8%A8%80%E5%9F%BA%E7%A1%80/10%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B/"/>
      <summary type="text">理解 C 语言的数据类型体系，包括基本类型、整数类型、浮点类型和逻辑类型。</summary>
      <content type="html"><![CDATA[<section><h1>【一】数据类型<a href="#一数据类型"><span>#</span></a></h1><p>在 C 语言中，数据类型用于描述数据的性质。一个对象或表达式的类型，会影响以下内容：</p><ul>
<li>数据在内存中的表示方式和通常占用的空间；</li>
<li>数据能够表示的取值范围与精度；</li>
<li>可以对数据执行哪些运算；</li>
<li>编译器应当如何解释对应的位模式。</li>
</ul><p>例如，同样一组二进制位，按整数、浮点数或字符解释时，含义可能完全不同。</p><p>C 语言的类型可以概括为以下几类：</p><ol>
<li><strong>基本类型</strong>：包括字符类型、整数类型、布尔类型和浮点类型。</li>
<li><strong>枚举类型</strong>：使用 <code>enum</code> 定义一组具名的整数常量。</li>
<li><strong>派生类型</strong>：包括数组类型、指针类型和函数类型。</li>
<li><strong>结构体与共用体类型</strong>：分别使用 <code>struct</code> 和 <code>union</code> 组织多个成员。</li>
<li><strong><code>void</code> 类型</strong>：表示“没有值”，常用于无返回值函数和通用对象指针 <code>void *</code>。</li>
</ol><blockquote><p>C 语言没有“引用类型”这一类别。引用是 C++ 等语言中的概念；C 语言主要通过指针间接访问其他对象。</p></blockquote><p>本章以初学阶段最常用的类型为主。除此之外，C99 还提供复数类型，C11 增加了原子类型相关机制，这些内容通常在数学计算和并发编程中进一步学习。</p></section>
<section><h1>【二】基础数据类型<a href="#二基础数据类型"><span>#</span></a></h1><p>C 语言的基本类型主要包括：</p>

<table><thead><tr><th>类别</th><th>常用类型</th><th>用途</th></tr></thead><tbody><tr><td>字符类型</td><td><code>char</code>、<code>signed char</code>、<code>unsigned char</code></td><td>保存字符编码单元或小整数</td></tr><tr><td>整数类型</td><td><code>short</code>、<code>int</code>、<code>long</code>、<code>long long</code> 及其无符号形式</td><td>保存整数</td></tr><tr><td>布尔类型</td><td><code>_Bool</code>，以及常用写法 <code>bool</code></td><td>表示逻辑真与假</td></tr><tr><td>浮点类型</td><td><code>float</code>、<code>double</code>、<code>long double</code></td><td>保存带小数部分或范围较大的近似数值</td></tr></tbody></table><p>数据类型的实际大小与取值范围由 C 标准的最低要求、编译器、目标平台和数据模型共同决定，不能简单认为 <code>int</code> 永远为 4 字节、<code>long</code> 永远为 8 字节。</p><p>C 标准规定了整数类型的最低精度与相对关系，例如：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>sizeof(char) &lt;= sizeof(short) &lt;= sizeof(int) &lt;= sizeof(long) &lt;= sizeof(long long)</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>相邻类型的大小允许相同。<code>sizeof(char)</code> 按定义始终为 <code>1</code>，但 C 语言中的 1 字节不一定等于 8 位；每字节的位数可通过 <code>&lt;limits.h&gt;</code> 中的 <code>CHAR_BIT</code> 查看。现代通用平台通常为 8 位。</p><p>可以使用 <code>sizeof</code> 查看当前编译环境中某个类型所占的字节数，并通过以下头文件查询类型范围：</p><ul>
<li><code>&lt;limits.h&gt;</code>：整数类型的范围和每字节位数；</li>
<li><code>&lt;float.h&gt;</code>：浮点类型的范围与精度；</li>
<li><code>&lt;stdint.h&gt;</code>：固定宽度整数类型及相关宏。</li>
</ul><section><h2>【1】浮点类型<a href="#1浮点类型"><span>#</span></a></h2><p>浮点类型用于表示带小数部分或数值范围较大的近似值：</p>

<table><thead><tr><th>类型</th><th>常见大小</th><th>常见有效数字</th><th>字面量示例</th></tr></thead><tbody><tr><td><code>float</code></td><td>4 字节</td><td>约 6～9 位十进制有效数字</td><td><code>3.14f</code></td></tr><tr><td><code>double</code></td><td>8 字节</td><td>约 15～17 位十进制有效数字</td><td><code>3.14</code></td></tr><tr><td><code>long double</code></td><td>8、12 或 16 字节</td><td>不低于 <code>double</code></td><td><code>3.14L</code></td></tr></tbody></table><p>表中的大小与精度是现代平台上的常见情况，实际结果仍取决于具体实现。可以使用 <code>sizeof</code> 查看大小，并通过 <code>&lt;float.h&gt;</code> 中的 <code>FLT_DIG</code>、<code>DBL_DIG</code>、<code>LDBL_DIG</code> 等宏查看精度。</p><p>浮点数使用有限位数保存数值，很多十进制小数无法被二进制浮点格式精确表示：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>#include</span><span> </span><span>&lt;stdio.h&gt;</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>int</span><span> </span><span>main</span><span>(</span><span>void</span><span>)</span></div></div><div><div><div>4</div></div><div><span>{</span></div></div><div><div><div>5</div></div><div><span>    </span><span>double</span><span> result </span><span>=</span><span> </span><span>0.1</span><span> </span><span>+</span><span> </span><span>0.2</span><span>;</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>    </span><span>printf</span><span>(</span><span>"</span><span>%.17f</span><span>\n</span><span>"</span><span>, result);</span></div></div><div><div><div>8</div></div><div><span>    </span><span>return</span><span> </span><span>0</span><span>;</span></div></div><div><div><div>9</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><p>常见输出为 <code>0.30000000000000004</code>。因此，判断浮点计算结果是否相等时，通常需要结合业务允许的误差范围，而不能一律直接使用 <code>==</code>。</p></section><section><h2>【2】<code>void</code> 类型<a href="#2void-类型"><span>#</span></a></h2><p><code>void</code> 表示“没有值”或“不指定具体对象类型”，主要有以下用途：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>void</span><span> </span><span>print_message</span><span>(</span><span>void</span><span>);</span><span>  // 函数没有返回值，并且不接收参数</span></div></div><div><div><div>2</div></div><div><span>void</span><span> </span><span>*</span><span>data;</span><span>                // 可以保存任意对象的地址</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><ul>
<li>不能定义 <code>void</code> 类型的普通变量，因为 <code>void</code> 没有可存储的值和确定的对象大小。</li>
<li><code>void *</code> 是通用对象指针，可以与其他对象指针相互转换。</li>
<li><code>void *</code> 不包含所指对象的具体类型信息，因此不能直接解引用；使用前需要转换或赋给正确类型的对象指针。</li>
</ul></section></section>
<section><h1>【三】逻辑类型<a href="#三逻辑类型"><span>#</span></a></h1><p>C99 引入了 <code>_Bool</code> 类型。包含 <code>&lt;stdbool.h&gt;</code> 后，在 C17 及更早标准中通常可以使用更易读的 <code>bool</code>、<code>true</code> 和 <code>false</code>；C23 已将 <code>bool</code>、<code>true</code> 和 <code>false</code> 纳入语言本身。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>#include</span><span> </span><span>&lt;stdbool.h&gt;</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>bool</span><span> is_ready </span><span>=</span><span> </span><span>true</span><span>;</span></div></div><div><div><div>4</div></div><div><span>bool</span><span> has_error </span><span>=</span><span> </span><span>false</span><span>;</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><p>在条件判断中：</p><ul>
<li>数值 <code>0</code> 表示假；</li>
<li>任何非零值都表示真；</li>
<li>将任意标量值转换为 <code>_Bool</code> 时，<code>0</code> 会转换为 <code>0</code>，非零值会转换为 <code>1</code>。</li>
</ul><p>因此，“非零为真”描述的是条件判断规则，并不表示所有非零值本身都等于整数 <code>1</code>。</p><p>例如：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>int</span><span> x;</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>if</span><span> (</span><span>0.5</span><span>) {</span></div></div><div><div><div>4</div></div><div><span><span>    </span></span><span>x </span><span>=</span><span> </span><span>12</span><span>;</span></div></div><div><div><div>5</div></div><div><span>} </span><span>else</span><span> {</span></div></div><div><div><div>6</div></div><div><span><span>    </span></span><span>x </span><span>=</span><span> </span><span>18</span><span>;</span></div></div><div><div><div>7</div></div><div><span>}</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span>// 0.5 是非零值，条件为真，因此 x 最终为 12。</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><blockquote><p>浮点数也可以作为判断条件，但实际程序通常应写出含义更明确的比较表达式，例如 <code>value != 0.0</code>。</p></blockquote></section>
<section><h1>【四】整数类型<a href="#四整数类型"><span>#</span></a></h1><p>C 的标准整数类型包括 <code>char</code>、<code>short</code>、<code>int</code>、<code>long</code> 和 <code>long long</code>，每种标准有符号整数类型（除 plain <code>char</code> 外）都有对应的无符号形式。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>signed char / unsigned char</span></div></div><div><div><div>2</div></div><div><span>signed short / unsigned short</span></div></div><div><div><div>3</div></div><div><span>signed int / unsigned int</span></div></div><div><div><div>4</div></div><div><span>signed long / unsigned long</span></div></div><div><div><div>5</div></div><div><span>signed long long / unsigned long long</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>其中，<code>signed</code> 可以省略，因此 <code>short</code> 等价于 <code>signed short</code>，<code>int</code> 等价于 <code>signed int</code>。但是，<code>char</code>、<code>signed char</code> 和 <code>unsigned char</code> 是三个不同的类型，普通 <code>char</code> 是否带符号由具体实现决定。</p><p>下面表格中的字节数和范围是常见 8 位字节、二进制补码环境中的典型结果，并非 C 标准对所有平台的固定要求。编写程序时，可以使用 <code>sizeof</code> 和 <code>&lt;limits.h&gt;</code> 在当前环境中确认。</p><section><h2>【1】字符类型（<code>char</code>）<a href="#1字符类型char"><span>#</span></a></h2>

<table><thead><tr><th>类型名称</th><th>常见长度</th><th>常见范围</th><th>说明</th></tr></thead><tbody><tr><td><code>char</code></td><td>1 字节</td><td>由实现决定</td><td>与 <code>signed char</code>、<code>unsigned char</code> 都是不同类型</td></tr><tr><td><code>signed char</code></td><td>1 字节</td><td>-128 ～ 127</td><td>明确表示有符号小整数</td></tr><tr><td><code>unsigned char</code></td><td>1 字节</td><td>0 ～ 255</td><td>也常用于查看对象的原始字节</td></tr></tbody></table><p>给整数类型赋值时，需要注意目标类型能否表示该值：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>char</span><span> c1 </span><span>=</span><span> </span><span>129</span><span>;</span></div></div><div><div><div>2</div></div><div><span>unsigned</span><span> </span><span>char</span><span> c2 </span><span>=</span><span> </span><span>-</span><span>1</span><span>;</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><ul>
<li>如果当前实现的普通 <code>char</code> 是有符号的，并且无法表示 <code>129</code>，转换结果由实现定义，编译器也可能发出警告；这不一定是编译错误。</li>
<li>转换到无符号整数类型时，数值会按该类型可表示值数量取模。在 8 位 <code>unsigned char</code> 环境中，<code>-1</code> 会转换为 <code>255</code>。</li>
</ul><blockquote><p>不应依赖超出范围后的隐式转换结果来表达正常业务逻辑。需要明确范围时，应先检查数值，再进行转换。</p></blockquote></section><section><h2>【2】<code>short</code> 类型<a href="#2short-类型"><span>#</span></a></h2>

<table><thead><tr><th>类型名称</th><th>常见长度</th><th>常见范围</th></tr></thead><tbody><tr><td><code>short</code>（<code>signed short</code>）</td><td>2 字节</td><td>-32768 ～ 32767</td></tr><tr><td><code>unsigned short</code></td><td>2 字节</td><td>0 ～ 65535</td></tr></tbody></table></section><section><h2>【3】int 类型<a href="#3int-类型"><span>#</span></a></h2>

<table><thead><tr><th>类型名称</th><th>常见长度</th><th>常见范围</th></tr></thead><tbody><tr><td><code>int</code>（<code>signed int</code>）</td><td>4 字节</td><td>-2147483648 ～ 2147483647</td></tr><tr><td><code>unsigned int</code></td><td>4 字节</td><td>0 ～ 4294967295</td></tr></tbody></table></section><section><h2>【4】long 类型<a href="#4long-类型"><span>#</span></a></h2><p><code>long</code> 的大小不能仅根据“32 位或 64 位系统”判断，它还取决于平台采用的数据模型：</p>

<table><thead><tr><th>常见环境</th><th>数据模型</th><th><code>long</code> 的常见长度</th><th><code>signed long</code> 的常见范围</th></tr></thead><tbody><tr><td>32 位 Windows / Linux</td><td>ILP32</td><td>4 字节</td><td>-2<sup>31</sup> ～ 2<sup>31</sup> - 1</td></tr><tr><td>64 位 Windows（包括 MinGW-w64）</td><td>LLP64</td><td>4 字节</td><td>-2<sup>31</sup> ～ 2<sup>31</sup> - 1</td></tr><tr><td>64 位 Linux / macOS</td><td>LP64</td><td>8 字节</td><td>-2<sup>63</sup> ～ 2<sup>63</sup> - 1</td></tr></tbody></table><p>相应的 <code>unsigned long</code> 范围通常为 0 ～ 2<sup>N</sup> - 1，其中 <code>N</code> 是该类型的位数。</p></section><section><h2>【5】<code>long int</code> 类型<a href="#5long-int-类型"><span>#</span></a></h2><p><code>long int</code> 不是另一种独立类型，它只是 <code>long</code> 的完整写法；同理，<code>unsigned long int</code> 与 <code>unsigned long</code> 完全等价。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>long</span><span> a </span><span>=</span><span> </span><span><span>10</span><span>L</span></span><span>;</span></div></div><div><div><div>2</div></div><div><span>long</span><span> </span><span>int</span><span> b </span><span>=</span><span> </span><span><span>10</span><span>L</span></span><span>;</span><span>                  // 与 long 相同</span></div></div><div><div><div>3</div></div><div><span>unsigned</span><span> </span><span>long</span><span> c </span><span>=</span><span> </span><span><span>10</span><span>UL</span></span><span>;</span></div></div><div><div><div>4</div></div><div><span>unsigned</span><span> </span><span>long</span><span> </span><span>int</span><span> d </span><span>=</span><span> </span><span><span>10</span><span>UL</span></span><span>;</span><span>        // 与 unsigned long 相同</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div></section><section><h2>【6】<code>long long</code> 类型<a href="#6long-long-类型"><span>#</span></a></h2>

<table><thead><tr><th>类型名称</th><th>常见长度</th><th>常见范围</th></tr></thead><tbody><tr><td><code>long long</code>（<code>signed long long</code>）</td><td>8 字节</td><td>-2<sup>63</sup> ～ 2<sup>63</sup> - 1</td></tr><tr><td><code>unsigned long long</code></td><td>8 字节</td><td>0 ～ 2<sup>64</sup> - 1</td></tr></tbody></table><p><code>long long</code> 从 C99 开始成为标准类型，标准保证它至少能够表示 -9223372036854775807 ～ 9223372036854775807。</p></section><section><h2>【7】注意事项<a href="#7注意事项"><span>#</span></a></h2><ul>
<li>
<p>有符号整数发生超出可表示范围的算术溢出时，会产生未定义行为。</p>
</li>
<li>
<p>无符号整数运算按 2<sup>N</sup> 取模，其中 <code>N</code> 是该类型的值位数，因此不会发生标准意义上的有符号溢出，但仍可能造成逻辑错误。</p>
</li>
<li>
<p><code>float</code>、<code>double</code> 和 <code>long double</code> 没有对应的 <code>unsigned</code> 形式，下面的写法都是语法错误：</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>unsigned</span><span> </span><span>float</span><span> value1;</span></div></div><div><div><div>2</div></div><div><span>unsigned</span><span> </span><span>double</span><span> value2;</span></div></div><div><div><div>3</div></div><div><span>unsigned</span><span> </span><span>long</span><span> </span><span>double</span><span> value3;</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div>
</li>
<li>
<p>需要明确位宽时，可以使用 <code>&lt;stdint.h&gt;</code> 中的 <code>int8_t</code>、<code>uint32_t</code>、<code>int64_t</code> 等类型。只有实现能够提供相应宽度时，这些类型才会被定义。</p>
</li>
</ul></section></section>
<section><h1>【五】整数进制<a href="#五整数进制"><span>#</span></a></h1><ul>
<li>按照进位规则计数的数制称为进位计数制，简称进位制。</li>
<li>C 源代码中的整数字面量可以使用二进制、八进制、十进制和十六进制表示。</li>
<li>进制只影响源代码的书写方式，不会改变整数在程序中的类型和值。例如，<code>10</code>、<code>012</code> 和 <code>0xA</code> 表示的数值都等于十进制的 10。</li>
</ul><section><h2>【1】二进制<a href="#1二进制"><span>#</span></a></h2><blockquote><p>基数为 2 的进位制称为二进制。</p><p>二进制只有 <code>0</code>、<code>1</code> 两种数字，计数时逢 2 进 1。</p><p>二进制整数字面量以 <code>0b</code> 或 <code>0B</code> 开头，例如 <code>0b1010</code>。</p></blockquote><p><code>0b</code> 前缀从 C23 开始成为标准语法；在更早的 C 标准模式中，它属于 GCC、Clang 等编译器提供的扩展。使用旧版编译器或严格的 C17 模式时，应先确认是否支持。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>0b1010 = 1 × 2^3 + 0 × 2^2 + 1 × 2^1 + 0 × 2^0</span></div></div><div><div><div>2</div></div><div><span><span>       </span></span><span>= 1 × 8   + 0 × 4   + 1 × 2   + 0 × 1</span></div></div><div><div><div>3</div></div><div><span><span>       </span></span><span>= 10</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h2>【2】八进制<a href="#2八进制"><span>#</span></a></h2><blockquote><p>基数为 8 的进位制称为八进制。</p><p>八进制包含 <code>0</code>～<code>7</code> 共八种数字，计数时逢 8 进 1。</p><p>八进制整数字面量以数字 <code>0</code> 开头。</p></blockquote><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>01010 = 1 × 8^3 + 0 × 8^2 + 1 × 8^1 + 0 × 8^0</span></div></div><div><div><div>2</div></div><div><span><span>      </span></span><span>= 1 × 512 + 0 × 64  + 1 × 8   + 0 × 1</span></div></div><div><div><div>3</div></div><div><span><span>      </span></span><span>= 520</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>注意区分普通十进制数和以 <code>0</code> 开头的八进制数。例如，<code>010</code> 表示十进制的 8；<code>08</code> 和 <code>09</code> 不是合法的八进制整数字面量。</p></blockquote></section><section><h2>【3】十进制<a href="#3十进制"><span>#</span></a></h2><blockquote><p>基数为 10 的进位制称为十进制。</p><p>十进制包含 <code>0</code>～<code>9</code> 共十种数字，计数时逢 10 进 1。</p><p>十进制整数字面量没有额外前缀。</p></blockquote><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>1010 = 1 × 10^3 + 0 × 10^2 + 1 × 10^1 + 0 × 10^0</span></div></div><div><div><div>2</div></div><div><span><span>     </span></span><span>= 1 × 1000 + 0 × 100  + 1 × 10   + 0 × 1</span></div></div><div><div><div>3</div></div><div><span><span>     </span></span><span>= 1010</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h2>【4】十六进制<a href="#4十六进制"><span>#</span></a></h2><blockquote><p>基数为 16 的进位制称为十六进制。</p><p>十六进制包含 <code>0</code>～<code>9</code> 和 <code>A</code>～<code>F</code>（不区分大小写）共 16 种数字，计数时逢 16 进 1。</p><p>十六进制整数字面量以 <code>0x</code> 或 <code>0X</code> 开头。</p></blockquote><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>0x1010 = 1 × 16^3 + 0 × 16^2 + 1 × 16^1 + 0 × 16^0</span></div></div><div><div><div>2</div></div><div><span><span>       </span></span><span>= 1 × 4096 + 0 × 256  + 1 × 16   + 0 × 1</span></div></div><div><div><div>3</div></div><div><span><span>       </span></span><span>= 4112</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>上述公式中的 <code>^</code> 仅用于表示数学上的乘方。在 C 表达式中，<code>^</code> 是按位异或运算符，并不表示乘方。</p></blockquote><p>整数的进制与输出格式可以不同。<code>printf</code> 常用的无符号整数格式说明符如下：</p>

<table><thead><tr><th>格式说明符</th><th>输出形式</th></tr></thead><tbody><tr><td><code>%u</code></td><td>无符号十进制</td></tr><tr><td><code>%o</code></td><td>无符号八进制</td></tr><tr><td><code>%x</code></td><td>无符号十六进制（小写）</td></tr><tr><td><code>%X</code></td><td>无符号十六进制（大写）</td></tr></tbody></table><p><code>printf</code> 没有标准的二进制格式说明符。如果需要输出二进制，通常需要自行逐位处理。</p></section><section><h2>【5】练习<a href="#5练习"><span>#</span></a></h2><section><h3>（1）进制表示<a href="#1进制表示"><span>#</span></a></h3><ul>
<li>要求：分别使用二进制、八进制、十进制和十六进制字面量表示整数，并统一使用十进制输出。</li>
</ul><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>#include</span><span> </span><span>&lt;stdio.h&gt;</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>int</span><span> </span><span>main</span><span>(</span><span>void</span><span>)</span></div></div><div><div><div>4</div></div><div><span>{</span></div></div><div><div><div>5</div></div><div><span>    </span><span>int</span><span> a </span><span>=</span><span> </span><span><span>0b</span><span>1010</span></span><span>;</span><span>  // 二进制字面量（C23，旧版 GCC 也支持此扩展）</span></div></div><div><div><div>6</div></div><div><span>    </span><span>int</span><span> b </span><span>=</span><span> </span><span><span>0</span><span>1010</span></span><span>;</span><span>   // 八进制字面量</span></div></div><div><div><div>7</div></div><div><span>    </span><span>int</span><span> c </span><span>=</span><span> </span><span>1010</span><span>;</span><span>    // 十进制字面量</span></div></div><div><div><div>8</div></div><div><span>    </span><span>int</span><span> d </span><span>=</span><span> </span><span><span>0x</span><span>1010</span></span><span>;</span><span>  // 十六进制字面量</span></div></div><div><div><div>9</div></div><div>
</div></div><div><div><div>10</div></div><div><span>    </span><span>printf</span><span>(</span><span>"a = </span><span>%d</span><span>\n</span><span>"</span><span>, a);</span><span>  // 以十进制输出</span></div></div><div><div><div>11</div></div><div><span>    </span><span>printf</span><span>(</span><span>"b = </span><span>%d</span><span>\n</span><span>"</span><span>, b);</span><span>  // 以十进制输出</span></div></div><div><div><div>12</div></div><div><span>    </span><span>printf</span><span>(</span><span>"c = </span><span>%d</span><span>\n</span><span>"</span><span>, c);</span><span>  // 以十进制输出</span></div></div><div><div><div>13</div></div><div><span>    </span><span>printf</span><span>(</span><span>"d = </span><span>%d</span><span>\n</span><span>"</span><span>, d);</span><span>  // 以十进制输出</span></div></div><div><div><div>14</div></div><div>
</div></div><div><div><div>15</div></div><div><span>    </span><span>return</span><span> </span><span>0</span><span>;</span></div></div><div><div><div>16</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><ul>
<li>运行结果</li>
</ul><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>a = 10</span></div></div><div><div><div>2</div></div><div><span>b = 520</span></div></div><div><div><div>3</div></div><div><span>c = 1010</span></div></div><div><div><div>4</div></div><div><span>d = 4112</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>（2）数据类型<a href="#2数据类型"><span>#</span></a></h3><ul>
<li>使用 <code>sizeof</code> 运算符查看当前编译环境中常用数据类型占用的字节数。</li>
</ul><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>#include</span><span> </span><span>&lt;stdio.h&gt;</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>int</span><span> </span><span>main</span><span>(</span><span>void</span><span>)</span></div></div><div><div><div>4</div></div><div><span>{</span></div></div><div><div><div>5</div></div><div><span>    </span><span>printf</span><span>(</span><span>"sizeof(char)               = </span><span>%zu</span><span>\n</span><span>"</span><span>, </span><span>sizeof</span><span>(</span><span>char</span><span>));</span></div></div><div><div><div>6</div></div><div><span>    </span><span>printf</span><span>(</span><span>"sizeof(unsigned char)      = </span><span>%zu</span><span>\n</span><span>"</span><span>, </span><span>sizeof</span><span>(</span><span>unsigned</span><span> </span><span>char</span><span>));</span></div></div><div><div><div>7</div></div><div><span>    </span><span>printf</span><span>(</span><span>"sizeof(short)              = </span><span>%zu</span><span>\n</span><span>"</span><span>, </span><span>sizeof</span><span>(</span><span>short</span><span>));</span></div></div><div><div><div>8</div></div><div><span>    </span><span>printf</span><span>(</span><span>"sizeof(unsigned short)     = </span><span>%zu</span><span>\n</span><span>"</span><span>, </span><span>sizeof</span><span>(</span><span>unsigned</span><span> </span><span>short</span><span>));</span></div></div><div><div><div>9</div></div><div><span>    </span><span>printf</span><span>(</span><span>"sizeof(int)                = </span><span>%zu</span><span>\n</span><span>"</span><span>, </span><span>sizeof</span><span>(</span><span>int</span><span>));</span></div></div><div><div><div>10</div></div><div><span>    </span><span>printf</span><span>(</span><span>"sizeof(unsigned int)       = </span><span>%zu</span><span>\n</span><span>"</span><span>, </span><span>sizeof</span><span>(</span><span>unsigned</span><span> </span><span>int</span><span>));</span></div></div><div><div><div>11</div></div><div><span>    </span><span>printf</span><span>(</span><span>"sizeof(long)               = </span><span>%zu</span><span>\n</span><span>"</span><span>, </span><span>sizeof</span><span>(</span><span>long</span><span>));</span></div></div><div><div><div>12</div></div><div><span>    </span><span>printf</span><span>(</span><span>"sizeof(unsigned long)      = </span><span>%zu</span><span>\n</span><span>"</span><span>, </span><span>sizeof</span><span>(</span><span>unsigned</span><span> </span><span>long</span><span>));</span></div></div><div><div><div>13</div></div><div><span>    </span><span>printf</span><span>(</span><span>"sizeof(long int)           = </span><span>%zu</span><span>\n</span><span>"</span><span>, </span><span>sizeof</span><span>(</span><span>long</span><span> </span><span>int</span><span>));</span></div></div><div><div><div>14</div></div><div><span>    </span><span>printf</span><span>(</span><span>"sizeof(unsigned long int)  = </span><span>%zu</span><span>\n</span><span>"</span><span>, </span><span>sizeof</span><span>(</span><span>unsigned</span><span> </span><span>long</span><span> </span><span>int</span><span>));</span></div></div><div><div><div>15</div></div><div><span>    </span><span>printf</span><span>(</span><span>"sizeof(long long)          = </span><span>%zu</span><span>\n</span><span>"</span><span>, </span><span>sizeof</span><span>(</span><span>long</span><span> </span><span>long</span><span>));</span></div></div><div><div><div>16</div></div><div><span>    </span><span>printf</span><span>(</span><span>"sizeof(unsigned long long) = </span><span>%zu</span><span>\n</span><span>"</span><span>, </span><span>sizeof</span><span>(</span><span>unsigned</span><span> </span><span>long</span><span> </span><span>long</span><span>));</span></div></div><div><div><div>17</div></div><div><span>    </span><span>printf</span><span>(</span><span>"sizeof(float)              = </span><span>%zu</span><span>\n</span><span>"</span><span>, </span><span>sizeof</span><span>(</span><span>float</span><span>));</span></div></div><div><div><div>18</div></div><div><span>    </span><span>printf</span><span>(</span><span>"sizeof(double)             = </span><span>%zu</span><span>\n</span><span>"</span><span>, </span><span>sizeof</span><span>(</span><span>double</span><span>));</span></div></div><div><div><div>19</div></div><div><span>    </span><span>printf</span><span>(</span><span>"sizeof(long double)        = </span><span>%zu</span><span>\n</span><span>"</span><span>, </span><span>sizeof</span><span>(</span><span>long</span><span> </span><span>double</span><span>));</span></div></div><div><div><div>20</div></div><div>
</div></div><div><div><div>21</div></div><div><span>    </span><span>return</span><span> </span><span>0</span><span>;</span></div></div><div><div><div>22</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p><code>sizeof</code> 表达式的结果类型是 <code>size_t</code>，使用 <code>printf</code> 输出时应匹配 <code>%zu</code>，不能使用 <code>%d</code>。</p><ul>
<li>运行结果</li>
</ul><p>以下结果用于展示平台差异，不代表所有编译环境都完全相同。</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># Windows 10/11，x86_64 MinGW-w64 GCC 13.2.0</span></div></div><div><div><div>2</div></div><div><span>sizeof(char)                  = 1</span></div></div><div><div><div>3</div></div><div><span>sizeof(unsigned char)         = 1</span></div></div><div><div><div>4</div></div><div><span>sizeof(short)                 = 2</span></div></div><div><div><div>5</div></div><div><span>sizeof(unsigned short)        = 2</span></div></div><div><div><div>6</div></div><div><span>sizeof(int)                   = 4</span></div></div><div><div><div>7</div></div><div><span>sizeof(unsigned int)          = 4</span></div></div><div><div><div>8</div></div><div><span>sizeof(long)                  = 4</span></div></div><div><div><div>9</div></div><div><span>sizeof(unsigned long)         = 4</span></div></div><div><div><div>10</div></div><div><span>sizeof(long int)              = 4</span></div></div><div><div><div>11</div></div><div><span>sizeof(unsigned long int)     = 4</span></div></div><div><div><div>12</div></div><div><span>sizeof(long long)             = 8</span></div></div><div><div><div>13</div></div><div><span>sizeof(unsigned long long)    = 8</span></div></div><div><div><div>14</div></div><div><span>sizeof(float)                 = 4</span></div></div><div><div><div>15</div></div><div><span>sizeof(double)                = 8</span></div></div><div><div><div>16</div></div><div><span>sizeof(long double)           = 16</span></div></div><div><div><div>17</div></div><div>
</div></div><div><div><div>18</div></div><div><span># Ubuntu 18.04，x86_64 GCC 的一种典型结果</span></div></div><div><div><div>19</div></div><div><span>sizeof(char)                  = 1</span></div></div><div><div><div>20</div></div><div><span>sizeof(unsigned char)         = 1</span></div></div><div><div><div>21</div></div><div><span>sizeof(short)                 = 2</span></div></div><div><div><div>22</div></div><div><span>sizeof(unsigned short)        = 2</span></div></div><div><div><div>23</div></div><div><span>sizeof(int)                   = 4</span></div></div><div><div><div>24</div></div><div><span>sizeof(unsigned int)          = 4</span></div></div><div><div><div>25</div></div><div><span>sizeof(long)                  = 8</span></div></div><div><div><div>26</div></div><div><span>sizeof(unsigned long)         = 8</span></div></div><div><div><div>27</div></div><div><span>sizeof(long int)              = 8</span></div></div><div><div><div>28</div></div><div><span>sizeof(unsigned long int)     = 8</span></div></div><div><div><div>29</div></div><div><span>sizeof(long long)             = 8</span></div></div><div><div><div>30</div></div><div><span>sizeof(unsigned long long)    = 8</span></div></div><div><div><div>31</div></div><div><span>sizeof(float)                 = 4</span></div></div><div><div><div>32</div></div><div><span>sizeof(double)                = 8</span></div></div><div><div><div>33</div></div><div><span>sizeof(long double)           = 16</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section></section></section>
<section><h1>【六】ASCII 码<a href="#六ascii-码"><span>#</span></a></h1><p>ASCII（American Standard Code for Information Interchange，美国信息交换标准代码）是一种早期且广泛使用的字符编码标准。</p><p>ASCII 使用 7 位编码，共定义 128 个码位，范围为十进制 <code>0</code>～<code>127</code>（十六进制 <code>0x00</code>～<code>0x7F</code>）。其中包含英文字母、十进制数字、常用符号和控制字符。</p><p>ASCII 的核心作用是建立<strong>字符与整数编码值之间的映射</strong>。例如，在 ASCII 中，字符 <code>'A'</code> 对应十进制值 <code>65</code>，字符 <code>'0'</code> 对应十进制值 <code>48</code>。</p><p>在 C 语言中，<code>char</code> 属于整数类型，因此字符可以参与整数运算，也可以分别按字符形式或整数形式输出：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>#include</span><span> </span><span>&lt;stdio.h&gt;</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>int</span><span> </span><span>main</span><span>(</span><span>void</span><span>)</span></div></div><div><div><div>4</div></div><div><span>{</span></div></div><div><div><div>5</div></div><div><span>    </span><span>char</span><span> ch </span><span>=</span><span> </span><span>'A'</span><span>;</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>    </span><span>printf</span><span>(</span><span>"字符：</span><span>%c</span><span>\n</span><span>"</span><span>, ch);</span></div></div><div><div><div>8</div></div><div><span>    </span><span>printf</span><span>(</span><span>"编码值：</span><span>%d</span><span>\n</span><span>"</span><span>, (</span><span>int</span><span>)(</span><span>unsigned</span><span> </span><span>char</span><span>)ch);</span></div></div><div><div><div>9</div></div><div><span>    </span><span>return</span><span> </span><span>0</span><span>;</span></div></div><div><div><div>10</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><p>在 ASCII 环境中，程序会输出字符 <code>A</code> 及其编码值 <code>65</code>。</p><blockquote><p>C 语言标准并不强制执行字符集必须采用 ASCII，但 Windows、Linux 和 macOS 等现代通用环境通常兼容 ASCII 的前 128 个码位。ASCII 之外的中文等字符需要结合 UTF-8、GBK 等字符编码理解，不能简单当作单个 <code>char</code> 处理。</p></blockquote><p>ASCII 可以划分为：</p><ul>
<li><code>0x00</code>～<code>0x1F</code>：32 个控制字符；</li>
<li><code>0x20</code>～<code>0x7E</code>：95 个可打印字符；</li>
<li><code>0x7F</code>：删除控制字符 DEL。</li>
</ul><p></p><figure><img src="https://oss.silentdream.top/2026/09/26/20-09-04-897c0d4e-image-20260922215505519-0ad119.png" alt="image-20260922215505519" /><figcaption>image-20260922215505519</figcaption></figure><p></p><section><h2>【1】不可打印字符<a href="#1不可打印字符"><span>#</span></a></h2><p>不可打印字符通常不直接显示图形，而是用于控制文本、终端或通信过程。常见示例如下：</p>

<table><thead><tr><th>ASCII 值</th><th>转义写法</th><th>名称</th><th>说明</th></tr></thead><tbody><tr><td>0</td><td><code>\0</code></td><td>NUL（空字符）</td><td>C 字符串的结束标志</td></tr><tr><td>8</td><td><code>\b</code></td><td>BS（退格）</td><td>对应退格控制功能</td></tr><tr><td>9</td><td><code>\t</code></td><td>HT（水平制表）</td><td>移动到下一个水平制表位置</td></tr><tr><td>10</td><td><code>\n</code></td><td>LF（换行）</td><td>Unix/Linux 文本中的换行字符</td></tr><tr><td>13</td><td><code>\r</code></td><td>CR（回车）</td><td>将位置移至当前行开头；Windows 文本换行通常使用 <code>\r\n</code></td></tr><tr><td>127</td><td>无常用转义写法</td><td>DEL（删除）</td><td>删除控制字符</td></tr></tbody></table><p>键盘上的 Enter 键会由终端或操作系统转换成相应的输入序列，并不能在所有环境下简单等同于单个 ASCII 10。</p></section><section><h2>【2】可打印字符<a href="#2可打印字符"><span>#</span></a></h2>

<table><thead><tr><th>ASCII 值</th><th>字符</th><th>描述</th></tr></thead><tbody><tr><td>32</td><td>空格</td><td>空格字符 <code>' '</code></td></tr><tr><td>39</td><td><code>'</code></td><td>单引号；在字符常量中写作 <code>'\''</code></td></tr><tr><td>47</td><td><code>/</code></td><td>正斜杠</td></tr><tr><td>48</td><td><code>0</code></td><td>数字字符 <code>'0'</code>，不要与编码值为 0 的 <code>\0</code> 混淆</td></tr><tr><td>65</td><td><code>A</code></td><td>大写英文字母 A</td></tr><tr><td>92</td><td><code>\</code></td><td>反斜杠；在 C 字符常量中写作 <code>'\\'</code></td></tr><tr><td>96</td><td><code>`</code></td><td>反引号</td></tr><tr><td>97</td><td><code>a</code></td><td>小写英文字母 a</td></tr><tr><td>124</td><td><code>|</code></td><td>竖线</td></tr></tbody></table><p>ASCII 中的数字字符和英文字母各自连续排列，因此可以进行一些简单换算：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>int</span><span> digit </span><span>=</span><span> </span><span>'7'</span><span> </span><span>-</span><span> </span><span>'0'</span><span>;</span><span>       // 得到整数 7</span></div></div><div><div><div>2</div></div><div><span>char</span><span> lower </span><span>=</span><span> </span><span>'A'</span><span> </span><span>+</span><span> </span><span>32</span><span>;</span><span>       // ASCII 中得到字符 'a'</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><p>其中，C 标准保证 <code>'0'</code>～<code>'9'</code> 连续，因此第一种数字转换写法具有可移植性；<code>'A' + 32</code> 依赖 ASCII 的字母排列方式。更通用的大小写转换应使用 <code>&lt;ctype.h&gt;</code> 中的 <code>tolower</code> 和 <code>toupper</code>：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>#include</span><span> </span><span>&lt;ctype.h&gt;</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>char</span><span> lower </span><span>=</span><span> (</span><span>char</span><span>)</span><span>tolower</span><span>((</span><span>unsigned</span><span> </span><span>char</span><span>)</span><span>'A'</span><span>);</span></div></div><div><div><div>4</div></div><div><span>char</span><span> upper </span><span>=</span><span> (</span><span>char</span><span>)</span><span>toupper</span><span>((</span><span>unsigned</span><span> </span><span>char</span><span>)</span><span>'a'</span><span>);</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><blockquote><p>为了在 Markdown 表格中显示竖线字符，表格中的 <code>|</code> 写作 <code>\|</code>。这只是 Markdown 转义，不属于字符本身。</p></blockquote></section></section>]]></content>
    </entry>
    <entry>
      <id>https://firefly.cuteleaf.cn/posts/language/c/20c%E8%AF%AD%E8%A8%80%E5%9F%BA%E7%A1%80/20%E8%AF%AD%E6%B3%95%E7%AC%A6%E5%8F%B7/</id>
      <title type="text">C 语言语法符号</title>
      <published>2026-09-26T00:00:00.000Z</published>
      <updated>2026-09-26T00:00:00.000Z</updated>
      <author><name>Dream</name></author>
      <link rel="alternate" href="https://firefly.cuteleaf.cn/posts/language/c/20c%E8%AF%AD%E8%A8%80%E5%9F%BA%E7%A1%80/20%E8%AF%AD%E6%B3%95%E7%AC%A6%E5%8F%B7/"/>
      <summary type="text">认识 C 语言的 Token、关键字、标识符、运算符、分隔符和标点符号。</summary>
      <content type="html"><![CDATA[<section><h1>【一】语法符号的理解<a href="#一语法符号的理解"><span>#</span></a></h1><p>每种编程语言都有自己的词汇和语法规则。编译器不会把源代码直接当作一整段文字理解，而是先进行词法分析，将代码识别成一个个具有语法意义的最小单元，这些单元通常称为 <strong>Token（记号或词法单元）</strong>。</p><p>例如：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>int</span><span> sum </span><span>=</span><span> a </span><span>+</span><span> </span><span>10</span><span>;</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><p>可以识别为：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>int    sum    =    a    +    10    ;</span></div></div><div><div><div>2</div></div><div><span>关键字 标识符  运算符 标识符 运算符 常量  标点符号</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>按照本系列笔记便于理解的分类方式，可以将常见语法符号分为：</p><ul>
<li><strong>关键字</strong>：由语言标准赋予固定含义的单词；</li>
<li><strong>标识符</strong>：由程序员命名的变量、函数、类型等名称；</li>
<li><strong>运算符</strong>：表示计算、比较、赋值或其他操作的符号；</li>
<li><strong>分隔符</strong>：用于分隔词法单元的空白字符和注释；</li>
<li><strong>标点符号</strong>：用于组织声明、表达式、语句和代码块的符号。</li>
</ul><p>此外，源代码中还有常量和字符串字面量。它们属于 C 语言 Token 的重要组成部分，将在“常量”章节单独讲解。</p><blockquote><p>从 C 标准的词法分类来看，许多“运算符”和“标点符号”会统一归入 <strong>punctuator（标点符号/界符）</strong>。本章将它们分开说明，是为了便于初学者按用途理解。</p></blockquote></section>
<section><h1>【二】关键字<a href="#二关键字"><span>#</span></a></h1><p>关键字是由 C 语言标准预先规定并赋予特殊语法含义的单词，不能用作变量名、函数名或其他标识符。</p><section><h2>【1】C90 的 32 个关键字<a href="#1c90-的-32-个关键字"><span>#</span></a></h2><p>C90 规定了 32 个经典关键字：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>auto       </span><span>break</span><span>      case       </span><span>char</span><span>       </span><span>const</span></div></div><div><div><div>2</div></div><div><span>continue</span><span>   default    </span><span>do</span><span>         </span><span>double</span><span>     </span><span>else</span></div></div><div><div><div>3</div></div><div><span>enum</span><span>       </span><span>extern</span><span>     </span><span>float</span><span>      </span><span>for</span><span>        </span><span>goto</span></div></div><div><div><div>4</div></div><div><span>if</span><span>         </span><span>int</span><span>        </span><span>long</span><span>       </span><span>register</span><span>   </span><span>return</span></div></div><div><div><div>5</div></div><div><span>short</span><span>      </span><span>signed</span><span>     </span><span>sizeof</span><span>     </span><span>static</span><span>     </span><span>struct</span></div></div><div><div><div>6</div></div><div><span>switch</span><span>     </span><span>typedef</span><span>    </span><span>union</span><span>      </span><span>unsigned</span><span>   </span><span>void</span></div></div><div><div><div>7</div></div><div><span>volatile</span><span>   </span><span>while</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><p>关键字区分大小写。例如，<code>int</code> 是关键字，而 <code>Int</code> 不是关键字；但不应通过改变大小写来创建含义相近的名称。</p></section><section><h2>【2】后续标准新增的关键字<a href="#2后续标准新增的关键字"><span>#</span></a></h2><p>C 语言会随标准更新而扩展，因此“C 语言只有 32 个关键字”只适用于 C90。常见新增关键字如下：</p><section><h3>（1）C99 新增<a href="#1c99-新增"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>inline</span><span>      </span><span>restrict</span><span>      </span><span>_Bool</span><span>      </span><span>_Complex</span><span>      </span><span>_Imaginary</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><ul>
<li><code>inline</code>：建议以内联方式处理函数；</li>
<li><code>restrict</code>：表达指针访问对象的别名约束；</li>
<li><code>_Bool</code>：布尔类型；</li>
<li><code>_Complex</code>、<code>_Imaginary</code>：复数和虚数类型相关关键字，其中虚数类型属于实现可选功能。</li>
</ul></section><section><h3>（2）C11 新增<a href="#2c11-新增"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>_Alignas        _Alignof        _Atomic         _Generic</span></div></div><div><div><div>2</div></div><div><span>_Noreturn       _Static_assert  _Thread_local</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><p>这些关键字主要用于对齐控制、原子操作、泛型选择、静态断言和线程存储期等功能。</p></section><section><h3>（3）C23 常用新增关键字<a href="#3c23-常用新增关键字"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>alignas          alignof          </span><span>bool</span><span>             constexpr</span></div></div><div><div><div>2</div></div><div><span>false</span><span>            nullptr         static_assert    thread_local</span></div></div><div><div><div>3</div></div><div><span>true</span><span>             typeof          typeof_unqual    _BitInt</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><p>C23 较新，不同编译器对这些关键字的支持程度可能不同。学习或使用 C23 功能时，应确认编译器版本和所选择的语言标准模式。</p></section></section><section><h2>【3】容易误认为关键字的名称<a href="#3容易误认为关键字的名称"><span>#</span></a></h2><p>以下名称虽然经常出现在 C 程序中，但它们并不是 C 语言关键字：</p>

<table><thead><tr><th>名称</th><th>实际性质</th></tr></thead><tbody><tr><td><code>main</code></td><td>程序入口函数的约定名称</td></tr><tr><td><code>printf</code>、<code>scanf</code></td><td>标准库函数名</td></tr><tr><td><code>NULL</code></td><td>标准头文件提供的宏</td></tr><tr><td><code>size_t</code></td><td>标准库定义的类型名</td></tr><tr><td><code>include</code>、<code>define</code></td><td>预处理指令中的名称</td></tr></tbody></table><p>它们分别受到标准库或预处理规则约束，不能简单按普通关键字理解。</p></section></section>
<section><h1>【三】标识符<a href="#三标识符"><span>#</span></a></h1><p>标识符是程序中名称的词法形式，可用于命名宏、变量、函数、形参、结构体成员、自定义类型等程序实体。</p><p>C 语言标识符的基本命名规则如下：</p><ol>
<li>基础且可移植的标识符由英文字母 <code>A-Z</code>、<code>a-z</code>、数字 <code>0-9</code> 和下划线 <code>_</code> 组成。</li>
<li>第一个字符必须是字母或下划线，不能是数字。</li>
<li>标识符不能与 C 语言关键字相同。</li>
<li>C 语言区分大小写，因此 <code>sum</code>、<code>Sum</code> 和 <code>SUM</code> 是三个不同的标识符。</li>
<li>标识符中不能包含空格、连字符 <code>-</code>、点号 <code>.</code>、<code>@</code> 等字符。</li>
</ol><blockquote><p>新版 C 标准也支持一定范围的通用字符名称及扩展字符，但其可用性还受源文件编码和编译器支持影响。基础学习及追求可移植性时，优先使用英文字母、数字和下划线。</p></blockquote><section><h2>【1】合法与非法标识符<a href="#1合法与非法标识符"><span>#</span></a></h2><p>下面是一些合法的标识符：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>x    y    sum    a100    student_name    score2</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>以下标识符不合法：</p>

<table><thead><tr><th>名称</th><th>原因</th></tr></thead><tbody><tr><td><code>1a</code></td><td>以数字开头</td></tr><tr><td><code>3'a</code></td><td>以数字开头，并且包含单引号</td></tr><tr><td><code>x*y</code></td><td>包含运算符 <code>*</code></td></tr><tr><td><code>@</code></td><td><code>@</code> 不能构成基础标识符</td></tr><tr><td><code>b.8</code></td><td>包含点号 <code>.</code></td></tr><tr><td><code>my-name</code></td><td>包含连字符 <code>-</code></td></tr><tr><td><code>my name</code></td><td>包含空格，会被识别为两个词法单元</td></tr><tr><td><code>while</code></td><td>与关键字相同</td></tr></tbody></table></section><section><h2>【2】命名建议<a href="#2命名建议"><span>#</span></a></h2><ul>
<li>名称应表达用途，例如用 <code>student_count</code> 表示学生数量，而不是随意使用 <code>a1</code>。</li>
<li>可以采用下划线命名法 <code>student_count</code> 或小驼峰命名法 <code>studentCount</code>，同一项目中应保持一致。</li>
<li>常量宏通常使用全大写字母和下划线，例如 <code>MAX_SIZE</code>。</li>
<li>不要只通过大小写区分含义相近的变量，例如同时定义 <code>data</code>、<code>Data</code> 和 <code>DATA</code>，这会降低可读性。</li>
<li>简短的局部循环变量可以使用 <code>i</code>、<code>j</code> 等惯用名称，但作用范围较大的名称应更具体。</li>
</ul></section><section><h2>【3】保留标识符<a href="#3保留标识符"><span>#</span></a></h2><p>某些形式的标识符保留给编译器、标准库或具体实现使用。编写用户代码时，应遵循以下安全规则：</p><ul>
<li>不要定义以双下划线开头的名称，如 <code>__value</code>；</li>
<li>不要定义以下划线加大写字母开头的名称，如 <code>_Value</code>；</li>
<li>在文件作用域中，避免定义任何以下划线开头的名称；</li>
<li>不要重用标准库中已有的函数名、宏名和类型名来表达其他含义。</li>
</ul><p>例如，<code>_A7b_3x</code> 从字符组成规则看是合法形式，但它以下划线和大写字母开头，属于实现保留标识符，不应在用户代码中使用。</p></section></section>
<section><h1>【四】运算符<a href="#四运算符"><span>#</span></a></h1><p>运算符用于表示计算、比较、赋值、成员访问等操作。一个运算符需要几个操作数，就称为几元运算符。例如，<code>-a</code> 中的 <code>-</code> 是一元运算符，<code>a - b</code> 中的 <code>-</code> 是二元运算符，<code>condition ? a : b</code> 是三元条件运算符。</p><p>按照功能，常用运算符可以概括为：</p>

<table><thead><tr><th>类别</th><th>常见运算符</th><th>作用概述</th></tr></thead><tbody><tr><td>算术运算符</td><td><code>+</code>、<code>-</code>、<code>*</code>、<code>/</code>、<code>%</code></td><td>执行基本算术运算</td></tr><tr><td>关系运算符</td><td><code>&lt;</code>、<code>&lt;=</code>、<code>&gt;</code>、<code>&gt;=</code>、<code>==</code>、<code>!=</code></td><td>比较两个值</td></tr><tr><td>逻辑运算符</td><td><code>&amp;&amp;</code>、`</td><td></td></tr><tr><td>位运算符</td><td><code>&amp;</code>、`</td><td><code>、</code>^<code>、</code>~<code>、</code>&lt;&lt;<code>、</code>&gt;&gt;`</td></tr><tr><td>赋值运算符</td><td><code>=</code>、<code>+=</code>、<code>-=</code>、<code>*=</code>、<code>/=</code> 等</td><td>为对象赋值或执行复合赋值</td></tr><tr><td>自增、自减运算符</td><td><code>++</code>、<code>--</code></td><td>将操作数增加或减少 1</td></tr><tr><td>条件运算符</td><td><code>?:</code></td><td>根据条件从两个表达式中选择一个</td></tr><tr><td>指针相关运算符</td><td><code>&amp;</code>、<code>*</code></td><td>获取对象地址或间接访问所指对象</td></tr><tr><td>成员访问运算符</td><td><code>.</code>、<code>-&gt;</code></td><td>访问结构体或共用体成员</td></tr><tr><td>其他运算符</td><td><code>sizeof</code>、类型转换、下标 <code>[]</code>、函数调用 <code>()</code>、逗号 <code>,</code></td><td>完成类型大小查询等操作</td></tr></tbody></table><p>同一个符号在不同上下文中可能具有不同含义。例如，<code>*</code> 既可以表示乘法，也可以用于声明指针或解引用指针；<code>&amp;</code> 既可以表示按位与，也可以表示取地址。</p><p>运算符还涉及优先级、结合性和求值规则。为了让表达式含义更清楚，不确定时应主动使用圆括号，而不是仅依赖记忆优先级。具体规则将在后续运算符章节中展开。</p></section>
<section><h1>【五】分隔符<a href="#五分隔符"><span>#</span></a></h1><p>分隔符用于划分相邻的词法单元。常见分隔内容包括：</p><ul>
<li>空格（space）；</li>
<li>水平制表符（tab）；</li>
<li>换行符（newline）；</li>
<li>其他空白字符，例如垂直制表和换页；</li>
<li>注释 <code>// ...</code> 和 <code>/* ... */</code>。</li>
</ul><p>在预处理阶段，注释会被替换为空白，因此注释也能起到分隔词法单元的作用。字符串或字符常量内部的 <code>//</code>、<code>/*</code> 并不会开始注释：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>const</span><span> </span><span>char</span><span> </span><span>*</span><span>url </span><span>=</span><span> </span><span>"https://example.com"</span><span>;</span><span>  // 字符串中的 // 是普通字符</span></div></div><div><div><div>2</div></div><div><span>char</span><span> slash </span><span>=</span><span> </span><span>'/'</span><span>;</span><span>                         // 字符常量中的 / 是普通字符</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><p>空白字符有时可以省略，有时则必不可少：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>int</span><span> count;</span><span>     // int 和 count 之间必须分隔</span></div></div><div><div><div>2</div></div><div><span>int</span><span> intcount;</span><span>  // intcount 是一个完整的标识符，不等同于 int count</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span>total</span><span>=</span><span>a</span><span>+</span><span>b;</span><span>     // 编译器能够识别，但不利于阅读</span></div></div><div><div><div>5</div></div><div><span>total </span><span>=</span><span> a </span><span>+</span><span> b;</span><span> // 含义相同，格式更清晰</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><p>还应注意：</p><ul>
<li><code>//</code> 注释持续到当前行末尾；</li>
<li><code>/* ... */</code> 块注释可以跨行，但不能嵌套；</li>
<li>换行通常只是空白，但它会结束 <code>//</code> 注释和预处理指令；</li>
<li>不能用空白拆开一个完整的多字符运算符，例如 <code>&gt;=</code>、<code>==</code>、<code>++</code>。</li>
</ul><p>合理使用空格、缩进和换行不会改变大多数代码的含义，却能显著提升可读性并帮助排查语法错误。</p></section>
<section><h1>【六】标点符号<a href="#六标点符号"><span>#</span></a></h1><p>C 语言中常见的标点符号包括逗号、分号、冒号、圆括号、方括号、花括号、点号和箭头等。它们用于组织声明、表达式、语句、函数、数组和代码块。</p>

<table><thead><tr><th>符号</th><th>常见用途</th></tr></thead><tbody><tr><td><code>,</code></td><td>分隔声明项、函数参数和初始化器；在特定上下文中也可作为逗号运算符</td></tr><tr><td><code>;</code></td><td>结束声明或表达式语句；单独的 <code>;</code> 表示空语句</td></tr><tr><td><code>:</code></td><td>用于 <code>case</code>、<code>default</code>、标签以及条件运算符 <code>?:</code></td></tr><tr><td><code>( )</code></td><td>函数声明与调用、条件、表达式分组和类型转换</td></tr><tr><td><code>[ ]</code></td><td>数组声明、数组下标和属性语法等</td></tr><tr><td><code>{ }</code></td><td>构成复合语句、函数体或初始化器</td></tr><tr><td><code>.</code></td><td>通过对象访问结构体或共用体成员</td></tr><tr><td><code>-&gt;</code></td><td>通过指针访问结构体或共用体成员</td></tr><tr><td><code>#</code>、<code>##</code></td><td>预处理指令及宏中的字符串化、记号拼接</td></tr><tr><td><code>...</code></td><td>可变参数函数或其他标准规定的省略形式</td></tr></tbody></table><p>标点符号与空白分隔符不同：它们具有严格的语法作用，不能随意省略。部分符号在特定上下文中也属于运算符，例如逗号、圆括号、方括号、点号和箭头。</p><p>下面的程序集中演示了常见标点符号的用法：</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>#include</span><span> </span><span>&lt;stdio.h&gt;</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>int</span><span> </span><span>add</span><span>(</span><span>int</span><span><span> </span><span>x</span><span>,</span><span> </span></span><span>int</span><span><span> </span><span>y</span><span>)</span></span></div></div><div><div><div>4</div></div><div><span>{</span></div></div><div><div><div>5</div></div><div><span>    </span><span>return</span><span> x </span><span>+</span><span> y;</span></div></div><div><div><div>6</div></div><div><span>}</span></div></div><div><div><div>7</div></div><div>
</div></div><div><div><div>8</div></div><div><span>int</span><span> </span><span>main</span><span>(</span><span>void</span><span>)</span></div></div><div><div><div>9</div></div><div><span>{</span></div></div><div><div><div>10</div></div><div><span>    </span><span>int</span><span> </span><span>values</span><span>[</span><span>2</span><span>] </span><span>=</span><span> {</span><span>3</span><span>, </span><span>4</span><span>};</span></div></div><div><div><div>11</div></div><div><span>    </span><span>int</span><span> result </span><span>=</span><span> </span><span>add</span><span>(</span><span>values</span><span>[</span><span>0</span><span>], </span><span>values</span><span>[</span><span>1</span><span>]);</span></div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span>    </span><span>switch</span><span> (result) {</span></div></div><div><div><div>14</div></div><div><span>        </span><span>case</span><span> </span><span>7</span><span>:</span></div></div><div><div><div>15</div></div><div><span>            </span><span>printf</span><span>(</span><span>"result = </span><span>%d</span><span>\n</span><span>"</span><span><span>,</span><span> result</span><span>);</span></span></div></div><div><div><div>16</div></div><div><span>            </span><span>break</span><span>;</span></div></div><div><div><div>17</div></div><div><span>        </span><span>default</span><span>:</span></div></div><div><div><div>18</div></div><div><span>            </span><span>printf</span><span>(</span><span>"unexpected result</span><span>\n</span><span>"</span><span>);</span></div></div><div><div><div>19</div></div><div><span>            </span><span>break</span><span>;</span></div></div><div><div><div>20</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>21</div></div><div>
</div></div><div><div><div>22</div></div><div><span>    </span><span>return</span><span> </span><span>0</span><span>;</span></div></div><div><div><div>23</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>在这个示例中：</p><ul>
<li>逗号分隔函数形参、实参和数组初始化元素；</li>
<li>分号结束声明、函数调用和 <code>return</code>、<code>break</code> 语句；</li>
<li>圆括号用于函数声明、函数调用和 <code>switch</code> 条件；</li>
<li>方括号用于数组声明及下标访问；</li>
<li>花括号构成初始化器、函数体和 <code>switch</code> 语句体；</li>
<li>冒号跟在 <code>case</code> 和 <code>default</code> 标签之后。</li>
</ul></section>]]></content>
    </entry>
    <entry>
      <id>https://firefly.cuteleaf.cn/posts/language/c/20c%E8%AF%AD%E8%A8%80%E5%9F%BA%E7%A1%80/30%E5%B8%B8%E9%87%8F/</id>
      <title type="text">C 语言常量</title>
      <published>2026-09-26T00:00:00.000Z</published>
      <updated>2026-09-26T00:00:00.000Z</updated>
      <author><name>Dream</name></author>
      <link rel="alternate" href="https://firefly.cuteleaf.cn/posts/language/c/20c%E8%AF%AD%E8%A8%80%E5%9F%BA%E7%A1%80/30%E5%B8%B8%E9%87%8F/"/>
      <summary type="text">学习 C 语言中的整型、浮点、字符和字符串常量，以及常量的使用方式。</summary>
      <content type="html"><![CDATA[<section><h1>【一】常量的理解<a href="#一常量的理解"><span>#</span></a></h1><p>常量是指在程序运行期间其数值不发生变化的数据。</p><p>常量包括以下几种：</p><ul>
<li>整型常量</li>
<li>浮点常量</li>
<li>字符常量</li>
<li>字符串常量</li>
<li>标识常量</li>
</ul></section>
<section><h1>【二】整型常量<a href="#二整型常量"><span>#</span></a></h1><p>整型常量通常简称为整数。</p><p>整数可以是十进制数、八进制数和十六进制数。</p><p>例如，十进制的数值3356可以有下列三种不同的表示形式：</p><ul>
<li>二进制数 0b1101 0001 1100</li>
<li>十进制数 3356</li>
<li>八进制数 06434</li>
<li>十六进制数 0xd1c</li>
</ul></section>
<section><h1>【三】浮点常量<a href="#三浮点常量"><span>#</span></a></h1><p>浮点常量又称为实数，一般含有小数部分。</p><p>C语言中，实数只有十进制的实数，它又分为单精度实数和双精度实数，它们的表示方法基本相同。</p><p>实数有两种表示方法，即一般形式和指数形式。</p><p><strong>一般形式</strong>的基本形式如下： <code>[ + | - ] M.N</code></p><p>例如：3.5，-12.5，3.1415926</p><p><strong>指数形式</strong>的实数一般是由尾数部分、字母e或E和指数部分组成。 当一个实数的符号为正号时，可以省略不写。</p><p>表示形式如下：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>[+|-]M.N&lt;e|E&gt;[+|-]T</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>例如：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>1.176e+10      表示   1.176x10^10</span></div></div><div><div><div>2</div></div><div><span>-3.5789e-8     表示  -3.5789x10^-8</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>通常表示特别大或特别小的数。</p></section>
<section><h1>【五】字符常量<a href="#五字符常量"><span>#</span></a></h1><p>字符常量是指一个单一字符，其表示形式是由两个单引号包括的一个字符。</p><p>例如：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>'A', 'a', 'Q', '0', '9', '+', ':', '?', ' ', '$'</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>都是字符常量。</p><p>在C语言中，字符常量具有数值。字符常量的值就是该字符的ASCII码值。</p><p>因此，可以这样说字符常量实际上是一字节的正整数。</p><section><h2>练习-字符常量<a href="#练习-字符常量"><span>#</span></a></h2><ul>
<li>计算并输出下面字符的结果</li>
</ul><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>char</span><span>  a, b, u, v ;</span><span>      // 说明a、b、u和v为字符变量</span></div></div><div><div><div>2</div></div><div><span>a </span><span>=</span><span> </span><span>'F'</span><span> ;</span><span>               // 将70送给a</span></div></div><div><div><div>3</div></div><div><span>b </span><span>=</span><span> </span><span>'A'</span><span>+</span><span>2</span><span>;</span><span>              // b存放的是 'c' 字符</span></div></div><div><div><div>4</div></div><div><span>u </span><span>=</span><span> </span><span>' '</span><span> </span><span>+</span><span> </span><span>'B'</span><span>;</span><span>          // u存放的是 'b' 字符</span></div></div><div><div><div>5</div></div><div><span>v</span><span>=</span><span> </span><span>'b'</span><span> </span><span>-</span><span> </span><span>32</span><span>;</span><span>            // v存放的是 'B' 字符</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><ul>
<li>等价运算</li>
</ul><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>#include</span><span> </span><span>&lt;stdio.h&gt;</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>int</span><span> </span><span>main</span><span>() {</span></div></div><div><div><div>4</div></div><div><span>    </span><span>char</span><span> a, b, u, v;</span><span> // 说明 : a b u v 是字符变量</span></div></div><div><div><div>5</div></div><div><span><span>    </span></span><span>a </span><span>=</span><span> </span><span>'F'</span><span>;</span><span> // 将 70 赋值给 a</span></div></div><div><div><div>6</div></div><div><span><span>    </span></span><span>b </span><span>=</span><span> </span><span>'A'</span><span> </span><span>+</span><span> </span><span>2</span><span>;</span><span> // b 存放的是 'C' 的字符</span></div></div><div><div><div>7</div></div><div><span><span>    </span></span><span>u </span><span>=</span><span> </span><span>' '</span><span> </span><span>+</span><span> </span><span>'B'</span><span>;</span><span> // u 存放是的是 'b' 的字符</span></div></div><div><div><div>8</div></div><div><span><span>    </span></span><span>v </span><span>=</span><span> </span><span>'b'</span><span> </span><span>-</span><span> </span><span>32</span><span>;</span><span> // v 存放的是 'B' 的字符</span></div></div><div><div><div>9</div></div><div>
</div></div><div><div><div>10</div></div><div><span>    </span><span>printf</span><span>(</span><span>"a=</span><span>%d</span><span>\n</span><span>"</span><span>, a);</span><span> // 70</span></div></div><div><div><div>11</div></div><div><span>    </span><span>printf</span><span>(</span><span>"b=</span><span>%d</span><span>\n</span><span>"</span><span>, b);</span><span> // 65 + 2 = 67</span></div></div><div><div><div>12</div></div><div><span>    </span><span>printf</span><span>(</span><span>"u=</span><span>%d</span><span>\n</span><span>"</span><span>, u);</span><span> // 66 + 32 = 98</span></div></div><div><div><div>13</div></div><div><span>    </span><span>printf</span><span>(</span><span>"v=</span><span>%d</span><span>\n</span><span>"</span><span>, v);</span><span> // 98 - 32 = 66</span></div></div><div><div><div>14</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>a</span><span>=</span><span> </span><span>70</span><span>;</span></div></div><div><div><div>2</div></div><div><span>b</span><span>=</span><span> </span><span>65</span><span>+</span><span>2</span><span>;</span></div></div><div><div><div>3</div></div><div><span>u</span><span>=</span><span> </span><span>32</span><span>+</span><span>66</span><span> ;</span></div></div><div><div><div>4</div></div><div><span>v</span><span>=</span><span> </span><span>97</span><span>-</span><span>32</span><span>;</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div></section></section>
<section><h1>【六】字符串常量<a href="#六字符串常量"><span>#</span></a></h1><p>字符串常量是指用双引号括起来的一串字符来表示的数据。</p><p>下面给出几个字符串常量的例子：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>"Helloworld!"</span><span>,   </span><span>"Student"</span><span>,   </span><span>"9"</span><span>,   </span><span>"LINUX"</span><span>,  </span><span>"李四"</span></div></div><div><div><div>2</div></div><div><span>"北京海淀成府路***号"</span><span>,   </span><span>"姓名："</span><span>,   </span><span>"******@qq.com"</span></div></div><div><div><div>3</div></div><div><span>"what matters is what you do, not what you think"</span></div></div><div><div><div>4</div></div><div><span>"行动比空想更重要。"</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div></section>
<section><h1>【七】标识常量<a href="#七标识常量"><span>#</span></a></h1><p>标识常量是指用标识符代替常量使用的一种常量，其名称通常是一个标识符，别名宏。</p><p>标识常量也叫符号常量，为了不与一般变量的名称相混淆，标识常量的名称一般使用大写英文字母的标识符。</p><p>标识常量在使用之前必须预先定义。</p><p>标识常量的一般说明形式为：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>#define </span><span>&lt;</span><span>标识常量名称</span><span>&gt;</span><span> </span><span>&lt;</span><span>常量</span><span>&gt;</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><p>例如：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>#define</span><span> </span><span>MAX</span><span> </span><span>50</span></div></div><div><div><div>2</div></div><div><span>#define</span><span> </span><span>PI</span><span> </span><span>3.1415926</span></div></div><div><div><div>3</div></div><div><span>#define</span><span> </span><span>NULL</span><span> </span><span>0</span></div></div><div><div><div>4</div></div><div><span>#define</span><span> </span><span>EOF</span><span> </span><span>-</span><span>1</span></div></div><div><div><div>5</div></div><div><span>#define</span><span> </span><span>ERROR</span><span> </span><span>-</span><span>1</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><p>其中，MAX、PI、NULL、EOF和ERROR都是标识常量，它们代替的常量分别是50、3.1415926、0、-1和-1。</p><p>这里，每个标识常量说明式子只能给出一个标识常量，并且占据一个书写行。</p><p>以下是图片内容的 Markdown 格式转换：</p><section><h2>练习-水分子数<a href="#练习-水分子数"><span>#</span></a></h2><p>一个水分子的质量约为3.0*10^-23g，1夸脱水大约有950g，编写程序，要求输入水的夸脱数，然后显示这么多水中包含多少水分子。</p><ul>
<li>代码实现:</li>
</ul><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>#include</span><span> </span><span>&lt;stdio.h&gt;</span></div></div><div><div><div>2</div></div><div><span>#include</span><span> </span><span>&lt;windows.h&gt;</span><span>  </span><span>// 引入 windows 头文件，用于设置控制台编码</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span>// 定义一个水分子的质量（单位：克）</span></div></div><div><div><div>5</div></div><div><span>#define</span><span> </span><span>WATER_MOLECULES</span><span> </span><span><span>3.0</span><span>e</span></span><span>-</span><span>23</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>int</span><span> </span><span>main</span><span>() {</span></div></div><div><div><div>8</div></div><div><span>    </span><span>// 强制控制台输出使用 UTF-8 编码，确保中文显示正常</span></div></div><div><div><div>9</div></div><div><span>    </span><span>SetConsoleOutputCP</span><span>(</span><span>65001</span><span>);</span></div></div><div><div><div>10</div></div><div>
</div></div><div><div><div>11</div></div><div><span>    </span><span>// 提示用户输入水的夸脱数</span></div></div><div><div><div>12</div></div><div><span>    </span><span>printf</span><span>(</span><span>"请输入水的夸脱数："</span><span>);</span></div></div><div><div><div>13</div></div><div>
</div></div><div><div><div>14</div></div><div><span>    </span><span>// 声明变量用于存储用户输入的夸脱数</span></div></div><div><div><div>15</div></div><div><span>    </span><span>int</span><span> num;</span></div></div><div><div><div>16</div></div><div>
</div></div><div><div><div>17</div></div><div><span>    </span><span>// 读取用户输入的整数（夸脱数）</span></div></div><div><div><div>18</div></div><div><span>    </span><span>scanf</span><span>(</span><span>"</span><span>%d</span><span>"</span><span>, </span><span>&amp;</span><span>num);</span></div></div><div><div><div>19</div></div><div>
</div></div><div><div><div>20</div></div><div><span>    </span><span>// 显示用户输入的夸脱数</span></div></div><div><div><div>21</div></div><div><span>    </span><span>printf</span><span>(</span><span>"水的夸脱数为:</span><span>%d</span><span>\n</span><span>"</span><span>, num);</span></div></div><div><div><div>22</div></div><div>
</div></div><div><div><div>23</div></div><div><span><span>    </span></span><span>/* 计算水分子数量的公式说明：</span></div></div><div><div><div>24</div></div><div><span><span>     </span></span><span>* 1. 首先计算总质量：夸脱数 × 950（每夸脱的质量）</span></div></div><div><div><div>25</div></div><div><span><span>     </span></span><span>* 2. 然后除以一个水分子的质量（3.0e-23克）</span></div></div><div><div><div>26</div></div><div><span><span>     </span></span><span>* 3. 得到的就是总的水分子数量</span></div></div><div><div><div>27</div></div><div><span><span>     </span></span><span>*/</span></div></div><div><div><div>28</div></div><div><span>    </span><span>printf</span><span>(</span><span>"</span><span>%d</span><span> 夸脱中 包含 </span><span>%e</span><span> 个水分子</span><span>\n</span><span>"</span><span>, num, num </span><span>*</span><span> </span><span>950</span><span> </span><span>/</span><span> WATER_MOLECULES);</span></div></div><div><div><div>29</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><ul>
<li>运行结果</li>
</ul><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>请输入水的夸脱数 &gt;:10</span></div></div><div><div><div>2</div></div><div><span>num=10</span></div></div><div><div><div>3</div></div><div><span>10 夸脱的水中有 3.166667e+026 个水分子</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h2>练习-求圆面积<a href="#练习-求圆面积"><span>#</span></a></h2><p>输入圆的半径计算圆的面积和周长</p></section></section>]]></content>
    </entry>
    <entry>
      <id>https://firefly.cuteleaf.cn/posts/language/c/20c%E8%AF%AD%E8%A8%80%E5%9F%BA%E7%A1%80/40%E5%8F%98%E9%87%8F/</id>
      <title type="text">C 语言变量与存储类型</title>
      <published>2026-09-26T00:00:00.000Z</published>
      <updated>2026-09-26T00:00:00.000Z</updated>
      <author><name>Dream</name></author>
      <link rel="alternate" href="https://firefly.cuteleaf.cn/posts/language/c/20c%E8%AF%AD%E8%A8%80%E5%9F%BA%E7%A1%80/40%E5%8F%98%E9%87%8F/"/>
      <summary type="text">理解 C 语言变量的定义、命名规则、作用域，以及 auto、register、extern 和 static 存储类型。</summary>
      <content type="html"><![CDATA[<section><h1>【一】变量的理解<a href="#一变量的理解"><span>#</span></a></h1><ul>
<li><strong>定义</strong>：变量是指在程序运行期间其数值可以发生变化的数据。</li>
<li><strong>表示方式</strong>：变量在程序中用变量名表示，变量名由用户根据其用途任意命名。</li>
<li><strong>命名规则</strong>：变量名命名遵从标识符的起名规则。
<ul>
<li>只能由字母、数字、下划线组成。</li>
<li>开头不能是数字。</li>
<li>不能和系统的关键字重名。</li>
</ul>
</li>
<li><strong>内存概念</strong>：在程序运行时，变量占据一定大小的存储空间，其大小由其数据类型来决定，作为某变量的内存空间的首地址，称为变量的地址。</li>
</ul></section>
<section><h1>【二】变量的定义<a href="#二变量的定义"><span>#</span></a></h1><ul>
<li><strong>使用前提</strong>：变量在程序中使用时，必须预先说明它们的存储类型和数据类型。</li>
<li><strong>一般形式</strong>：
<code>&lt;存储类型&gt; &lt;数据类型&gt; &lt;变量名&gt;;</code>
<ul>
<li><code>&lt;存储类型&gt;</code>：可以是关键词 <code>auto</code>、<code>register</code>、<code>static</code> 和 <code>extern</code> 之一。</li>
<li><code>&lt;数据类型&gt;</code>：可以是前面讲的基本数据类型，也可以是后面要讲的自定义的数据类型。</li>
<li><code>&lt;变量名&gt;</code>：是一个合法的标识符，其前面的32字符有效。</li>
</ul>
</li>
<li><strong>注意事项</strong>：在上述变量说明的式子中，<code>&lt;变量名&gt;</code> 之后有一个分号 <code>;</code>，意味着它是一个语句，该语句通常称为变量的说明语句。</li>
<li><strong>常见基本数据类型</strong>：
<code>char</code>, <code>short</code>, <code>int</code>, <code>long</code>, <code>long int</code>, <code>long long</code>, <code>float</code>, <code>double</code>, <code>long double</code>。</li>
</ul><p>这张图片是上一份笔记的延续，接着讲解了C语言中变量的另外三种<strong>存储类型</strong>：<code>auto</code>、<code>register</code> 和 <code>extern</code>。</p><p>为了方便你阅读和复习，我同样将图片内容整理成了结构化的笔记：</p></section>
<section><h1>【三】auto存储类型<a href="#三auto存储类型"><span>#</span></a></h1><ul>
<li><strong>作用域</strong>：用 <code>auto</code> 存储类型说明的变量都是局部于某个程序范围内的，只能在某个程序范围内使用，通常在函数体内或函数中的复合语句里。</li>
<li><strong>语法特点</strong>：C语言中，在函数体的某程序段内说明 <code>auto</code> 存储类型的变量时<strong>可以省略关键字 <code>auto</code></strong>。</li>
<li><strong>代码示例</strong>：
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>auto </span><span>int</span><span> k ;</span><span>   //说明一个auto整型的k变量</span></div></div><div><div><div>2</div></div><div><span>int</span><span> j ;</span><span>        //省略了auto，说明一个auto整型的j变量</span></div></div><div><div><div>3</div></div><div><span>double</span><span> x;</span><span>      //省略了auto，说明一个auto双精度型的变量</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div>
</li>
</ul></section>
<section><h1>【四】register存储类型<a href="#四register存储类型"><span>#</span></a></h1><ul>
<li>
<p><strong>定义</strong>：<code>register</code> 称为寄存器型。</p>
</li>
<li>
<p><strong>目的</strong>：使用 <code>register</code> 关键字说明的变量主要目的是想将所说明的变量放入CPU的寄存器存储空间中，这样可以<strong>加快程序的运行速度</strong>。</p>
</li>
<li>
<p><strong>机制</strong>：如申请不到就使用一般内存，同 <code>auto</code>。</p>
</li>
<li>
<p><strong>使用频率</strong>：<code>register</code> 在程序中使用较少（现代编译器优化已经很强大，通常不需要手动指定）。</p>
</li>
<li>
<p><strong>代码示例</strong>：</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>register</span><span> </span><span>int</span><span> count;</span><span>     // 定义一个存储类型为register的整型变量;</span></div></div><div><div><div>2</div></div><div><span>register</span><span> </span><span>float</span><span> number;</span><span>  // 定义一个存储类型为register的浮点变量;</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div>
</li>
</ul></section>
<section><h1>【五】extern存储类型<a href="#五extern存储类型"><span>#</span></a></h1><ul>
<li><strong>定义</strong>：<code>extern</code> 称为外部参照引用型。</li>
<li><strong>目的</strong>：使用 <code>extern</code> 说明的变量是想引用在其它文件中函数体外部定义的变量。</li>
<li><strong>作用域</strong>：当变量在一个文件中的函数体外定义，所有其他文件中的函数或程序段都可引用这个变量。</li>
<li><strong>用途</strong>：一般用于在文件之间传递数据。</li>
</ul><p>这是关于变量基础知识的最后一部分内容，主要讲解了 <strong><code>static</code>（静态）存储类型</strong>以及<strong>变量的初始化</strong>。</p><p>基于你上传的图片，我继续为你整理成结构化笔记，并补充了一些初学者容易混淆的关键知识点，希望能帮到你：</p></section>
<section><h1>【六】static存储类型<a href="#六static存储类型"><span>#</span></a></h1><p><code>static</code> 为静态存储类型，既可以在函数体内定义，也可以在函数体外定义 <code>static</code> 类型的变量。</p><ul>
<li><strong>在函数体内定义（静态局部变量）</strong>：
<ul>
<li>在内存中以固定地址存放。</li>
<li>程序运行时<strong>会保持其值</strong>。它下次再调用该函数，该变量不再重新定义，还保留上次存入的数值。</li>
<li><em>💡 补充提示：静态局部变量只初始化一次。即使函数结束，它的内存也不会被回收，下一次调用函数时，它会保留上一次运行结束时的值。</em></li>
</ul>
</li>
<li><strong>在函数体外定义（静态全局变量）</strong>：
<ul>
<li>主要作用是<strong>限定变量的作用域</strong>，限定文件的作用域在本文件内。</li>
<li><em>💡 补充提示：普通全局变量可以通过 <code>extern</code> 跨文件引用，但 <code>static</code> 全局变量只能在当前源文件内使用（内部链接），其他文件即使写了 <code>extern</code> 也无法访问，这有助于避免不同文件间的变量命名冲突。</em></li>
</ul>
</li>
</ul><hr /></section>
<section><h1>【七】变量的初始化<a href="#七变量的初始化"><span>#</span></a></h1><ul>
<li>
<p><strong>一般形式</strong>：
<code>&lt;存储类型&gt; &lt;数据类型&gt; &lt;变量&gt; = &lt;表达式&gt; ;</code></p>
</li>
<li>
<p><strong>概念</strong>：变量的初始化是指变量在被定义的同时赋给一个初值。</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>int</span><span> i</span><span>=</span><span>0</span><span>;</span></div></div><div><div><div>2</div></div><div><span>static</span><span> </span><span>double</span><span> w</span><span>=</span><span>100.56</span><span>;</span></div></div><div><div><div>3</div></div><div><span>double</span><span> result </span><span>=</span><span> </span><span>1</span><span>;</span></div></div><div><div><div>4</div></div><div><span>double</span><span> x </span><span>=</span><span> </span><span>5</span><span>, y </span><span>=</span><span> x</span><span>*</span><span>2</span><span> ;</span><span>  // 定义x并赋值为5，定义y并赋值为x*2 (10)</span></div></div><div><div><div>5</div></div><div><span>register</span><span> </span><span>int</span><span> count </span><span>=</span><span> </span><span>0</span><span> ;</span></div></div><div><div><div>6</div></div><div><span>auto </span><span>double</span><span> s </span><span>=</span><span> </span><span>0</span><span> ;</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div>
</li>
</ul><p>这是关于变量基础知识的最后一小部分内容，主要讲解了 <strong>常变量（<code>const</code>）</strong> 以及它与 <strong>符号常量（<code>#define</code>）</strong> 的核心区别。这也是C语言中非常经典的考点。</p><p>按照惯例，我为你整理了结构化的笔记，并补充了详细的对比表格：</p></section>
<section><h1>【八】常变量<a href="#八常变量"><span>#</span></a></h1><ul>
<li>
<p><strong>概念</strong>：C99标准允许使用常变量，方法是在定义变量时，前面加一个关键字 <code>const</code>。</p>
</li>
<li>
<p><strong>特点</strong>：在程序运行期间其值不能改变。</p>
</li>
<li>
<p><strong>代码示例</strong>：</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>const</span><span> </span><span>int</span><span> a3 </span><span>=</span><span> </span><span>3</span><span>;</span><span>   // 定义一个整型变量，指定其值为3，在程序运行期间其值不能改变。</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div>
</li>
</ul><hr /><section><h3>常变量与符号常量的区别（核心重点）<a href="#常变量与符号常量的区别核心重点"><span>#</span></a></h3><p>图片中给出了 <code>#define</code> 和 <code>const</code> 的对比示例：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>#define</span><span> </span><span>Pi</span><span> </span><span>3.1415926</span><span>           // 定义符号常量</span></div></div><div><div><div>2</div></div><div><span>const</span><span> </span><span>float</span><span> Pi </span><span>=</span><span> </span><span>3.1415926</span><span>     // 定义常变量</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><p>虽然两者在程序中都能代表 <code>3.1415926</code>，但在底层机制上有本质区别：</p>

<table><thead><tr><th>对比维度</th><th>符号常量 (<code>#define Pi 3.14...</code>)</th><th>常变量 (<code>const float Pi = 3.14...</code>)</th></tr></thead><tbody><tr><td><strong>本质</strong></td><td>预编译指令（宏定义）</td><td>变量（带只读属性）</td></tr><tr><td><strong>处理阶段</strong></td><td><strong>预编译阶段</strong></td><td><strong>编译和运行阶段</strong></td></tr><tr><td><strong>工作机制</strong></td><td>简单的<strong>字符替换</strong>（全置换）</td><td>分配内存，存入数值</td></tr><tr><td><strong>存储单元</strong></td><td><strong>不分配</strong>存储单元（预编译后名字就消失了）</td><td><strong>要占用</strong>存储单元</td></tr><tr><td><strong>类型检查</strong></td><td>无类型，仅仅是文本替换</td><td>有明确数据类型，编译器会进行安全检查</td></tr><tr><td><strong>生命周期</strong></td><td>预编译后就不存在了</td><td>存在于程序的运行期间</td></tr></tbody></table><ul>
<li>💡 <strong>通俗理解</strong>：<code>#define</code> 就像是Word文档里的“查找替换”，在真正编译前，代码里所有的 <code>Pi</code> 都被换成了数字；而 <code>const</code> 是真正在内存里划了一小块地（存储单元），放进了数字，只不过这块地是“只读”的，不允许被修改。</li>
</ul></section></section>]]></content>
    </entry>
    <entry>
      <id>https://firefly.cuteleaf.cn/posts/language/c/20c%E8%AF%AD%E8%A8%80%E5%9F%BA%E7%A1%80/50%E5%BC%BA%E5%88%B6%E7%B1%BB%E5%9E%8B%E8%BD%AC%E6%8D%A2/</id>
      <title type="text">C 语言强制类型转换</title>
      <published>2026-09-26T00:00:00.000Z</published>
      <updated>2026-09-26T00:00:00.000Z</updated>
      <author><name>Dream</name></author>
      <link rel="alternate" href="https://firefly.cuteleaf.cn/posts/language/c/20c%E8%AF%AD%E8%A8%80%E5%9F%BA%E7%A1%80/50%E5%BC%BA%E5%88%B6%E7%B1%BB%E5%9E%8B%E8%BD%AC%E6%8D%A2/"/>
      <summary type="text">学习 C 语言显式与隐式类型转换、整数提升及其常见使用场景。</summary>
      <content type="html"><![CDATA[<section><h1>【一】强制类型转换理解<a href="#一强制类型转换理解"><span>#</span></a></h1><ul>
<li><strong>目的</strong>：C语言的强制类型转换用于将一个数据类型转换为另一个数据类型，目的是为了让程序在编译和运行时能够正确地执行。</li>
<li><strong>转换方式</strong>：分为两种：
<ul>
<li>显式的数据类型转换</li>
<li>隐式的数据类型转换</li>
</ul>
</li>
</ul></section>
<section><h1>【二】显式的数据类型转换<a href="#二显式的数据类型转换"><span>#</span></a></h1><ul>
<li><strong>一般形式</strong>：<code>(数据类型名称) &lt;表达式&gt;</code></li>
<li><strong>代码示例解析</strong>：
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>int</span><span> a</span><span>=</span><span>2</span><span>, b</span><span>=</span><span>0</span><span> ;</span></div></div><div><div><div>2</div></div><div><span>float</span><span> c </span><span>=</span><span> </span><span>4.8</span><span>, d</span><span>=</span><span> </span><span>3.3</span><span>;</span></div></div><div><div><div>3</div></div><div><span>b </span><span>=</span><span> (</span><span>int</span><span>) (a </span><span>+</span><span> c </span><span>+</span><span>d) ;</span><span>   // b存入右边表达式的计算 结果为10</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div>
<ul>
<li><strong>计算过程</strong>：<code>a + c + d</code> 的结果是 <code>2 + 4.8 + 3.3 = 10.1</code>（此时是浮点型 float）。</li>
<li>通过 <code>(int)</code> 强制转换，<code>10.1</code> 被转换为整型 <code>10</code>，最后赋值给整型变量 <code>b</code>。</li>
</ul>
</li>
</ul></section>
<section><h1>【三】隐式的数据类型转换<a href="#三隐式的数据类型转换"><span>#</span></a></h1><ul>
<li><strong>定义</strong>：类型转换可以是隐式的，由编译器自动执行。</li>
<li><strong>代码示例解析</strong>：
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>int</span><span> a</span><span>=</span><span>2</span><span>, b</span><span>=</span><span>0</span><span> ;</span></div></div><div><div><div>2</div></div><div><span>float</span><span> c </span><span>=</span><span> </span><span>4.8</span><span>, d</span><span>=</span><span> </span><span>3.3</span><span>;</span></div></div><div><div><div>3</div></div><div><span>b </span><span>=</span><span> a </span><span>+</span><span> c </span><span>+</span><span> d ;</span><span>   // b存入右边表达式的计算 结果为10</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div>
<ul>
<li><strong>计算过程</strong>：<code>a + c + d</code> 的结果依然是浮点型 <code>10.1</code>。</li>
<li>但在赋值给整型变量 <code>b</code> 时，编译器会自动将 <code>10.1</code>（float）隐式转换为 <code>10</code>（int），然后存入 <code>b</code>。</li>
</ul>
</li>
</ul><p>这是关于C语言数据类型转换的进阶内容，主要讲解了<strong>整数提升（Integer Promotion）<strong>和</strong>常用算术转换</strong>的底层规则。这也是理解C语言表达式求值顺序和类型的核心。</p><p>结合你之前的学习脉络，我为你整理成结构化笔记，并补全了图片中未展示完整的部分：</p></section>
<section><h1>【四】整数提升<a href="#四整数提升"><span>#</span></a></h1><ul>
<li><strong>概念</strong>：整数提升是指把<strong>小于 <code>int</code> 或 <code>unsigned int</code></strong> 的整数类型（如 <code>char</code>、<code>short</code>、<code>bool</code>、位域等）转换为 <code>int</code> 或 <code>unsigned int</code> 的过程。</li>
<li><strong>常用算术转换</strong>：是隐式地把值强制转换为相同的类型。编译器在处理算术运算时，遵循以下两步：
<ol>
<li><strong>首先执行整数提升</strong>（把小的整型提升为 <code>int</code> 或 <code>unsigned int</code>）。</li>
<li>如果操作数类型不同，则它们会被转换为<strong>下列层次中出现的最高层次的类型</strong>。</li>
</ol>
</li>
</ul><ul>
<li>C语言标准规定的算术转换层次（从低到高）依次为：
<code>int</code> -&gt; <code>unsigned int</code> -&gt; <code>long</code> -&gt; <code>unsigned long</code> -&gt; <code>long long</code> -&gt; <code>unsigned long long</code> -&gt; <code>float</code> -&gt; <code>double</code> -&gt; <code>long double</code></li>
</ul></section>]]></content>
    </entry>
    <entry>
      <id>https://firefly.cuteleaf.cn/posts/language/c/20c%E8%AF%AD%E8%A8%80%E5%9F%BA%E7%A1%80/60%E7%AE%97%E6%95%B0%E8%BF%90%E7%AE%97%E7%AC%A6/</id>
      <title type="text">C 语言算术运算符</title>
      <published>2026-09-26T00:00:00.000Z</published>
      <updated>2026-09-26T00:00:00.000Z</updated>
      <author><name>Dream</name></author>
      <link rel="alternate" href="https://firefly.cuteleaf.cn/posts/language/c/20c%E8%AF%AD%E8%A8%80%E5%9F%BA%E7%A1%80/60%E7%AE%97%E6%95%B0%E8%BF%90%E7%AE%97%E7%AC%A6/"/>
      <summary type="text">学习 C 语言表达式、算术运算符、整数除法和浮点除法的基本规则。</summary>
      <content type="html"><![CDATA[<section><h1>【一】表达式<a href="#一表达式"><span>#</span></a></h1><ul>
<li><strong>定义</strong>：所谓表达式是指由运算符、运算量和标点符号组成的有效序列，是用来说明一个计算过程。</li>
<li><strong>表达式语句</strong>：表达式可以独立形成语句，该语句称为表达式语句。</li>
<li><strong>一般形式</strong>：
<code>&lt;表达式&gt; ;</code> （注意末尾必须有分号）</li>
</ul></section>
<section><h1>【二】算术运算符<a href="#二算术运算符"><span>#</span></a></h1>

<table><thead><tr><th>运算符</th><th>功能说明</th><th>举例</th></tr></thead><tbody><tr><td><code>+</code></td><td>加，一目取正（一元正号）</td><td><code>a+b</code>, <code>+a</code></td></tr><tr><td><code>-</code></td><td>减，一目取负（一元负号）</td><td><code>a-b</code>, <code>-a</code></td></tr><tr><td><code>*</code></td><td>乘法</td><td><code>a*b</code></td></tr><tr><td><code>/</code></td><td>除法</td><td><code>a/b</code></td></tr><tr><td><code>%</code></td><td>取模或求余</td><td><code>a%b</code></td></tr><tr><td><code>++</code></td><td>增1（自增）</td><td><code>a++</code>, <code>++b</code></td></tr><tr><td><code>--</code></td><td>减1（自减） <em>(被UI遮挡)</em></td><td><code>a--</code>, <code>--b</code></td></tr></tbody></table><p>这张图片紧接着上一节的算术运算符，专门针对最容易出错的<strong>除法运算符 <code>/</code></strong> 和<strong>取模运算符 <code>%</code></strong> 进行了详细区分。这是C语言初学者最容易踩坑的地方，也是考试必考的核心点。</p><p>按照惯例，我为你整理了结构化笔记，并补充了极其重要的实战避坑指南：</p></section>
<section><h1>【三】整数除法和实数除法<a href="#三整数除法和实数除法"><span>#</span></a></h1><p>C语言的除法运算符分为整数除法和实数除法。</p><section><h2>【1】整数除法<a href="#1整数除法"><span>#</span></a></h2><ul>
<li><strong>求整 <code>/</code></strong>：得到两个整数相除的<strong>整数部分</strong>。</li>
<li><strong>求余 <code>%</code></strong>：得到两个整数相除的<strong>余数部分</strong>。</li>
<li><strong>举例</strong>：
<ul>
<li><code>1/2</code> 的结果为 <code>0</code> （小数部分被直接丢弃）</li>
<li><code>1%2</code> 的结果为 <code>1</code> （1除以2，商0余1）</li>
</ul>
</li>
</ul></section><section><h2>【2】实数除法<a href="#2实数除法"><span>#</span></a></h2><ul>
<li><strong>除法 <code>/</code></strong>：得到两个实数相除的结果为一个<strong>实数</strong>。</li>
<li><strong>举例</strong>：
<ul>
<li><code>1.0/2</code> 的结果为 <code>0.5</code></li>
</ul>
</li>
</ul><p>这张图片是一个具体的实战练习题（练习9），通过实际代码运行来验证上一节关于<strong>整数除法和实数除法</strong>的理论知识。</p><p>按照惯例，我为你整理了结构化笔记，并针对代码中的细节和考点进行深度解析：</p></section></section>
<section><h1>【四】练习<a href="#四练习"><span>#</span></a></h1><section><h2>【1】除法运算符<a href="#1除法运算符"><span>#</span></a></h2><ul>
<li>
<p><strong>题目</strong>：计算 <code>1/2</code>、<code>1.0/2</code>、<code>1%2</code> 的结果分别是多少？</p>
</li>
<li>
<p><strong>源代码</strong>：</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>#include</span><span> </span><span>&lt;stdio.h&gt;</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>int</span><span> </span><span>main</span><span>(</span><span>int</span><span><span> </span><span>argc</span><span>,</span><span> </span></span><span>char</span><span> </span><span>const</span><span> </span><span>*</span><span>argv</span><span>[]</span><span>)</span></div></div><div><div><div>4</div></div><div><span>{</span></div></div><div><div><div>5</div></div><div><span>    </span><span>printf</span><span>(</span><span>"1/2 =</span><span>%d</span><span>\n</span><span>"</span><span>,</span><span>1</span><span>/</span><span>2</span><span>);</span></div></div><div><div><div>6</div></div><div><span>    </span><span>printf</span><span>(</span><span>"1.0/2=</span><span>%f</span><span>\n</span><span>"</span><span>,</span><span>1.0</span><span>/</span><span>2</span><span>);</span></div></div><div><div><div>7</div></div><div><span>    </span><span>printf</span><span>(</span><span>"1</span><span>%%</span><span>2 =</span><span>%d</span><span>\n</span><span>"</span><span>,</span><span>1</span><span>%</span><span>2</span><span>);</span></div></div><div><div><div>8</div></div><div><span>    </span><span>return</span><span> </span><span>0</span><span>;</span></div></div><div><div><div>9</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div>
</li>
<li>
<p><strong>运行结果</strong>：</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>1/2=0</span></div></div><div><div><div>2</div></div><div><span>1%2=1</span></div></div><div><div><div>3</div></div><div><span>1.0/2=0.500000</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
</ul><p>这张图片详细讲解了C语言中极其重要且容易出错的<strong>自增（<code>++</code>）与自减（<code>--</code>）运算符</strong>。图片通过定义和七行代码示例，精准地展示了“前缀（先算后用）”和“后缀（先用后算）”的区别。</p><p>按照惯例，我为你整理了结构化笔记，并对代码示例进行了深度拆解，最后补充了考试必考的避坑指南：</p></section><section><h2>【2】自增自减运算符<a href="#2自增自减运算符"><span>#</span></a></h2><section><h3>（1）自增运算符<a href="#1自增运算符"><span>#</span></a></h3><ul>
<li><code>i++</code>：表示 <code>i</code> 的值<strong>先参与运算</strong>，最后再自增1（后缀）。</li>
<li><code>++i</code>：表示 <code>i</code> 的值<strong>先自增1</strong>，之后再参与运算（前缀）。</li>
</ul></section><section><h3>（2）自减运算符<a href="#2自减运算符"><span>#</span></a></h3><ul>
<li><code>i--</code>：表示 <code>i</code> 的值<strong>先参与运算</strong>，最后再自减1（后缀）。</li>
<li><code>--i</code>：表示 <code>i</code> 的值<strong>先自减1</strong>，之后再参与运算（前缀）。</li>
</ul><hr /><p><strong>假设每一行代码都从头执行，即初始值始终是 <code>x=5, y=9</code></strong>。如果连续执行而不重置变量，结果会不同。</p><p>我们按照图片给出的初始值 <code>x=5, y=9</code>，逐行拆解：</p><ol>
<li><code>z = ++x;</code>
<ul>
<li>前缀：<code>x</code>先加1变成6，然后把6赋给<code>z</code>。</li>
<li>结果：<code>z=6</code>，<code>x=6</code></li>
</ul>
</li>
<li><code>z = x++;</code>
<ul>
<li>后缀：先把<code>x</code>当前值5赋给<code>z</code>，然后<code>x</code>再加1变成6。</li>
<li>结果：<code>z=5</code>，<code>x=6</code></li>
</ul>
</li>
<li><code>z = --x;</code>
<ul>
<li>前缀：<code>x</code>先减1变成4，然后把4赋给<code>z</code>。</li>
<li>结果：<code>z=4</code>，<code>x=4</code></li>
</ul>
</li>
<li><code>z = x--;</code>
<ul>
<li>后缀：先把<code>x</code>当前值5赋给<code>z</code>，然后<code>x</code>再减1变成4。</li>
<li>结果：<code>z=5</code>，<code>x=4</code></li>
</ul>
</li>
<li><code>z = ++x+y++;</code>
<ul>
<li>前缀+后缀混合：<code>++x</code>使<code>x</code>变成6（取6参与运算），<code>y++</code>取<code>y</code>当前值9参与运算（然后<code>y</code>变成10）。<code>z = 6 + 9 = 15</code>。</li>
<li>结果：<code>z=15</code>，<code>x=6</code>，<code>y=10</code></li>
</ul>
</li>
<li><code>z = --x+y++;</code>
<ul>
<li><code>--x</code>使<code>x</code>变成4（取4参与运算），<code>y++</code>取<code>y</code>当前值9参与运算（然后<code>y</code>变成10）。<code>z = 4 + 9 = 13</code>。</li>
<li>结果：<code>z=13</code>，<code>x=4</code>，<code>y=10</code></li>
</ul>
</li>
<li><code>z = ++x+y--;</code>
<ul>
<li><code>++x</code>使<code>x</code>变成6（取6参与运算），<code>y--</code>取<code>y</code>当前值9参与运算（然后<code>y</code>变成8）。<code>z = 6 + 9 = 15</code>。</li>
<li>结果：<code>z=15</code>，<code>x=6</code>，<code>y=8</code></li>
</ul>
</li>
</ol></section></section><section><h2>【3】算术运算符<a href="#3算术运算符"><span>#</span></a></h2><ul>
<li><strong>源代码</strong>（基于输出结果还原，利用重置变量来独立验证每一行的逻辑）：
<div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>#include</span><span> </span><span>&lt;stdio.h&gt;</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>int</span><span> </span><span>main</span><span>() {</span></div></div><div><div><div>4</div></div><div><span>    </span><span>int</span><span> x, y, z;</span></div></div><div><div><div>5</div></div><div>
</div></div><div><div><div>6</div></div><div><span>    </span><span>// 第一行</span></div></div><div><div><div>7</div></div><div><span><span>    </span></span><span>x </span><span>=</span><span> </span><span>5</span><span>; y </span><span>=</span><span> </span><span>9</span><span>; z </span><span>=</span><span> </span><span>++</span><span>x;</span><span>      // 前缀：x先加1变6，z=6</span></div></div><div><div><div>8</div></div><div><span>    </span><span>printf</span><span>(</span><span>"z=</span><span>%d</span><span>, x=</span><span>%d</span><span>\n</span><span>"</span><span>, z, x);</span></div></div><div><div><div>9</div></div><div>
</div></div><div><div><div>10</div></div><div><span>    </span><span>// 第二行</span></div></div><div><div><div>11</div></div><div><span><span>    </span></span><span>x </span><span>=</span><span> </span><span>5</span><span>; y </span><span>=</span><span> </span><span>9</span><span>; z </span><span>=</span><span> x</span><span>++</span><span>;</span><span>      // 后缀：z=5，x再加1变6</span></div></div><div><div><div>12</div></div><div><span>    </span><span>printf</span><span>(</span><span>"z=</span><span>%d</span><span>, x=</span><span>%d</span><span>\n</span><span>"</span><span>, z, x);</span></div></div><div><div><div>13</div></div><div>
</div></div><div><div><div>14</div></div><div><span>    </span><span>// 第三行</span></div></div><div><div><div>15</div></div><div><span><span>    </span></span><span>x </span><span>=</span><span> </span><span>5</span><span>; y </span><span>=</span><span> </span><span>9</span><span>; z </span><span>=</span><span> </span><span>--</span><span>x;</span><span>      // 前缀：x先减1变4，z=4</span></div></div><div><div><div>16</div></div><div><span>    </span><span>printf</span><span>(</span><span>"z=</span><span>%d</span><span>, x=</span><span>%d</span><span>\n</span><span>"</span><span>, z, x);</span></div></div><div><div><div>17</div></div><div>
</div></div><div><div><div>18</div></div><div><span>    </span><span>// 第四行</span></div></div><div><div><div>19</div></div><div><span><span>    </span></span><span>x </span><span>=</span><span> </span><span>5</span><span>; y </span><span>=</span><span> </span><span>9</span><span>; z </span><span>=</span><span> x</span><span>--</span><span>;</span><span>      // 后缀：z=5，x再减1变4</span></div></div><div><div><div>20</div></div><div><span>    </span><span>printf</span><span>(</span><span>"z=</span><span>%d</span><span>, x=</span><span>%d</span><span>\n</span><span>"</span><span>, z, x);</span></div></div><div><div><div>21</div></div><div>
</div></div><div><div><div>22</div></div><div><span>    </span><span>// 第五行</span></div></div><div><div><div>23</div></div><div><span><span>    </span></span><span>x </span><span>=</span><span> </span><span>5</span><span>; y </span><span>=</span><span> </span><span>9</span><span>; z </span><span>=</span><span> </span><span>++</span><span>x </span><span>+</span><span> y</span><span>++</span><span>;</span><span> // ++x为6，y++取9，z=15；运算后x=6, y=10</span></div></div><div><div><div>24</div></div><div><span>    </span><span>printf</span><span>(</span><span>"z=</span><span>%d</span><span>, x=</span><span>%d</span><span>, y=</span><span>%d</span><span>\n</span><span>"</span><span>, z, x, y);</span></div></div><div><div><div>25</div></div><div>
</div></div><div><div><div>26</div></div><div><span>    </span><span>// 第六行</span></div></div><div><div><div>27</div></div><div><span><span>    </span></span><span>x </span><span>=</span><span> </span><span>5</span><span>; y </span><span>=</span><span> </span><span>9</span><span>; z </span><span>=</span><span> </span><span>--</span><span>x </span><span>+</span><span> y</span><span>++</span><span>;</span><span> // --x为4，y++取9，z=13；运算后x=4, y=10</span></div></div><div><div><div>28</div></div><div><span>    </span><span>printf</span><span>(</span><span>"z=</span><span>%d</span><span>, x=</span><span>%d</span><span>, y=</span><span>%d</span><span>\n</span><span>"</span><span>, z, x, y);</span></div></div><div><div><div>29</div></div><div>
</div></div><div><div><div>30</div></div><div><span>    </span><span>// 第七行</span></div></div><div><div><div>31</div></div><div><span><span>    </span></span><span>x </span><span>=</span><span> </span><span>5</span><span>; y </span><span>=</span><span> </span><span>9</span><span>; z </span><span>=</span><span> </span><span>++</span><span>x </span><span>+</span><span> y</span><span>--</span><span>;</span><span> // ++x为6，y--取9，z=15；运算后x=6, y=8</span></div></div><div><div><div>32</div></div><div><span>    </span><span>printf</span><span>(</span><span>"z=</span><span>%d</span><span>, x=</span><span>%d</span><span>, y=</span><span>%d</span><span>\n</span><span>"</span><span>, z, x, y);</span></div></div><div><div><div>33</div></div><div>
</div></div><div><div><div>34</div></div><div><span>    </span><span>return</span><span> </span><span>0</span><span>;</span></div></div><div><div><div>35</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div>
</li>
</ul></section></section>]]></content>
    </entry>
    <entry>
      <id>https://firefly.cuteleaf.cn/posts/language/c/20c%E8%AF%AD%E8%A8%80%E5%9F%BA%E7%A1%80/70%E5%85%B3%E7%B3%BB%E4%B8%8E%E9%80%BB%E8%BE%91%E8%BF%90%E7%AE%97%E7%AC%A6/</id>
      <title type="text">C 语言关系与逻辑运算符</title>
      <published>2026-09-26T00:00:00.000Z</published>
      <updated>2026-09-26T00:00:00.000Z</updated>
      <author><name>Dream</name></author>
      <link rel="alternate" href="https://firefly.cuteleaf.cn/posts/language/c/20c%E8%AF%AD%E8%A8%80%E5%9F%BA%E7%A1%80/70%E5%85%B3%E7%B3%BB%E4%B8%8E%E9%80%BB%E8%BE%91%E8%BF%90%E7%AE%97%E7%AC%A6/"/>
      <summary type="text">学习 C 语言的关系运算符、逻辑运算符、短路求值和条件判断规则。</summary>
      <content type="html"><![CDATA[<section><h1>【一】关系运算符<a href="#一关系运算符"><span>#</span></a></h1>

<table><thead><tr><th>运算符</th><th>功能说明</th><th>举例</th></tr></thead><tbody><tr><td><code>&gt;</code></td><td>大于</td><td><code>a &gt; b</code></td></tr><tr><td><code>&gt;=</code></td><td>大于等于</td><td><code>a &gt;= 5</code></td></tr><tr><td><code>&lt;</code></td><td>小于</td><td><code>3 &lt; x</code></td></tr><tr><td><code>&lt;=</code></td><td>小于等于</td><td><code>x &lt;= y + 1</code></td></tr><tr><td><code>==</code></td><td>等于</td><td><code>x + 1 == 0</code></td></tr><tr><td><code>!=</code></td><td>不等于</td><td><code>c != '\0'</code></td></tr></tbody></table><ul>
<li>真为1，假为0，非零为真，0为假</li>
</ul><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>int</span><span> a</span><span>=</span><span>5</span><span>, b</span><span>=</span><span>6</span><span>;</span></div></div><div><div><div>2</div></div><div><span>a</span><span>&gt;</span><span>(b</span><span>-</span><span>1</span><span>)</span><span>        // 结果值为0</span></div></div><div><div><div>3</div></div><div><span>(a </span><span>+</span><span>1</span><span>)</span><span>==</span><span> b</span><span>     // 结果值为1</span></div></div><div><div><div>4</div></div><div><span>a</span><span>&gt;=</span><span>(b</span><span>-</span><span>2</span><span>)</span><span>       // 结果值为1</span></div></div><div><div><div>5</div></div><div><span>a</span><span>&lt;</span><span>100</span><span>          // 结果值为1</span></div></div><div><div><div>6</div></div><div><span>(a</span><span>+</span><span>3</span><span>)</span><span>&lt;=</span><span>b</span><span>       // 结果值为0</span></div></div><div><div><div>7</div></div><div><span>a </span><span>!=</span><span> (b</span><span>-</span><span>1</span><span>)</span><span>     // 结果值为0</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div></section>
<section><h1>【二】逻辑运算符<a href="#二逻辑运算符"><span>#</span></a></h1>

<table><thead><tr><th>运算符</th><th>功能说明</th><th>举例</th></tr></thead><tbody><tr><td><code>!</code></td><td>逻辑反（非）</td><td><code>!(x == 0)</code></td></tr><tr><td><code>&amp;&amp;</code></td><td>逻辑与</td><td><code>x &gt; 0 &amp;&amp; x &lt; 100</code></td></tr><tr><td>`</td><td></td><td>`</td></tr></tbody></table></section>
<section><h1>【三】逻辑非运算符<a href="#三逻辑非运算符"><span>#</span></a></h1><p>逻辑非 <code>!</code> 运算符的运算律如下（一元运算符）：</p>

<table><thead><tr><th>运算量</th><th>结果</th></tr></thead><tbody><tr><td>1</td><td>0</td></tr><tr><td>0</td><td>1</td></tr></tbody></table><p><em>结合我们上一节学的“非零为真，0为假”，可以推导出：<code>!非0</code> = <code>0</code>；<code>!0</code> = <code>1</code>。</em></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>int</span><span> k</span><span>=</span><span>8</span><span>;</span></div></div><div><div><div>2</div></div><div><span>!</span><span> (k </span><span>==</span><span>0</span><span>)</span><span>      // 结果值为1</span></div></div><div><div><div>3</div></div><div><span>!</span><span> ((k</span><span>-</span><span>8</span><span>) </span><span>==</span><span> </span><span>0</span><span>)</span><span> // 结果值为0</span></div></div><div><div><div>4</div></div><div><span>!</span><span> (k</span><span>&lt;=</span><span> </span><span>0</span><span>)</span><span>      // 结果值为1</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div></section>
<section><h1>【四】逻辑与运算符 (<code>&amp;&amp;</code>)<a href="#四逻辑与运算符-"><span>#</span></a></h1><p>逻辑与 <code>&amp;&amp;</code> 运算符的运算规律如下（二元运算符）：</p>

<table><thead><tr><th>左运算量</th><th>右运算量</th><th>结果</th></tr></thead><tbody><tr><td>1</td><td>1</td><td><strong>1</strong></td></tr><tr><td>1</td><td>0</td><td><strong>0</strong></td></tr><tr><td>0</td><td>1</td><td><strong>0</strong></td></tr><tr><td>0</td><td>0</td><td><strong>0</strong></td></tr></tbody></table><p><em>提炼核心规则</em>：<strong>全真才真，一假即假</strong>。只有当左右两边都为“真”（非0）时，整个表达式的结果才为“真”（1）。</p></section>
<section><h1>【五】逻辑与的短路特性<a href="#五逻辑与的短路特性"><span>#</span></a></h1><ul>
<li><strong>定义</strong>：如果第一个操作数是 <code>false</code>（假，即0），那么无论第二个操作数是什么值，结果也不可能等于 <code>true</code>（真，即1）。</li>
<li><strong>形式</strong>：<code>(表达式1) &amp;&amp; (表达式2)</code></li>
<li><strong>规则</strong>：如果表达式1为假，则表达式2<strong>不会进行运算</strong>，即表达式2“被短路”。</li>
</ul><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>int</span><span> x </span><span>=</span><span> </span><span>5</span><span>, y </span><span>=</span><span> </span><span>6</span><span> ;</span></div></div><div><div><div>2</div></div><div><span>(x</span><span>&gt;</span><span>5</span><span>)</span><span>&amp;&amp;</span><span>(y</span><span>++</span><span>) ;</span><span>   // 结果为假 ，运算后 x=5, y=6</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div></section>
<section><h1>【六】逻辑或运算符 (<code>||</code>)<a href="#六逻辑或运算符-"><span>#</span></a></h1><p>逻辑或 <code>||</code> 运算符的运算规律如下（二元运算符）：</p>

<table><thead><tr><th>左运算量</th><th>右运算量</th><th>结果</th></tr></thead><tbody><tr><td>1</td><td>1</td><td><strong>1</strong></td></tr><tr><td>1</td><td>0</td><td><strong>1</strong></td></tr><tr><td>0</td><td>1</td><td><strong>1</strong></td></tr><tr><td>0</td><td>0</td><td><strong>0</strong></td></tr></tbody></table><p><em>提炼核心规则</em>：<strong>有真即真，全假才假</strong>。只要左右两边有一个为“真”（非0），整个表达式的结果就为“真”（1）。只有当两边都为“假”（0）时，结果才为“假”（0）。</p></section>
<section><h1>【七】逻辑或的短路特性<a href="#七逻辑或的短路特性"><span>#</span></a></h1><ul>
<li><strong>定义</strong>：如果第一个操作数是 <code>true</code>（真，非0），第二个操作符就不会再被求值了。</li>
<li><strong>形式</strong>：<code>(表达式1) || (表达式2)</code></li>
<li><strong>规则</strong>：如果表达式1为真，则表达式2<strong>不会进行运算</strong>，即表达式2“被短路”。</li>
</ul><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>int</span><span> x </span><span>=</span><span> </span><span>5</span><span>, y </span><span>=</span><span> </span><span>6</span><span> ;</span></div></div><div><div><div>2</div></div><div><span>(x</span><span>&lt;=</span><span> </span><span>5</span><span>)</span><span>||</span><span>(y</span><span>++</span><span>) ;</span><span>   // 结果为真 ，运算后 x=5, y=6</span></div></div></code></pre><div><div></div><div></div></div><div></div></figure></div><ol>
<li>初始状态：<code>x = 5</code>，<code>y = 6</code>。</li>
<li>计算左侧 <code>(x &lt;= 5)</code>：<code>5 &lt;= 5</code> 为真，返回 <code>1</code>。</li>
<li><strong>触发短路</strong>：因为 <code>||</code> 的左侧为 <code>1</code>（真），整个 <code>||</code> 表达式的结果已确定为真（1）。</li>
<li><strong>跳过右侧</strong>：编译器<strong>直接跳过</strong>右侧的 <code>(y++)</code>，根本不执行。</li>
<li>最终结果：整个表达式为真（1），<code>x</code> 依然是5，<code>y</code> 依然是6。</li>
</ol></section>]]></content>
    </entry>
</feed>
