视频加载失败

C 语言语法符号

2699 字
13 分钟
C 语言语法符号

【一】语法符号的理解#

每种编程语言都有自己的词汇和语法规则。编译器不会把源代码直接当作一整段文字理解,而是先进行词法分析,将代码识别成一个个具有语法意义的最小单元,这些单元通常称为 Token(记号或词法单元)。

例如:

int sum = a + 10;

可以识别为:

int sum = a + 10 ;
关键字 标识符 运算符 标识符 运算符 常量 标点符号

按照本系列笔记便于理解的分类方式,可以将常见语法符号分为:

  • 关键字:由语言标准赋予固定含义的单词;
  • 标识符:由程序员命名的变量、函数、类型等名称;
  • 运算符:表示计算、比较、赋值或其他操作的符号;
  • 分隔符:用于分隔词法单元的空白字符和注释;
  • 标点符号:用于组织声明、表达式、语句和代码块的符号。

此外,源代码中还有常量和字符串字面量。它们属于 C 语言 Token 的重要组成部分,将在“常量”章节单独讲解。

从 C 标准的词法分类来看,许多“运算符”和“标点符号”会统一归入 punctuator(标点符号/界符)。本章将它们分开说明,是为了便于初学者按用途理解。

【二】关键字#

关键字是由 C 语言标准预先规定并赋予特殊语法含义的单词,不能用作变量名、函数名或其他标识符。

【1】C90 的 32 个关键字#

C90 规定了 32 个经典关键字:

auto break case char const
continue default do double else
enum extern float for goto
if int long register return
short signed sizeof static struct
switch typedef union unsigned void
volatile while

关键字区分大小写。例如,int 是关键字,而 Int 不是关键字;但不应通过改变大小写来创建含义相近的名称。

【2】后续标准新增的关键字#

C 语言会随标准更新而扩展,因此“C 语言只有 32 个关键字”只适用于 C90。常见新增关键字如下:

(1)C99 新增#

inline restrict _Bool _Complex _Imaginary
  • inline:建议以内联方式处理函数;
  • restrict:表达指针访问对象的别名约束;
  • _Bool:布尔类型;
  • _Complex、_Imaginary:复数和虚数类型相关关键字,其中虚数类型属于实现可选功能。

(2)C11 新增#

_Alignas _Alignof _Atomic _Generic
_Noreturn _Static_assert _Thread_local

这些关键字主要用于对齐控制、原子操作、泛型选择、静态断言和线程存储期等功能。

(3)C23 常用新增关键字#

alignas alignof bool constexpr
false nullptr static_assert thread_local
true typeof typeof_unqual _BitInt

C23 较新,不同编译器对这些关键字的支持程度可能不同。学习或使用 C23 功能时,应确认编译器版本和所选择的语言标准模式。

【3】容易误认为关键字的名称#

以下名称虽然经常出现在 C 程序中,但它们并不是 C 语言关键字:

名称实际性质
main程序入口函数的约定名称
printf、scanf标准库函数名
NULL标准头文件提供的宏
size_t标准库定义的类型名
include、define预处理指令中的名称

它们分别受到标准库或预处理规则约束,不能简单按普通关键字理解。

【三】标识符#

标识符是程序中名称的词法形式,可用于命名宏、变量、函数、形参、结构体成员、自定义类型等程序实体。

C 语言标识符的基本命名规则如下:

  1. 基础且可移植的标识符由英文字母 A-Z、a-z、数字 0-9 和下划线 _ 组成。
  2. 第一个字符必须是字母或下划线,不能是数字。
  3. 标识符不能与 C 语言关键字相同。
  4. C 语言区分大小写,因此 sum、Sum 和 SUM 是三个不同的标识符。
  5. 标识符中不能包含空格、连字符 -、点号 .、@ 等字符。

新版 C 标准也支持一定范围的通用字符名称及扩展字符,但其可用性还受源文件编码和编译器支持影响。基础学习及追求可移植性时,优先使用英文字母、数字和下划线。

【1】合法与非法标识符#

下面是一些合法的标识符:

x y sum a100 student_name score2

以下标识符不合法:

名称原因
1a以数字开头
3'a以数字开头,并且包含单引号
x*y包含运算符 *
@@ 不能构成基础标识符
b.8包含点号 .
my-name包含连字符 -
my name包含空格,会被识别为两个词法单元
while与关键字相同

【2】命名建议#

  • 名称应表达用途,例如用 student_count 表示学生数量,而不是随意使用 a1。
  • 可以采用下划线命名法 student_count 或小驼峰命名法 studentCount,同一项目中应保持一致。
  • 常量宏通常使用全大写字母和下划线,例如 MAX_SIZE。
  • 不要只通过大小写区分含义相近的变量,例如同时定义 data、Data 和 DATA,这会降低可读性。
  • 简短的局部循环变量可以使用 i、j 等惯用名称,但作用范围较大的名称应更具体。

【3】保留标识符#

某些形式的标识符保留给编译器、标准库或具体实现使用。编写用户代码时,应遵循以下安全规则:

  • 不要定义以双下划线开头的名称,如 __value;
  • 不要定义以下划线加大写字母开头的名称,如 _Value;
  • 在文件作用域中,避免定义任何以下划线开头的名称;
  • 不要重用标准库中已有的函数名、宏名和类型名来表达其他含义。

