C 언어 이상 처리 메커니즘 사례 설명

이상 처리 메커니즘:setjmp()함수 와 longjmp()함수
C 표준 라 이브 러 리 는 두 가지 특수 한 함 수 를 제공 합 니 다.setjmp()와 longjmp()입 니 다.이 두 함 수 는 구조 화 이상 의 기초 이 고 바로 이 두 함수 의 특성 을 이용 하여 이상 을 실현 합 니 다.
따라서 이상 한 처리 과정 은 다음 과 같이 묘사 할 수 있다.
먼저 점프 점(setjmp()함 수 를 설정 하면 이 기능 을 실현 할 수 있 습 니 다)을 설정 한 다음 에 그 후의 코드 에서 임의의 곳 에서 longjmp()를 이 점프 점 으로 호출 하여 이상 이 발생 했 을 때 이상 을 처리 하 는 프로그램 으로 이동 합 니 다.그 다음 에 어떻게 실현 하 는 지 소개 합 니 다.
setjmp()는 저장 현장 을 되 돌려 주 고 이상 처리 프로그램 을 제공 합 니 다.longjmp()는 점프(이상 던 지기)를 합 니 다.setjmp()와 longjmp()는 함수 간 에 점프 를 할 수 있 습 니 다.이것 은 전역 적 인 goto 문장 처럼 함수 간 에 점프 를 할 수 있 습 니 다.
예 를 들 어 프로그램 은 main()함수 에서 setjmp()를 사용 하여 점프 를 설정 하고 다른 함수 A 를 호출 합 니 다.함수 A 에서 B 를 호출 하고 B 에서 이상(longjmp()함 수 를 호출 합 니 다)을 던 지면 프로그램 은 main()함수 에서 setjmp()를 사용 하 는 곳 으로 직접 뛰 어 내 려 가 값 을 되 돌려 줍 니 다.
-------------------------------------------------------------------------------------------------------------------------
jmp_buf 이상 구조
setjmp()및 longjmp()함 수 를 사용 하기 전에 jmp 를 먼저 알 아야 합 니 다.buf 이상 구조.jmp_buf 는 setjmp()함수 에 사 용 됩 니 다.현재 프로그램 현장 저장(현재 필요 한 레지스터 의 값 저장),jmpbuf 구 조 는 setjmp.h 파일 에서 설명 합 니 다:

typedef struct
{
unsigned j_sp; //        
unsigned j_ss; //    
unsigned j_flag; //      
unsigned j_cs; //    
unsigned j_ip; //        
unsigned j_bp; //     
unsigned j_di; //     
unsigned j_es; //    
unsigned j_si; //    
unsigned j_ds; //    
} jmp_buf;
jmp_buf 구 조 는 현재 레지스터 의 값 을 저장 하여 longjmp()를 사용 한 후 이 실행 점 으로 돌아 가 계속 실행 할 수 있 도록 합 니 다.
-------------------------------------------------------------------------------------------------------------------------
setjmp()와 longjmp()함수 상세 설명
setjmp()와 longjmp()함수 원형 은 다음 과 같 습 니 다.
  void _Cdecl longjmp(jmp_buf jmpb, int retval);
  int _Cdecl setjmp(jmp_buf jmpb);
