16.关键字
关于static
1.static修饰局部变量
//1. void test() { int a = 1; a++; printf("%d ", a); } int main() { int i = 0; while (i < 10) { test(); i++; } return 0; } //每次调用test函数,为a变量创建空间,出test函数后,a被销毁。每次进入函数都初始化为1. 所以打印10个2 2.加上static修饰后 void test() { static int a = 1; a++; printf("%d ", a); } int main() { int i = 0; while (i < 10) { test(); i++; } return 0; } //打印2-11 //static修饰的变量放到静态区,出了test函数也不销毁,变量a的生命周期和程序的生命周期一样 ,但a仍是局部变量。 只是改变了a的生命周期,并没有改变作用域 复制代码
2.static修饰全局变量
3.static修饰外部变量
add.c文件: int g_val = 2021; test.c文件 extern int g_val; //声明了外部符号,会产生链接 int main() { printf("%d\n",g_val); //2021 g_val = 2022; printf("%d\n",g_val); //2022 return 0; } 复制代码
//使用static修饰后 add.c文件: static int g_val = 2021; test.c文件 extern int g_val; //加了static修饰后,失去外部链接属性 int main() { printf("%d\n",g_val); //错误 g_val = 2022; printf("%d\n",g_val); return 0; } 复制代码
.static修饰外部变量注意事项:
使用static修饰外部变量时时,即使声明了,也不能使用
默认一个全局变量具有【外部】链接属性的,而如果全局变量被static修饰,会使全局变量的外部链接属性变成了内部链接属性,这个时候这个全局变量只能在本源文件内部使用,其他源文件无法链接到,也无法使用
4.static修饰函数
//函数也具有外部链接属性 add.c文件 int Add(int x,int y) { return x+y; } test.c文件 extern int Add(int x,int y); int main() { int a = 10; int b = 20; int c = Add(a,b); printf("%d\n",c); //30 } 复制代码
//使用static修饰后,不能被外部使用 add.c文件 static int Add(int x,int y) { return x+y; } test.c文件 extern int Add(int x,int y); int main() { int a = 10; int b = 20; int c = Add(a,b); //err printf("%d\n",c); } 复制代码
static修饰外部函数注意事项
函数也具有外部链接属性,如果被static修饰,外部链接属性就变成了内部链接属性,使函数只能在自己的源文件内部使用,不能被其他源文件内部使用
17.一个程序可以有多个.c文件,但多个.c文件只能有一个主函数
18.#define定义表达式和符号
定义符号:#define NUM 100
定义宏:#define MAX(X,Y) (X>Y?X:Y) MAX是宏的名字 X,Y是宏的参数,(X>Y?X:Y)是宏体
#define NUM 100 #define MAX(X,Y) (X>Y?X:Y) //取最大的值 int main() { printf("%d\n",NUM); //100 int a = 10; int b = 20; int c =MAX(a,b); //c为a,b的较大者 //等价替换 相当于 //int c = (a > b ? a : b); printf("%d\n",c); return 0; } 复制代码
19.想要查看文件的后缀名
20.为什么一个内存单元是一个字节
对于32位机器:有32根地址线 (每一根都为1 或者 0)
共有2^32种组成
从00000000 00000000 00000000 00000000
到11111111 11111111 11111111 11111111
->共有2^32次方个地址,每个地址线管理一个内存单元(1个字节)
若一个内存单元是一个比特位 2^32 bit =4,294,967,296bit 除 8 -> 536,870,912byte 字节 ->除1024 -> 524,288kb ->除1024 -> 512MB ->除1024 ->0.5GB 这样的话,1.过于浪费地址, 2.只能管理0.5GB的空间,空间太小,不合适 复制代码
若一个内存单元是一个字节 1字节 = 8比特位 则能管理0.5*8 = 4GB的空间 复制代码
21.指针
因为地址可以找到(指向)这块空间,所以把地址也称为指针
int* pa = &a // *:表示pa是指针变量 int :表示pa指向的对象a是int类型 复制代码
&p :取出的是低地址位置
%p:以16进制打印地址
pa的值为20:对于的16进制为 0X00000014
此处的%p 只是以地址的形式打印,打印的还是里面的值20,把那个值当成地址打印,%p:十六进制形式打印
pa是指针变量 *pa是指针指向的对象 ->a
指针变量是用来存放地址的,地址是几个字节,指针变量就是几个字节
32位机器:有32根地址线, 32个0或1排列组合 ,共32位->4个字节
22.结构体
用来描述复杂对象、复杂类型
例如:学生:名字。年龄,性别,身高
书:书名,作者,出版社,书号,定价
struct Student { char name[20]; int age; char sex[5]; }; int main() { //方法1:结构体变量 // .操作符 访问方法1 :结构体变量.成员名 struct Student s = {"张三",15,"MALE"}; printf("名字:%s 年龄:%d 性别:%s\n",s.name,s.age,s.sex); //方法2:结构体指针变量 struct Student b = {"张三",15,"MALE"}; struct Student * pb = &b; //访问方法2:解引用结构体指针变量.成员名 printf("名字:%s 年龄:%d 性别:%s\n",(*pb).name,(*pb).age,(*pb).sex); //访问方法3:结构体指针->成员名 printf("名字:%s 年龄:%d 性别:%s\n",pb->name,pb->age,pb->sex); return 0; }