目录
1. 变量
变量( variable)来源于数学,是计算机语言中能储存计算结果或能表示值的抽象概念。
1.1 变量的分类
- 局部变量是函数内部定义的变量。
- 全局变量是函数外部定义的变量。
当全局变量和局部变量名字相同的情况下局部优先,但是建议不要将全局和局部变量的名字写成一样的。
#include <stdio.h>
int a = 100; // 全局变量
int main()
{
int a = 10; // 局部变量
printf("a=%d\n", a); // a=10
return 0;
}
#include <stdio.h>
int x = 5, y = 7; // 全局变量
void swap()
{
int z;
z = x;
x = y;
y = z;
}
// swap函数内部使用的x、y是全局变量
int main()
{
int x = 3, y = 8; // 局部变量
swap();
printf("%d,%d\n", x, y); // 3,8 这里是局部优先原则
return 0;
}
1.2 变量的使用——定义、赋值、初始化
#include <stdio.h>
int main()
{
int num1; // 未初始化的定义
num1 = 10; // 赋值:在已经定义的变量中放入数值
int num2 = 20; // 初始化:在定义变量的时候放入数值
int a, b; // 一次定义多个变量时,用逗号分隔变量名
a = 5; // 赋值
b = 15; // 赋值
int sum = num1 + num2;
int diff = a - b;
printf("%d %d\n", sum, diff); // 30 -10
return 0;
}
变量在未初始化的定义时会被放入不确定的值。因此在定义变量时,最好初始化。
int a; // 未初始化的定义,不建议这样写
int a = 0; // 初始化的定义,建议这样写
1.3 变量的属性
存储期
- 自动存储期。变量在所属块被执行时获得内存单元,并在块终止时释放内存单元,从而会导致变量失去值。具有自动存储期的变量不初始化默认为随机值。
- 静态存储期。变量在程序的执行期间一直存在。具有静态存储期的变量不初始化默认为0。
作用域
- 块作用域。变量从定义处到所属块的末尾都是可见的。
- 文件作用域。变量从定义处到所属文件的末尾都是可见的。
链接
- 外部链接。变量可以被程序中的几个(或许全部)文件共享。
- 内部链接。变量只能属于单独一个文件,但是此文件中的函数可以共享这个变量。如果具有相同名字的变量出现在另一个文件中,那么系统会把它作为不同的变量来处理。
- 无链接。变量属于单独一个函数,而且根本不能被共享。
局部变量和全局变量有默认的属性。另外,函数也有链接属性。默认情况下,函数具有外部链接属性。
int i; // 全局变量:静态存储期、文件作用域、外部链接
void f() // 函数:外部链接
{
int j; // 局部变量:自动存储期、块作用域、无链接
}
1.4 变量声明和定义的关系
声明(declaration)使得名字为程序所知,一个文件如果想使用别处定义的名字则必须包含对那个名字的声明。而定义(definition)负责创建与名字关联的实体。
变量声明规定了变量的类型和名字,在这一点上定义与之相同。但是除此之外,定义还申请存储空间,也可能会为变量赋一个初始值。
如果想声明一个变量而非定义它,就在变量名前添加关键字extern,而且不要显式地初始化变量:
extern int i; // 声明i而非定义i
int j; // 声明并定义j
任何包含了显式初始化的声明即成为定义。我们能给由extern关键字标记的变量赋一个初始值,但是这么做也就抵消了extern的作用。extern语句如果包含初始值就不再是声明,而变成定义了:
extern double pi = 3.1416; // 定义
在函数体内部,如果试图初始化一个由extern关键字标记的变量,将引发错误。
变量能且只能被定义一次,但是可以被多次声明。
2. 常量
常量(constant)是“不变化的量”。
2.1 字面常量
// 数值常量——整数常量
16 // 整数常量默认为十进制
020 // 0为八进制的前导符号
0x10 // 0x或0X为十六进制的前导符号
// 数值常量——浮点常量
3.14 // 浮点常量默认为double类型
3.14f // f或F为float类型的后缀
3.14L // l或L为long double类型的后缀(建议使用L,因为字母l和数字1容易混淆)
// 字符常量
'w'
// 字符串常量
"abc"
2.2 常变量
const修饰的变量,本质是变量,但是不能直接修改,有常量的属性,称为常变量。
const float pi = 3.14f;
// 等价于float const pi = 3.14f;
pi = 5.14; // err
常变量一旦创建后其值就不能再改变,所以必须初始化。
const int a; // err
如果利用一个变量去初始化另外一个变量,则它们是不是const都无关紧要。常变量的常量特征仅仅在执行改变常变量的操作时才会发挥作用。
int i = 42;
const int ci = i // ok
int j = ci; // ok
2.3 宏常量
#define 常量名 常量值
宏替换是在预处理阶段进行的,宏不占用内存空间。
#define MAX 100
#define STR "abcdef"
#include <stdio.h>
int main()
{
printf("%d\n", MAX); // 100
int a = MAX;
printf("%d\n", a); // 100
printf("%s\n", STR); // abcdef
return 0;
}
2.4 枚举常量
虽然枚举和结构体、联合体没有什么共同的地方,但是它们的声明方法很类似。与结构体或联合体的成员不同,枚举常量的名字必须不同于作用域范围内声明的其他标识符。
enum 枚举名
{
枚举常量 [= 整型常量],
枚举常量 [= 整型常量],
...
枚举常量 [= 整型常量]
}枚举变量;
如果枚举常量都没有被显式初始化,则从第一个枚举常量开始依次默认为0,1,2……
如果某个枚举常量被显式初始化,且其后的一些成员没有被显式初始化,则其后的成员按依次加1的规则确定其值。
enum Season
{
SPR, // 0
SUM, // 1
FAL, // 2
WIN // 3
};
enum Day // 星期
{
Mon = 1, // 1
Tues, // 2
Wed, // 3
Thur, // 4
Fri, // 5
Sat, // 6
Sun // 7
};
enum Color
{
RED, // 0
GREEN = 5, // 5
BLUE // 6
};
枚举的使用:
#include <stdio.h>
enum Color
{
RED = 1,
GREEN = 2,
BLUE = 4
}clr1;
int main()
{
enum Color clr1 = RED; // ok
printf("clr1 = %d\n", clr1);
int clr2 = GREEN; // ok
printf("clr2 = %d\n", clr2);
enum Color clr3 = 10; // C语言ok,C++err
printf("clr3 = %d\n", clr3);
return 0;
}