例如,_A7b_3x 从字符组成规则看是合法形式,但它以下划线和大写字母开头,属于实现保留标识符,不应在用户代码中使用。

【四】运算符#

运算符用于表示计算、比较、赋值、成员访问等操作。一个运算符需要几个操作数,就称为几元运算符。例如,-a 中的 - 是一元运算符,a - b 中的 - 是二元运算符,condition ? a : b 是三元条件运算符。

按照功能,常用运算符可以概括为:

类别常见运算符作用概述
算术运算符+、-、*、/、%执行基本算术运算
关系运算符<、<=、>、>=、==、!=比较两个值
逻辑运算符&&、`
位运算符&、`、^、~、<<、>>`
赋值运算符=、+=、-=、*=、/= 等为对象赋值或执行复合赋值
自增、自减运算符++、--将操作数增加或减少 1
条件运算符?:根据条件从两个表达式中选择一个
指针相关运算符&、*获取对象地址或间接访问所指对象
成员访问运算符.、->访问结构体或共用体成员
其他运算符sizeof、类型转换、下标 []、函数调用 ()、逗号 ,完成类型大小查询等操作

同一个符号在不同上下文中可能具有不同含义。例如,* 既可以表示乘法,也可以用于声明指针或解引用指针;& 既可以表示按位与,也可以表示取地址。

运算符还涉及优先级、结合性和求值规则。为了让表达式含义更清楚,不确定时应主动使用圆括号,而不是仅依赖记忆优先级。具体规则将在后续运算符章节中展开。

【五】分隔符#

分隔符用于划分相邻的词法单元。常见分隔内容包括:

  • 空格(space);
  • 水平制表符(tab);
  • 换行符(newline);
  • 其他空白字符,例如垂直制表和换页;
  • 注释 // ... 和 /* ... */。

在预处理阶段,注释会被替换为空白,因此注释也能起到分隔词法单元的作用。字符串或字符常量内部的 //、/* 并不会开始注释:

const char *url = "https://example.com"; // 字符串中的 // 是普通字符
char slash = '/'; // 字符常量中的 / 是普通字符

空白字符有时可以省略,有时则必不可少:

int count; // int 和 count 之间必须分隔
int intcount; // intcount 是一个完整的标识符,不等同于 int count
total=a+b; // 编译器能够识别,但不利于阅读
total = a + b; // 含义相同,格式更清晰

还应注意:

  • // 注释持续到当前行末尾;
  • /* ... */ 块注释可以跨行,但不能嵌套;
  • 换行通常只是空白,但它会结束 // 注释和预处理指令;
  • 不能用空白拆开一个完整的多字符运算符,例如 >=、==、++。

合理使用空格、缩进和换行不会改变大多数代码的含义,却能显著提升可读性并帮助排查语法错误。

【六】标点符号#

C 语言中常见的标点符号包括逗号、分号、冒号、圆括号、方括号、花括号、点号和箭头等。它们用于组织声明、表达式、语句、函数、数组和代码块。

符号常见用途
,分隔声明项、函数参数和初始化器;在特定上下文中也可作为逗号运算符
;结束声明或表达式语句;单独的 ; 表示空语句
:用于 case、default、标签以及条件运算符 ?:
( )函数声明与调用、条件、表达式分组和类型转换
[ ]数组声明、数组下标和属性语法等
{ }构成复合语句、函数体或初始化器
.通过对象访问结构体或共用体成员
->通过指针访问结构体或共用体成员
#、##预处理指令及宏中的字符串化、记号拼接
...可变参数函数或其他标准规定的省略形式

标点符号与空白分隔符不同:它们具有严格的语法作用,不能随意省略。部分符号在特定上下文中也属于运算符,例如逗号、圆括号、方括号、点号和箭头。

下面的程序集中演示了常见标点符号的用法:

#include <stdio.h>
int add(int x, int y)
{
return x + y;
}
int main(void)
{
int values[2] = {3, 4};
int result = add(values[0], values[1]);
switch (result) {
case 7:
printf("result = %d\n", result);
break;
default:
printf("unexpected result\n");
break;
}
return 0;
}

在这个示例中:

  • 逗号分隔函数形参、实参和数组初始化元素;
  • 分号结束声明、函数调用和 return、break 语句;
  • 圆括号用于函数声明、函数调用和 switch 条件;
  • 方括号用于数组声明及下标访问;
  • 花括号构成初始化器、函数体和 switch 语句体;
  • 冒号跟在 case 和 default 标签之后。

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或打赏支持!

打赏
C 语言语法符号
https://firefly.cuteleaf.cn/posts/language/c/20c语言基础/20语法符号/
作者
Dream
发布于
2026-09-26
许可协议
CC BY-NC-SA 4.0
Profile Image of the Author
Dream
Hello, I'm Dream.
公告
欢迎来到我的博客!爱学习爱进步。
分类
标签
最新动态
站点统计
文章
11
分类
1
标签
26
总字数
23,674
运行时长
0 天
最后活动
0 天前
站点信息
构建平台
Vercel
博客版本
Firefly v6.16.8
文章许可
CC BY-NC-SA 4.0
文章目录