首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> C 語言入門

C語言常用庫函數深度解析:exit、memset 實戰與避坑指南

     編輯:C 語言入門

C 標準庫函數是系統編程的基石。本文深度解析 exit() 進程終止語義與 memset() 內存填充機制,結合實戰代碼演示常見誤區與最佳實踐。

1. exit():進程終止的標準方式

#include 
void exit(int status);

核心語義

  • 立即終止進程:無論在 main 還是任意嵌套函數中調用,進程直接退出。
  • 狀態碼語義:status=0 表示成功,非零 表示失敗(具體值可自定義錯誤類型)。
  • 清理動作:刷新所有輸出流、關閉打開流、調用 atexit() 註冊的函數(逆序)、調用 C++ 局部靜態對象析構函數、返回狀態碼給父進程/Shell。
  • 不返回:exit() 永不返回,後續代碼不可達。

exit vs return 對比

關鍵區別:局部對象析構

#include 
#include 

class A { public: ~A() { printf("~A()\n"); } };

void foo() {
    A a;
    exit(0);  // 直接退出,~A() 不調用!
}

int main() {
    foo();
    return 0; // 正常返回,~A() 會調用(但這裡執行不到)
}

結論:C++ 代碼中優先使用 return 或拋出異常,避免 exit() 導致資源洩漏(鎖、內存、文件句柄等)。

2. memset():內存填充的「字節級」語義

#include 
void* memset(void* s, int c, size_t n);

參數含義

  • s:目標內存起始地址
  • c:填充值(取 unsigned char 低 8 位)
  • n:填充字節數
  • 返回值:s

經典誤區:以為按 int 填充

int arr[5];
memset(arr, 1, sizeof(arr));  // 錯誤!每字節填 0x01
// 結果:每個 int = 0x01010101 = 16843009,而非 1

正確用法場景

特性exit(status)return status (在 main)
作用域整個進程僅 main 函數
調用位置任意函數僅 main
流刷新是是
atexit 執行是是
C++ 靜態對象析構是是
局部對象析構否 (棧不展開)是 (正常返回展開棧)
場景填充值代碼示例
結構體/數組置零0memset(&st, 0, sizeof(st))
字符數組置特定字符'a', '0'memset(buf, '0', len)
標志位數組置 0xFF-1 (即 0xFF)memset(flags, -1, n)
鏈表節點初始化0memset(pNode, 0, sizeof(Node))

實戰演示

#include 
#include 

int main() {
    char str[] = "abcde";
    printf("原始: %s\n", str);        // abcde
    
    memset(str, 0, strlen(str));     // 置零(字符串結束符)
    printf("置零: [%s]\n", str);      // 空字符串
    
    memset(str, '0', strlen(str));   // 填充字符 '0'
    printf("填'0': %s\n", str);       // 00000
    
    int arr[3] = {1,2,3};
    memset(arr, 0, sizeof(arr));     // 正確置零 int 數組
    printf("arr[0]=%d\n", arr[0]);    // 0
    
    return 0;
}

3. 避坑檢查清單

  1. memset 只能按字節填充:不可直接填充多字節整數(除非值為 0 或 -1/0xFF 等字節全同模式)。
  2. 結構體填零陷阱:浮點數 0.0 位模式全 0 可用 memset;指針 NULL 位模式全 0 在絕大多數平台可用,但標準不保證。
  3. exit 在 C++ 中慎用:優先 RAII + 異常 / return,確保析構函數執行。
  4. atexit 註冊順序:後註冊先執行(LIFO),適合資源反向釋放。

熟練掌握 exit 與 memset 的語義邊界,是編寫健壯 C/C++ 系統代碼的基本功。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved