作者前言
有兴趣的小可爱可以来参观我的giteehttps://gitee.com/qin-laoda
目录
内存的大概划分
插播二:
在VScode中 ,每个.c文件的运行都是单独的经过编译器处理的
关键字
extern float for goto if int long register return short signed
sizeof static struct switch typedef union unsigned void volatile while
auto(使局部变量自动创建与自动销毁)
#include <stdio.h>
int main()
{
auto int a = 0;
int b = 0;
return 0;
}
其实在定义局部变量的时候我们只是省略了auto
关键字 typedef
代码:
#include <stdio.h>
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 <stdio.h>
//没有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 <stdio.h>
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修饰的全局变量会把全局变量的外部链接属性变成内部链接属性(就是全局变量不能跨文件使用,只能在自己的.c文件使用),注意存储的地方还是静态区,加了static修饰的全局变量只是告诉编译器 "这个全局变量你只能在自己的,c文件使用,,不能乱跑"
可以理解为改变了作用域
static修饰函数
可以看出函数也是有外部链接属性,可以跨文件使用
当我们利用static修饰函数时
可以看出其实被static修饰的函数会把函数的外部链接属性变成内部链接属性(就是全局变量不能跨文件使用,只能在自己的.c文件使用)
#define 定义常量和宏
我们前面回顾一下常量的定义
字面常量
#define定义常量
const修饰常变量
枚举常量(enum)
#include <stdio.h>
//定义标识符常量
#define M 100
#define CH 'g'
//
int main()
{
printf("M=%d\n", M);
printf("CH=%c\n", CH);
return 0;
}
#define定义宏
宏可以有参数也可以无参数,宏是替换的
代码:
#include <stdio.h>
//宏
#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 <stdio.h>
int main()
{
int a = 10;
return 0;
}
如果是多个内存储存一个变量,只会显示第一个内存的指针,因为我们可以通过运算算出其他指针
指针变量
代码:
#include <stdio.h>
int main()
{
int a = 10;
//指针变量
int* p = &a;//0x007AFBA8---内存的编号==地址==指针
//*说明p为指针变量
//int 是说明p指向的是int 类型的变量
*p;//*解引用操作符 ,通过地址找到所指向的对象,即a *pa==a
printf("%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 <stdio.h>
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 <stdio.h>
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;
}
结果:
结构体变量.结构体成员
结构体地址->结构体成员
(*结构体地址).结构体成员文章来源:https://www.toymoban.com/news/detail-500899.html
总结
以上就是我所分享的内容,有不理解的小可爱可以来私聊我,这初识C语言就到此结束了,下面我会慢慢的一点点解释文章来源地址https://www.toymoban.com/news/detail-500899.html
到了这里,关于C语言第四课--------要我们一起快乐的学习吧的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!