内存分区基础内容看这C++核心编程

数据区/全局区

分为静态数据区,常量区,全局变量区
即static,const修饰的变量,常量,全局变量都定义在此区
此区定义的变量若没有初始化会自动初始化为0

代码区

存放程序中的代码,函数代码,函数名就是这个函数的地址

栈区

编译器自动分配的一块内存,定义局部变量都定义在此区,由编译器负责分配和释放

栈区详解:

栈,从数据结构的角度看是线性表,是操作受限的线性表
栈(stack):仅能在表尾进行插入或删除
栈顶(top):表的尾端
栈底(botton):表的头端
不含任何元素的栈叫做空栈

栈的基础操作

  1. //对栈的基础操作
  2. #include <iostream>
  3. using namespace std;
  4. #pragma warning(disable:4996)
  5. #define SIZE 50//栈的大小
  6. struct SeqStack
  7. {
  8. int data[SIZE + 1];//数据元素
  9. int top; //栈顶
  10. };
  11. //初始化栈 :1).给栈申请空间 2).初始化栈顶为0
  12. struct SeqStack* Init()
  13. {
  14. struct SeqStack* p = (struct SeqStack*)malloc(sizeof(struct SeqStack));
  15. if (p)
  16. {
  17. p->top = 0; //设置栈顶为0
  18. return p; //指向栈的指针
  19. }
  20. return NULL;
  21. }
  22. //释放栈'
  23. void Free(struct SeqStack* s)
  24. {
  25. if (s)
  26. free(s);
  27. }
  28. //判断栈满
  29. int IsFull(struct SeqStack* s)
  30. {
  31. return(s->top == SIZE);
  32. }
  33. //入栈
  34. int Push(struct SeqStack* s, int in_data)
  35. {
  36. if (IsFull(s))
  37. {
  38. cout << "栈溢出!" << endl;
  39. return 0;
  40. }
  41. s->data[++s->top] = in_data; //将元素入栈
  42. return 1;
  43. }
  44. //判断栈空
  45. int IsEmpty(struct SeqStack* s)
  46. {
  47. return (s->top == 0);
  48. }
  49. //出栈
  50. int Pop(struct SeqStack* s)
  51. {
  52. if (IsEmpty(s))
  53. {
  54. cout << "栈空!" << endl;
  55. return 0;
  56. }
  57. return (s->data[s->top--]); //出栈
  58. }
  59. //获取栈顶元素值
  60. int GetTop(struct SeqStack* s)
  61. {
  62. if (IsEmpty(s))
  63. {
  64. cout << "栈空!" << endl;
  65. return 0;
  66. }
  67. return (s->data[s->top]); //出栈
  68. }
  69. //清空栈
  70. void Clear(struct SeqStack* s)
  71. {
  72. s->top = 0;
  73. }
  74. int main()
  75. {
  76. struct SeqStack* s = Init();
  77. int data;
  78. cout << "入栈操作:" << endl;
  79. for (int i = 1; i <= 3; i++)
  80. {
  81. cout << "输入整数:";
  82. cin >> data;
  83. Push(s, data);
  84. }
  85. cout << "获取栈顶元素" << endl;
  86. cout << GetTop(s) << endl;
  87. for (int i = 1; i <= 2; i++)
  88. {
  89. cout << "出栈操作:" << endl;
  90. cout << Pop(s) << endl;
  91. }
  92. cout << "判断栈是否为空操作:" << endl;
  93. if (IsEmpty(s))
  94. cout << "栈空" << endl;
  95. else
  96. cout << "栈非空" << endl;
  97. cout << "清空栈操作:" << endl;
  98. Clear(s);
  99. cout << "判断栈是否为空操作:" << endl;
  100. if (IsEmpty(s))
  101. cout << "栈空" << endl;
  102. else
  103. cout << "栈非空" << endl;
  104. Free(s); //释放栈
  105. return 0;
  106. }

1.顺序队列

