【C】 8_goto 和 void 分析

遭人遺棄的 goto

  • 高手潛規則 : 禁用 goto
  • 項目經驗 : 程序質量與 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
    • 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!  
}

實例分析:經過 void* 實現 MemSet 函數

#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

相關文章
相關標籤/搜索