什么是标识符?
在 C 语言中,标识符是程序员为程序中的各种元素(如变量、函数、结构体、联合体、枚举等)起的名字,你可以把它理解为给程序中的“东西”贴上的标签,以便在代码中引用它们。

(图片来源网络,侵删)
标识符就是 C 语言中合法的“名字”。
标识符的命名规则
C 语言的编译器对标识符的命名有严格的语法规定,一个合法的标识符必须满足以下所有规则:
-
只能由字母、数字和下划线 (
_) 组成。- 字母:可以是小写字母 (a-z) 或大写字母 (A-Z)。
- 数字:可以是 0 到 9。
- 下划线:
_是一个特殊的字符,常用于命名。
-
第一个字符必须是字母或下划线 (
_)。
(图片来源网络,侵删)- 标识符不能以数字开头。
123name是非法的,但name123或_123name是合法的。
- 标识符不能以数字开头。
-
区分大小写。
- C 语言是大小写敏感的语言,这意味着
myVar、myvar和MYVAR是三个完全不同的标识符。
- C 语言是大小写敏感的语言,这意味着
-
不能是 C 语言的关键字。
- 关键字是 C 语言本身已经使用的、有特殊含义的保留字,
int、for、if、while、return等,你不能用它们作为自定义的标识符。
- 关键字是 C 语言本身已经使用的、有特殊含义的保留字,
-
长度限制。
虽然 C 标准本身没有规定标识符的最大长度,但具体的编译器会有自己的限制(前 31 个字符或前 63 个字符被视为有效),为了可移植性,建议标识符不要太长。
(图片来源网络,侵删)
标识符的命名规范(最佳实践)
上面的规则是语法上的要求,而下面的规范是编程风格上的建议,遵循这些规范可以使你的代码更易读、更易维护,这是成为一名优秀程序员的重要一步。
-
见名知意
- 标识符的名字应该清晰地表达其用途,使用有意义的英文单词或缩写。
- 好例子:
studentAge,userName,calculateTotalPrice - 坏例子:
a,b,c,x1,temp2(除非是在非常小的、作用域明确的循环或临时变量中)
-
驼峰命名法
- 这是 C 语言中最常用的命名规范之一。
- 小驼峰法:第一个单词的首字母小写,后面每个单词的首字母大写。
myStudentName,getUserName(),maxValue
- 大驼峰法(帕斯卡命名法):每个单词的首字母都大写,常用于命名函数、结构体、类型等。
MyStudentName,GetUserName(),MaxValue,Student(结构体名)
-
下划线命名法
- 单词之间用下划线
_分隔,所有字母通常小写,这在 C 语言库和一些开源项目中非常常见。 my_student_name,get_user_name,max_value,student(结构体名)
- 单词之间用下划线
-
常量命名
- 习惯上,使用全大写字母和下划线来命名宏定义或
const常量,以突出其“常量”属性。 #define MAX_STUDENTS 100,const float PI = 3.14159;
- 习惯上,使用全大写字母和下划线来命名宏定义或
-
函数命名
- 通常使用动词或动词+名词的形式,表示一个动作。
printMessage(),calculateSum(),getUserInput()
-
变量命名
- 使用名词或名词短语,表示一个数据实体。
int studentCount;,char* bookTitle;
示例:合法与非法的标识符
| 合法标识符 | 非法标识符 | 非法原因 |
|---|---|---|
myVar |
2myVar |
以数字开头 |
_privateVar |
my-var |
包含非法字符 |
student_name |
int |
是 C 语言的关键字 |
MaxValue |
Max Value |
包含空格 |
counter |
counter! |
包含非法字符 |
userName123 |
user@name |
包含非法字符 |
__internal_func |
.hidden_var |
以点号 开头 |
标识符的作用域
标识符不仅是一个名字,它还有一个重要的属性——作用域,作用域指的是一个标识符在程序中可以被有效访问的区域。
C 语言中的主要作用域有:
-
文件作用域
- 在所有函数之外定义的标识符(例如全局变量)具有文件作用域。
- 它们从定义点开始,直到当前源文件(
.c文件)的末尾都是可见的。
-
函数作用域
- 这是一个比较特殊的作用域,仅适用于(
label),也就是在语句前加冒号的名字,如start:,标签可以通过goto语句在函数的任何地方跳转到。
- 这是一个比较特殊的作用域,仅适用于(
-
块作用域
- 在任何代码块(由一对花括号 包围的区域)内部定义的标识符具有块作用域。
- 最常见的例子就是函数内的局部变量,它们只在定义它们的 块内有效。
-
函数原型作用域
- 在函数声明(原型)中,参数的名字只在该声明语句中有效,在
int my_func(int a, int b);中,a和b的名字可以被省略或随意替换,它们不会与函数定义中的参数名冲突。
- 在函数声明(原型)中,参数的名字只在该声明语句中有效,在
作用域示例:
#include <stdio.h>
// file1.c
// counter 具有文件作用域,从这里开始到文件末尾都可见
int counter = 100;
// 函数定义
void my_function() {
// a 具有块作用域,只在 my_function 函数内部有效
int a = 10;
if (a > 5) {
// b 具有块作用域,只在 if 语句这个块内有效
int b = 20;
printf("Inside if: b = %d\n", b);
}
// printf("%d\n", b); // 错误!b 在这里已经超出了作用域
}
int main() {
printf("Global counter: %d\n", counter); // 可以访问全局 counter
my_function();
// a = 15; // 错误!a 在这里已经超出了作用域
return 0;
}
- 定义:标识符是 C 程序中变量、函数等的名字。
- 规则:必须由字母、数字、下划线组成,不能以数字开头,区分大小写,不能是关键字。
- 规范:遵循命名规范(如驼峰法、下划线法)和见名知意的原则,是写出高质量代码的关键。
- 作用域:标识符的有效范围决定了它在程序的哪些地方可以被访问,理解作用域对于避免变量冲突和程序错误至关重要。