顺序队列,利用一组连续的内存依次存放自队尾到队头的每一个元素
用顺序存储的时候,会遇到这种情况,数组并没有满,却入不了队(假溢出),原因是队头没有在数组为0的下标处
一般对于这种假溢出的情况采取循环队列(取余)
顺序队列的操作

  1. #include <iostream>
  2. using namespace std;
  3. #pragma warning(disable:4996)
  4. #define QUEUEMAX 50 //栈的大小
  5. //定义队列的数据类型
  6. struct CycQueue
  7. {
  8. int data[QUEUEMAX];
  9. int head; //队头
  10. int tail; //队尾
  11. };
  12. //对队列初始化 :分配内存
  13. struct CycQueue* CycQueueInit()
  14. {
  15. struct CycQueue* q = (struct CycQueue*)malloc(sizeof(struct CycQueue));
  16. if (q)
  17. {
  18. q->head = 0;
  19. q->tail = 0;
  20. return q;
  21. }
  22. return NULL;
  23. }
  24. //对队列进行释放
  25. void CycQueueFree(struct CycQueue* q)
  26. {
  27. if (q)
  28. free(q);
  29. }
  30. //判断队满
  31. int CycQueueIsFull(struct CycQueue* q)
  32. {
  33. return ((q->tail + 1) % QUEUEMAX == q->head);
  34. }
  35. //入队
  36. int CycQueueIn(struct CycQueue* q, int data)
  37. {
  38. //判断队是否为满
  39. if (CycQueueIsFull(q))
  40. {
  41. cout << "队列已满!" << endl;
  42. return 0;
  43. }
  44. q->tail = (q->tail + 1) % QUEUEMAX;
  45. q->data[q->tail] = data;
  46. }
  47. //判断队空
  48. int CycQueueIsEmpty(struct CycQueue* q)
  49. {
  50. return (q->head == q->tail);
  51. }
  52. //出队
  53. int* CycQueueOut(struct CycQueue* q)
  54. {
  55. //判断队是否为空
  56. if (CycQueueIsEmpty(q))
  57. {
  58. cout << "队列为空!" << endl;
  59. return NULL;
  60. }
  61. q->head = q->head + 1;
  62. return &(q->data[q->head]);
  63. }
  64. //获取队头元素值
  65. //获取队列长度
  66. int CycQueueLen(struct CycQueue* q)
  67. {
  68. int n;
  69. n = q->tail - q->head;
  70. if (n < 0)
  71. n = QUEUEMAX + n;
  72. return n;
  73. }
  74. int main()
  75. {
  76. return 0;
  77. }

2.链队

练习:

栈区进制转换练习

对于输入的任意一个非负十进制整数,打印输出与其等值的八进制数,利用栈实现
练习的是对出入栈的理解
123

  1. #include <iostream>
  2. using namespace std;
  3. #pragma warning(disable:4996)
  4. #define SIZE 50 //栈的大小
  5. struct SeqStack
  6. {
  7. int data[SIZE + 1]; //数据元素
  8. int top; //栈顶
  9. };
  10. //初始化栈 :1).给栈申请空间 2).初始化栈顶为0
  11. struct SeqStack* Init()
  12. {
  13. struct SeqStack* p = (struct SeqStack*)malloc(sizeof(struct SeqStack));
  14. if (p)
  15. {
  16. p->top = 0; //设置栈顶为0
  17. return p; //指向栈的指针
  18. }
  19. return NULL;
  20. }
  21. //释放栈
  22. void Free(struct SeqStack* s)
  23. {
  24. if (s)
  25. free(s);
  26. }
  27. //判断栈满
  28. int IsFull(struct SeqStack* s)
  29. {
  30. return(s->top == SIZE);
  31. }
  32. //入栈
  33. int Push(struct SeqStack* s, int in_data)
  34. {
  35. if (IsFull(s))
  36. {
  37. cout << "栈溢出!" << endl;
  38. return 0;
  39. }
  40. s->data[++s->top] = in_data; //将元素入栈
  41. return 1;
  42. }
  43. //判断栈空
  44. int IsEmpty(struct SeqStack* s)
  45. {
  46. return (s->top == 0);
  47. }
  48. //出栈
  49. int Pop(struct SeqStack* s)
  50. {
  51. if (IsEmpty(s))
  52. {
  53. cout << "栈空!" << endl;
  54. return 0;
  55. }
  56. return (s->data[s->top--]); //出栈
  57. }
  58. //获取栈顶元素值
  59. int GetTop(struct SeqStack* s)
  60. {
  61. if (IsEmpty(s))
  62. {
  63. cout << "栈空!" << endl;
  64. return 0;
  65. }
  66. return (s->data[s->top]); //出栈
  67. }
  68. //清空栈
  69. void Clear(struct SeqStack* s)
  70. {
  71. s->top = 0;
  72. }
  73. //进制转换
  74. void Conversion(int i)
  75. {
  76. struct SeqStack* s = Init();
  77. while (i)
  78. {
  79. Push(s, i % 8);
  80. i = i / 8;
  81. }
  82. while (!IsEmpty(s))
  83. {
  84. cout << Pop(s);
  85. }
  86. }
  87. int main()
  88. {
  89. int i = 39;
  90. cout << "将十进制转换成八进制:";
  91. Conversion(i);
  92. return 0;
  93. }

堆区

用来手动分配的一块内存
通过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;
}