C语言实现异常处理(使用 setjmp 和 longjmp 函数)

来源:互联网 发布:mfc编程实例 编辑:程序博客网 时间:2024/05/18 09:17

C语言实现异常处理(使用 setjmp 和 longjmp 函数)

废话少说,直接贴上 MSDN 的实例代码,如果看不懂说明你水平不行 :)

 

// crt_fpreset.c// This program uses signal to set up a// routine for handling floating-point errors.#include <stdio.h>#include <signal.h>#include <setjmp.h>#include <stdlib.h>#include <float.h>#include <math.h>#include <string.h>jmp_buf mark;              // Address for long jump to jump toint     fperr;             // Global error numbervoid __cdecl fphandler( int sig, int num );   // Prototypesvoid fpcheck( void );int main( void ){   double n1 = 5.0;   double n2 = 0.0;   double r;   int jmpret;   // Unmask all floating-point exceptions.     _control87( 0, _MCW_EM );   // Set up floating-point error handler. The compiler   // will generate a warning because it expects   // signal-handling functions to take only one argument.   if( signal( SIGFPE, (void (__cdecl *)(int)) fphandler ) == SIG_ERR )    {       fprintf( stderr, "Couldn't set SIGFPE\n" );       abort();    }   // Save stack environment for return in case of error. First    // time through, jmpret is 0, so true conditional is executed.    // If an error occurs, jmpret will be set to -1 and false    // conditional will be executed.   jmpret = setjmp( mark );   if( jmpret == 0 )   {      printf( "Dividing %4.3g by %4.3g...\n", n1, n2 );      r = n1 / n2;      // This won't be reached if error occurs.      printf( "\n\n%4.3g / %4.3g = %4.3g\n", n1, n2, r );      r = n1 * n2;      // This won't be reached if error occurs.      printf( "\n\n%4.3g * %4.3g = %4.3g\n", n1, n2, r );   }   else      fpcheck();   system("pause"); //[]}// fphandler handles SIGFPE (floating-point error) interrupt. Note// that this prototype accepts two arguments and that the // prototype for signal in the run-time library expects a signal // handler to have only one argument.//// The second argument in this signal handler allows processing of// _FPE_INVALID, _FPE_OVERFLOW, _FPE_UNDERFLOW, and // _FPE_ZERODIVIDE, all of which are Microsoft-specific symbols // that augment the information provided by SIGFPE. The compiler // will generate a warning, which is harmless and expected.void fphandler( int sig, int num ){   // Set global for outside check since we don't want   // to do I/O in the handler.   fperr = num;   // Initialize floating-point package. */   _fpreset();   // Restore calling environment and jump back to setjmp. Return    // -1 so that setjmp will return false for conditional test.   longjmp( mark, -1 );}void fpcheck( void ){   char fpstr[30];   switch( fperr )   {   case _FPE_INVALID:       strcpy_s( fpstr, sizeof(fpstr), "Invalid number" );       break;   case _FPE_OVERFLOW:       strcpy_s( fpstr, sizeof(fpstr), "Overflow" );       break;   case _FPE_UNDERFLOW:       strcpy_s( fpstr, sizeof(fpstr), "Underflow" );       break;   case _FPE_ZERODIVIDE:       strcpy_s( fpstr, sizeof(fpstr), "Divide by zero" );       break;   default:       strcpy_s( fpstr, sizeof(fpstr), "Other floating point error" );       break;   }   printf( "Error %d: %s\n", fperr, fpstr );}


 

执行结果:
Dividing    5 by    0...
Error 131: Divide by zero

 

注: Linux系统也有 setjmp 和 longjmp 函数

 

0 0
原创粉丝点击