带你从零开始认识内存
一:程序执行需要内存的支持
对于程序来说,内存就是程序的立足之地(程序是被放在内存中运行的);程序的运行时必须要有内存来存储一些临时变量
二:内存的管理是由操作系统来完成的
(1)内存本身在物理上是一个硬件器件,有硬件系统来提供
(2)内存是由操作系统来统一管理。为了内存管理方便又合理,所以操作系统提供了很多的机制(栈、堆、数据区)来让我们程序员来使用内存。
这些机制彼此不同,各自有各自的特点,我们可以通过自己的实际情况来选择某种方式来获取内存。
三种内存来源:栈内存(stack)、堆内存(heap)、数据区(.data)
在C语言中,能够获取内存的三种方式:局部变量使用栈内存、malloc申请堆内存、数据区(一般是初始化为非零的全局变量)。
栈内存的特点:
(1)运行时由操作系统自动分配和回收:栈是自动管理的,程序员不需要手工干预方便简单。
(2)栈内存是可以反复使用的:栈内存在程序中其实就是一块地址,程序会反反复复使用那一块空间。
(3)脏内存:栈内存由于反复使用,每次使用后程序是不会去清理(就类似我们住酒店,我们住完是不需要清理的,作者为什么这样做呢,因为你永远不知道谁最后的使用者)。
(4)临时性:由于是变量是临时占用的,所有我们不能在函数中返回局部变量的指针,因为这个空间是临时的。
(5)栈溢出:因为操作系统事先给定了栈的大小,如果在函数中无限的分配栈内存总能使用完。
栈图解:
栈在C语言中的运用:
#include <stdio.h>
#define STACK_SIZE 20 //定义栈的大小
struct Stack
{
int datas[STACK_SIZE]; //栈数据的保存区;
int top; //栈顶标志位
};
// 初始化栈
void Int_Stack(struct Stack* stack)
{
stack->top = -1;
}
//清空栈内存
void Empty(struct Stack* stack)
{
stack->top = -1;
}
//判断栈是否为空
int IsEmpty(struct Stack* stack)
{
if (stack->top == -1)
{
return 1;
}
else return 0;
}
// 判断栈是否已经满
int Isfull(struct Stack* stack)
{
if (stack->top == (STACK_SIZE - 1))
{
return 1;
}
else return 0;
}
//入栈操作
int push(struct Stack* stack,int data)
{
//先判断栈是否满
if (Isfull(stack) == 1)
{
return 0;
}
//栈指针移动在赋值
stack->datas[++stack->top] = data;
return 1;
}
//出栈操作
int pop(struct Stack* stack, int* data)
{
//判断栈是否为空
if(IsEmpty(stack) == 1)
{
return 0;
}
*data = stack->datas[stack->top--];
return 1;
}
//读栈操作
int getTOP(struct Stack* stack, int* data)
{
//判断栈是否为空
if (IsEmpty(stack) == 1)
{
return 0;
}
*data = stack->datas[stack->top];
return 1;
}
//输出栈的内容
int printStack(struct Stack* stack)
{
int i = 0;
//判断栈是否为空
if (IsEmpty(stack) == 1)
{
printf("当前是个空栈!\n");
return 0;
}
printf("当前栈的内容如下:\n");
//遍历栈
for (i = stack->top; i > -1; i--)
{
printf("[%d]:%d\n", i, stack->datas[i]);
}
printf("==================END==================\n");
}
int main(void)
{
int data ; //出栈值
struct Stack stack;
Int_Stack(&stack); //输入值为栈地址,初始化栈
//压栈,也就是写入数据
for (int i = 0; i <= 10; i++)
{
push(&stack, i * 10); //向栈中写入数据
}
printStack(&stack);
//出栈操作
for (int i = 0; i < 4; i++)
{
pop(&stack, &data);
}
printStack(&stack);
return 0;
}