c語(yǔ)言沒(méi)有try catch的替代方案
setjmp與longjmp
后綴jmp指的就是jump,關(guān)看名字就能猜到這哥倆是干啥的了。使用他們倆就可以讓程序控制流轉(zhuǎn)移,進(jìn)而實(shí)現(xiàn)對(duì)異常的處理。
異常處理的結(jié)構(gòu)可以劃分為以下三個(gè)階段:
- 準(zhǔn)備階段:在內(nèi)核棧保存通用寄存器內(nèi)容
- 處理階段:保存硬件出錯(cuò)碼和異常類(lèi)型號(hào),然后向當(dāng)前進(jìn)程發(fā)送信號(hào)
- 恢復(fù)階段:恢復(fù)保存在內(nèi)核棧中的各個(gè)寄存器內(nèi)容,返回當(dāng)前進(jìn)程的斷電處繼續(xù)執(zhí)行
過(guò)程有點(diǎn)類(lèi)似遞歸,只有文字你可能看的有點(diǎn)云里霧里,我們結(jié)合一個(gè)小例子來(lái)看看
#include <stdio.h>
#include <setjmp.h>
static jmp_buf buf;
void second(void) {
printf("second\n");
// 跳回setjmp的調(diào)用處 - 使得setjmp返回值為1
longjmp(buf, 1);
}
void first(void) {
second();
//這行到不了,因?yàn)閟econd里面longjmp已經(jīng)跳轉(zhuǎn)回去了
printf("first\n");
}
int main() {
int rc;
rc = setjmp(buf);
if (rc==0) {
// 進(jìn)入此行前,setjmp返回0
first();
}
// longjmp跳轉(zhuǎn)回,setjmp返回1,因此進(jìn)入此行
else if(rc==1){
printf("main\n");
}
return 0;
}
/*
the ressult as:
second
main
*/

現(xiàn)在我們?cè)賮?lái)看看兩個(gè)函數(shù)的聲明:
- setjmp(env) :將程序上下文存儲(chǔ)在env中
- longjmp(env,status):env指代setjmp中所保存的函數(shù)執(zhí)行狀態(tài)變量,status則是作為setjmp的返回值
當(dāng)然你也可以用switch代替上面的if else,其實(shí)try catch就相當(dāng)于上面的那個(gè)函數(shù)你可以參考這個(gè)實(shí)現(xiàn)try catch。
signal信號(hào)處理
個(gè)人覺(jué)得這個(gè)在linux下更好用,并且也提供了更多的信號(hào)量宏。
下面給出的是signal頭文件中的定義
#define SIGINT 2 // interrupt #define SIGILL 4 // illegal instruction - invalid function image #define SIGFPE 8 // floating point exception #define SIGSEGV 11 // segment violation #define SIGTERM 15 // Software termination signal from kill #define SIGBREAK 21 // Ctrl-Break sequence #define SIGABRT 22 // abnormal termination triggered by abort call
這里僅給出維基上的例子
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
static void catch_function(int signal) {
puts("Interactive attention signal caught.");
}
int main(void) {
if (signal(SIGINT, catch_function) == SIG_ERR) {
fputs("An error occurred while setting a signal handler.\n", stderr);
return EXIT_FAILURE;
}
puts("Raising the interactive attention signal.");
if (raise(SIGINT) != 0) {
fputs("Error raising the signal.\n", stderr);
return EXIT_FAILURE;
}
puts("Exiting.");
return 0;
}
總結(jié)
到此這篇關(guān)于c語(yǔ)言沒(méi)有try catch的替代方案的文章就介紹到這了,更多相關(guān)c語(yǔ)言try catch內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語(yǔ)言超詳細(xì)講解隊(duì)列的實(shí)現(xiàn)及代碼
隊(duì)列(Queue)與棧一樣,是一種線性存儲(chǔ)結(jié)構(gòu),它具有如下特點(diǎn):隊(duì)列中的數(shù)據(jù)元素遵循“先進(jìn)先出”(First?In?First?Out)的原則,簡(jiǎn)稱(chēng)FIFO結(jié)構(gòu)。在隊(duì)尾添加元素,在隊(duì)頭刪除元素2022-04-04
C++ LeetCode1805字符串不同整數(shù)數(shù)目
這篇文章主要為大家介紹了C++ LeetCode1805字符串不同整數(shù)數(shù)目,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12
C++類(lèi)的構(gòu)造與析構(gòu)特點(diǎn)及作用詳解
本文章將會(huì)可能會(huì)涉及到匯編的知識(shí),不過(guò)沒(méi)有關(guān)系,我會(huì)講的盡量通俗易懂;另外本篇文章開(kāi)始前,建議了解下什么是函數(shù)重載,這個(gè)概念很簡(jiǎn)單的--有相同的函數(shù)名,但參數(shù)列表不相同的函數(shù),就是函數(shù)重載2022-10-10
C++實(shí)現(xiàn)四則運(yùn)算器(帶括號(hào))
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)四則運(yùn)算器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-11-11
概率的問(wèn)題:使用遞歸與多次試驗(yàn)?zāi)M的分析
以下對(duì)概率的問(wèn)題:使用了遞歸和多次試驗(yàn)?zāi)M。需要的朋友參考下2013-05-05
C語(yǔ)言二維數(shù)組應(yīng)用之井字棋游戲
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言二維數(shù)組應(yīng)用之井字棋游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06
C++11右值引用和移動(dòng)語(yǔ)義的實(shí)例解析
左值和右值都是針對(duì)表達(dá)式,左值是指表達(dá)式結(jié)束后依然存在的持久對(duì)象,右值是指表達(dá)式結(jié)束時(shí)就不再存在的臨時(shí)對(duì)象,下面這篇文章主要給大家介紹了關(guān)于C++11右值引用和移動(dòng)語(yǔ)義的相關(guān)資料,需要的朋友可以參考下2022-09-09

