课程目标:
C 语言中的基本元素 | ⭐ |
---|---|
常量、变量的概念和命名规则 | ⭐⭐ |
变量的声明、初始化和定义 | ⭐⭐⭐ |
先在Ubuntu下建立本章文件夹:
b07@SB:~/c$ mkdir chapter4
b07@SB:~/c$ cd chapter4
b07@SB:~/c/chapter4$ mkdir bin include obj src
b07@SB:~/c/chapter4$ ls
bin include obj src
1. C 语言中的基本元素
2. 常量、变量的概念和命名规则
必知概念在程序执行过程中,其值不发生改变的量称为常量。
在程序中,常量可以不经说明而直接使用。常量分类有两种:
- 直接常量(字面常量\字面值),其对应数据类型的常量包括:
- 整型常量:
12U
、0L
、-3
- 实型常量:
4.6F
、-1.23
- 字符常量:
'a'
,'b'
- 字符串常量:
"Hello world!"
- 整型常量:
- 符号常量:符号常量定义成宏的形式:
#define 符号常量 值
,并且习惯上符号常量使用大写字母- 符号常量与变量不同,它的值在其作用域内不能改变,也不能再被赋值。
- 优点:含义清楚,能做到“一改全改”
常量示例:
#include <stdio.h>
#define PRICE 30 // 每次修改此处就行
int main() {
// 10 和 0 都是字面常量
int num = 10;
int total = 0;
// PRICE 是宏定义得到的符号常量
total = num * PRICE;
printf("total = %d\n", total);
return 0;
}
必知概念在程序执行过程中,其值可以改变的量称为变量。
- 一个变量应该有一个名字(标识符),在内存中占据一定的存储单元。 - 变量定义必须放在变量使用之前,一般放在函数体的开头部分。 - 要区分变量名和变量值是两个不同的概念 |
![]() |
---|---|
必知概念用来标识变量名、符号常量名、函数名、数组名、类型名、文件名的有效字符序列称为标识符。
标识符的命名规则:
- 可以由字母、数字和
_
(下划线)组合而成,必须以字母或_
开头且区分大小写。 - 不能包含除
_
以外的任何特殊字符, 如 %、#、逗号、空白字符(换行符、空格和制表符)等。 - C 语言中的某些关键字(int 、float 等)称为保留字,具有特殊意义不能用作标识符。
案例:变量值修改过程如下
b07@SB:~/c/chapter4$ cat src/variable.c
#include <stdio.h>
int main() {
// 定义变量并赋初值 6
int a = 6;
printf("Before a = %d\n", a);
a = 9;
printf("After a = %d\n", a);
return 0;
}
b07@SB:~/c/chapter4$ gcc -Wall src/variable.c -o bin/variable
b07@SB:~/c/chapter4$ ./bin/variable
Before a = 6
After a = 9
3. 变量的声明、初始化和定义
因为 C 语言是静态类型语言,一个变量的类型在整个程序运行期间不能发生改变。
必知概念变量的声明主要是告诉编译器变量的类型和名字,在使用之前知道有这样一个变量的存在,它并不分配存储空间。其格式为数据类型 变量名;
,例如int count;
和double ratio;
必知概念变量的定义和初始化是为变量分配存储空间,同时指明变量的类型和名字。其格式为数据类型 变量名 = 变量值;
如 int count = 100; //在定义时进行初始化
:::info
变量声明和定义的区别:
- 关键点:是否分配存储空间?声明不分配存储空间,而定义分配。
- 严格意义上讲
int a;
属于定义式声明,也就说其分配存储空间,但是其值是随机的。而extern int a;
才是引用式声明(将在后面讲到),因此统一将int a;
和int a = 100;
都认为是“定义”。 - 在 C 语言中,变量有且只能有一次定义,而可以有多次声明!
:::
案例1:(定义式)声明与定义和初始化区别
```shell
b07@SB:~/c/chapter4$ cat src/declareDefine.c
include
int main() {
int a; // 定义式声明
printf(“Before assignment: a = %d\n”, a);
// 对 a 进行赋值
a = 6;
printf(“After assignment: a = %d\n”, a);
int b = 2; // 定义变量 b 的同时赋初值
printf(“Define and initial: b = %d\n”, b);
return 0;
}
b07@SB:~/c/chapter4$ gcc -Wall src/declareDefine.c -o bin/declareDefine
src/declareDefine.c: In function ‘main’:
src/declareDefine.c:5:2: warning: ‘a’ is used uninitialized in this function [-Wuninitialized]
printf(“Before assignment: a = %d\n”, a);
^~~~~~~~~~~~
b07@SB:~/c/chapter4$ ./bin/declareDefine
Before assignment: a = 0
After assignment: a = 6
Define and initial: b = 2
在此电脑上的`gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)`默认将未初始化的变量赋值为`0`。<br />**案例2**:变量不能多次定义
```shell
b07@SB:~/c/chapter4$ cat src/redeclaration.c
#include <stdio.h>
int main() {
int a; // 定义式声明
int a; // 表面上是声明,但是实际是重复定义
int b = 2; // 定义变量 b 的同时赋初值
int b = 3; // 重复定义
return 0;
}
b07@SB:~/c/chapter4$ gcc -Wall src/redeclaration.c -o bin/redeclaration
src/redeclaration.c: In function ‘main’:
src/redeclaration.c:5:9: error: redeclaration of ‘a’ with no linkage
int a; // 表面上是声明,但是实际是重复定义
^
src/redeclaration.c:4:9: note: previous declaration of ‘a’ was here
int a; // 定义式声明
^
src/redeclaration.c:8:9: error: redefinition of ‘b’
int b = 3; // 重复定义
^
src/redeclaration.c:7:9: note: previous definition of ‘b’ was here
int b = 2; // 定义变量 b 的同时赋初值
^
src/redeclaration.c:8:9: warning: unused variable ‘b’ [-Wunused-variable]
int b = 3; // 重复定义
^
src/redeclaration.c:5:9: warning: unused variable ‘a’ [-Wunused-variable]
int a; // 表面上是声明,但是实际是重复定义
从上面看到编译器不允许重复定义变量,那么是不是extern int b;
就可以随便用呢?
b07@SB:~/c/chapter4$ cat src/referenceDeclare.c
#include <stdio.h>
int main() {
int a; // 定义式声明
extern int a; // 引用式声明
int b = 2; // 定义变量 b 的同时赋初值
extern int b; // 引用式声明
return 0;
}
b07@SB:~/c/chapter4$ gcc -Wall src/referenceDeclare.c -o bin/referenceDeclare
src/referenceDeclare.c: In function ‘main’:
src/referenceDeclare.c:5:16: error: extern declaration of ‘a’ follows declaration with no linkage
extern int a; // 引用式声明
^
src/referenceDeclare.c:4:9: note: previous declaration of ‘a’ was here
int a; // 定义式声明
^
src/referenceDeclare.c:8:16: error: extern declaration of ‘b’ follows declaration with no linkage
extern int b; // 引用式声明
^
src/referenceDeclare.c:7:9: note: previous definition of ‘b’ was here
int b = 2; // 定义变量 b 的同时赋初值
^
src/referenceDeclare.c:8:16: warning: unused variable ‘b’ [-Wunused-variable]
extern int b; // 引用式声明
^
src/referenceDeclare.c:5:16: warning: unused variable ‘a’ [-Wunused-variable]
extern int a; // 引用式声明
从报错信息看,该源代码需要链接其它模块才能够实现引用式声明。关于引用式声明的使用将在之后编译多个文件和作用域的时候提到。