目录
1. 什么是变量
在C语言中,我们可以认为变量是指向某一个块数据可以被修改的内存的标识符。
2. 变量名
变量名,即变量的标识符。
2.1 变量命名规则
在C语言中,变量名需要遵循一些规则,以确保代码的可读性和一致性:
- 变量名只能包含字母、数字和下划线,而且只能以字母或下划线开头。
- C语言的标识符都是大小写敏感的,所以变量名 name 和变量名 Name 是两个不同的变量名。
- 避免使用C语言的关键字作为变量名,因为关键字在C语言中是有特殊的含义和用途的,使用关键字作为变量名,默认会被编译器当作关键字来看待,而不是我们想要的变量名。
- 变量名应该具有描述性,能够清晰地表达变量的用途,见名知其意,说的就是这个意思。
3. 变量数据类型
对于某一块内存,我们用变量名可以找到它在内存的位置,但只通过变量名还无法确定这块内存的大小,所以在定义变量时,我们还需要明确指出变量的数据类型。
C语言的基本数据类型如下表所示:
内存大小(byte) | 类型 | 值范围 |
---|---|---|
1 | char (signed char) | -128 ~ 127 |
unsigned char | 0 ~ 255 | |
2 | short int (signed short int) | -(2^15) ~ (2^15)-1 |
unsigned short int | 0 ~ (2^16)-1 | |
4 | int (signed int) | -(2^31) ~ (2^31)-1 |
unsigned int | 0 ~ (2^32)-1 | |
4 | float | 1.175494351e-38F 到 3.402823466e+38F |
8 | double | 2.22507e-308 到 1.79769e+308 |
4. 变量定义
变量定义是告诉编译器变量的数据类型和名字,并创建它。
变量定义的格式如下:
变量类型 变量名;
- 变量类型是变量的数据类型,它指明了这个变量对应的内存的大小。
- 变量类型 变量名; // 告诉编译器,内存中给我一块可以存储数据,而且数据可以被修改的占用字节数为 变量类型 大小的内存,并把这块内存的名称标识为 变量名 的名称。
有了这个变量名,我们程序对这个变量的操作,就是对这个变量对应的内存进行操作。
比如:
char c; // 定义一个 char 型变量,变量名为 c
short int si; // 定义一个 short int 型变量,变量名为 si
int age; // 定义一个 int 型变量,变量名为 age
float f; // 定义一个 float 型变量,变量名为 f
double d; // 定义一个 double 型变量,变量名为 d
我们可以一个语句定义多个同数据类型的变量
int age, height; // 定义了两个 int 型变量,变量名分别为 age, height
4.1 变量初始化
变量初始化,就是告诉编译器,这个变量指向的这块内存存放的初始值,一般情况下,我们应该在定义变量的时候,对它进行初始化。比如:
char c = 'a'; // 定义一个 char 型变量,变量名为 c, 并初始化为 'a'
short int si = -1; // 定义一个 short int 型变量,变量名为 si,并初始化为 -1
int age = 10; // 定义一个 int 型变量,变量名为 age,并初始化为 10
float f = 3.2f; // 定义一个 float 型变量,变量名为 f,并初始化为 3.2
double d = 3.2; // 定义一个 double 型变量,变量名为 d,并初始化为 3.2
我们可以一个语句定义多个同数据类型的变量,并初始化
int age = 20, height = 165; // 定义了两个 int 型变量,变量名分别为 age, height,并初始化 age 为 20,hegith 为 165
4.2 变量声明
变量声明是告诉编译器变量的数据类型和名字。
在C语言中,变量声明用 extern 关键字,格式如下
extern int g_counter; // 说明 g_counter 变量在别的地方有定义
例如:
student.c
#include "student.h"
int g_counter = 0; //定义全局变量
int get_counter() {
return g_counter;
}
main.c
#include <stdio.h>
extern int g_counter; // 说明 g_counter 变量在别的地方有定义,在本文件中,
// 不用将定义 g_counter 变量的文件包含进来,但编译的
// 时,需要将定义 g_counter 变量的文件一起编译,从而
// 达到模块化编程和代码分离的作用
int main() {
printf("g_counter = %d\n", g_counter);
return 0;
}
注:变量定义和变量声明的区别
变量定义是会分配内存空间的,变量声明不会分配内存空间
一个变量只能被定义一次,但可以声明多次
变量定义也是变量声明,但变量声明不一定是变量定义
5. 变量是左值
左值:指向内存位置的表达式称为左值 (lvalues),左值可以出现在赋值号 (=) 的左边或右边
右值:存储在内存中某些地址的值称为右值 (rvalues),右值只能出现在赋值号 (=) 的右边
比如:
1 = 2 // error, 1 是右值,不能出现在赋值号 (=) 的左边
变量是指向内存某一位置的表达式,所以变量是左值,可以出现在赋值号 (=) 的左边或右边
比如:
int a = 10; // 变量a做左值
int b = 11; // 变量b做左值
b = a; // 变量b做左值,变量a做右值
6. 变量作用域
C语言中,变量的作用域 (Scope) 是指变量在程序中可见的区域。
在C语言中,有三个地方可以定义变量:
- 在函数或块内部定义的局部变量对应的作用域为局部作用域。
- 在所有函数外部定义的全局变量对应的作用域为全局作用域。
- 在函数定义中定义的函数形参对应的作用域为函数形参作用域。
6.1 局部作用域
在函数或块内部定义的局部变量,具有局部作用域。程序可以访问这个变量的区域被限制在函数或块内部。
#include <stdio.h>
int show() {
int a = 1; // 在函数内部定义的局部变量a,具有局部作用域,变量a在show函数内可见
printf("a = %d\n", a);
for (int i = 0; i < 3; i++) {
int b = 0; // 在块内部定义的局部变量b,具有局部作用域,变量b在这个for循环块内可见
b++;
printf("b = %d\n", b);
}
}
int main() {
show();
return 0;
}
6.2 全局作用域
在所有函数外部定义的全局变量,具有全局作用域,全局变量在整个程序可见。
#include <stdio.h>
int g_counter = 0; // 在所有函数外部定义的全局变量g_counter,具有全局作用域,整个程序可见
void incre_counter() {
g_counter++; // 全局变量,全局可见
}
void decre_counter() {
g_counter--; // 全局变量,全局可见
}
int main() {
incre_counter();
printf("g_counter = %d\n", g_counter); // 全局变量,全局可见
decre_counter();
printf("g_counter = %d\n", g_counter);
return 0;
}
6.3 函数形参作用域
在函数定义中定义的函数形参具有函数形参作用域,形参变量在该函数内可见
#include <stdio.h>
int my_add(int a, int b) // a 和 b 是函数参数,具有函数参数作用域,在my_add函数内可见
{
return a + b;
}
int main() {
printf("%d + %d = %d\n", 3, 5, my_add(3, 5));
return 0;
}
6.4 同名变量的作用域规则
在嵌套的作用域中,变量的访问按照就近原则。也就是说,程序会优先查找最内层的作用域,如果找不到变量,就会逐级向外查找。所以,对于同名变量,内层作用域会屏蔽外层的作用域。例如:
#include <stdio.h>
int counter = 100;
void show() {
printf("1111 counter = %d\n", counter); // 此处counter具有全局作用域
int counter = 5; // 此处counter具有函数作用域,屏蔽掉了函数作用域以外的作用域
printf("2222 counter = %d\n", counter);
for (int i = 0; i < 1; i++) {
int counter = 20; // 此处counter具有块作用域,屏蔽掉了for循环之外的作用域
printf("3333 counter = %d\n", counter);
for (int j = 0; j < 1; j++) {
int counter = 88; // 此处counter具有块作用域,屏蔽掉了内for循环之外的作用域
printf("4444 counter = %d\n", counter);
}
}
}
int main() {
show();
return 0;
}