路边的茶楼 人影错落
街上传来 两三声吆喝
人前摇扇 醒木拍桌
各位看官 你细听分说
目录
关键字 static
各位客官,许久未见,
温壶热茶,先看这段:
1. static 修饰局部变量
#include<stdio.h> void test() { int n = 1; n++; printf("%d ", n); } int main() { int i = 0; while (i < 10) { test(); i++; } return 0; }
结果是什么呢?
CTRL+f5代码走起来,我们一看究竟:
这是为什么呢?我先来为大家画张图讲解一二:
//因为是局部变量,所以每次进函数创建变量n,然后出函数的时候销毁
//注意这个地方每次是新创建一个变量,并不是直接拿取上次的
接下来呢,我给大家展示一下另一段加上static的代码:
void test() { static int n = 1; n++; printf("%d ", n); } int main() { int i = 0; while (i < 10) { test(); i++; } return 0; }
CTRL+f5代码走起来,我们一看究竟:
意思就是再次进入的时候不创建变量,而是使用上次的变量,变量出函数后不销毁。
可能上面的解释,客官们还不能接受,那老头子我就再为大家伙讲解一二:
总结一下就是:
static 修饰局部变量的时候,改变了局部变量的存储类型:
本来一个局部变量是存储在栈区的,被 static 修饰的局部变量是存储在静态区的。
存储在静态区的变量出了它的作用域变量也不销毁,所以生命周期较长。
static 修饰的局部变量的生命周期和程序的生命周期一样。
2. static 修饰全局变量
各位客官注意咯,这个地方,我们为了能够讲清楚这个点,我们再创建一个文件:
全局变量有外部链接属性
那如果我们在前面加上一个 static 会发生什么呢?
static 修饰全局变量的时候,改变了全局变量的链接属性:
本来一个全局变量是具有外部链接属性的,但是被 static 修饰之后就
变成了内部链接属性。
这时 static 修饰的全局变量只能在本源文件(.c)中使用,其他文件无法再使用。
3. static 修饰函数
各位客官呢,我们先来看这一段代码:
//static修饰函数 int Add(int x, int y) { int z = x + y; return z; } int main() { int a = 0; int b = 0; scanf("%d %d", &a, &b); int sum = Add(a, b); printf("%d\n", sum); return 0; }
显而易见,我自己写的加法函数,直接就可以使用。
但是呢,有客官就要说了,那我要是不在同一个文件中呢?
CTRL+f5,代码走起来:
这里出现了一个警告!
那么我们就在这里声明一下:
结果:
//说明函数也是具有外部链接属性
这个时候就会有客官说了,那我们在他的前面加上static呢?
为什么呢?当static修饰的时候外部链接属性就开始发生变化了。
其实static修饰函数和修饰全局变量是类似的,一个函数本来也是具有外部链接属性的。
当被static修饰的时候,外部链接属性就变成了内部链接属性,这个函数就只能本源文件内部使用,其他文件不能再使用了。
#define 定义常量和宏
//#define 定义常量和宏 //define 定义常量 #define NUM 100 #define STR "hehe" int main() { printf("%d\n", NUM);//printf("%d\n", 100); printf("%s\n", STR);//printf("%s\n", "hehe"); return 0; }
CTRL+f5代码走起来:
//#define 定义宏-是有参数的 #define ADD(x,y)((x)+(y)) int main() { //printf("%d\n", NUM);//printf("%d\n", 100); //printf("%s\n", STR);//printf("%s\n", "hehe"); int a = 10; int b = 20; int sum = ADD(a, b);//int sum = (a+b); printf("%d\n", sum); return 0; }
CTRL+f5代码走起来:
指针
各位客官不要慌,指针没有想象中的那么难,并且这里我们只是提前做一个了解
要想学好内存,首先我们应该知道内存:
内存:
//内存单元有编号 (地址/指针) int main() { int a = 10; int *pa = &a;//& - 取地址 *pa = 20;//* 解引用操作符 // //指针变量是用来存放地址的一种变量 // printf("%d\n", a); char ch = 'w'; char *pc = &ch; //pa被称为指针变量 //0000 0000 0000 0000 0000 0000 0000 1010 //00 00 00 0a // return 0; }
int main() { char ch = 'a'; char* pc = &ch; *pc = 'b'; printf("%c\n", ch); return 0; }
//1. 内存会被划分为小的内存单元,一个内存单元的大小是1个字节
//2. 每个内存单元都有编号,这个编号也被称为:地址/指针
//3. 地址/指针就可以存放在一个变量中,这个变量被称为指针变量
//4. 通过指针变量中存储的地址,就能找到指针指向的空间指针变量的大小:
接下来,我们来验证一下一个指针变量占几个字节:
int main() { char ch = 'w'; int n = 100; double d = 3.14; char* pc = &ch; int* pi = &n; double* pd = &d; printf("%d\n", sizeof(pc)); printf("%d\n", sizeof(pi)); printf("%d\n", sizeof(pd)); return 0; }
CTRL+f5代码走起来:
指针变量是用来存放地址的
地址的存放需要多大空间,指针变量的大小就应该是多大。
32位机器 - 支持的32位虚拟地址空间 - 产生的地址就是32bit位 - 需要32bit的空间存储 4byte - 指针变量的大小也是4byte
64位机器 - 支持的64位虚拟地址空间 - 产生的地址就是64bit位 - 需要64bit的空间存储 8byte - 指针变量的大小也是8byte
结构体
描述一个生活中的复杂对象:
那各位客官就要问了,如何描述生活中的复杂对象呢?
需要结构体来描述
//描述一个学生 //创建的一个学生类型 struct Stu { char name[20]; int age; char sex[5]; double score; }; int main() { struct Stu s1 = { "张三",20,"男",90.5 }; struct Stu s2 = { "如花",40,"女",99.5 }; scanf("%s %d %s %lf", s1.name, &(s1.age), s1.sex, &(s1.score)); //printf("%s %d %s %lf\n", s1.name, s1.age, s1.sex, s1.score); //结构成员访问操作符 //结构体变量,结构体成员 struct Stu* ps = &s1; //printf("%s %d %s %lf\n", (*ps).name, (*ps).age, (*ps).sex, (*ps).score); printf("%s %d %s %lf\n", ps->name, ps->age, ps ->sex, ps->score); //-> 结构成员访问操作符 //结构体指针->结构体成员 // return 0; }
欲知后事如何 且听我下回分说
(江湖游历在外,还要多多仰仗各位衣食父母,方便的话点个赞,点个关注呗,谢谢你嘞,客官慢走)