常量、变量
1、常量
不能被改变的量,称为常量
(1)整型常量
1 234 0664 0XAC
(2)浮点型常量
3.14 5.19 7.52 浮点型常量用科学计数法的表示方式: 0.0001 -> 1e-4 10000 -> 1e4 浮点型常量用二进制表示: 0.25 转化成二进制 0.25 * 2 == 0.5 --> 0 0.5 * 2 == 1.0 --> 1 0.0 0.25 转化为二进制为 0.01
(3)字符型常量
'A' 'a' '\0' '\n' '+' ' ' '0' 字符型常量被单引号括起来 字符型常量的转义: \:反斜杠 /:斜杠 ' \' ' --> 表示字符单引号' ' \" ' --> 表示字符双引号" ' \\ ' --> 表示字符反斜杠\ ' \072 ' --> 表示字符冒号 : 冒号的ASCII码为58,对应八进制的072 ' \x37 ' --> 表示字符7 字符7('7')的ASCII码为55,对应十六进制的0X37
(4) 字符串常量
"hello world('\0') xxx \n" 字符串常量用双引号括起来,并且字符串结尾包含'\0' 字符串常量遇到'\0'结束 例: "hello \075 \n \0 world \x23 \\ \'"这个字符串里面包含了多少个字符 11
(5)标识符常量(宏定义)
定义在main函数上面,头文件下面 作用:在一个代码中,如果一个常量使用次数较多,则可以定义成一个标识符常量,方便修改 #define 标识符名字 表达式 在编译过程中,宏会原样展开 注意:宏定义语句结尾没有分号
#include <stdio.h> #define NUM 3+4 int main() { int a = 2 * NUM;//int a = 2 * 3 + 4; printf(" a = %d\n", a); //printf(" a = %d", a); return 0; } //输出的结果为10
2、变量
变量的定义:
可以被改变的量称之为变量,变量在内存中有自己的空间用于存储数据
定义变量就是在向系统申请一份(不确定大小,大小跟申请者有关)内存空间,并且获得该空间存储数据的权利
不能存放超过该空间大小的变量
也不能把变量存储在未申请的内存空间
定义变量的一般形式:
<存储类型> <数据类型> <标识符>;
(auto) int a;
局部变量
局部变量:被定义在一个模块中,存放于栈区,作用域小,该模块结束之后就会被释放
局部变量的初始化:
int a = 10;
局部变量未初始化:
int a;
若局部变量未初始化,则为随机值(但如果变量比较少,gcc会帮我们做出优化,默认为0)
例:
#include <stdio.h> int main(int argc, char *argv[]) { int a,b,c,d,e,f; printf("a:%d\n", a); printf("b:%d\n", b); printf("c:%d\n", c); printf("d:%d\n", d); printf("e:%d\n", e); printf("f:%d\n", f); return 0; }
全局变量
全局变量:定义在函数外部,存放于静态区,作用范围广,程序结束之后才会被释放
全局变量的初始化:
int a = 10;
全局变量未初始化
int a;
全局变量的未初始化会为0('\0')
#include <stdio.h> int a; int main(int argc, char *argv[]) { printf("a:%d\n", a);//printf("%d",a); return 0; } //int a = 10;//写在此处会报错
如果局部变量和全局变量重名,则局部变量会覆盖全局变量
标识符
标识符的命名规则
1、只能由数字、字母、下划线构成 a(√) AC(√) ___AC(√) 1_NUMBER(不行) 2、不能以数字开头 3、不能和32个关键字重名
32个关键字
数据类型: char:字符型数据 short:短整型数据 int:整型数据 long:长整型数据 float:浮点型数据 double:双精度型 存储类型: unsigned:无符号数 signed:有符号数 auto:自动存储 static:静态存储 extern:外部调用存储 register:寄存器存储 const:只读 volatile:防止被编译器优化用的 控制语句: if:条件控制语句 else:和if搭配使用 switch:开关语句 case:和switch搭配使用 default:和switch搭配使用 break:和switch搭配使用时跳出switch结构,用于循环中跳出循环 while:循环语句 do:和while搭配使用 for:循环语句 continue:用于循环中,跳过本次循环,进入下一次循环 goto:跳转指令 return:返回 构造: enum:枚举型 struct:结构体 union:联合体 空类型: void:空类型 取别名: typedef:取别名 求字节: sizeof:求字节大小
数据类型
char
字符型数据(默认为有符号数) 字节大小:1 取值范围: 无符号数的取值范围 0 ~ 255 有符号数的取值范围 -128 ~ 127
short
短整型数据(默认为有符号数) 字节大小:2 取值范围: 无符号数的取值范围: 0~2^16-1 有符号数的取值范围: -2^(16-1) ~ 2^(16-1) - 1
int
整型数据(默认为有符号数) 字节大小:4 取值范围: 无符号数的取值范围: 0~2^32-1 有符号数的取值范围: -2^(32-1)~2^(32-1)-1
long
长整型数据(默认为有符号数) 字节大小:8 取值范围 无符号数的取值范围: 0~2^64-1 有符号数的取值范围: -2^(64-1)~2^(64-1)-1
flota
浮点型数据(默认有符号位) 字节大小:4 一位存符号位 剩下的存数值位
double
双精度型数据(默认有符号位) 字节大小:8
#include <stdio.h> int main(int argc, char *argv[]) { int a = sizeof(int); int b = sizeof(char); int c = sizeof(short); int d = sizeof(long); int e = sizeof(float); int f = sizeof(double); printf("int:%d\n", a); printf("char:%d\n", b); printf("short:%d\n", c); printf("long:%d\n", d); printf("float:%d\n", e); printf("double:%d\n", f); return 0; } //运行结果为: int:4 char:1 short:2 long:8 float:4 double:8
思考:如何交换两个变量的值?
#include <stdio.h> int main(int argc, char *argv[]) { int a = 10; int b = 20; /* int c = 0; c = a; a = b; b = c; 坏处:多开辟了一个4字节的内存空间 */ /* a = a + b; b = a - b; a = a - b; 坏处:若两个数比较大,则会超出该变量的取值范围 */ a = a ^ b; b = a ^ b; a = a ^ b; //浮点数有时候不适用这种方法 printf("a:%d\n", a); printf("b:%d\n", b); return 0; }
存储类型
auto
自动存储 如果定义变量时不写存储类型,则默认进行自动存储
register
寄存器存储 有可能会因为寄存器不足而申请失败的 特点为效率高,速度快 ctrl + c 强制结束程序
#include <stdio.h> int main(int argc, char *argv[]) { int a = 0; //register int a = 0; while( a != 1000000000)//while循环 a++; return 0; }
static
静态存储 1、 static 修饰局部变量时,延长生命周期,将该局部变量存储于静态区(全局变量区),会在程序结束后被释放 #include <stdio.h> int main(int argc, char *argv[]) { int a = 0; while( a != 3) { int num = 20; num = num + 20; a++; printf("num:%d\n", num); } return 0; } //结果为 num:40 num:40 num:40 #include <stdio.h> int main(int argc, char *argv[]) { int a = 0; while( a != 3) { static int num = 20; num = num + 20; a++; printf("num:%d\n", num); } return 0; } //结果为: num:40 num:60 num:80 2、 static 修饰全局变量,限制作用域,被static修饰的全局变量只能在本文件中使用 demo10_extern.c: #include <stdio.h> extern int a; int main(int argc, char *argv[]) { printf("a:%d\n", a); return 0; } 1.c: #include <stdio.h> static int a = 20; gcc demo10_extern.c 1.c 编译会报错,找不到外部对a的定义,因为static限制了全局变量只能在本文件中使用 3、 static 修饰函数时,限制作用域,被static修饰的函数只能在本文件中使用
extern
外部调用存储 被extern修饰的变量表示该变量在其他地方定义 demo10_extern.c: #include <stdio.h> extern int a; int main(int argc, char *argv[]) { printf("a:%d\n", a); return 0; } 1.c: #include <stdio.h> int a = 20; gcc demo10_extern.c 1.c ./a.out 运行结果为: a:20
const
将变量常量化,被const修饰的变量,其内容不可修改,变成了read-only 例: #include <stdio.h> int main(int argc, char *argv[]) { const int a = 10; a = 20; return 0; } 编译时报错: demo11_const.c: In function ‘main’: demo11_const.c:12:7: error: assignment of read-only variable ‘a’ 12 | a = 20; | ^
volatile
防止代码被优化 从内存当中直接读取数据而非缓冲区
3、类型转换
隐式转换
低精度的数据 --> 高精度的数据
#include <stdio.h> int main(int argc, char *argv[]) { int a = 4; float pi = 3.14; int b = a + pi; float p = a + pi; printf("b:%d\n", b);//打印有符号十进制正数 printf("p:%f\n", p);//打印浮点型数据 return 0; } 结果为: b:7 p:7.140000
有符号数 --> 无符号数
#include <stdio.h> int main(int argc, char *argv[]) { int a = -5; unsigned int b = 4; int c = ( a > b )?1:2; printf("c:%d\n", c); unsigned int num = -5; printf("num:%u\n", num);//%u打印无符号十进制正数 return 0; } 结果为: c:1 num:4294967291
强制类型转换
(数据类型)表达式 可以将括号后面的表达式强制进行数据类型转换 浮点数转换为整型没有四舍五入的过程,小数点后面的数据直接舍弃
#include <stdio.h> int main(int argc, char *argv[]) { int a = 10; float b = 3.94; float c = a + b; printf("c:%f\n", ((int)c + 1.1 +2.2)); return 0; } 结果为: c:16.300000