setjmp được sử dụng để đặt một dấu hiệu đến nơi cuộc gọi của longjump sẽ trả về, nó trả về 0 nếu nó được gọi trực tiếp, nó trả về 1 nếu được gọi vì longjmp đến setjmp đó được gọi.
Bạn phải suy nghĩ về setjmp như một cái gì đó có thể được gọi bình thường và không làm bất cứ điều gì (trở về 0) trong hoạt động bình thường trong khi trả về 1 và nó gián tiếp gọi (và trở về từ đó) khi một bước nhảy dài được gọi. Tôi biết những gì bạn có nghĩa là về bối rối vì nó thực sự khó hiểu ..
này được ví dụ do wikipedia:
#include <stdio.h>
#include <setjmp.h>
static jmp_buf buf;
void second(void)
{
printf("second\n"); // prints
longjmp(buf,1); // jumps back to where setjmp was called - making setjmp now return 1
}
void first(void)
{
second();
printf("first\n"); // does not print
}
int main()
{
if (! setjmp(buf))
{
first(); // when executed, setjmp returns 0
}
else
{ // when longjmp jumps back, setjmp returns 1
printf("main"); // prints
}
return 0;
}
Bạn có thể hiểu được nó? Khi chương trình được khởi chạy setjmp
được thực hiện bằng chính và trả về 0 (vì nó được gọi trực tiếp), do đó, first
được gọi, gọi second
và sau đó đến longjmp
chuyển ngữ cảnh quay trở lại nơi setjmp
đã được sử dụng, nhưng lần này, vì nó trở lại từ một bước nhảy và nó được gián tiếp gọi là hàm trả về 1.
Điều hữu ích của phương pháp setjmp/longjmp là bạn có thể xử lý các tình huống lỗi mà không cần giữ cờ giữa các cuộc gọi hàm (đặc biệt là khi bạn có nhiều , suy nghĩ về một thủ tục đệ quy cho typechecking trong một trình biên dịch). Nếu có điều gì đó sai trong việc đánh máy sâu trong ngăn xếp cuộc gọi bình thường, bạn phải trả lại một lá cờ và tiếp tục trả lại nó để cảnh báo người gọi rằng việc gõ lỗi đã thất bại. Với longjmp bạn chỉ cần đi ra ngoài và xử lý lỗi mà không cần quan tâm đến việc truyền lại cờ. Vấn đề duy nhất là điều này buộc một chuyển đổi ngữ cảnh không quan tâm đến deallocation chuẩn của bộ nhớ stack/heap, do đó bạn nên xử lý nó một mình.
người đàn ông tuyệt vời, cảm ơn –
Là longJmp như ném, và nó được gọi là ngay sau khi nơi mà ngoại lệ có thể được nâng lên. Và cũng tại sao bạn sử dụng số 42, bạn có thể thực hiện cùng một công việc 1, hoặc là 42 bất kỳ số nguyên dương nào khác 0. –
Điểm quan trọng là hàm setjmp() có thể trả về một lần, hoặc nó có thể trở lại nhiều lần. Nó sẽ trở lại một lần từ 'lời gọi trực tiếp' (sẽ trả về 0); bất kỳ trở về sau là kết quả của một longjmp() và sẽ trả về một giá trị khác không. –