作者前言
有兴趣的小可爱可以来参观我的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语言就到此结束了,下面我会慢慢的一点点解释