查找栈的增长方向的分析及C代码实现

对于栈这种数据结构,大家应该不会陌生,它是一种后进先出的数据结构。在一般的计算机系统中,栈存在着两种存放数据的方式,一种是向上增长的,一种是向下增长的,如图1所示。

图1 栈的两种增长方向

在图1的(a)中,栈是向上增长的,即数据A对应的地址小于数据B对应的地址;在图1的(b)中,栈是向下增长的,即数据A对应的地址大于数据B对应的地址。

那么,我们怎样来查看(最好用程序)自己所使用的系统中的栈的增长方向到底属于哪一种呢?(注:这是我偶然在网上看到的一个问题。)

我们知道,作为一种常用的数据结构,栈主要用于存放程序中的局部变量和函数的输入参数。那么,我们就可以设计一个程序,在程序中通过比较某一个局部变量的前后两次的地址值来判断栈的增长方向。利用这个想法编写出来的程序如下所示:

/**********************************************************************
* 版权所有 (C)2015, Zhou Zhaoxiong。
*
* 文件名称:FindStackDirection.c
* 文件标识:无
* 内容摘要:查看栈的增长方向
* 其它说明:无
* 当前版本:V1.0
* 作    者:Zhou Zhaoxiong
* 完成日期:20151202
*
**********************************************************************/
#include <stdio.h>

// 重定义数据类型
typedef unsigned char  UINT8;
typedef signed   int   INT32;

// 函数声明
void FindStackDirection(void);

/**********************************************************************
* 功能描述:主函数
* 输入参数:无
* 输出参数:无
* 返 回 值:无
* 其它说明:无
* 修改日期        版本号      修改人              修改内容
* ---------------------------------------------------------------
* 20151202        V1.0     Zhou Zhaoxiong          创建
***********************************************************************/
INT32 main()
{
    FindStackDirection();

    return 0;
}

/**********************************************************************
* 功能描述:查找栈增长方向
* 输入参数:无
* 输出参数:无
* 返 回 值:无
* 其它说明:无
* 修改日期        版本号      修改人              修改内容
* ---------------------------------------------------------------
* 20151202        V1.0     Zhou Zhaoxiong          创建
***********************************************************************/
void FindStackDirection(void)
{
    UINT8  iStackAddr        = 0;        // 用于获取栈地址
    static UINT8 *pStackAddr = NULL;     // 用于存放第一个iStackAddr的地址 

    if (pStackAddr == NULL)              // 第一次进入
    {
        pStackAddr = &iStackAddr;        // 保存iStackAddr的地址
        FindStackDirection();            // 递归
    }
    else                                 // 第二次进入
    {
        if (&iStackAddr > pStackAddr)        // 第二次iStackDirection的地址大于第一次iStackDirection, 那么说明栈增长方向是向上的
        {
            printf("Stack grows up!\n");
        }
        else if (&iStackAddr < pStackAddr)   // 第二次iStackDirection的地址小于第一次iStackDirection, 那么说明栈增长方向是向下的
        {
            printf("Stack grows down!\n");
        }
        else
        {
            printf("Bad stack!\n");
        }
    }
} 

我们可以看到,函数FindStackDirection中出现了递归调用,即首次进入该函数的时候,将iStackAddr变量(局部变量)的地址值赋给pStackAddr,第二次进入该函数的时候,用新的iStackAddr变量的地址值与第一次进入该函数时iStackAddr变量的地址值相比较,如果前者大于后者,那么说明栈增长方向是向上的,否则,说明栈增长方向是向下的。

将以上代码上传到Linux机器上,使用“gcc -g -o FindStackDirection FindStackDirection.c”命令对程序进行编译之后,运行“FindStackDirection”命令,结果如下:

Stack grows down!

即我所使用的系统中的栈的增长方向是向下的。大家也可以将以上代码在自己的系统中运行一下,看看结果是什么。

在大部分人(包括我)的印象中,栈的增长方向只有一种,那就是向上(如图1中的(a)),但程序运行出来的结果与我们预期的恰恰相反。从这点也可以看出,计算机系统在设计上的精妙与复杂,里面有很多东西都值得我们细细研究的。

原文中的代码已提到了GitHub上,欢迎下载阅读:https://github.com/zhouzxi/FindStackDirection

时间: 2024-09-22 01:26:26

查找栈的增长方向的分析及C代码实现的相关文章

内存管理-堆、栈的地址高低? 栈的增长方向?

问题描述 堆.栈的地址高低? 栈的增长方向? 程序员的自我修养>说栈的地址比堆高,栈是向下增长的,堆是向上增长的. #include #include int main(){using namespace std;double a0[4] = {1.2 2.4 3.6 4.8};double a1[4] = {1.2 2.4 3.6 4.8};vector a2(4);vector a3(4);a2[0] = 1.0/3.0;a2[1] = 1.0/5.0;a2[2] = 1.0/7.0;a2[

判断栈的增长方向

  dreamhead老大曾经讨论过这个问题,寻找一种可移植的方式来判断栈的增长方向,见<栈的增长方向>.今天在读Ruby hacking guide第5章,介绍alloca函数的部分,提到ruby实现的C语言版本的alloca.c,读了下代码,发现这里倒是实现了一个很漂亮的函数用于实现判断栈的增长方向,利用了局部static变量,与dreamhead老大的想法其实是一致的. #include<stdio.h>static void find_stack_direction(voi

嵌入式开发-嵌入式的底层驱动方向和上层应用方向的分析

问题描述 嵌入式的底层驱动方向和上层应用方向的分析 刚刚得到帮助了解了方向,觉得搞嵌入式软件这两个方向其中之一,还是想进一步了解两者,以及两者的区别和学习内容,如果可以,给小弟提一点建议,谢谢 解决方案 底层驱动的技术要求比应用高,可以从应用入手,再掌握驱动之类的底层开发 解决方案二: 嵌入式行业新人系列之一 - 如何选择自己的嵌入式开发方向? 嵌入式开发联盟-www.mcuos.com Osboy原创:qq:82475491mcuos.com@gmail.com 废话不多说.首先声明osboy

linux内核中打印栈回溯信息 - dump_stack()函数分析【转】

转自:http://blog.csdn.net/jasonchen_gbd/article/details/45585133 版权声明:本文为博主原创文章,转载请附上原博链接.   目录(?)[-] 简介 相关基本知识 关键寄存器介绍 内核中的函数栈 dump_stack函数   简介 当内核出现比较严重的错误时,例如发生Oops错误或者内核认为系统运行状态异常,内核就会打印出当前进程的栈回溯信息,其中包含当前执行代码的位置以及相邻的指令.产生错误的原因.关键寄存器的值以及函数调用关系等信息,这

从网站内容方向来分析网编与SEO的关系

摘要: 网编是做SEO的必经之路吗?身边多数seo朋友多说自己也是网编出身,自己也在某某公司做了多长的网编.对于SEO我有些迷惑,SEO到底是什么?多数人告seo就优化,也有直接告诉我做关键词 网编是做SEO的必经之路吗?身边多数seo朋友多说自己也是网编出身,自己也在某某公司做了多长的网编.对于SEO我有些迷惑,SEO到底是什么?多数人告seo就优化,也有直接告诉我做关键词排名,监控.那为什么说网编是SEO的必经之路呢?因为在日常的工作中都揉合着seo的重要因素,不知大家赞同不赞同"内容为王,

getcellvar函数-cell插件根据变量名称查找单元格和数据区域,下面的代码会出现类型不匹配

问题描述 cell插件根据变量名称查找单元格和数据区域,下面的代码会出现类型不匹配 var a: var col; var row; var sheet; a = document.getElementById("DCellWeb1").GetCellVar("ce",col,row,sheet);

求解-分析俩段代码else的最后两句是干什么?求大神指点

问题描述 分析俩段代码else的最后两句是干什么?求大神指点 下边俩段代码,else里的最后两句为什么他俩不一样啊?第一段代码else的最后两句是干什么? 第二段代码else的最后两句是干什么? public String getList() throws Exception { quZhengGuiZeList = dao.getList(TrainingOrCompetitionID); if(quZhengGuiZeList.size()>0){ quZhengGuiZe=quZhengG

java问题分析-分析如下Java代码,如果想在控制台上输出“B类的test()方法”,则在主函数应填入( )

问题描述 分析如下Java代码,如果想在控制台上输出"B类的test()方法",则在主函数应填入( ) 分析如下Java代码,如果想在控制台上输出"B类的test()方法",则在主函数应填入( )class A {public void test() { System.out.println(""A类的test()方法"");}}class B extends A {public void test() { System.ou

c++-C++模板,我不太懂里面&amp;amp;amp; 字符啥意思(能帮忙分析这段代码吗?)

问题描述 C++模板,我不太懂里面& 字符啥意思(能帮忙分析这段代码吗?) 下面是我在<软件技术基础>里面看到的一部分内容,其中我不明白的地方就是 & 字符所在的地方 比如: Matrix& Matrix:: operator– (Matrix& x) 在此先谢谢大家帮忙解答了 8.2.2 矢量和矩阵的模板 由上述定义可知,矢量就是数的线性排列,序列就是它们最自然的表示方式.矩阵又可视为矢量的线性集合,所以可用序列的数组表示.下面就是矢量和矩阵的模板: 矢量模板