_Cdecl 성명 함수 의 매개 변 수 는 표준 C 의 스 택 방식(오른쪽 에서 왼쪽으로)을 사용 하여 스 택 을 누 릅 니 다.Cdecl 은 C 언어의 호출 약정 이 며,이외에 PASCAL 도 호출 약정 중 하나 입 니 다.C 표준 호출 약정(Cdecl)에서 설명 한 함수 가 스 택 을 자동 으로 제거 하지 않 습 니 다.이 업 무 는 호출 자가 스스로 책임 집 니 다.이것 도 C 가 고정 되 지 않 은 매개 변 수 를 지원 할 수 있 는 이유 입 니 다.그 밖 에 이 호출 약속 은 함수 이름 앞 에 밑줄 문 자 를 추가 합 니 다.예 를 들 어 특정한 함수 가 다음 과 같이 설명 합 니 다.
int cdecl DoSomething(void);
컴 파일 시 DoSomething 에 밑줄 접 두 사 를 자동 으로 붙 입 니 다.즉,함수 이름 은: 입 니 다.DoSomething。
setjmp()와 longjmp()함수 모두 jmp 사용buf 구 조 는 형 삼 으로 그들의 호출 관 계 는 다음 과 같다.
먼저 setjmp()함 수 를 호출 하여 jmp 를 초기 화 합 니 다.buf 구조 변수 jmpb 는 현재 CPU 의 대부분 을 프로그램 실행 에 영향 을 미 치 는 레지스터 의 값 을 jmpb 에 저장 하여 longjmp()함수 에 점프 를 제공 합 니 다.setjmp()함 수 는 재 미 있 는 함수 입 니 다.두 번 되 돌아 갈 수 있 습 니 다.모든 라 이브 러 리 함수 중 유일 하 게 두 번 되 돌아 갈 수 있 는 함수 입 니 다.첫 번 째 는 초기 화 시 0 으로 되 돌아 갑 니 다.두 번 째 longjmp()함수 호출 후,longjmp()함수 가 setjmp()함 수 를 두 번 째 로 되 돌려 줍 니 다.반환 값 은 longjmp()의 두 번 째 매개 변수 에 의 해 제 시 됩 니 다(정형,이 때 는 0 으로 되 돌아 가지 말 아야 합 니 다).
setjmp()를 사용 하여 jmpb 를 초기 화 한 후,다음 프로그램 에서 임의의 곳 에서 longjmp()함 수 를 사용 하여 setjmp()함수 의 위치 로 이동 할 수 있 습 니 다.longjmp()의 첫 번 째 매개 변 수 는 setjmp()가 초기 화 한 jmpb 입 니 다.방금 설정 한 setjmp()로 돌아 가 려 면 longjmp()함수 의 첫 번 째 매개 변 수 는 setjmp()가 초기 화 한 jmpb 입 니 다.이것 또한 jmpb 라 는 이상 을 설명 합 니 다.일반적으로 전역 변수 로 정의 해 야 합 니 다.그렇지 않 으 면 국부 변수 라면 크로스 함수 호출 시 거의 사용 할 수 없습니다.longjmp()함수 의 두 번 째 인 자 는 setjmp()에 전 달 된 두 번 째 반환 값 입 니 다.이것 은 setjmp()함 수 를 소개 할 때 이미 소개 되 었 습 니 다.
이상 처리 과정
먼저 C++의 이상 처 리 를 비교(참고)해 보 세 요.C++는 언어 층 에 이상 처리 체 제 를 추 가 했 습 니 다.try 블록 을 사용 하여 오류 가 발생 할 수 있 는 코드 를 포함 할 수 있 습 니 다.try 블록 코드 에서 이상 을 던 질 수 있 습 니 다.C+는 throw 를 사용 하여 이상 을 던 질 수 있 습 니 다.이상 을 던 지면 이상 처리 프로그램 으로 이동 합 니 다.C++catch 블록 을 사용 하여 이상 을 처리 하 는 코드 를 포함 합 니 다.catch 블록 은 서로 다른 유형의 이상 을 받 을 수 있 습 니 다.설명 이 필요 한 것 은 throw 는 일반적으로 try 블록 안의 코드 에서 이상 을 던 지지 않 습 니 다.try 블록 안의 코드 는 다른 함 수 를 호출 했 습 니 다.예 를 들 어 함수 A,함수 A 는 함수 B 를 호출 했 습 니 다.throw 는 함수 B 에서 이상 을 던 지 거나 더 깊 은 함수 호출 층 을 던 질 수 있 습 니 다.어쨌든 이상 이 있 으 면 프로그램 은 catch 로 이동 하여 실 행 됩 니 다.
C 에서 어떻게 실현 합 니까?아니면 이 기능 을 모 의 한 것 이 라 고 명확 하 게 말 합 니까?
다음은 간단 한 방법 들 을 소개 한다.
현재 longjmp()의 두 번 째 값 이 1 이 라 고 가정 하면 setjmp()는 두 번 째 로 1 을 되 돌려 줍 니 다.setjmp()와 longjmp()대신 간단 한 매크로 를 사용 합 니 다.
우선 전역 의 이상 을 정의 합 니 다:
jmp_buf Jump_Buffer;
setjmp()는 첫 번 째 호출 초기 화 후 0 으로 되 돌아 가 고 두 번 째 는 0 이 아 닌 매크로 를 정의 하여 C++의 try 에 접근 할 수 있 습 니 다.
#define try if(!setjmp(Jump_Buffer))
setjmp()함수 가 처음 0 일 때,실제 가 아 닌 것 을 가 져 오 면 try 블록 내의 코드 를 실행 합 니 다.예 를 들 어:
try{
Test();
}
longjmp()를 호출 하여 이상 을 던 져 서 setjmp()가 두 번 째 로 되 돌 아 왔 을 때(프로그램 은 setjmp()함수 로 돌아 갑 니 다.이때 실행 해 야 할 것 은 이상 처리 코드 입 니 다.longjmp()는 setjmp()함 수 를 0 이 아 닌 if(!setjmp(JumpBuffer)에서 값 을 가 져 오 는 것 은 가짜 입 니 다.이상 처 리 를 한 다음 에 else 를 사용 해 야 합 니 다.
#define catch else
이렇게 보면 C++와 비슷 합 니 다.setjmp()함수 의 두 번 째 반환 으로 인해 if()의 표현 식 값 이 가짜 이 고 catch 블록 이 실 행 될 수 있 습 니 다.예 를 들 어:
try{
Test();
}catch{
puts("Error");
}
C++와 같은 throw 문 구 를 실현 하고,사실상 롱 jmp(jmpbuf,int)호출:
#define throw longjmp(Jump_Buffer, 1)
이 매크로 를 어떻게 사용 하 는 지 설명 합 니 다.
-------------------------------------------------------------------------------------------------------------------------

#include"stdio.h"
#include"conio.h"
#include"setjmp.h"
jmp_buf Jump_Buffer;
#define try if(!setjmp(Jump_Buffer))
#define catch else
#define throw longjmp(Jump_Buffer,1)
int Test(int T)
{
    if(T>100)
        throw;
    else
          puts("OK.");
    return 0;
}
int Test_T(int T)
{
    Test(T);
    return 0;
}
int main()
{
    int T;
    try{
          puts("Input a value:");
          scanf("%d",&T);
          T++;
          Test_T(T);
      } catch{
          puts("Input Error!");
      }
    getch();
    return 0;
}
여기 서 C 언어 이상 처리 체제 사례 에 대한 설명 은 여기까지 입 니 다.더 많은 C 언어 이상 처리 체제 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 많은 응원 바 랍 니 다!

좋은 웹페이지 즐겨찾기