内存分区
堆区、栈区、全局区、文字常量区、代码区
- 1.堆区:
malloc
、calloc
、realloc
、free
操作,可读可写; - 2.栈区:局部变量、函数形参、返回值 、可读可写
- 3.全局区:全部变量、静态局部变量、静态全局变量 、可读可写;
- 4.文字常量区:常量、字符常量、字符串常量 只读
- 5.代码区:代码的二进制指令 只读
宏函数(空间换时间
) #define
销毁宏undef
#define Uli(a,b) a*b
#define Uli2(a,b) (a)*(b)
Uli(5+2,2+2)=(5+2*2+2)=11
Uli2(5+2,2+2)=((5+2)*(2+2))=28
Uli(Uli(5+2,2+2),Uli2(5+2,2+2))=(5+2*2+2*(5+2)*(2+2))=65//注意此处计算是不能统一计算需要展开
注意:宏函数定义带括号跟不带括号的区别,计算方式也是不同的
- 带参的宏 在预处理时展开 有大量的重复代码(占空间)没有函数调用带来的出入栈测开销(时间)用空间换时间
- 宏的参数没有时间类型 不能保证参数的完整性
- 宏没有作用域的限制,不能作为结构体或者类的成员 (重点)
函数(时间换空间
)
- 函数调用 需要出入栈的开销时间,代码只有一份节约空间,时间换空间
- 函数的参数有类型 ,可以保证参数的完整性
- 有作用域的限制 能作为结构体或者类的成员
静态区static
-
在c语言中定义静态变量的时候,会改变当前变量的生命周期,并改变变量的村粗区域,首先
局部变量
存储在栈中,全局变量存储在堆中,当你使用static进行修饰的时候,改变了变量的存储类型使之存储在静态区
中,这时的生命周期跟全局变量
的生命周期一样都是在等程序的销毁才结束,内存才回收,那么这时候的变量就可以当做全局变量来看,看以下代码
这段代码主要就是循环执行5次test方法,第一种定义变量的时候i作为局部变量
在每次函数执行完毕就直接销毁了,所以每次进入test方法都重新赋值一遍。 第二种方式在方法里面定义静态变量让其变量i
保存在静态区
生命周期同程序销毁一起,所以每次i++的值都保存了下来,直到程序结束 -
static
关键字创建的变量如果不复制默认是0,跟int
、char
这些关键字创建的变量不一样,他们创建出来的都是随机指向一个内存地址
-
static
修饰全局变量,那么这个变量只能在本源文件中使用,原本全局变量默认是具有外部链接属性的,在外部文件中使用只需要使用extern
关键字进行引入,然后同时执行两个文件就行,但是使用了static进行修饰的时候,让其变为只具备内部链接属性
在进行比对不难发现外部定义的变量不能使用了,外部函数
同样也是这种效果,我就不展示