什么是标识符?
标识符就是程序员为 C 程序中的各个元素(如变量、函数、数组、结构体、标签等)起的名字。

(图片来源网络,侵删)
你可以把它想象成我们现实世界中的“人名”或“地名”,通过这个名字,我们可以在程序中唯一地引用和区分不同的元素。
标识符的命名规则
C 语言对标识符的命名有非常严格的语法规则,如果不符合这些规则,编译器就会报错,规则如下:
必须遵守的规则:
-
只能由字母、数字和下划线 (
_) 组成。- 字母: 可以是
a-z,A-Z中的任意字母。 - 数字: 可以是
0-9中的任意数字。 - 下划线:
_是一个特殊的字符,常用于命名。
- 字母: 可以是
-
第一个字符必须是字母或下划线 (
_)。
(图片来源网络,侵删)- 标识符不能以数字开头。
1st_number是非法的,但first_number1是合法的。
- 标识符不能以数字开头。
-
区分大小写。
- 这是 C 语言的一个关键特性。
myVar,myvar,MYVAR被视为三个完全不同的标识符。 int age;和int Age;是两个不同的变量。
- 这是 C 语言的一个关键特性。
-
不能是 C 语言的关键字。
- 关键字是 C 语言本身已经预留并具有特殊含义的单词(如
int,for,if,return等),你不能用它们来命名自己的变量或函数。 int int;是非法的,因为int是关键字。
- 关键字是 C 语言本身已经预留并具有特殊含义的单词(如
-
长度有限制。
C 标准本身并没有规定标识符的最大长度,但具体的 C 编译器会有自己的限制(通常是 31 或 63 个字符),为了可移植性,建议不要使用过长的名字。
(图片来源网络,侵删)
良好实践(强烈推荐,但非强制规则):
虽然以下规则不会导致编译错误,但遵循它们能让你的代码更清晰、更易于阅读和维护。
-
见名知意
- 使用有意义的名字来描述变量的用途,用
student_age而不是sa,用calculate_sum而不是cs。
- 使用有意义的名字来描述变量的用途,用
-
遵循命名约定
- 驼峰命名法: 第一个单词首字母小写,后面每个单词首字母大写。
myStudentName,getUserName。 - 下划线命名法: 单词之间用下划线
_分隔。my_student_name,get_user_name。 - 全大写命名法: 通常用于宏定义或常量。
MAX_SIZE,PI。
- 驼峰命名法: 第一个单词首字母小写,后面每个单词首字母大写。
-
避免使用容易混淆的字符
- 尽量避免使用单个字母
l(小写L) 和1(数字1),O(大写O) 和0(数字0),因为它们在某些字体中看起来非常相似。
- 尽量避免使用单个字母
合法与非法标识符示例
| 标识符 | 是否合法 | 原因 |
|---|---|---|
my_var |
合法 | 由字母和下划线组成。 |
student_age |
合法 | 由字母、数字和下划线组成,且含义清晰。 |
_private_data |
合法 | 以下划线开头,常用于表示内部变量。 |
MAX_SIZE |
合法 | 全大写,常用于宏定义。 |
calculateSum |
合法 | 驼峰命名法,清晰易读。 |
123abc |
非法 | 以数字开头。 |
my-var |
非法 | 包含了非法字符 。 |
if |
非法 | 是 C 语言的关键字。 |
int |
非法 | 是 C 语言的关键字。 |
my var |
非法 | 包含了空格。 |
a*b |
非法 | 包含了非法字符 。 |
my$variable |
非法 | 包含了非法字符 。 |
标识符的作用域
标识符不仅要有合法的名字,还需要在正确的“作用域”中使用。作用域指的是一个标识符在程序中可以被有效访问的区域。
C 语言中主要有几种作用域:
-
文件作用域
- 在所有函数外部定义的标识符(例如全局变量)具有文件作用域。
- 它们从定义点开始,直到整个源文件结束都是可见的。
int global_var = 100; // 文件作用域 void function1() { printf("%d\n", global_var); // 可以访问 } -
函数作用域
- 这个范围很小,只适用于 (label),也就是
goto语句跳转的目标。 - 标签在整个函数内都是可见的,无论它在函数的哪个位置定义。
void my_function() { start: printf("Hello\n"); goto start; // 可以跳转到 'start' 标签 } - 这个范围很小,只适用于 (label),也就是
-
块作用域
- 在任何代码块(由 包围的区域)内部定义的标识符(例如局部变量)具有块作用域。
- 它们从定义点开始,直到该代码块结束都是可见的。
void function2() { int x = 10; // 块作用域,只在 function2 内部可见 if (x > 5) { int y = 20; // 块作用域,只在 if 语句块内可见 printf("%d, %d\n", x, y); // 可以访问 x 和 y } // printf("%d\n", y); // 错误!y 在这里已经超出作用域,无法访问 } -
函数原型作用域
在函数声明(原型)中,参数标识符的作用域仅限于该声明本身,这是一个比较特殊且不常用的规则。
| 特性 | 描述 |
|---|---|
| 定义 | 程序员为变量、函数等元素起的名字。 |
| 规则 | 必须由字母、数字、下划线组成;不能以数字开头;区分大小写;不能是关键字。 |
| 最佳实践 | 见名知意,遵循命名约定(驼峰、下划线)。 |
| 作用域 | 决定了标识符在程序中可以被访问的范围,包括文件作用域、函数作用域和块作用域。 |
正确地理解和使用标识符是编写清晰、可维护、无错误的 C 程序的第一步。
