如何用C语言实现异常/状况处理机制
反对,不会显示你的姓名
余天升网络安全、密码学、编程语言、编程话题优秀回答者 …
2 人赞同
在没有垃圾回收的情况下,使用异常机制绝对会降低程序的质量。Symbian C++中,使用了一种Leave机制,是对C++中异常机制的包装,而且因为Symbian系统运行在资源有限的嵌入式设备上的原因,栈空间很小,几乎所有的数据都要放在堆上,所以Symbian C++中引入了… 显示全部
在没有垃圾回收的情况下,使用异常机制绝对会降低程序的质量。Symbian C++中,使用了一种Leave机制,是对C++中异常机制的包装,而且因为Symbian系统运行在资源有限的嵌入式设备上的原因,栈空间很小,几乎所有的数据都要放在堆上,所以Symbian C++中引入了清除栈机制来避免内存泄漏的问题。
Symbian C++中要求,刚创建的对象,在没有保存到别的对象之前,应该立刻放到清除栈中保存,以便一旦产生Leave(异常),系统可以将清除栈中的对象销毁,防止内存泄漏。于是这样子代码就好麻烦了,每一次都要写类似的代码
HSomeClass* anInstance = HSomeClass.NewL();
CleanupStack::PushL(anInstance);
HSomeOtherClass* aNewInstance = HSomeOtherClass.NewL();
CleanupStack::PushL(aNewInstance);
…….
CleanupStack::Pop();
return;
所以,如果你想在C中使用异常机制的话,那么你需要:包装把setjump包装成TRAP宏,然后在实现一个清除栈。这个清除栈要分类型,一般的数据是一种,句柄又是一种,C中还不好实现类似IDispose之类的接口。另外,Symbian没落的一个原因是,这样的机制过于复杂,好多人都搞不懂,还是负责垃圾回收的Java比较方便,详见另外一则答案 。
c语言检测到无效的异常处理要导入什么库才能使用
这个用C实现的异常处理的关键函数是setjmp和longjmp,setjmp函数可以实现非局部标号,而longjmp实现程序内部的任意跳转(与之类似的我们经常使用的goto只能实现函数内部的跳转)。这两个函数的相互组合使用,百度百科给了如下总结:
1.setjmp(j)设置“jump”点,用正确的程序上下文填充jmp_buf对象j。这个上下文包括程序存放位置、栈和框架指针,其它重要的寄存器和内存数据。当初始化完jump的上下文,setjmp()返回0值。
2. 以后调用longjmp(j,r)的效果就是一个非局部的goto或“长跳转”到由j描述的上下文处(也就是到那原来设置j的setjmp()处)。当作为长跳转的目标而被调用时,setjmp()返回r或1(如果r设为0的话)。(记住,setjmp()不能在这种情况时返回0。)
通过有两类返回值,setjmp()让你知道它正在被怎么使用。当设置j时,setjmp()如你期望地执行;但当作为长跳转的目标时,setjmp()就从外面“唤醒”它的上下文。
我封装的异常处理库也是按照上面总结的方法使用的,理解了上面的总结再看代码就非常简单了。
在需要抛出异常的地方使用Throw宏抛出异常,它两个参数,一个是异常类型,一个是异常说明字符串。也可以使用ThrowAll来抛出一个任意类型的异常,但是此时只能使用Except才能捕获。
将可能出现异常的代码段使用Try包含起来。OnExcept用来捕获异常,它有一个参数,标记需要捕获什么类型的异常。如果此时有异常产生,异常类型与OnExcept要捕获的类型一致能会捕获到这个异常,否则抛弃。而如果使用Except宏则会捕获任意类型的异常。
最后需要调用Finally宏来进行清理,包括释放在Try宏内申请的内存空间。
一个简单的使用例子如下:
[cpp] view plaincopyprint?
#include stdio.h
#include excp.h
void fun(void* p){
if(p == NULL) Throw(1, “这个指针是空的呀!!!”);
else printf(“神马都是浮云!/n”);
}
int main(){
void* p = NULL;
Try{
fun(p);
}
OnException(1){
printf(“%s/n”, Message);
}
Finally{
printf(“这个指针是空的我有啥用呀?/n”);
}
return 0;
}
[cpp] view plaincopyprint?
#include stdio.h
#include excp.h
void fun(void* p){
if(p == NULL) Throw(1, “这个指针是空的呀!!!”);
else printf(“神马都是浮云!/n”);
}
int main(){
void* p = NULL;
Try{
fun(p);
}
OnException(1){
printf(“%s/n”, Message);
}
Finally{
printf(“这个指针是空的我有啥用呀?/n”);
}
return 0;
}
文章知识点与官方知识档案匹配
C技能树首页概览
108976 人正在系统学习中
点
C语言异常处理和exit()怎样使用?
c语言中exit()函数的用法:
用exit()函数可以退出程序并将控制权返回给操作系统,而用return语句可以从一个函数中返回并将控制权返回给调用该函数的函数。如果在main()函数中加入return语句,那么在执行这条语句后将退出main()函数并将控制权返回给操作系统,这样的一条return语句和exit()函数的作用是相同的。下例是一个使用了exit()函数和return语句的程序:
#include stdio.h
#include stdlib.h
int main (int, char** );
int do_processing (void);
int do_something_daring();
int main (int argc, char** argv)
{
int ret_code;
if (argc 3)
{
printf (“Wrong number of arguments used ! \n”);
/* return 1 to the operating system * /
exit(1);
}
ret_code = do_processing ();
……
/* return 0 to the operating system * /
exit(0);
}
int do_processing(void)
{
int rc;
rc = do_aomcthing_daring();
if (rc == ERROR)
{
printf (“Something fiahy ia going on around here… *\n);
/* return rc to the operating syatem * /
exit (re);
}
/* return 0 to the calling function * /
return 0;
}
在上例的main()函数中,如果argc小于3,程序就会退出。语句“exit(1)”指示程序在退出时将数字1返回给操作系统。操作系统有时会根据程序的返回值进行一些相关的操作,例如许多DOS批处理文件会通过一个名为ERRORLEVEL的全局变量来检查可执行程序的返回值。
c语言未经处理的异常,求大佬指点
您好,很高兴回答您的问题。
您的这个题目,系统已经很明显告诉您了错误的原因。因为您定义的x为字符型数据,那么它对应的输入输出格式符为%c,但是您在输入语句中写的是%s,是字符串格式,不符合字符型单个变量的输入输出。根据题目意思,应该是要输入字符串,那么定义的时候就要写成char x[2],因为存放的是性别中文字,所以数组长度定义为2就可以了。您再试试哦。
c语言库函数中有error函数吗?
c语言标准库函数里没有error函数。C语言对异常的处理确实不够好,大多的时候都需要人工除错。
有几个类似的函数,分别处理各种情况下的异常:
ferror函数:在调用各种输入输出函数(如
putc.getc.fread.fwrite等)时,如果出现错误,除了函数返回值有所反映外,还可以用ferror函数检查。
它的一般调用形式为
ferror(fp);如果ferror返回值为0(假),表示未出错。如果返回一个非零值,表示出错。应该注意,对同一个文件
每一次调用输入输出函数,均产生一个新的ferror函
数值,因此,应当在调用一个输入输出函数后立即检
查ferror函数的值,否则信息会丢失。在执行fopen函数时,ferror函数的初始值自动置为0。在库函数中有个errno变量,每个errno值对应着以字符串表示的错误类型。当你调用”某些”函数出错时,该函数已经重新设置了errno的值。perror函数只是将你输入的一些信息和现在的errno所对应的错误一起输出。
perror函数:
用来将上一个函数发生错误的原因输出到标准设备(stderr)。参数
s
所指的字符串会先打印出,后面再加上错误原因字符串。此错误原因依照全局变量errno
的值来决定要输出的字符串。
strerror函数:用来
从错误号码
查
用英文表达的错误内容,返回指针,指向这段英文字符串。如果你不知道错误号,那么在出错发生时,及时用
errno
的当前值
作参数,打印这段字符串。
C语言出现异常怎么解决?
操作起来很简单:在菜单栏以此单击”Build”→“Bulid Options”弹出一个对话框,在Category那有个下拉列表的(默认好像是C++ Language),点击选择C Lanuage。然后紧接着下面有五个小钩钩,去掉最后一个。(或者把Raw Options下面那个框里的-fallow-single-precision删掉,是一样的。)点击OK,完成。
我的Cfree还没汉化,不知道你的汉化了没,所以直接照我的来告诉你了。天哪…这个问题也困扰了我很久,装了无数个版本的Cfree…