1. 变量及其作用
想象一下,你正在编写一个程序来记录学生的成绩。你需要一个地方来暂时存放这些成绩,这就是变量的用武之地。
变量不仅可以存储数值,还能保存字符、布尔值等多种数据类型,使你的程序能够处理多样化的信息。
代码示例:存储学生分数
#include <stdio.h>
int main() {
int studentScore; // 声明一个整型变量来存储学生成绩
studentScore = 95; // 给变量赋值
printf("The student's score is: %d\n", studentScore); // 输出变量值
return 0;
}
2. 变量名
变量名是程序员与计算机沟通的桥梁,它遵循一定的命名规则,确保程序易于阅读和理解。
命名规则
- ①必须以字母(a-z, A-Z)或下划线
_
开始。 - ②不能以数字开头。
- ③后续可以包含字母、数字(0-9)或下划线。
- ④不得使用C语言的关键字(如
if
,else
,int
等)作为变量名。 - ⑤建议使用有意义的名称,如
age
而不是a
,以提高代码的可读性。
①~④是必须遵守的C语言规范,⑤是实战中的最佳实践。
关键字
④中提到的关键字,是指C语言中有特殊意义的词,编译器会根据这些词执行对应的编译过程,这些词就像海洋中的灯塔一样,引领着编译器,不能随便使用。
比如编译器会将关键字if
后的代码块作为一个整体,其后的代码必须遵循规范,所以其不能作为变量名。
下面的词都是C语言中的关键字。
auto, break, case, char, const, continue, default, do, double, else, enum, extern, float, for, goto, if, inline, int, long, register, restrict, return, short, signed, sizeof, static, struct, switch, typedef, union, unsigned, void, volatile, while
关于这些关键字,完全没必要记住。
在写代码的过程中,如果使用关键字作为变量名,IDE会提示错误。好钢用在刀刃上,让大脑干最重要的活吧。
3. 声明变量
声明变量是告诉编译器为其分配内存空间并指定数据类型的过程。
变量必须先声明后使用,使用未声明的变量,编译时会报错。
C语言是强类型语言,声明变量必须指定数据类型。
C语言提供了多种基本数据类型,如int
, float
, char
, double
等。
示例:声明不同类型的变量
int age; // 整型变量,用于存储年龄
float height; // 浮点型变量,用于存储身高
char grade; // 字符型变量,用于存储成绩等级
变量类型一定确定,后续不能改变类型。
4. 变量赋值
赋值操作是将具体值赋予变量的过程。你可以直接在声明时赋值,也可以在之后的程序中进行。赋值操作通过赋值运算符 =
完成。
示例:变量赋值与重新赋值
int score = 85; // 在声明时赋初值
score = 92; // 之后重新赋值
注意score = 92;
是赋值语句,score = 92
是赋值表达式,区别在于是否带分号;
。
4.1 变量的默认值
不同于Java语言会给变量赋默认值,C语言中的变量默认值是随机的,取决于为变量分配的内存原来存储的数据。
所以,在使用变量前,一定要明确赋值。
int main()
{
int j;
// 使用未赋值的变量j,j的值不可预测
printf("Hello, %d World!\n", j);
return 0;
}
4.2 值类型
变量的值应该与类型一致,不应该赋予不是同一个类型的值,比如num的类型是整数,就不应该赋值为小数。虽然 C 语言会自动转换类型,但是应该避免赋值运算符两侧的类型不一致,否则可能产生难以预测的结果。
4.3 赋值表达式的结果
我们知道,表达式是有结果的,赋值表达式也是有计算结果的。所以赋值表达式有两重效果:
- ①给变量赋值。
- ②表达式本身也会返回计算结果,结果是变量的值。
如下代码,赋值表达式 j = 10
的计算结果是10,正是因为这个特性,赋值表达式 j = 10
才能作为参数传递给函数。
int main()
{
int j;
printf("Hello, %d World!\n", j = 10);
return 0;
}
4.4 左右值
C 语言有左值(left value)和右值(right value)的概念。
左值是可以放在赋值运算符左边的值,一般是变量;右值是可以放在赋值运算符右边的值,一般是一个具体的值。
这是为了强调有些值不能放在赋值运算符的左边,比如 x = 1
是合法的表达式,但是 1 = x
就会报错。
5. 变量作用域
作用域决定了变量在程序中的可见性和生命周期。
5.1 代码块
C语言变量作用域和代码块密切相关,代码块是一对大括号{ }
包裹的代码集合。
在C语言中,代码块可以分为如下几种。
5.1.1 函数体代码块
函数是C语言中执行特定任务的代码块,每个函数由返回类型、函数名、参数列表和函数体组成。
#include <stdio.h>
// 定义一个函数,用于打印问候语
void greet() {
printf("Hello, World!\n");
}
int main() {
greet(); // 调用函数
return 0;
}
5.1.2 复合语句代码块
复合语句是由大括号包围的一组语句,常用于if语句、循环语句等控制结构中。
int main() {
int x = 10;
if (x > 5) {
// 这是一个复合语句代码块
printf("x is greater than 5.\n");
}
return 0;
}
5.1.3 循环体代码块
在for、while、do-while循环中,循环体本身就是一个代码块。
int main() {
for (int i = 0; i < 5; i++) {
// 循环体代码块
printf("Iteration: %d\n", i);
}
return 0;
}
5.1.4 switch-case代码块
switch语句中的每个case部分和可选的default部分也是代码块。
int main() {
int day = 3;
switch(day) {
case 1:
printf("Monday\n");
break;
case 2:
printf("Tuesday\n");
break;
case 3:
printf("Wednesday\n"); // 当day为3时,执行此代码块
break;
default:
printf("Invalid day\n");
}
return 0;
}
5.1.5 初始化代码块
虽然C语言标准中没有直接支持初始化代码块的概念,但可以在函数开始或复合语句中初始化多个变量。
int main() {
{
// 这个代码块用于初始化
int a = 1;
int b = 2;
printf("a: %d, b: %d\n", a, b);
} // 此处代码块结束,a和b的作用域结束
return 0;
}
5.1.6 注意事项,
关于代码块,有两个注意事项。
一是C语言的代码块不能独立于函数外单独存在。
#include <stdio.h>
int i;
// 在函数体外单独定义代码块
{
i = 10;
}
int main() {
return 0;
}
如上,在函数体外单独定义代码块,编译时报错。
二是C语言的代码块中可以嵌套代码块。
{
// 这个代码块用于初始化
int a = 1;
int b = 2;
{
int a = 1;
int b = 2;
printf("第二层嵌套:a: %d, b: %d\n", a, b);
}
printf("第一层嵌套:a: %d, b: %d\n", a, b);
} // 此处代码块结束,a和b的作用域结束
return 0;
}
5.2 作用域分类
C 语言的变量作用域主要有两种:文件作用域(file scope)和块作用域(block scope)。
5.2.1 快作用域
在函数或代码块内部定义的变量,仅在此范围内可见。
块作用域(block scope)指的是由大括号 {}
组成的代码块,它形成一个单独的作用域。凡是在块作用域里面声明的变量,只在当前代码块有效,代码块外部不可见。
#include <stdio.h>
int i = 10101;
int main() {
int a = 1;
int b = 2;
{
// 这个代码块用于初始化
int a = 1;
int b = 2;
{
// 内层代码块覆盖外层代码块同名变量
int a = 1;
int b = 20;
int c = 200;
printf("第二层嵌套:a: %d, b: %d\n", a, b);
}
printf("第一层嵌套:a: %d, b: %d\n", a, b);
} // 此处代码块结束,a和b的作用域结束
return 0;
}
如上,在嵌套的作用域中,有两点需要注意:
- ①如果内层的变量与外层同名,那么会在当前作用域覆盖外层变量。示例中第二层嵌套中的变量
b
会覆盖外层的变量,其值是20
。
- ②外层代码块不能访问内层代码块定义的变量,如下图外层代码块试图使用内层代码块声明的变量
c
,编译器会报错。
{
int a = 0;
{
int c = 0;
}
printf("c = %d", c);
}
5.2.2 文件作用域
文件作用域(file scope)指的是,在源码文件顶层声明的变量,从声明的位置到文件结束都有效。
#include <stdio.h>
int i = 10101;
int main() {
return 0;
}
如上代码中定义的变量 i
的作用域就是文件作用域。