内存分区基础内容看这C++核心编程
数据区/全局区
分为静态数据区,常量区,全局变量区
即static,const修饰的变量,常量,全局变量都定义在此区
此区定义的变量若没有初始化会自动初始化为0
代码区
栈区
编译器自动分配的一块内存,定义局部变量都定义在此区,由编译器负责分配和释放
栈区详解:
栈,从数据结构的角度看是线性表,是操作受限的线性表
栈(stack):仅能在表尾进行插入或删除
栈顶(top):表的尾端
栈底(botton):表的头端
不含任何元素的栈叫做空栈
栈的基础操作
//对栈的基础操作
#include <iostream>
using namespace std;
#pragma warning(disable:4996)
#define SIZE 50//栈的大小
struct SeqStack
{
int data[SIZE + 1];//数据元素
int top; //栈顶
};
//初始化栈 :1).给栈申请空间 2).初始化栈顶为0
struct SeqStack* Init()
{
struct SeqStack* p = (struct SeqStack*)malloc(sizeof(struct SeqStack));
if (p)
{
p->top = 0; //设置栈顶为0
return p; //指向栈的指针
}
return NULL;
}
//释放栈'
void Free(struct SeqStack* s)
{
if (s)
free(s);
}
//判断栈满
int IsFull(struct SeqStack* s)
{
return(s->top == SIZE);
}
//入栈
int Push(struct SeqStack* s, int in_data)
{
if (IsFull(s))
{
cout << "栈溢出!" << endl;
return 0;
}
s->data[++s->top] = in_data; //将元素入栈
return 1;
}
//判断栈空
int IsEmpty(struct SeqStack* s)
{
return (s->top == 0);
}
//出栈
int Pop(struct SeqStack* s)
{
if (IsEmpty(s))
{
cout << "栈空!" << endl;
return 0;
}
return (s->data[s->top--]); //出栈
}
//获取栈顶元素值
int GetTop(struct SeqStack* s)
{
if (IsEmpty(s))
{
cout << "栈空!" << endl;
return 0;
}
return (s->data[s->top]); //出栈
}
//清空栈
void Clear(struct SeqStack* s)
{
s->top = 0;
}
int main()
{
struct SeqStack* s = Init();
int data;
cout << "入栈操作:" << endl;
for (int i = 1; i <= 3; i++)
{
cout << "输入整数:";
cin >> data;
Push(s, data);
}
cout << "获取栈顶元素" << endl;
cout << GetTop(s) << endl;
for (int i = 1; i <= 2; i++)
{
cout << "出栈操作:" << endl;
cout << Pop(s) << endl;
}
cout << "判断栈是否为空操作:" << endl;
if (IsEmpty(s))
cout << "栈空" << endl;
else
cout << "栈非空" << endl;
cout << "清空栈操作:" << endl;
Clear(s);
cout << "判断栈是否为空操作:" << endl;
if (IsEmpty(s))
cout << "栈空" << endl;
else
cout << "栈非空" << endl;
Free(s); //释放栈
return 0;
}
1.顺序队列
顺序队列,利用一组连续的内存依次存放自队尾到队头的每一个元素
用顺序存储的时候,会遇到这种情况,数组并没有满,却入不了队(假溢出),原因是队头没有在数组为0的下标处
一般对于这种假溢出的情况采取循环队列(取余)
顺序队列的操作
#include <iostream>
using namespace std;
#pragma warning(disable:4996)
#define QUEUEMAX 50 //栈的大小
//定义队列的数据类型
struct CycQueue
{
int data[QUEUEMAX];
int head; //队头
int tail; //队尾
};
//对队列初始化 :分配内存
struct CycQueue* CycQueueInit()
{
struct CycQueue* q = (struct CycQueue*)malloc(sizeof(struct CycQueue));
if (q)
{
q->head = 0;
q->tail = 0;
return q;
}
return NULL;
}
//对队列进行释放
void CycQueueFree(struct CycQueue* q)
{
if (q)
free(q);
}
//判断队满
int CycQueueIsFull(struct CycQueue* q)
{
return ((q->tail + 1) % QUEUEMAX == q->head);
}
//入队
int CycQueueIn(struct CycQueue* q, int data)
{
//判断队是否为满
if (CycQueueIsFull(q))
{
cout << "队列已满!" << endl;
return 0;
}
q->tail = (q->tail + 1) % QUEUEMAX;
q->data[q->tail] = data;
}
//判断队空
int CycQueueIsEmpty(struct CycQueue* q)
{
return (q->head == q->tail);
}
//出队
int* CycQueueOut(struct CycQueue* q)
{
//判断队是否为空
if (CycQueueIsEmpty(q))
{
cout << "队列为空!" << endl;
return NULL;
}
q->head = q->head + 1;
return &(q->data[q->head]);
}
//获取队头元素值
//获取队列长度
int CycQueueLen(struct CycQueue* q)
{
int n;
n = q->tail - q->head;
if (n < 0)
n = QUEUEMAX + n;
return n;
}
int main()
{
return 0;
}
2.链队
练习:
栈区进制转换练习
对于输入的任意一个非负十进制整数,打印输出与其等值的八进制数,利用栈实现
练习的是对出入栈的理解
123
#include <iostream>
using namespace std;
#pragma warning(disable:4996)
#define SIZE 50 //栈的大小
struct SeqStack
{
int data[SIZE + 1]; //数据元素
int top; //栈顶
};
//初始化栈 :1).给栈申请空间 2).初始化栈顶为0
struct SeqStack* Init()
{
struct SeqStack* p = (struct SeqStack*)malloc(sizeof(struct SeqStack));
if (p)
{
p->top = 0; //设置栈顶为0
return p; //指向栈的指针
}
return NULL;
}
//释放栈
void Free(struct SeqStack* s)
{
if (s)
free(s);
}
//判断栈满
int IsFull(struct SeqStack* s)
{
return(s->top == SIZE);
}
//入栈
int Push(struct SeqStack* s, int in_data)
{
if (IsFull(s))
{
cout << "栈溢出!" << endl;
return 0;
}
s->data[++s->top] = in_data; //将元素入栈
return 1;
}
//判断栈空
int IsEmpty(struct SeqStack* s)
{
return (s->top == 0);
}
//出栈
int Pop(struct SeqStack* s)
{
if (IsEmpty(s))
{
cout << "栈空!" << endl;
return 0;
}
return (s->data[s->top--]); //出栈
}
//获取栈顶元素值
int GetTop(struct SeqStack* s)
{
if (IsEmpty(s))
{
cout << "栈空!" << endl;
return 0;
}
return (s->data[s->top]); //出栈
}
//清空栈
void Clear(struct SeqStack* s)
{
s->top = 0;
}
//进制转换
void Conversion(int i)
{
struct SeqStack* s = Init();
while (i)
{
Push(s, i % 8);
i = i / 8;
}
while (!IsEmpty(s))
{
cout << Pop(s);
}
}
int main()
{
int i = 39;
cout << "将十进制转换成八进制:";
Conversion(i);
return 0;
}
堆区
用来手动分配的一块内存
通过malloc()/calloc()/recalloc()/new()
来分配内存,由free()/delete()
来释放
函数原型:(void *)malloc(int size)
原理:
通过malloc在堆上分配size个字节的内存
成功,则返回该内存的起始地址,默认为void 型
失败,则返回NULL
例:`char p=(char )malloc(100)`
*手动释放内存:free(p);
p=NULL;
释放p所指向的那块内存,这里虽然是把p所指向的那块内存释放掉了,但是内存还在,p代表的地址还在,只是我们不能再访问它,它的控制权交还给系统了
练习
手动分配一块内存给学生,输入学生的个人基本信息并打印出来
char的使用看字符串
char写法
//char写法:结构体最好用char,不要用string,string可以用在类里
#include<iostream>
using namespace std;
struct Student
{
int m_Id;
char m_Name[20];
int m_Age;
};
void test01()
{
struct Student* stu = (struct Student*)malloc(sizeof(struct Student));
stu->m_Age = 10;
stu->m_Id = 20;
strcpy(stu->m_Name , "Tom");//用char的常用函数来赋值不能直接等号
cout << "学号:" << stu->m_Id << endl
<< "姓名:" << stu->m_Name << endl
<< "年龄:" << stu->m_Age << endl;
}
int main()
{
test01();
return 0;
}
string写法
//string写法:用string不能用malloc来开辟堆区,要用new因为new和string是c++的语法,malloc是c的语法,不能两者混用
#include<iostream>
#include<string>
using namespace std;
struct Student
{
int m_Id;
string m_Name;
int m_Age;
};
void test01()
{
struct Student* stu = new(struct Student);
stu->m_Age = 10;
stu->m_Id = 20;
stu->m_Name = "Tom";
cout << "学号:" << stu->m_Id << endl
<< "姓名:" << stu->m_Name << endl
<< "年龄:" << stu->m_Age << endl;
}
int main()
{
test01();
return 0;
}