读《C专家编程》笔记-第六章

auto 和static关键字

对堆栈怎么实现函数调用的描述也同时解释了为什么不能从函数中返回一个指向该函数局部自动变量的指针,例如:

char * favorite_fruit(){
char deciduous[]="apple";
return deciduous;
}

当进入该函数时,自动变量decidudous在堆栈中分配。当函数结束后,变量不复存在,它所占有的堆栈空间被回收,可能在任何时候被覆盖。这样,指针就失去了有效性(引用不存在的东西),被称为“垂悬指针”-他们并不引用有用的东西,而是悬在地址空间内。如果想返回一个指向在函数内部定义的变量的指针时,要把那个变量声明为static,这样就能保证该变量被保存在数据段中而不是堆栈中。该变量的生命周期就和程序一样长,当定义该变量的函数退出时,该变量的值依然能保持。当该函数下一次进入时,该值依然有效。
存储类型说明符auto在实际中从来用不着,他通常由编辑器设计设使用。他在函数内部声明的数据缺省就是这种分配。

static用途

-当static修饰函数
限制函数的作用域,起到一个封装的作用,被static修饰的函数只能在本文件内使用,其他文件不能调用次函数。
- 当static修饰变量
static修饰的变量在函数内声明的不会随着函数的返回而自动回收,被static修饰的变量在整个程序运行周期内有效,只初始化一次,在内存中的静态变量区。当static修饰的变量(函数外),可以被这个模块内所有函数访问,但不能被模块外其他函数访问,是一个本地全局变量。

setjmp和longjmp

setjmp和longjmp是通过操纵过程活动记录实现的,它是C语言所特有的。这两个函数协同工作。
- setjmp(jmp_buf j)必须首先被调用。它表示“使用变量j记录现在的位置。函数返回零。”
- longjmp(jmp_buf,int i)可以接着被调用。它表示“回到j所记录的位置,让它看上去像是从原先的setjmp()函数返回一样”,但是函数返回i,是代码能够知道它是实际上是通过longjmp()返回的。
- 当使用longjmp()时,j的内容被销毁。
setjmp保存了一份程序的计数器和当前栈顶指针。如果喜欢也可以保存一些初始值,longjmp恢复这些值,有效的转移控制并把状态重置回保存状态的时候。这被称作“展开堆栈”,因为从堆栈中展开过程活动记录,知道取得保存在其中的值。尽管longjmp会导致转移,但它和goto不同,切别如下:
- goto语句不能跳出c语言当前函数(这也是longjmp名字的由来,它可以跳的很远,甚至可以调到其他文件的函数中)。
- 用longjmp只能跳回到曾经到过的地方。在执行setjmpde 的地方仍留有一个过程活动记录。从这个角度讲,longjmp更像是“从何出来”而不是“往哪里去”。lonmgjmp接受一个额外的整型参数并返回它的值,这可以知道是由longjmp转移到这里的还是从上一条语句执行后自然而然到这里的。
下面的代码举例这两个函数的应用。

#include<setjmp.h>
jmp_buf buf;
#include <setjmp.h>
banana(){
    printf("in banana() \n");
    longjmp(buf,1);
    printf("you'll never see this,because i longjmp'd");
}
main()
{
    if(setjmp(buf))
        printf("back in main\n");
    else{
        printf("first time through \n");
        banana();
        }
}

输出结果如下:

% a.out
first time through
in banana()
back in main

需要注意的地方是:保证局部变量在longjmp过程中一直保持它的值得唯一可靠办法是把它生命为volatile(这适用于那些值在setjmp执行和longjmp返回之间会改变的量)。
setjmp/longjmp最大的用途是错误恢复。只要还没有从函数中返回,一旦发现一个不可恢复的错误,可以把控制转移到主输入循环,并从哪里重新开始。setjmp和longjmp在C++中变为更为普通的异常处理机智catch和throw

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值