C語(yǔ)言標(biāo)準(zhǔn)庫(kù)<math.h>和<setjmp.h>的實(shí)現(xiàn)
<math.h>
簡(jiǎn)介
<math.h> 是 C 標(biāo)準(zhǔn)庫(kù)中的一個(gè)頭文件,主要提供了數(shù)學(xué)運(yùn)算相關(guān)的函數(shù)和宏定義。它允許您在 C 程序中執(zhí)行各種常見的數(shù)學(xué)計(jì)算,如三角函數(shù)、對(duì)數(shù)、指數(shù)、冪運(yùn)算等。
庫(kù)宏
下面是這個(gè)庫(kù)中定義的唯一的一個(gè)宏:
HUGE_VAL 是 <math.h> 頭文件中定義的一個(gè)宏,用于表示一個(gè)特定的很大的值。當(dāng)數(shù)學(xué)函數(shù)的結(jié)果無法表示為浮點(diǎn)數(shù)時(shí),可以使用 HUGE_VAL 來表示超出范圍的結(jié)果。
具體來說,如果函數(shù)的結(jié)果幅度太大以至于無法表示,則函數(shù)會(huì)將 errno 設(shè)置為 ERANGE,表示范圍錯(cuò)誤,并返回 HUGE_VAL 或 -HUGE_VAL。這允許您判斷函數(shù)是否返回了一個(gè)超出可表示范圍的值。
另一方面,如果函數(shù)的結(jié)果幅度太小,則可能會(huì)返回零值。在這種情況下,errno 可能被設(shè)置為 ERANGE,也可能不被設(shè)置為 ERANGE。因此,在使用數(shù)學(xué)函數(shù)并處理其返回值時(shí),需要注意檢查 errno 的值是否指示了錯(cuò)誤。
總之,HUGE_VAL 宏對(duì)于處理超出可表示范圍的數(shù)值是非常有用的,可以幫助進(jìn)行錯(cuò)誤處理和邊界檢查。
庫(kù)函數(shù)
下面列出了頭文件 math.h 中定義的函數(shù):
double acos(double x):返回以弧度表示的 x 的反余弦。
double asin(double x):返回以弧度表示的 x 的反正弦。
double atan(double x):返回以弧度表示的 x 的反正切。
double atan2(double y, double x):返回以弧度表示的 y/x 的反正切。y 和 x 的值的符號(hào)決定了正確的象限。
double cos(double x):返回弧度角 x 的余弦。
double cosh(double x):返回 x 的雙曲余弦。
double sin(double x):返回弧度角 x 的正弦。
double sinh(double x):返回 x 的雙曲正弦。
double tanh(double x):返回 x 的雙曲正切。
double exp(double x):返回 e 的 x 次冪的值。
double frexp(double x, int *exponent):把浮點(diǎn)數(shù) x 分解成尾數(shù)和指數(shù)。返回值是尾數(shù),并將指數(shù)存入 exponent 中。所得的值是 x = mantissa * 2 ^ exponent。
double ldexp(double x, int exponent):返回 x 乘以 2 的 exponent 次冪。
double log(double x):返回 x 的自然對(duì)數(shù)(基數(shù)為 e 的對(duì)數(shù))。
double log10(double x):返回 x 的常用對(duì)數(shù)(基數(shù)為 10 的對(duì)數(shù))。
double modf(double x, double *integer):返回值為小數(shù)部分(小數(shù)點(diǎn)后的部分),并設(shè)置 integer 為整數(shù)部分。
double pow(double x, double y):返回 x 的 y 次冪。
double sqrt(double x):返回 x 的平方根。
double ceil(double x):返回大于或等于 x 的最小的整數(shù)值。
double fabs(double x):返回 x 的絕對(duì)值。
double floor(double x):返回小于或等于 x 的最大的整數(shù)值。
double fmod(double x, double y):返回 x 除以 y 的余數(shù)。
實(shí)例
以下是一個(gè)簡(jiǎn)單的代碼示例,展示了如何使用 <math.h> 頭文件中的一些函數(shù)來進(jìn)行數(shù)學(xué)計(jì)算:
#include <stdio.h>
#include <math.h> // 引入 math.h 頭文件
int main() {
double x = 1.5;
double y = 2.7;
// 計(jì)算 x 的雙曲正弦值和反正切值
double sinh_x = sinh(x);
double atan_x = atan(x);
// 計(jì)算 x 的立方根和以 2 為底的對(duì)數(shù)
double cbrt_x = cbrt(x);
double log2_x = log2(x);
// 計(jì)算 y 的向下取整值和 x 與 y 的余數(shù)
double floor_y = floor(y);
double fmod_xy = fmod(x, y);
// 打印計(jì)算結(jié)果
printf("sinh(%.2f) = %.2f\n", x, sinh_x);
printf("atan(%.2f) = %.2f\n", x, atan_x);
printf("cbrt(%.2f) = %.2f\n", x, cbrt_x);
printf("log2(%.2f) = %.2f\n", x, log2_x);
printf("floor(%.2f) = %.2f\n", y, floor_y);
printf("%.2f %% %.2f = %.2f\n", x, y, fmod_xy);
return 0;
}
需要注意的是,這些函數(shù)在使用的時(shí)候需要特別小心,因?yàn)樗鼈冇锌赡軙?huì)產(chǎn)生一些異常情況(例如超出計(jì)算機(jī)數(shù)值范圍等)。
讓我們編譯和運(yùn)行上面的程序,這將產(chǎn)生下列結(jié)果:
sinh(1.50) = 2.13
atan(1.50) = 0.98
cbrt(1.50) = 1.14
log2(1.50) = 0.58
floor(2.70) = 2.00
1.50 % 2.70 = 1.50
<setjmp.h>
簡(jiǎn)介
<setjmp.h> 是 C 標(biāo)準(zhǔn)庫(kù)中的一個(gè)頭文件,提供了一種非局部跳轉(zhuǎn)的機(jī)制,允許程序在一個(gè)函數(shù)中設(shè)置一個(gè)跳轉(zhuǎn)點(diǎn),并在另一個(gè)函數(shù)中跳轉(zhuǎn)到該點(diǎn)。
庫(kù)變量
<setjmp.h> 頭文件并沒有定義任何變量。只定義了 jmp_buf 類型作為 setjmp 和 longjmp 函數(shù)的參數(shù)類型。jmp_buf 是一個(gè)用于存儲(chǔ)跳轉(zhuǎn)點(diǎn)信息的數(shù)組類型,具體的實(shí)現(xiàn)細(xì)節(jié)是未定義的,通常被編譯器實(shí)現(xiàn)為一個(gè)足夠大的數(shù)組。
請(qǐng)注意,雖然 <setjmp.h> 中沒有定義變量,但您可以在程序中創(chuàng)建自己的 jmp_buf 變量,并將其傳遞給 setjmp 和 longjmp 函數(shù)來實(shí)現(xiàn)非局部跳轉(zhuǎn)的功能。
庫(kù)函數(shù)
<setjmp.h> 頭文件中定義了兩個(gè)函數(shù):setjmp 和 longjmp,用于實(shí)現(xiàn)非局部跳轉(zhuǎn)和異常處理機(jī)制。
1、int setjmp(jmp_buf env) 函數(shù)
該函數(shù)將調(diào)用它的地方的當(dāng)前執(zhí)行狀態(tài)保存在 env 中,并返回 0。如果 setjmp 是由 longjmp 跳轉(zhuǎn)回來的,則返回一個(gè)非零值。
2、void longjmp(jmp_buf env, int val) 函數(shù)
該函數(shù)根據(jù)傳遞的 env 參數(shù),恢復(fù)相應(yīng)的執(zhí)行狀態(tài),并跳轉(zhuǎn)到相應(yīng)的位置。val 參數(shù)是返回到 setjmp 的返回值。
這兩個(gè)函數(shù)一起提供了非常有用的異常處理機(jī)制,通常用于處理錯(cuò)誤或異常情況,以及在程序中實(shí)現(xiàn)類似于異常處理的功能。
使用 <setjmp.h> 頭文件時(shí),需要注意以下幾點(diǎn):
- setjmp 和 longjmp 必須在同一個(gè)函數(shù)調(diào)用鏈中使用,而且 setjmp 必須在 longjmp 之前調(diào)用。
- jmp_buf 類型是一個(gè)數(shù)組類型,它存儲(chǔ)了用于保存執(zhí)行狀態(tài)的信息。然而,具體的實(shí)現(xiàn)細(xì)節(jié)是未定義的,因此不能直接訪問 jmp_buf 的成員。
- 使用 setjmp 和 longjmp 時(shí)應(yīng)謹(jǐn)慎,因?yàn)樗鼈儠?huì)導(dǎo)致程序的控制流程變得復(fù)雜,并且可能使代碼更難理解和維護(hù)。
需要注意的是,<setjmp.h> 頭文件提供了一種非常底層的編程機(jī)制,一般情況下并不推薦頻繁使用。
實(shí)例
#include <stdio.h>
#include <setjmp.h>
jmp_buf exception_env; // 用于保存執(zhí)行狀態(tài)的全局變量
void handle_exception() {
printf("捕獲到異常,進(jìn)行異常處理\n");
}
void do_something_dangerous(int input) {
if (input < 0) {
longjmp(exception_env, 1); // 跳轉(zhuǎn)到異常處理代碼
} else {
printf("正常處理輸入:%d\n", input);
}
}
int main() {
if (setjmp(exception_env) == 0) { // 設(shè)置異常跳轉(zhuǎn)點(diǎn)
// 正常情況
do_something_dangerous(10);
do_something_dangerous(-5); // 這里會(huì)觸發(fā)異常
do_something_dangerous(20); // 這里不會(huì)執(zhí)行
} else {
// 異常處理
handle_exception();
}
return 0;
}
讓我們編譯并運(yùn)行上面的程序,這將產(chǎn)生以下結(jié)果:
正常處理輸入:10
捕獲到異常,進(jìn)行異常處理
這個(gè)示例中定義了一個(gè)全局的 jmp_buf 類型的變量 exception_env,用于保存執(zhí)行狀態(tài)。在 main 函數(shù)中,通過 setjmp 設(shè)置了一個(gè)異常跳轉(zhuǎn)點(diǎn),并在 do_something_dangerous 函數(shù)中對(duì)輸入進(jìn)行判斷,如果輸入小于 0,則調(diào)用 longjmp 跳轉(zhuǎn)到異常處理代碼。在跳轉(zhuǎn)回來后,程序可以進(jìn)行相應(yīng)的異常處理。
需要注意的是,setjmp 和 longjmp 是比較底層的機(jī)制,使用時(shí)需要特別小心,因?yàn)樗鼈儠?huì)使程序的控制流程變得復(fù)雜,也容易引入難以調(diào)試的錯(cuò)誤。
到此這篇關(guān)于C語(yǔ)言標(biāo)準(zhǔn)庫(kù)<math.h>和<setjmp.h>的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)C語(yǔ)言 <math.h>和<setjmp.h>內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語(yǔ)言實(shí)現(xiàn)將字符串轉(zhuǎn)換為數(shù)字的方法
這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)將字符串轉(zhuǎn)換為數(shù)字的方法,涉及系統(tǒng)函數(shù)atoi()函數(shù)的使用技巧,需要的朋友可以參考下2014-12-12
C++標(biāo)準(zhǔn)模板庫(kù)函數(shù)sort的那些事兒
sort函數(shù)是標(biāo)準(zhǔn)模板庫(kù)的函數(shù),已知開始和結(jié)束的地址即可進(jìn)行排序,可以用于比較任何容器(必須滿足隨機(jī)迭代器),任何元素,任何條件,執(zhí)行速度一般比qsort要快2013-09-09
C++實(shí)現(xiàn)的一個(gè)可以寫遞歸lambda的Y函數(shù)
這篇文章主要介紹了C++實(shí)現(xiàn)的一個(gè)可以寫遞歸lambda的Y函數(shù),在Y函數(shù)的幫助,這個(gè)lambda表達(dá)是可以成功看到自己,然后遞歸調(diào)用的,需要的朋友可以參考下2014-07-07
c++實(shí)現(xiàn)圖像像素計(jì)算的示例詳解
我們知道每張圖像都能夠用矩陣來表示,矩陣中每個(gè)元素的值表示了圖像中每個(gè)像素值,像素值的大小就對(duì)應(yīng)著圖像的亮暗,本文主要來和大家介紹一下C++進(jìn)行圖像像素計(jì)算的相關(guān)知識(shí),感興趣的可以了解下2023-12-12

