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

C語言易忽略細節精選(第四彈):void*運算、static、return/exit、setbuf、多維數組、標號作用域

     編輯:關於C語言

C語言易忽略細節精選(第四彈)

1. void* 不能參與算術運算

原因:指針運算需知道對象大小(如 p+1 移動 sizeof(*p) 字節),void* 無類型信息,無法計算偏移。僅允許賦值、比較、sizeof。

2. 不能對非左值取地址

  • 字面常量(&10)無地址,存符號表。
  • 數組名是指針常量:int a[10] ≡ int *const a;int b[3][4] ≡ int (*const b)[4]。不可修改數組名值。

3. return 0 vs exit(0)

4. static 減少命名衝突

static int a; 限制符號在文件內可見,多文件可定義同名 static 變量互不干擾。函數同理。

5. setbuf 緩衝區陷阱

char buf[BUFSIZ];
setbuf(stdout, buf);  // 錯誤!buf 在 main 棧上,main 結束前被釋放,運行時庫清理時訪問野指針
// 修正:
static char buf[BUFSIZ];           // 靜態存儲期
// 或 全局定義
// 或 setbuf(stdout, malloc(BUFSIZ)); // 動態分配不主動釋放

6. 多維數組參數傳遞

  • 元素按行優先存儲,需知列數計算偏移。
  • 編譯器計算地址不需第一維長度,故可省略:void f(int a[][4][5])。
  • C/C++ 不檢查越界,編譯器不依賴第一維長度。

7. 多維數組轉指針等價形式

a[i][j]  ≡  *(a[i] + j)  ≡  (*(a + i))[j]  ≡  *(*(a + i) + j)

8. 下標運算符返回左值引用

a[3] = 100;  ≡  int &ri = a[3]; ri = 100;

9. 動態多維數組接收類型

char *q = new char[5]; delete []q;
char (*p)[4] = new char[5][4]; delete []p;  // 指向數組的指針,非元素指針

10. 標號與作用域

  • 標號(label:)具有**函數作用域**,無論定義在何處(即使嵌套塊內),函數體任處可 goto label。
  • 局部變量遮蔽同名全局變量,可用 ::a 訪問全局(C++),C 中無此運算符需避免同名。

這些細節往往隱藏在代碼角落,一旦觸發極難排查,寫入肌肉記憶才是真功夫。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
return 0exit(0)
層級語言級(函數返回)系統調用級(進程終止)
控制權交給調用者交給操作系統
清理調用棧展開,調用析構/清理函數運行時庫清理(刷新流、調用 atexit)
main 中等價於 exit(0)直接終止進程