跳到內容

C++ 程式設計/程式碼/標準 C 庫/其他

來自華夏公益教科書,開放的書籍,為開放的世界

其他標準 C 函式

[編輯 | 編輯原始碼]

本節將介紹幾個位於上述細分領域之外的函式,但它們是 C 標準庫的一部分。

語法
#include <cstdlib>
void abort( void );

abort() 函式終止當前程式。根據實現的不同,函式的返回值可以指示取消(例如,您使用 signal() 函式捕獲了 SIGABRT)或失敗的中止。

SIGABRT 是程序在呼叫 abort libc 函式時向自身傳送的訊號,該函式在 cstdlib 中定義。SIGABRT 訊號可以被捕獲,但不能被阻塞;如果訊號處理程式返回,則所有開啟的流將被關閉並重新整理,程式將終止(如果合適,則轉儲核心)。這意味著 abort 呼叫永遠不會返回。由於這種特性,它通常用於在支援庫中發出致命條件的訊號,在這些情況下,當前操作無法完成,但主程式可以在退出之前執行清理。如果斷言失敗,也會使用它。

相關主題
assert - atexit - exit
語法
#include <cassert>
assert( exp );

assert() 宏用於測試錯誤。如果 exp 評估為零,則 assert() 將資訊寫入 stderr 並退出程式。如果定義了 NDEBUG 宏,則 assert() 宏將被忽略。

相關主題
abort
語法
#include <cstdlib>
int atexit( void (*func)(void) );

atexit() 函式會導致程式終止時呼叫 func 指向的函式。您可以多次呼叫 atexit()(至少 32 次,具體取決於您的編譯器),這些函式將按照其建立的相反順序呼叫。atexit() 函式成功返回零,失敗返回非零值。

相關主題
abort - exit
語法
#include <cstdlib>
void* bsearch( const void *key, const void *base, size_t num, size_t size, int (*compare)(const void *, const void *));

bsearch() 函式在一個排序陣列中執行搜尋,返回指向所查詢元素的指標或 NULL

*key 指向與 *base* 中搜索的專案匹配的物件。該陣列包含 num 個元素,每個元素的大小為 size。

compare 函式接受指向陣列中物件的兩個指標 - 這些指標需要先被轉換為正在檢查的物件型別。如果第一個引數應該在第二個引數之前,則該函式返回 -1,如果第一個引數在之後,則返回 1,如果物件匹配,則返回 0。

相關主題
qsort
語法
#include <cstdlib>
void exit( int exit_code );

exit() 函式停止程式。exit_code 被傳遞作為程式的返回值,其中通常零表示成功,非零表示錯誤。

相關主題
abort - atexit - system
語法
#include <cstdlib>
char *getenv( const char *name );

getenv() 函式返回與 name 關聯的環境資訊,並且高度依賴於實現。如果 name 的資訊不可用,則返回 NULL

相關主題
system
語法
#include <csetjmp>
void longjmp( jmp_buf env, int val );

longjmp() 函式的行為就像一個跨函式的 goto 語句:它將執行點移動到 env 中找到的記錄,並導致 setjmp() 返回 val。使用 longjmp() 可能會對 setjmp() 呼叫函式中在初始返回後修改的變數產生一些副作用。

longjmp() 不會呼叫任何建立物件的解構函式。因此,它已被 C++ 異常系統取代,該系統使用 throw 和 catch 關鍵字。

相關主題
setjmp
語法
#include <cstdlib>
void* qsort( const void *base, size_t num, size_t size, int (*compare)(const void *, const void *));

qsort() 函式在一個數組上執行 快速排序。請注意,一些實現可能改為使用更有效的排序演算法。

*base 指向要排序的陣列。該陣列包含 num 個元素,每個元素的大小為 size。

compare 函式接受指向陣列中物件的兩個指標 - 這些指標需要先被轉換為正在檢查的物件型別。如果第一個引數應該在第二個引數之前,則該函式返回 -1,如果第一個引數在之後,則返回 1,如果物件匹配,則返回 0。

相關主題
bsearch
語法
#include <csignal>
int raise(int)

raise() 函式發出引數指定的訊號。

如果失敗,它將返回一個非零值。

相關主題
signal
語法
#include <cstdlib>
int rand( void );

rand() 函式返回一個介於零和 RAND_MAX 之間的偽隨機整數。一個例子

srand( time(NULL) );
for( i = 0; i < 10; i++ )
  printf( "Random number #%d: %d\n", i, rand() );

rand() 函式必須在首次呼叫之前使用 srand() 函式進行播種 - 否則,它將在程式重新啟動時始終返回相同的數字。

注意
隨機數的生成對於 密碼學 至關重要。然而,由計算機模擬的任何 隨機過程(隨機數生成)並非真正隨機,而是偽隨機;也就是說,計算機的隨機性不是來自不穩定化學同位素的隨機放射性衰變,而是來自預定義的隨機過程,這就是為什麼此函式需要播種的原因。

相關主題
srand
語法
#include <csetjmp>
int setjmp( jmp_buf env );

