# 变量基本概念
## 什么是变量
- 表示的数据是可以经常修改的。当一个数据的值需要经常改变或者不确定时,就应该用变量来表示。
+ 例如:游戏积分
+ 变量分为全局变量,局部变量。全局变量定义在函数外部,程序开始到结束都一直在,而局部变量定义在函数内部,只能供函数使用,在函数内部有效
## 如何定义变量
- 定义变量(声明), 任何变量在使用之前,必须先进行定义。
- 定义变量的目:在内存中分配一块存储空间给变量,方便以后存储数据。
- 如果定义了多个变量,就会为这多个变量分别分配不同的存储空间。
+ **格式1: 变量类型 变量名称 **
```
int a;
float b;
char ch;
```
+ **格式2:变量类型 变量名称,变量名称**
+ 连续定义, 多个变量之间用逗号(,)号隔开
```
int a,b;
int a,b,c,d;
```
>+ 不同类型的变量占用不同大小的存储空间。内存极其有限,分配适当的存储空间
- 变量明的命名的规范
- 变量名属于标识符,所以必须严格遵守标识符的命名原则
- 变量名要尽可能的望文知意、简洁
## 变量初始化和引用
### 如何使用变量
- 赋值就是往变量里面存点东西,就是赋值。赋值语句后带个分号;
```
int value;
value = 998; // 赋值
```
>+ 注意:这里的等号=,并不是数学中的“相等”,而是C语言中的赋值运算符,作用是将右边的常量998赋值给左边的变量value
>+ 赋值的时候,= 号的左侧必须是变量 (10=b,错)
>+ (2)规范:习惯将 = 的两侧 各加上一个 空格
### 变量的初始化
- 变量第一次赋值,可以称为“初始化”
- 初始化的两种形式
+ 先定义,后初始化
```
int value;
value = 998; // 初始化
```
+ 定义的同时进行初始化
```
int a = 10; // 完全初始化
int a, b=10; //部分初始化
int a=4, b=2;
```
+ 其它表现形式
* 批量初始化
```
int a,b,c;
a = b = c =0;
```
+ 思考: 不初始化里面存储什么?
```
int a; //不会报错,a里面存的内容:
1)随机数
2)上次程序分配的存储空间,存数一些 内容,“垃圾”
3)系统正在用的一些数据
```
### 如何修改变量值
- 可以修改变量的值,多次赋值。每次赋值都会覆盖原来的值
```
int i = 10;
i = 20; // 修改变量值
```
### 变量之间的值传递
- 可以将一个变量的值赋值给另一个变量
```
int a = 10;
int b = a;
```
- 连续赋值
```
int a,b,c;
a = b = c = 0;
```
---
### 如何查看变量的值
- 使用`printf`输出一个/多个变量的值
```
int a = 10, c = 11;
printf("a=%d, c=%d", a, c);
```
- double\float\char的输出,格式符的一些小技巧
```
double height = 1.75;
char blood = 'A';
printf("height=%.2f, 血型是%c", height, blood);
```
## 变量的作用域
### 变量的作用域
C语言中所有变量都有自己的作用域,申明变量的类型不同,其作用域也不同。C语言中的变 量,按照作用域的范围可分为两种, 即局部变量和全局变量。
### 局部变量
局部变量也称为内部变量。局部变量是在函数内作定义说明的。其作用域仅限于函数内(代码块), 离开该 函数后再使用这种变量是非法的。
+ 例如:
```
int main(){
int i = 998; // 作用域开始
return 0;
}// 作用域结束
```
```
int main(){
{
int i = 998; // 作用域开始
}// 作用域结束
return 0;
}
```
```
int main(){
{
{
int i = 998;// 作用域开始
}// 作用域结束
}
return 0;
}
```
- 作用域补充说明(了解):
+ 主函数中定义的变量也只能在主函数中使用,不能在其它函数中使用。同时,主函数中 也不能使用其它函数中定义的变量。因为主函数也是一个函数,它与其它函数是平行关系。
+ 形参变量是属于被调函数的局部变量,实参变量是属于主调函数的局部变量。
+ 允许在不同的函数中使用相同的变量名,它们代表不同的对象,分配不同的单元,互不 干扰,也不会发生混淆。虽然允许在不同的函数中使用相同的变量名,但是为了使程序明了易 懂,不倡在不同的函数中使用相同的变量名。
### 全局变量
- 全局变量也称为外部变量,它是在函数外部定义的变量。
### 常见错误
- 变量名相同 int a = 10; int a = 12;
- 变量的作用域不对
- 变量的创建和释放过程
- 代码块作用域 { int a = 10; }
## 变量内存分析
### 字节和地址
- 为了更好地理解变量在内存中的存储细节,先来认识一下内存中的“字节”和“地址”。
- 内存以“字节为单位”
### 变量的存储
- 一个变量所占用的存储空间,不仅跟变量类型有关,而且还跟编译器环境有关系。同一种类型的变量,在不同编译器环境下所占用的存储空间又是不一样的
+ 所占用字节数跟类型有关,也跟编译器环境有关
+ **内存由大到小寻址**
+ 变量存储单元的第一个字节的地址就是该变量的地址
+ 任何变量在内存中都是以二进制的形式存储。一个负数的二进制形式,其实就是对它的正数的二进制形式进行取反后再+1。(取反的意思就是0变1、1变0)
|类型|16位编译器|32位编译器|64位编译器|
|--|--|--|--|
|char|1|1|1|
|int|2|4|4|
|float|4|4|4|
|double|8|8|8|
|short|2|2|2|
|long|4|4|8|
|long long|8|8|8|
|void*|2|4|8|
- 内存寻址示例
```
#include <stdio.h>
int main(int argc, const char * argv[]) {
// 内存寻址从大到小,如果按照这种规则,那么先定义的遍历内存地址一定大于后定义的变量
int number = 0;
int value = 0;
// 获得变量的详细地址(变量地址,16进制)'&变量名'
printf("%p\n",&number); // 0x7fff5fbff6ec
printf("%p\n",&value); // 0x7fff5fbff6e8
return 0;
}
```
### 取值范围
- 不同数据类型所占的存储空间是不一样的,字节长度不一样,包含的二进制位数就不一样,能表示的数据范围也就不一样
- 如果赋值的时候超出了变量的取值范围,那么将损失精度,得到“垃圾数据”(“垃圾数据”就是指并非我们想要的数据)
|关键字|所占字节数|表示范围|
|--|--|--|--|
|int|4|-2(31) ~ 2(31)-1|
|signed short int|2|-2(15) ~ 2(15)-1|
|signed long int|4|-2(31) ~ 2(31)-1|
|unsigned int|4|0 ~ 2(32)-1|
|unsigned short int|2|0 ~ 2(16)-1|
|unsigned long int|4|0 ~ 2(32)-1|
|float|4|绝对值E-37 ~ E+38|
|double|8|绝对值E-307 ~ E+308|