作者前言

有兴趣的小可爱可以来参观我的giteehttps://gitee.com/qin-laoda

目录

关键字 typedef关键字static#define 定义常量和宏 指针结构体 ___________________________________________________________紧接上一篇博客,在上一篇博客中我简单的解释了那些关键字的意思 下面我们插播一些小知识插播一:

内存的大概划分

插播二:

在VScode中 ,每个.c文件的运行都是单独的经过编译器处理的

关键字

autobreakcasecharconstcontinuedefaultdodouble elseenum
extern floatforgotoifintlongregister returnshortsigned
sizeofstatic structswitchtypedef unionunsignedvoidvolatilewhile

auto(使局部变量自动创建与自动销毁)

代码:

#include int main(){auto int a = 0;int b = 0;return 0; }

其实在定义局部变量的时候我们只是省略了auto

关键字 typedef

代码:

#include typedef unsigned int uint;typedef int INT;int main(){unsigned int a = 0;uint b = 2;INT c = 3;printf("a=%d b=%d c=%d", a, b, c);return 0;}

结果:

可以看出typedef(类型重定义),太长的数据类型我们就需要简化

uint INT都是别名

关键字static(静态的)

有三种用法 修饰局部变量 修饰全局变量 修饰函数

下面我

来简单介绍

static 修饰局部变量

代码:

#include //没有static修饰int Add_1(){int i = 0;i += 2;return i;}//有static修饰int Add_2(){static int i = 0;i += 2;return i;}int main(){int a = 0;int b = 0;while (a < 5){int c = 0;c = Add_1();printf("c=%d\n", c);a++;}while (b < 5){int d = 0;d = Add_2();printf("d=%d\n", d);b++;}return 0;}

结果:

static int i = 0的创建是进入函数就创建好了,不是运行它才创建,往后再调用就会继续使用之前的i.不会创建新的i

我们可以查看反汇编

两者不同

查看反汇编的方法

调试到如图中的为位置

然后右击鼠标

static修饰局部变量总结:

局部变量在没有static修饰会在出函数范围就自动销毁,有static修饰的局部变量,在第一次运行函数就创建了,出函数也不会销毁,就无需再次创建,可以理解为生命周期延长了,但是作用域不变

本质:在没有static修饰的局部变量就会存放在栈区,而被static修饰的局部变量就会存放在静态区,静态区的变量的生命周期和全局变量是一样的

static修饰全局变量

第一种

代码1:

#include int a = 12;int g_val(){printf("a_val():%d\n", a);}int main(){printf("a=%d\n", a);g_val();return 0;}

结果:

第二种

可以看出全局变量有外部链接属性,这种属性决定了全局变量可以在多个文件使用

extern 声明外部符

当我们利用static修饰全局变量时

原因是啥呢” />

可以理解为改变了作用域

static修饰函数

可以看出函数也是有外部链接属性,可以跨文件使用

当我们利用static修饰函数时

可以看出其实被static修饰的函数会把函数的外部链接属性变成内部链接属性(就是全局变量不能跨文件使用,只能在自己的.c文件使用)

#define 定义常量和宏

我们前面回顾一下常量的定义

字面常量

#define定义常量

const修饰常变量

枚举常量(enum)

#include //定义标识符常量#define M 100#define CH 'g'//int main(){printf("M=%d\n", M);printf("CH=%c\n", CH);return 0;}

#define定义宏

宏可以有参数也可以无参数,宏是替换的

代码:

#include //宏#define ADD(x, y) (x+y)//函数int Add(int x, int y){return x + y;}int main(){int a = 12;int b = 13;int c = ADD(a, b);printf("c=%d", c);return 0;}

结果

指针

内存空间为了有效的进行管理:

1.把内存划分为一个个有效的内存单元(比如1个字节)

2.给每个内存单元编号==地址==指针

地址怎么来呢

图中是32位机器,就有32根地址线,一根地址线产生1个bit位,共有2^32个地址,一个地址有32位bit

注意指针大小和内存单位大小是两个不同的概念,指针大小是指针大小,内存单位大小是内存单位大小

我们还可以参考内存

代码:

#include int main(){int a = 10;return 0;}

如果是多个内存储存一个变量,只会显示第一个内存的指针,因为我们可以通过运算算出其他指针

指针变量

代码:

#include int main(){int a = 10;//指针变量int* p = &a;//0x007AFBA8---内存的编号==地址==指针//*说明p为指针变量//int 是说明p指向的是int 类型的变量*p;//*解引用操作符 ,通过地址找到所指向的对象,即a *pa==aprintf("%d", *p);return 0;}

*说明p为指针变量

int 是说明p指向的是int 类型的变量

我们创建的指针变量是放入的是一个指针(内存的编号),不是内存

指针总结:

1.内存会划分以字节为单位的内存单元

2.每个内存单元都有编号,编号==指针==地址

3.c语言中创建的变量,是向内存申请一块空间,比如int a = 12,就是向内存申请一块4个字节的内存空间,这个空间有编号

4.这个地址要存储起来创建一个指针变量,如 int* p = &a

5.p存放的是a申请空间的编号,即指针,所以叫指针变量(用于存储编号的)

6. *p通过p存放的编号找到a

注意一下:

存入指针变量的任何东西都当作指针处理

指针变量的大小

代码:

#include int main(){char* a;int* b;float* c;printf("%d\n", sizeof a);printf("%d\n", sizeof b);printf("%d\n", sizeof c);return 0;}

结果:

可以看出指针变量空间大小为4,

其实一个指针变量的空间大小是由地址线的条数决定的,一根地址线产生一个bit ,

结构体(复杂的对象)

比如 一个人:名字,身份证……..

代码:

#include struct Stu{char name[20];int age;int score;};int main(){int num = 0;struct Stu name1 = { "张三", 18, 88};struct Stu name2 = { "张以", 15, 85};struct Stu name3 = { "张地方", 10, 86};struct Stu* ps = &name1;printf("%s %d %d\n", name1.name, name1.age, name1.score);printf("%s %d %d\n", name2.name, name2.age, name2.score);printf("%s %d %d\n", name3.name, name3.age, name3.score);printf("%s %d %d\n", ps->name, ps->age, ps->score);printf("%s %d %d\n", (*ps).name, (*ps).age, (*ps).score);return 0;}

结果:

结构体变量.结构体成员

结构体地址->结构体成员

(*结构体地址).结构体成员

总结

以上就是我所分享的内容,有不理解的小可爱可以来私聊我,这初识C语言就到此结束了,下面我会慢慢的一点点解释