【C】 06 - 標準庫概述

來源:互聯網
上載者:User

標籤:style   blog   color   os   使用   io   strong   ar   檔案   

  任何程式都會有一些通用的功能需求,對這些需求的實現組成了庫。它可以提高程式的複用性、健壯性和可移植性,這也是模組化設計的體現。C規範定義了一些通用介面庫,這裡只作概述性介紹,具體細節當然還是要查閱規範。

  為了提高效率,C的很多庫函數會同時有一個宏定義的版本,所以傳遞參數時盡量使用沒有副作用的運算式,以免發生錯誤。若不想使用宏版本的函數,可以採用三個方法:(1)先undef宏;(2)函數名用括弧括起來;(3)不include標頭檔。

// method 1#include <stdlib.h>#undef atoiatoi("123");// method 2#include <stdlib.h>(atoi)("123");// method 3extern int atoi(const char*);atoi("123");

  輸入輸出庫<stdio.h>包含對檔案的操作、對流的控制、輸入輸出。C的所有讀寫對象被稱為流,它的所有資訊包含在結構體FILE裡,包含buffer、位置資訊等。系統有3個全域指標變數(stdin、stdout、stderr)指向預定義的流,分別是scanf、printf、assert的預設流。庫中對檔案的操作包括刪除、重新命名、開啟、關閉、buffer設定等。對流的控制包括重新整理、位置擷取和設定、錯誤處理等。輸入輸出包括直接輸入輸出、字元和字串的輸入輸出、格式化輸入輸出等,相對應的寬字元輸入輸出在<wchar.h>中定義。標準庫對buffer邊界的檢查不是很嚴格,如需更安全的介面,請查看ISO/IEC TR 24731。以printf為例,格式化輸出提供了度量類型的可控格式輸出。scanf的格式比printf簡單,不作介紹,僅需注意其中空白僅起分割作用。每個格式的形式為%[flags][width][.precision][length]type,方括弧為可選,具體意義如下表所示。參數傳遞時會先做整型提升、float轉為double、指標轉為void*,length和type共同決定最終輸出的類型,而不是未經處理資料的類型。

flag -  靠左對齊, 預設靠右對齊
+  顯示符號, 預設僅顯示負號
空格  不顯示符號的正數符號位用空格
#  8/16進位顯示首碼, 浮點數總顯示小數點
0  整數和浮點前置0填充, 若靠左對齊或整數有精度則不填充
width 正整數, *  顯示的最小寬度, *表示最小寬度由參數決定
precision 正整數, 空  整數的最少數字, g/G的最多有效位, 其它浮點數的小數位元, 為空白表示0
length hh, h, l, ll, j, z, t  整數分別為char/short/long/long long/intmax_t/size_t/ptrdiff_t, n為相應指標, lc為wint_t, ls為wchar_t
L  浮點數為long double
type d, i, o, u, x, X  整數, d/i為有符號整數, o/u/x/X為8/10/16進位不帶正負號的整數
f, F, e, E, g, G, a, A  浮點數, f/F為10進位浮點, e/E為10進位科學記號標記法, g/G為前兩者較短者, a/A為16進位科學記號標記法
c, s  c為字元, s為字串
p  指標
n  向整型指標參數寫入已列印的字元數
%  %

  可變參數庫<stdarg.h>舊名<varargs.h>,提供了一些宏擷取隱式參數。函數參數的壓棧順序是基於實現的,所以編譯器也要負責可變參數的管理。參數序列的資訊的地址存放在va_list(指標)裡,它通過va_start從參數中擷取,或者用va_copy拷貝得來。va_arg從列表頭部擷取某個類型的參數,取完後從列表中刪除。va_clean徹底釋放列表資訊。

// interfaces of <stdarg.h>void va_start(va_list ap, paraN);void va_copy(va_list dst, va_list src);type va_arg(va_list ap, type);void va_end(va_list ap);// example#include <stdarg.h>#include <stdio.h>void fun(int n, ...){    va_list va, copy;    int a;    va_start(va, n);    va_copy(copy, va);    a = va_arg(va, int);    va_end(va);    va_end(copy);}

  通用函數庫<stdlib.h>提供了非常多的常用介面,它原本也是標準庫的大本營。包含字串轉為數、隨機數產生、動態記憶體管理、系統控制和調用、排序尋找演算法、整數的絕對值和除法、寬字元和多位元組字元的轉換等。通用宏定義<stddef.h>包含一些常用宏定義,包含ptrdiff_t、size_t、wchar_t、NULL、offsetof、max_align_t等。時間庫<time.h>包含了時間和日期的擷取和格式化列印,本地化庫<local.h>可以將C配置成符合各地區習慣的書寫風格,預設在初始化時設定為setlocal(LC_ALL,"C")。

// some interfaces in <stdlib.h>int atoi(const char* nptr);double atof(const char* nptr);int rand(void);void srand(unsigned int seed);void* malloc(size_t size);void* realloc(void* ptr, size_t size);_Noreturn void abort(void);int system(const char* string);void qsort(void* base, size_t nmemb, size_t size, int (*compar)(const void*, const void*));void* bsearch(const void* key, const void* base, size_t nmemb, size_t size, int (*compar)(const void*, const void*));int abs(int j);div_t div(int numer, int denom);int mbtowc(wchar_t* restrict pwc, const char* restrict s, size_t n);

  範圍庫<limits.h>定義了各類整型的取值範圍,整數類型庫<stdint.h>定義了各種長度要求的整型及其取值範圍。整數類型庫<inttypes.h>包含<stdint.h>,另外還有為各種整型在格式化輸入輸出定義了格式宏,以及這些整型的對應的通用庫(<stdlib.h>)。浮點庫<float.h>定義平台浮點表示的具體細節,包括各個域的範圍等。浮點環境庫<fenv.h>包括浮點運算環境的擷取和配置,以及當前浮點運算的狀態和異常資訊等。

// some macros in <limits.h>#define CHAR_BIT     8#define SCHAR_MIN    -128#define INT_MAX      (-2147483647 - 1)// some macros in <stdint.h>#define int32_t      int#define intmax_t     long long#define INT32_MAX    INT_MAX// some macros in <inttypes.h>#include <stdint.h>#define PRId64 "lld"intmax_t imaxabs(intmax_t j);intmax_t strtoimax(const char* restrict nptr, char** restrict endptr, int base);

  數學函數庫<math.h>定義了各種浮點數的數學函數,複數函數庫<complex.h>定義了複數相關的宏以及複數的數學函數,<tgmath.h>包含了前兩者,並為相同的函數使用了統一的宏(名稱和中<math.h>一樣)。

  字元類型庫<ctype.h>和寬字元類型庫<wctype.h>提供了介面判斷字元的類型,還可以進行大小寫轉換。字串庫<string.h>提供了對字串(記憶體段)的操作,包括複製、串連、尋找等。寬字元庫<wchar.h>包含各種函數的寬字元版本,包括格式化輸入輸出、字串操作、時間顯示、寬字元與單字元的轉換等。unicode庫<uchar.h>包括對unicode的操作和轉換,符號庫<iso646.h>為iso_646中沒有的符號提供了單詞表示,比如and表示&&。

// some interfaces in <ctype.h>int isdigit(int c);int islower(int c);int toupper(int c);// some interfaces in <string.h>void* memcpy(void* restrict s1, const void* restrict s2, size_t n);char* strcpy(char* restrict s1, const char* restrict s2);char* strcat(char* restrict s1, const char* restrict s2);int memcmp(const void* s1, const void* s2, size_t n);char* strstr(const char* s1, const char* s2);

  長跳轉庫<setjmp.h>提供了函數間直接跳轉的介面,用於快速回到舊的執行點。jmp_buf是個數群組類型,它儲存了跳轉的必要資訊。setjmp儲存當前點,longjmp跳轉到某個時間點。setjmp返回0表示是從setjmp返回的,否則是從longjmp跳轉的。訊號庫<signal.h>提供了向系統註冊訊號回呼函數和發起訊號的介面,檢查庫<assert.h>在運行或編譯時間檢查條件並報錯,錯誤號碼庫<errno.h>中定義的全域變數記錄了上一次出錯的編號。

#include <setjmp.h>jmp_buf buf;void f(void) {g();}void g(void) {longjmp(buf, 1);}int main (void){    if (0 == setjmp(buf)) f();    // from setjmp    else {}                       // from longjmp}

  庫<stdbool.h><stdalign.h><stdnoreturn.h>為新加的關鍵字定義了全小寫宏。庫<threads.h><stdatomic.h>提供了線程和原子操作相關的宏和介面,相應內容在這裡已被全部忽略(沒仔細看,也沒看懂),請參考規範相應內容(包括關鍵字_Thread_local和_Atomic的使用)。

 

【全篇完】

 

【C】 06 - 標準庫概述

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.