C语言进阶之堆栈

栈, 是硬件, 主要作用表现为一种数据结构, 是只能在一端(栈顶, 另一端为栈底)插入和删除数据的特殊线性表, 在计算机系统的动态内存区域.

关于栈, 有后进先出/先进后出两个说法, 其实都是正确的, 只是关注点不一样, 一个是后入栈的数据, 一个是先入栈的数据. 根据栈的特性, 后入栈的数据总在先入栈的数据上方, 因为栈仅有一个口(出口和入口是统一的), 先入栈的数据要出栈的话, 就必须把在这之后的数据全部出栈. 有点类似从羽毛球桶里面取球和放球的操作, 当然, 另一头是封死的.

从书中看到, “压栈的操作使栈顶的地址减小,弹出的操作使栈顶的地址增大”, 这句是存疑的. 也就是说栈的数据从高地址向低地址的走向, 但是现在是虚拟内存地址, 总感觉这里怪怪的, 栈顶的走向应该体系架构相关的.

堆, 是一种动态存储结构, 实际上就是数据段中的自由存储区, 常常用于存储、分配动态数据.

堆中存入的数据地址向增加方向变动. 关于堆, 有先进先出的特性, 也就是一边是入口, 一边是出口, 像管道一样, 两头通, 只是限制每头的入和出. 堆内存通常malloc() , calloc(), realloc()三个函数来分配, 使用free()释放.

#include <stdio.h>
#include <stdlib.h>

int main() {
    char *a;
    char *b;
    char *c;
    a = (char *)malloc(sizeof(char));
    b = (char *)malloc(sizeof(char));
    c = (char *)malloc(sizeof(char));
    printf("%p\n", a); // 0x55a165fba2a0
    printf("%p\n", b); // 0x55a165fba2c0
    printf("%p\n", c); // 0x55a165fba2e0
    return 0;
}

就实际输出来看(可能这里显示是虚拟内存地址), 这堆内存的分配是从低地址向高地址进行的. 还句话来说, 堆和栈的生长方向相反的, 栈向低地址方向生长, 而堆向高地址方向生长.

由于这里不懂汇编, 只能从C中的树组打印出来的地址观察一下, 栈的生长方向, 首先需要说一下, 树组的压栈顺序是从右到左.

#include <stdio.h>

int main() {
    int a[] = {1, 2, 3, 4,5 ,66};
    for (int i = 0; i < 6; ++i) {
        printf("%p\n", &a[i]);
        // 0x7fffab21b330
        // 0x7fffab21b334
        // 0x7fffab21b338
        // 0x7fffab21b33c
        // 0x7fffab21b340
        // 0x7fffab21b344
    }
    return 0;
}

从右到左, 在输出中, 从下到上, 确实是从高地址到低地址生长的.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值