1 初识变量
1.1 变量的意义
在程序设计中,变量是程序中不可或缺的组成单位,最基本的存储单元。它如同现实生活中的容器,用于临时或长期保存各种类型的数据,为程序提供灵活的数据操作能力。
以选购手机为例,手机的各项配置(如颜色、内存、版本等)均可通过变量进行抽象表示。
- 颜色:可用字符串变量存储(例如 "瑞红"、"玄黑")。
- 内存:可用数值或字符串变量表示(例如 "16GB+512GB"、"16GB+1TB")。
通过变量,程序能够动态地处理和管理这些配置信息,实现更高效的逻辑运算和数据处理。
1.2 变量的本质
变量是内存中的一个命名存储单元,用于存储程序运行期间可以改变的数据。
每个变量都具有以下三个核心要素:
- 数据类型:定义变量可以存储的数据的种类(如整数、浮点数、字符等)以及该数据在内存中占用的空间大小。
- 变量名:用于标识和引用该存储单元,通过它可访问或修改存储的值。
- 存储的值:变量当前所保存的数据内容,可以在符合其数据类型的范围内进行变更。
变量名在 C 语言中充当了内存中特定存储单元的标识符。每个变量在内存中都有一个唯一的地址,而变量名就是对这个地址的抽象表示,使得程序员可以通过变量名来访问和操作该地址上的数据。通过变量名,程序可以方便地访问或修改存储在相应内存单元中的值。这是程序进行数据处理和计算的基础。例如,通过变量名可以对变量进行赋值、读取、运算等操作。
1.3 变量的声明与赋值
1.3.1 声明与赋值规则
- 先声明后使用:变量必须先声明后才能在程序中使用。
- 声明与赋值方式:变量可以在声明后单独赋值;也可以在声明时直接初始化赋值。
- 多变量声明:支持同时声明多个同类型变量,并可选择性地对其进行初始化赋值。
- 值可变性:变量的值可以在其数据类型允许的范围内动态改变。
- 唯一性约束:在同一作用域内,变量名必须唯一,禁止重复声明同名变量。
1.3.2 声明、定义、初始化与赋值的关系
在编程学习中,我们经常会遇到 “声明变量”、“定义变量”、“初始化变量” 和 “赋值变量” 这几个专业术语。为什么要理清楚这几个的关系呢?因为在有些教材和课本中,这些术语虽然频繁出现,但它们的具体含义和区别却可能并不十分清晰。为了准确理解和运用这些概念,我们需要弄清楚这些专业术语到底表示什么意思。
-
声明变量:声明变量是指告诉编译器变量的类型和名称,但不为其分配具体的值。例如,int a; 只是声明了一个整型变量 a,此时 a 还没有被赋予任何具体的值。
-
定义变量:在 C 语言中,声明变量通常也意味着定义变量,即为变量分配内存空间。因此,int a; 既可以看作是声明,也可以看作是定义。但在某些上下文中(如函数原型中),声明变量可能只是声明而不定义,即只告诉编译器变量的类型和名称,而不为其分配内存空间。
-
初始化变量:初始化变量是指在声明变量的同时为其分配一个初始值。例如,int a = 5; 既声明了变量 a,又为其初始化了值 5。这样,在变量 a 被声明的同时,它就已经有了一个具体的值。
-
赋值变量:赋值变量是指在变量已经声明并定义后,为其分配一个新的值。例如,a = 10; 是在变量 a 已经存在的情况下,为其赋予新的值 10。此时,变量 a 的值从原来的 5 变成了 10。
理解这些概念的区别和联系,有助于我们更好地掌握变量的使用和管理,避免在编程过程中出现混淆和错误。
1.3.3 案例演示
首先,我们创建一个名为 “Chapter2_variable” 的文件夹,并用 VS Code 打开。接着,在该文件夹中新建一个名为 “var01.c” 的源文件,具体操作如下:
然后编写如下代码:
#include <stdio.h>
int main()
{
// 1. 先声明后使用:变量必须先声明后才能在程序中使用。
int a; // 声明变量 a,但未初始化
// 2. 声明与赋值方式:
// 2.1 变量可以在声明后单独赋值。
a = 10; // 在声明后单独给变量 a 赋值
// 2.2 变量也可以在声明时直接初始化赋值。
int b = 20; // 在声明时直接给变量 b 初始化赋值
// 3. 多变量声明:支持同时声明多个同类型变量,并可选择性地对其进行初始化赋值。
int c = 30, d, e = 40; // 同时声明多个整型变量,其中 c 和 e 被初始化,d 未初始化
d = 50; // 单独给变量 d 赋值
// 4. 值可变性:变量的值可以在其数据类型允许的范围内动态改变。
a = a + 5; // 改变变量 a 的值
b = b - 10; // 改变变量 b 的值
// 5. 唯一性约束:在同一作用域内,变量名必须唯一,禁止重复声明同名变量。
// 下面的代码会导致编译错误,因为变量 b 已经在前面声明过
// int b = 999; // 错误:重复声明变量 b
// 变量未定义就使用:会导致编译错误
// f = 60;
return 0;
}
如果将上面示例代码中的 25 行和 28 行代码注释取消掉,编译器会提示错误,如下所示:
由此可见,在使用变量时,遵循声明与赋值规则是个不错的习惯,能让我们的编程之路更加平坦。
2 printf 输出变量
2.1 使用方法
printf 的标准含义是格式化输出文本,其名称来源于 "print formatted"(格式化打印)的缩写。printf 的标准语法规则如下:
-
格式化字符串:用双引号括起来的一个字符串,里面包括格式占位符和普通字符。普通字符会直接输出,而格式占位符则用于指定输出数据的格式。
-
格式占位符(也叫格式声明符):由 “%” 和格式字符组成,作用是将输出的数据转换为指定的格式后输出。例如,%d 表示整数。更多的格式占位符在后续的学习中会进行讲解。
-
输出列表:是程序需要输出的一些数据,可以是常量、变量或表达式,与格式占位符一一对应。
2.2 案例演示
新建文件 “printf01.c”,然后编写如下代码:
#include <stdio.h>
int main()
{
// 1. 先声明后使用:变量必须先声明后才能在程序中使用。
int a; // 声明变量 a,但未初始化
// 2. 声明与赋值方式:
// 2.1 变量可以在声明后单独赋值。
a = 10; // 在声明后单独给变量 a 赋值
printf("变量 a 在单独赋值后的值: %d\n", a);
// 2.2 变量也可以在声明时直接初始化赋值。
int b = 20; // 在声明时直接给变量 b 初始化赋值
printf("变量 b 在初始化后的值: %d\n", b);
// 3. 多变量声明:支持同时声明多个同类型变量,并可选择性地对其进行初始化赋值。
int c = 30, d, e = 40; // 同时声明多个整型变量,其中 c 和 e 被初始化,d 未初始化
d = 50; // 单独给变量 d 赋值
printf("变量 c: %d, 变量 d: %d, 变量 e: %d\n", c, d, e);
// 4. 值可变性:变量的值可以在其数据类型允许的范围内动态改变。
a = a + 5; // 改变变量 a 的值
b = b - 10; // 改变变量 b 的值
printf("变量 a 在修改后(+5)的值: %d\n", a);
printf("变量 b 在修改后(-10)的值: %d\n", b);
// 5. 唯一性约束:在同一作用域内,变量名必须唯一,禁止重复声明同名变量。
// 下面的代码会导致编译错误,因为变量 b 已经在前面声明过
// int b = 999; // 错误:重复声明变量 b
// 解决方案:我们可以使用不同的变量名
int f = 999; // 声明新的变量 f
printf("变量 f: %d\n", f);
return 0;
}
程序在 VS code 中的运行结果如下所示:
3 scanf 输入变量
3.1 使用方法
scanf 主要用于从标准输入(stdin,通常是键盘)读取数据并将其存储到指定的变量中。这些变量需要提前声明。scanf 函数位于头文件 <stdio.h> 中。
与 printf 相同,scanf 也可以通过不同的格式占位符为不同类型的变量获取值。例如,%d 用于读取整数,%f 用于读取浮点数等。更多的格式占位符在后续的学习中会进行讲解。
需要注意的是,在 scanf 中,变量名前面需要添加 & 符号,该符号称为取地址符。这是因为 scanf 需要知道变量的内存地址,以便将输入的数据存储到该地址中。后续会在指针部分详细讲解取地址符的用法。
3.2 案例演示
新建文件 “scanf01.c”,然后编写如下代码:
#include <stdio.h>
int main()
{
// 声明一个整数变量 num
int num;
// 提示用户输入一个数字
printf("请输入一个数字:");
// 从标准输入读取一个整数,并将其存储到变量 num 中
scanf("%d", &num);
// 输出用户输入的数字
printf("您输入的数字是:%d\n", num);
// 声明三个整数变量 num1, num2, num3
int num1, num2, num3;
// 提示用户输入三个数字
printf("请输入三个数字(使用空格分隔):");
// 从标准输入读取三个整数,使用空格分隔,并将它们分别存储到变量 num1, num2, num3 中
scanf("%d %d %d", &num1, &num2, &num3);
// 输出用户输入的三个数字
printf("数字是:%d, %d, %d\n", num1, num2, num3);
// 返回 0,表示程序正常结束
return 0;
}
程序在 VS code 中的运行结果如下所示:
4 关键字
关键字是 C 语言中具有特殊含义的保留单词,不能用作标识符(如变量名、函数名等)。随着 C 语言标准的不断发展,关键字的数量也在逐渐增加。
ANSI C 有 32 个关键字,C99 标准增加了 5 个关键字,C11 标准增加了 7 个关键字。如下所示:
类别 | ANSI C 关键字 | C99 新增关键字 | C11 新增关键字 |
---|---|---|---|
控制语句关键字 | break, case, continue, default, do, else, for, goto, if, return, switch, while | - | - |
数据类型关键字 | char, enum, double, long, float, int, short, signed, struct, unsigned, union, void | - | - |
存储类型关键字 | auto, extern, register, static | - | - |
其他关键字 | const, sizeof, typedef, volatile | inline, restrict, _Bool, _Complex, _Imaginary | _Alignas, _Alignof, _Atomic, _Static_assert, _Noreturn, _Thread_local, _Generic |
- 控制语句关键字:用于控制程序的流程,如条件判断、循环、跳转等。
- 数据类型关键字:用于定义变量的数据类型,如整型、浮点型、字符型等。
- 存储类型关键字:用于定义变量的存储类型,如自动存储、静态存储、外部链接等。
- 其他关键字:包括常量定义、类型别名、变量大小获取、易变变量声明等,以及 C99 和 C11 标准新增的关键字,用于支持新的语言特性和功能。
5 标识符
在 C 语言中,变量、函数、数组名、结构体等要素命名时使用的字符序列,称为标识符。标识符是程序中用于唯一标识这些实体的名称。
5.1 强制命名规范
为了确保代码的可读性和可维护性,标识符的命名需要遵循以下强制规范:
- 组成字符:标识符只能由小写或大写英文字母(a-z, A-Z)、数字(0-9)或下划线(_)组成。
- 开头字符:标识符不能以数字开头。
- 关键字限制:标识符不能是 C 语言的关键字。
- 大小写敏感:标识符严格区分大小写字母。例如,Hello 和 hello 是两个不同的标识符。
- 长度限制:标识符具有长度限制,不同编译器和平台可能会有所不同,一般限制在 63 个字符内。
合法标识符举例:
a
BOOK_sun
MAX_SIZE
Mouse
student23
Football
FOOTBALL
max
_add
num_1
sum_of_numbers
非法标识符举例:
$zj
:包含非法字符$
。3sum
:以数字开头。ab#cd
:包含非法字符#
。23student
:以数字开头。Foot-baii
:包含非法字符-
。s.com
:包含非法字符.
。b&c
:包含非法字符&
。j**p
:包含非法字符*
。book-1
:包含非法字符-
。tax rate
:包含空格。don't
:包含单引号'
。
5.2 建议命名规范
除了强制规范外,为了提高代码的可读性和可维护性,以下是一些建议的标识符命名规范:
- 使用有意义的单词:为了提高阅读性,建议使用有意义的单词作为标识符,使代码见名知意。例如,sum、name、max、year 等。
- 使用下划线连接多个单词:对于由多个单词组成的标识符,建议使用下划线
_
连接各个单词,以提高可读性。例如,max_classes_per_student。 - 使用小驼峰命名法:除了使用下划线连接外,也可以使用小驼峰命名法(Camel Case)。在这种命名法中,除第一个单词外,后续单词的首字母大写。例如,myVariableName、maxClassesPerStudent。
- 避免仅靠大小写区分:为了避免混淆,建议不要使用仅靠大小写区分的不同标识符。例如,name 和 Name 容易让人混淆,应尽量避免。
- 避免使用下划线开头的标识符:系统内部使用了一些下划线开头的标识符,如 C99 标准添加的类型 _Bool。为了防止命名冲突,建议开发者尽量避免使用下划线开头的标识符。
6 编程练习
6.1 计算输入整数的和
目标:定义两个整数变量,通过键盘输入为它们赋值,然后计算这两个整数的和并输出结果。
#include <stdio.h>
// 定义主函数
int main()
{
// 声明三个整型变量 a, b 和 sum
int a, b, sum;
// 提示用户输入两个整数,并使用空格隔开
printf("请输入两个整数(使用空格隔开):");
// 从标准输入读取两个整数,并分别存储到变量 a 和 b 中
scanf("%d %d", &a, &b);
// 计算变量 a 和 b 的和,并将结果存储到变量 sum 中
sum = a + b;
// 输出计算结果
printf("两数之和为:%d\n", sum);
// 返回 0,表示程序正常结束
return 0;
}
程序在 VS code 中的运行结果如下所示:
6.2 交换两个整数的值
目标:编写一个程序,输入两个整数,交换它们的值并输出。
提示:可以使用一个临时变量来辅助交换。
#include <stdio.h>
int main()
{
int a, b, temp;
printf("请输入两个整数(使用空格隔开):");
scanf("%d %d", &a, &b);
printf("交换前的值为:a = %d, b = %d\n", a, b);
// 交换 a 和 b 的值
temp = a;
a = b;
b = temp;
printf("交换后的值为:a = %d, b = %d\n", a, b);
return 0;
}
程序在 VS code 中的运行结果如下所示: