精华内容
下载资源
问答
  • 栈是先入后出的,一般由高地址向低地址生长。 生长方向: 对于堆来讲,生长方向向上的,也就是向着内存地址增加的方向; 对于来讲,它的生长方向向下的,向着内存地址减小的方向增长。 的伸展方向...
  • 什么是栈

    万次阅读 多人点赞 2019-05-08 10:57:59
    我常常会问自己的学生“”这个字的意思到底是什么?大家想到的多是客栈。我们翻翻字典也不难发现,的第一个释义是:储存货物或供旅客住宿的房屋。所以客栈的想法并没有错,但是这也未免太过抽象。 ...

    什么是栈?

    ps:文章来自于网络

    当提及“栈”这个概念,很多初学者都会很迷茫。在C语言里,我们有一个内存区域叫做栈区。在单片机里,我们又常常听到一个操作叫做压栈。而在算法中,我们也有一个同名结构叫做栈。

    我常常会问自己的学生“栈”这个字的意思到底是什么?大家想到的多是客栈。我们翻翻字典也不难发现,栈的第一个释义是:储存货物或供旅客住宿的房屋。所以客栈的想法并没有错,但是这也未免太过抽象。

    我们先来解释一下在计算机领域什么是栈。

    栈某种意义上讲,它像是一个开口的盒子,先放进去的东西总是会被后放进去的东西压在下面,那么如果想拿出被压住的东西,必须要先取出顶部的东西,也就是后放进去的东西。换个说法就是先入后出。那它有点像什么呢?想象一下装在盘子里的若干张油饼。

    对,他们是摞在一起的。如果想拿下面的油饼是不是要先拿开上面的呢?或许,这就是栈的根源。但是,又和“栈”这个字有什么关系呢?单纯的从释义上看,好似找不出什么关联性。但是当我们打开汉英词典:

    对计算机中提及的“栈”的英文愿意是stack!我们一定要记得,是一群说英语的人创造了计算机,也是他们研究了初的算法。那么stack又是什么意思?

    注意箭头指向的那一摞书们,和饼们的相处方式是不是很像!堆叠到一起。那个根源出来了,其实栈就是一种将数据依次“堆叠”的一种数据组织方式。

    或者到这里,我们恍然大悟,哦,原来是这样!栈还有堆叠的意思。但是,我个人更觉得这是一种初期程序员之间的交流翻译吴缪。暂且放下这个不谈,至少我们明白一件事情,在某些领域,如果一个词汇很生涩,那么,不妨去查找一下他的英文愿意,或许你会有更深入的收获。

    我们在来探讨下一个话题——“栈”stack,这种摞大饼大数据组织方式到底有什么用?

    比如说,你有一些书,我们通常会这样摆放:

    而不是这样:

    为什么呢?当然是第二种摆放方式不方便拿其中的某一本书。可是在“栈”(stack)结构里面,“书”就是这样摆放的。那也就是说,“栈”(stack)不适合存放需要随机查找的东西。那它能做什么呢?

    首先说说CPU里的“堆栈”。我们可以这样设想:一个CPU等同于一个完全没有记忆力的人,他只知道按照一份很详细的说明文档(也就是程序)来一步一步做某件事情,并且,他永远不会记得之前做过什么。我们在电影里常常会看到这样的情节,失忆症的人常常会随身携带一些本子和照片,然后按顺序把发生的事情记录下来,方便自己查阅。CPU也有这样的需求。

    在CPU里,有一种机制叫做“中断”interrupt,就是中途插一嘴的意思。怎么插呢?比方说,你正在玩儿一个单机游戏,在更要通关的时候,外面突然有人敲门。那么是不是要把你的游戏暂停一下?然后再去开门。然后正在你去开门的路上,厨房的煤气报警器响起,是不是要赶紧去厨房看一下是不是误报警?确认是误报警后,我们是先去开门呢?还是继续打游戏呢?对于CPU来说,也会有同样的困惑。对于人,我们或许可以思考一下——哦,开门这件事器比较紧迫,应该先开门。但是对于CPU来说,又如何区分紧迫度呢?这就变成了一个很麻烦的问题。我们回头再想想“栈”,他是如何组织数据的?先入后出。玩游戏是先发生的事情,那么打断他的事情就是更紧迫的事情,开门虽然比游戏紧迫,但是他次于煤气报警,所以,它才是紧迫的事情。不过到现在也应该注意到了。紧迫的事情往往在后产生,又要被优先处理。

    在CPU的中断机制里,每当cpu执行的一个任务被打断时,cpu就需要备份当前的处理状态,就像没有记忆的人,总是要记笔记拍照。那么cpu怎么区分优先次序呢?就像你吃盘子里的饼!先拿上面的。而存储数据的过程,就像你向盘子里放饼的过程。

    再说说C语言分段里的“栈区”,我们都知道,局部自动变量分配到内存的“栈区”,栈区里的数据组织方式也类似摞饼,每当你调用了一个子函数,那么编译器会将子函数里的局部变量分配到栈区的栈顶位置(与当前函数的空间相邻),当子函数在再调用另一个函数是,也是会做同样处理。儿关于局部变量的释放,其实本质就是讲栈顶的一块空间的使用权归还回去,看起来就好像客栈一样,来人的时候开房,走人的时候退房。或许这也是stack会被翻译成“栈”的原由。

    后在来说“栈”,这种单纯的逻辑结构。它和前两者一样,遵循类似先入后出的数据处理规则。

    那这个“盒子“什么时候会用到呢?典型的例子,就是迷宫算法(具体细节可以自己搜索一下),我们可以用栈来存放已经走过的有效路线。也或者利用栈来模拟局部变量分配,实现将递归算法转换为非递归。也或者利用栈来优化,自己的程序处理逻辑,在实际问题解决中,如果你涉及到了临时保存数据,那么你可以尝试考虑一下使用栈,或许可以让自己的程序在逻辑上变得更加清晰明了。

    简单的总结一下:所谓“栈”,其实就是一本 相互堆叠的便签儿。我们可以逐次备份自己要保存的信息,然后在反向依次处理。

    展开全文
  • 任务到底存放的一些什么东西?这个我觉得有必要弄清楚。C语言,中断发生时,保存的当前函数的什么,指令地址和寄存器值么? 。 ...

    任务栈里到底存放的是一些什么东西?这个我觉得有必要弄清楚。C语言的栈也是,中断发生时,栈保存的是当前函数的什么,指令地址和寄存器值么?

     

    任务控制块为什么那么设计?

     

     

    经过各种资料我应该可以确定为是     寄存器    和     程序计数器

    程序计数器肯定是要保存的,寄存器也是各个资料都讲到了的。

     

    我现在发现,程序计数器其实也是保存在一个寄存器里面的值,所以上面可以统一归为保存寄存器。我之所以这么想也是看下面给我的感受,完整课放大的照片可以往下翻,这里只是附上截图。

    其实想想本质就是各种寄存器嘛,你不管什么值不都是保存在内存里,寄存器本质就是内存嘛。

     

    下面拍自原子的freertos书

    https://baike.baidu.com/item/%E4%B8%8A%E4%B8%8B%E6%96%87%E5%88%87%E6%8D%A2/4842616?fr=aladdin

    https://blog.csdn.net/weixin_40599145/article/details/88032916

     

     

    看freertos的任务切换函数的具体步骤,你会发现里面大部分步骤都是在保存寄存器的值

    拍自正点原子的《FreeRTOS源码详解与应用开发》

     

     

     

     

     

     

     

     

     

     

    展开全文
  • 什么是代码区、常量区、静态区(全局区)、...下面就结合STM32内核来具体讨论分析这些区到底是什么回事,每种关键字定义的变量又到底是存在什么区。 如下图,是自己总结的内存分区的示意图。一般内存主要分为:代码...

    本文链接:https://blog.csdn.net/u014470361/article/details/79297601
    什么是代码区、常量区、静态区(全局区)、堆区、栈区?
    一直对这些区搞不清楚,每次听到这些区头都大了,感觉很混乱。下面就结合STM32内核来具体讨论分析这些区到底是什么回事,每种关键字定义的变量又到底是存在什么区。
    如下图,是自己总结的内存分区的示意图。一般内存主要分为:代码区、常量区、静态区(全局区)、堆区、栈区这几个区域。

    è¿éåå¾çæè¿°

    代码区:存放程序的代码,即CPU执行的机器指令,并且是只读的。
    常量区:存放常量(程序在运行的期间不能够被改变的量,例如: 10,字符串常量”abcde”, 数组的名字等)
    静态区(全局区):静态变量和全局变量的存储区域是一起的,一旦静态区的内存被分配, 静态区的内存直到程序全部结束之后才会被释放
    堆区:由程序员调用malloc()函数来主动申请的,需使用free()函数来释放内存,若申请了堆区内存,之后忘记释放内存,很容易造成内存泄漏
    栈区:存放函数内的局部变量,形参和函数返回值。栈区之中的数据的作用范围过了之后,系统就会回收自动管理栈区的内存(分配内存 , 回收内存),不需要开发人员来手动管理。栈区就像是一家客栈,里面有很多房间,客人来了之后自动分配房间,房间里的客人可以变动,是一种动态的数据变动。
    下面结合STM32内核和代码实际测试各关键字存储的区域和特点。
    本文使用是STM32L152芯片,keil V5环境下默认的内存配置见下图:

    è¿éåå¾çæè¿°

    默认分配的ROM区域是0x8000000开始,大小是0x20000的一片区域,那么这篇区域是只读区域,不可修改,也就是存放的代码区和常量区。
    默认分配的RAM区域是0x20000000开始,大小是0x4000的一片区域,这篇区域是可读写区域,存放的是静态区、栈区和堆区。该芯片的内部分区如下图所示:

    è¿éåå¾çæè¿°
    基于STM32内核的代码测试
    下面进行详细的测试,查看各关键字所在的各分区。

    代码区
    代码区的内存是由系统控制的
    代码区的存放 :程序中的函数编译后cpu指令
    代码区的地址:函数的地址,程序的入口地址,程序的名字
    函数的名称也是一个指针,可以通过查询函数名称所处的内存地址,查询函数存放的区域。
    void test(void)
    {
        printf("main:0x%p\n",main);//打印main函数的存放地址
    }
    è¿éåå¾çæè¿°
    可以看到main函数确实存放在0x08002e81这片地址区域,在代码区中。

    常量区
    下面来分析一句代码:
    char *p = “abcdef”;
    这句代码和char *p; p= “abcdef”;是等价的。
    上面的两种定义方式的具体意思是:定义一个char * 型的指针p,p存放的是字符串常量”abcdef”的首地址,字符串常量”abcdef”是存放在常量区的,也就是p是指向常量区的。那么p指向的区域里面的内容是不可以得修改,只可以 *p来读取p指向的内容,当然也可以把指针p移走,指向其他区域。
    测试如下:

    void test(void)
    {   
        char *p="abcdef";
        printf("0x%p: %s\n", p , p);//打印指针p的地址和p指向的字符串内容
        p="qwedma";
        printf("0x%p: %s\n", p , p);//打印指针p的地址和p指向的字符串内容
        p[0]='1';                     //尝试把p指向的第一个字符q修改为1
        printf("0x%p: %s\n", p , p);//打印指针p的地址和p指向的字符串内容
    }
    è¿éåå¾çæè¿°
    可以看到,abcdef字符串常量存放在0x08002ecc区域,p指针指向该区域,并把p指针移走指向qwedma字符串常量的首地址0x08002ee0。当尝试修改p指向的第一个字符,即把qwedma修改为1wedma,发现打印出来的内容并未改变,常量区的内容不可以改变。

    继续看这句 char str[] = “abcd”;这句话是定义了一个字符数组,但是这个str数组是存放在栈区的,然后再把字符串常量”abcd”拷贝到栈区的str数组内,那么此时的str是可以修改的。

    void test(void)
    {
        char str[] = "abcd";
        printf("0x%p: %s\n", str , str);
        str[0]='e';
        printf("0x%p: %s\n", str , str);
    }
    è¿éåå¾çæè¿°
     可以看到str是指向栈区的地址:0x200007c0,且指向的内容可以被修改,第一个字符a被修改为e。

    静态区(全局区)
    static int a;
    int c;
    void test(void)
    {
        static int b=1;
        b++;
        printf("b:0x%p: %d\n", &b , b);
    }
    int main()
    {
        printf("a: 0x%p: %d\n", &a , a);
        printf("c: 0x%p: %d\n", &c , c);
        for(uint8_t i=0;i<5;i++)
        {
            test();
        }
        return 0;
    }
    a是静态全局变量,b静态局部变量,c是全局变量,它们都存放在静态区;a和c并未初始化,打印出来都是0,说明编译器自动把他们初始化为0;b在for循环中初始化5次,但实际效果是b仅初始化一次,后面每次调用b都是上次的值,且b的地址一直是不变的,编译器只会为第一次初始化的b分配内存,后面4次初始化是无效的。

    堆区
    堆区是调用malloc函数来申请内存空间,这部分空间使用完后需要调用free()函数来释放。
    void * mallc(size_t);函数的输入是分配的字节大小,返回是一个void*型的指针,该指针指向分配空间的首地址,void *型指针可以任意转换为其他类型的指针。

    void test(void)
    {   
        int *p1=malloc(4);//申请4字节的空间
        *p1=123;// 该空间赋值123
        printf("0x%p:%d\n",p1,*p1);
        printf("0x%p\n",&p1);
        free(p1);
        printf("0x%p:%d\n",p1,*p1);
        p1 = NULL;
        printf("0x%p\n",p1);
    }

    int *p1=malloc(4);语句是申请了4个字节的空间,空间的首地址赋给指针p1,可以看到这个首地址是0x200003e8,存在是堆区;
    printf(“0x%p\n”,&p1);指针p1本身也是需要存放的,p1本身是存放在栈区的0x200009d0;
    free(p1);内存释放函数 free(开辟的内存的首地址) ,将内存标记为可用且将里面的内容清空为0,但指针p1还是指向这片空间。比较安全的做法是p1 = NULL;把p1指针释放,避免造成野指针。

    void test(void)
    {   
        int *p1=malloc(4);
        int *p2=malloc(4);
        printf("p1:0x%p\n",p1);
        printf("p2:0x%p\n",p2);
    }
    p2的地址是大于p1的地址,验证堆区是向上生长的,后申请的空间地址会依次增加。

    栈区
    栈区由编译器自动分配释放,存放函数的参数值、返回值和局部变量,在程序运行过程中实时分配和释放,栈区由操作系统自动管理,无须手动管理。栈区是先进后出原则,即先进去的被堵在屋里的最里面,后进去的在门口,释放的时候门口的先出去。

    void test(void)
    {   
        int a;
        int b=0;    
        printf("a:0x%p:%d\n",&a,a);
        printf("b:0x%p:%d\n",&b,b);
    }

    可以看到后定义的局部变量b地址是比a小的,即栈区是向下生长的;
    a变量没有进行初始化,打印出的a是垃圾值,编译器不会把局部变量初始化为0。但是,需要注意:如果你运行于debug调试模式,运行时机制会把你的栈空间全部初始化为0,这就是解释了为什么平时在debug时看到的未初始化的局部变量初始值是0.
    使用局部变量时,尽量要先进行初始化,避免垃圾值造成错乱。

    大小端测试
    数据在内存中存放,有大段模式和小端模式。
    小端模式(little-endian):低位字节存在低地址上,高位字节存在高地址上;
    大端模式( big-endian):低位字节存在高地址上,高位字节存在低地址上,刚好与小端模式相反。
    另:网络字节序:TCP/IP各层协议将字节序定义为Big-Endian,因此TCP/IP协议中使用的字节序通常称之为网络字节序

    static uint32_t m=0x87654321;
    char *p=(char*)&m;
    void test(void)
    {   
        printf("P  :0x%p: %x\n",p,*p);
        printf("P+1:0x%p: %x\n",p+1,*(p+1));
        printf("P+2:0x%p: %x\n",p+2,*(p+2));
        printf("P+3:0x%p: %x\n",p+3,*(p+3));
    }
    低字节21放在低地址,高字节87放在高地址,与小端模式相符。

    keil中代码和数据量所占字节的查询
    keil软件勾选上生成批处理文件,在keil编译完成后,可以查看到代码和定义的数据所占的字节大小。

    è¿éåå¾çæè¿°
    如上图,Code是程序代码所占的字节,即代码区;
    RO-data 代表只读数据,程序中所定义的常量数据和字符串等都位于此处,即常量区;
    RW-data 代表已初始化的读写数据,程序中定义并且初始化的全局变量和静态变量位于此处,一部分静态区(全局区);
    ZI-data 代表未初始化的读写数据,程序中定义了但没有初始化的全局变量和静态变量位于此处,另一部分的静态区(全局区)。ZI英语是zero initial,就是程序中用到的变量并且被系统初始化为0的变量的字节数,keil编译器默认是把你没有初始化的变量都赋值一个0,这些变量在程序运行时是保存在RAM中的。
    Total ROM Size (Code + RO Data + RW Data)这样所写的程序占用的ROM的字节总数,也就是说程序所下载到ROM flash 中的大小。

    为什么Rom中还要存RW,因为掉电后RAM中所有数据都丢失了,每次上电RAM中的数据是被重新赋值的,每次这些固定的值就是存储在Rom中的,为什么不包含ZI段呢,是因为ZI数据都是0,没必要包含,只要程序运行之前将ZI数据所在的区域一律清零即可,包含进去反而浪费存储空间。

    实际上,ROM中的指令至少应该有这样的功能:
    1. 将RW从ROM中搬到RAM中,因为RW是变量,变量不能存在ROM中。
    2. 将ZI所在的RAM区域全部清零,因为ZI区域并不在Image中,所以需要程序根据编译器给出的ZI地址及大小来将相应得RAM区域清零。ZI中也是变量,同理:变量不能存在ROM中。
    在程序运行的最初阶段,RO中的指令完成了这两项工作后C程序才能正常访问变量。否则只能运行不含变量的代码。
    ————————————————
    版权声明:本文为CSDN博主「夜风~」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/u014470361/article/details/79297601

    展开全文
  • 2. 虚拟内存到底是什么?为什么我们在C语言中看到的地址是假的? 3. 虚拟地址空间以及编译模式 4. C语言内存对齐,提高寻址效率 5. 内存分页机制,完成虚拟地址的映射 6. 分页机制究竟是如何实现的? 7. MMU部件以及...
  • C语言嵌入式linux编程

    2018-10-09 12:38:45
    C语言到底学到什么程度,才能胜任Linux内核、驱动或嵌入式系统的开发?一般来讲,不同的软件开发职位,对C语言的要求不同的。嵌入式开发,对C语言的要求相比其它职位,相对很高。不仅要求学员掌握C语言的基本语法...
  • C程序底为高地址,栈顶为低地址,因为地址空间向低地址方向扩展。函数参数入栈顺序的确从右至左的。可到底什么呢?查了一直些文献得知,参数入栈顺序和具体编译器实现相关的。比如,Pascal语言中参数...

    C程序栈底为高地址,栈顶为低地址,因为栈地址空间是向低地址方向扩展。函数参数入栈顺序的确是从右至左的。可到底为什么呢?查了一直些文献得知,参数入栈顺序是和具体编译器实现相关的。比如,Pascal语言中参数就是从左到右入栈的,有些语言中还可以通过修饰符进行指定,如Visual C++.即然两种方式都可以,为什么C语言要选择从右至左呢?

    进一步发现,Pascal语言不支持可变长参数,而C语言支持这种特色,正是这个原因使得C语言函数参数入栈顺序为从右至左。具体原因为:C方式参数入栈顺序(从右至左)的好处就是可以动态变化参数个数。通过栈堆分析可知,自左向右的入栈方式,最前面的参数被压在栈底。除非知道参数个数,否则是无法通过栈指针的相对位移求得最左边的参数。这样就变成了左边参数的个数不确定,正好和动态参数个数的方向相反。

    因此,C语言函数参数采用自右向左的入栈顺序,主要原因是为了支持可变长参数形式。换句话说,如果不支持这个特色,C语言完全和Pascal一样,采用自左向右的参数入栈方式。

    int main()

    {

      int i=10;

      printf( "%d, %d", i, i++, i++); 

    }

    输出结果为:12, 11

    根据以上的原理,就很容易分析清楚了。自右向左入栈,依次为10,11,12,栈顶元素是12.然后按照格式字符串的规则,只输出两个值,仅仅将栈顶元素输出,因此,是12, 11.





    本文也是借鉴了其他优秀博文的成果和自己的测试结果得出的。

    参考链接:

    http://blog.csdn.net/jiejiaozhufu/article/details/7677427

    http://www.cnblogs.com/xkfz007/archive/2012/03/27/2420158.html


    展开全文
  • Linux C语言指针与内存 前面我们对于: c语言的基本用法 makeFile文件的使用 main函数的详解 标准输入输出流以及错误流管道 ...我们可以看到cpu到底做了什么事,而内存中又发生了什么变化 C语言...
  • c语言深度剖析

    2012-08-18 18:59:34
    c语言 深度 剖析 解开程序员面试笔试的秘密 第一章关键字..................................................................................................................................9 1.1,最宽恒...
  • C语言深度解剖(c语言进阶的好教程) 目 录 第一章 关键字................................................................................................................................... 9 1.1,最宽...
  • C语言深度揭秘

    2012-04-12 13:21:16
    1.6.4,else到底与哪个 if配对呢?.....................22 1.6.5,if语句后面的分号..................................... 23 1.6.6,使用if语句的其他注意事项.................... 24 1.7,switch、case组合.......
  • C语言深度解剖

    2012-08-09 19:43:35
    1.6.4,else 到底与哪个 if 配对呢?............................................................................... 22 1.6.5,if 语句后面的分号.............................................................
  • c语言编写单片机技巧

    2009-04-19 12:15:17
    初学者到底是应该先学C还是汇编? 答:对于单片机的初学者来说,应该从汇编学起。因为汇编语言是最接近机器码的一种语言,可以加深初学者对单片机各个功能模块的了解,从而打好扎实的基础。 7. 我是一名武汉...
  • 堆和栈到底是什么 栈和堆(托管堆)都存在于进程的虚拟内存中。 栈(Stack) 是操作系统在建立某个进程时或者线程(在支持多线程的操作系统中是线程)为这个线程建立的存储区域。 栈中存储值类型 栈上是向下填充的...
  • 文章目录malloc()和free()的基本概念以及基本用法:函数原型及说明函数的用法关于函数使用需要注意的一些地方malloc()到底从哪里得来了内存...什么是什么是栈free()到底释放了什么malloc()以及free()的机制 malloc...
  • 一直在说要扎实自己的数据结构与算法的能力,可是到底什么是数据结构,到底什么是算法呢? 数据结构与算法有啥区别呢? 突然想起来,得把最经典的数据结构(C语言) 严蔚敏、吴伟民编著的教材翻翻了。 全书...
  • 1.6.4,else 到底与哪个if 配对呢?...............................................................................22 1.6.5,if 语句后面的分号................................................................
  • C语言深度解剖_word版

    2010-04-25 22:21:15
    C语言深度解剖 word版 解开程序员面试笔试的秘密第一章关键字......................................................................................................................9 1.1,最宽恒大量的关键字...
  • 1.6.4,else 到底与哪个if 配对呢?...............................................................................22 1.6.5,if 语句后面的分号................................................................
  • 本人感觉小白一个,刚学完操作系统原理,可是进程和线程总是很难理解啊,从编程的角度来讲:这都面向对象的东西,实际编程时感觉很难下手,从理论到实践真的差别很大,感觉用先前的c语言的知识很难理解执行顺序...
  • 我如何认识指针

    2020-12-02 20:44:18
    那么,指针到底是什么东西呢?我们来看看下面这个图。 上面的这个图可以理解为电脑中的内存,内存从上到下生长,地址连续降低。内存从下到上依次是代码区、字符常量区、全局数据区、堆区和区,这里注意,堆区和...
  • 我们在做单片机编程的时候,大部分都用KEIL自带的启动文件来使程序进入C语言main函数,然后进行C语言编程开发的工作。那么这个启动文件到底做了什么呢?相信朋友们肯定和我一样好奇,想弄明白启动文件到底都干了些...
  • 3.2.5 栈到底是什么玩意儿 81 3.2.6 实模式下的ret 84 3.2.7 实模式下的call 85 3.2.8 实模式下的jmp 92 3.2.9 标志寄存器flags 97 3.2.10 有条件转移 99 3.2.11 实模式小结 101 3.3 让我们直接对显示器说点什么吧 ...
  • JAVA实现单链表超详解(图解)

    千次阅读 2020-07-30 14:27:59
    这一篇,说一下java的单链表的实现...那,我们知道这行代码是一个对象的实例化,那这行代码到底是什么意思呢? 我们这样理解: stu这个变量存储在内存中,右边的new Student()存储在堆内存中,就像这样: 也就是可以
  • 这篇博客讲解比较好 到底什么是后缀表达式 又怎么转化的 直接用中缀表达式进行计算 二、的基本思想 按照基本思想 View里写每个按钮 并且使用Masonry进行布局 通过观察计算器按钮的布局 发现前四排一样的...

空空如也

空空如也

1 2
收藏数 38
精华内容 15
关键字:

c语言栈到底是什么

c语言 订阅