- 高手潛規則 : 禁用 goto
- 項目經驗 : 程序質量與 goto 的出現次數成反比
- 最後判決 : 將 goto 打入冷宮
#include <stdio.h> #include <malloc.h> void func(int n) { int* p = NULL; if( n < 0 ) { goto STATUS; } p = (int*)malloc(sizeof(int) * n); STATUS: p[0] = n; free(p); } int main() { printf("begin ...\n"); printf("void func( 1 ) :\n"); func(1); printf("void func( -1 ) :\n"); func(-1); printf("end ...\n"); return 0; }
輸出: begin ... void func( 1 ) : void func( -1 ) : 段錯誤 分析: 破壞了程序的結構化特性(順序執行,條件執行,循環執行); 增長閱讀與調試難度。
void 修飾函數返回值和參數函數
- 若是函數沒有返回值,那麼應該將其聲明爲 void
- 若是函數沒有參數,應該聲明參數爲 void
- void 修飾函數返回值和參數是爲了表示 "無"
#include <stdio.h> func() { } int main() { int i = func(1, 2, 3); printf("%d\n", i); return 0; }
輸出:(編譯器無警告,無報錯,輸出隨機值) -1074333820 分析: 沒有寫參數,意味着能夠接收任意多參數 沒有寫返回值,意味着返回值爲 int
不存在 void 變量 (可理解void是一個抽象類型)oop
- C 語言沒有定義 void 到底是多大內存的別名
- 沒有 void 標尺,沒法在內存中裁剪出 void 對應的變量
void code() { void var; void array[5]; void* pv; }
小貼士指針
- ANSI C : 標準 C語言的規範
- 擴展 C : 在 ANSI C 的基礎上進行了擴充
- C 語言的灰色地帶
void code() { printf("%d\n", sizeof(void)); }
上面的代碼在 ASNI C編譯器(BCC)中沒法經過編譯,可是對於支持 GNU 標準的 gcc 編譯器而言是合法的。 BCC : Error GCC : 1
void 指針的意義調試
- C 語言規定只有相同類型的指針才能夠互相賦值
- void* 指針做爲左值用於 接收 任意類型指針
- void* 指針做爲右值使用時須要進行強制類型轉換"
- 指針爲相應機器的固定寬度,能夠裁剪相應的內存大小,因此能夠定義 void* 指針
void code() { int* pI = (int*)malloc(sizeof(int)); char* pC = (char*)malloc(sizeof(int)); void* p = NULL; int* pni = NULL; char* pnc = NULL; p = pI; // OK pni = p; // oops! p = pC; // OK pnc = p; // oops! }
#include <stdio.h> void MemSet(void* src, int length, unsigned char n) { unsigned char* p = (unsigned char*)src; int i = 0; for(i=0; i<length; i++) { p[i] = n; } } int main() { int a[5]; int i = 0; MemSet(a, sizeof(a), 0); for(i=0; i<5; i++) { printf("%d\n", a[i]); } return 0; }
輸出: 0 0 0 0 0
- 現代軟件工程中禁用 goto 語句
- void 是一種抽象的數據類型
- void 數據類型不能用於定義變量
- void 類型用於聲明函數無參數
- void 類型用於聲明函數無返回值
- 能夠定義 void* 類型的指針
- void* 類型的指針能夠接收任意類型的指針
以上內容參考狄泰軟件學院系列課程,請你們保護原創!code