setjmp() 函式將當前執行狀態儲存在 env 中,並返回 0。執行狀態包括有關正在執行的程式碼的基本資訊,以備 longjmp() 函式呼叫。如果並且當 longjmp 被呼叫時,setjmp() 將返回 longjmp 提供的引數 - 但是,在第二次返回時,在初始 setjmp() 呼叫後修改的變數可能具有未定義的值。

緩衝區僅在呼叫函式返回之前有效,即使它是靜態宣告的。

由於 setjmp() 不理解建構函式或解構函式,因此它已被 C++ 異常系統取代,該系統使用 throw 和 catch 關鍵字。

注意
setjmp 似乎不在 std 名稱空間 中。

相關主題
longjmp
語法
#include <csignal>
void (*signal( int sig, void (*handler)(int)) )(int)

signal() 函式接受兩個引數 - 第一個是訊號識別符號,第二個是指向訊號處理程式的函式指標,該處理程式接受一個引數。signal 的返回值是指向先前處理程式的函式指標(如果更改訊號處理程式時出錯,則為 SIG_ERR)。

預設情況下,大多數引發的訊號由處理程式 SIG_DFL(通常會關閉程式的預設訊號處理程式)或 SIG_IGN(忽略訊號並繼續執行程式)處理。

當您指定自定義處理程式並且引發訊號時,訊號處理程式將恢復為預設值。

雖然訊號處理程式被throwcatch取代,但某些系統可能仍然要求您使用這些函式來處理某些重要事件。例如,基於 Unix 的系統上的 SIGTERM 訊號表示程式應儘快終止。

注意
Solaris 中的標準訊號列表
SIGHUP、SIGINT、SIGQUIT、SIGILL、SIGTRAP、SIGABRT、SIGEMT、SIGFPE、SIGKILL、SIGBUS、SIGSEGV、SIGSYS、SIGPIPE、SIGALRM、SIGTERM、SIGUSR1、SIGUSR2、SIGCHLD、SIGPWR、SIGWINCH、SIGURG、SIGIO、SIGSTOP、SIGTSTP、SIGCONT、SIGTTIN、SIGTTOU、SIGVTALRM、SIGPROF、SIGXCPU、SIGXFSZ、SIGWAITING、SIGLWP、SIGFREEZE、SIGTHAW、SIGCANCEL、SIGLOST

相關主題
raise
語法
#include <cstdlib>
void srand( unsigned seed );

srand() 函式用於對 rand() 生成的隨機序列進行播種。對於任何給定的種子rand() 將一次又一次地生成特定的“隨機”序列。

srand( time(NULL) );
for( i = 0; i < 10; i++ )
  printf( "Random number #%d: %d\n", i, rand() );
相關主題
rand
(標準 C 時間和日期函式) time
語法
#include <cstdlib>
int system( const char *command );

system() 函式透過將其傳遞給預設命令直譯器來執行給定的命令。

如果命令執行沒有錯誤,返回值通常為零。如果命令為NULL,system() 將測試是否有可用的命令直譯器。如果有可用的命令直譯器,則將返回非零值,如果沒有,則返回零。

相關主題
exit - getenv
語法
#include <cstdarg>
type va_arg( va_list argptr, type );
void va_end( va_list argptr );
void va_start( va_list argptr, last_parm );

va_arg() 宏用於將可變數量的引數傳遞給函式。

  1. 首先,您必須呼叫 va_start(),傳遞有效的va_list和省略號 ("...") 之前最後一個引數變數的名稱。第一個引數可以是任何東西;一種使用方法是將其作為描述正在傳遞的引數數量的整數。
  2. 接下來,您呼叫 va_arg(),傳遞va_list和要返回的引數型別。va_arg() 的返回值是當前引數。
  3. 對 va_arg() 重複呼叫,以獲取您擁有的引數數量。
  4. 最後,必須呼叫 va_end() 並傳遞va_list以進行適當的清理。
int sum( int num, ... ) {
  int answer = 0;
  va_list argptr;            

  va_start( argptr, num );            

  for( ; num > 0; num-- ) {
    answer += va_arg( argptr, int );
  }           

  va_end( argptr );           

  return( answer );
}             
                

int main( void ) {            

  int answer = sum( 4, 4, 3, 2, 1 );
  printf( "The answer is %d\n", answer );           

  return( 0 );
}

此程式碼顯示 10,即 4+3+2+1。

以下是可變引數函式的另一個示例,它是一個簡單的列印函式

void my_printf( char *format, ... ) {
  va_list argptr;             

  va_start( argptr, format );          

  while( *format != '\0' ) {
    // string
    if( *format == 's' ) {
      char* s = va_arg( argptr, char * );
      printf( "Printing a string: %s\n", s );
    }
    // character
    else if( *format == 'c' ) {
      char c = (char) va_arg( argptr, int );
      printf( "Printing a character: %c\n", c );
      break;
    }
    // integer
    else if( *format == 'd' ) {
      int d = va_arg( argptr, int );
      printf( "Printing an integer: %d\n", d );
    }          

    *format++;
  }            

  va_end( argptr );
}              
                

int main( void ) {             

  my_printf( "sdc", "This is a string", 29, 'X' );         

  return( 0 );
}

此程式碼在執行時顯示以下輸出

Printing a string: This is a string
Printing an integer: 29
Printing a character: X
華夏公益教科書