C語言基礎及指針⑨聯合體與枚舉

接續上篇C語言基礎及指針⑧文件IO

在上篇中 , 我們初步了解了C語言的IO操作 , 編寫IO操作的大致流程:

文件IO編寫步驟:

1.使用fopen函數 , 得到文件指針
2.指定fopen的操作模式r,w (指定輸入輸出流)
3.創建緩沖區 , 緩存讀寫數據(將流數據讀入到內存或寫入到磁盤)
3.關閉流 (關閉文件流)

接著介紹了文件的加密解密 , 文件的存儲都是以二進制保存在磁盤上的 , 所以我們可以通過二進制運算來進行文件的加密解密操作 。在C語言的IO函數中 , 沒有直接獲取文件大小的函數 , 所以我們需要自己通過文件指針來獲取文件的大小:

/*獲取文件大小*/
void getFileSize() {

    char* path = "E:\\android_pdf\\研磨設計模式.pdf";
    // 打開文件
    FILE* fp = fopen(path, "r");
    if (fp == NULL) {
        printf("打開文件失敗\n");
        return;
    }

    // 重新定位文件指針 , SEEK_END文件末尾,0是文件指針的偏移量
    fseek(fp, 0l, SEEK_END);
    // 返回當前的文件指針,相對于文件開頭的位移量
    long fileSize = ftell(fp);

    printf("文件大小:%ld M\n", fileSize / 1024 / 1024);

}

在jni.h中 , 我們可以看到這樣一段代碼:

typedef union jvalue {
    jboolean    z;
    jbyte       b;
    jchar       c;
    jshort      s;
    jint        i;
    jlong       j;
    jfloat      f;
    jdouble     d;
    jobject     l;
} jvalue;

這樣C語言中的聯合體 , 那么什么是聯合體呢 ?

聯合體:不同類型的變量共用一段內存(相互覆蓋) , 始終只有一個成員存在 , 最后賦值的那個 , 有利于節省內存。
聯合體大小:成員中最大的成員所占的字節數

聯合體 , 將不同的類型聯合起來 , 組成一個新的聚合類型 , 這個類型可以是聯合體中的任意類型 。

/*聯合體*/
/*
    不同類型的變量共用一段內存(相互覆蓋) , 始終只有一個成員存在 , 最后賦值的那個 , 有利于節省內存
    聯合體大小:成員中最大的成員所占的字節數
*/
union mValue
{
    int     i;
    short   s;
    long    l;
    float   f;

};

/*聯合體示例*/
void useUnion() {
    union mValue m;
    m.f = 23.4f;
    m.i = 100;  // 最后一次賦值有效

    printf("聯合體:\n%f - %d\n", m.f, m.i);
}

在java中 , 當我們需要一個類列舉幾個狀態時 , 因為狀態是固定的 , 所以我們通常的做法是使用枚舉 , 將狀態列舉出來 , 在C語言也有枚舉這個類型:

/*
    枚舉(列舉所有的情況)
    限定值,保證取值的安全性
*/
enum NetStatus {
    NET_SUCEESS,
    NET_ERROR,
    NOT_NET,
    NET_FAILURE
};

下面我們來看一個示例 , 來大致了解一下枚舉的使用場景:

/*枚舉*/
/*
    枚舉(列舉所有的情況)
    限定值,保證取值的安全性
*/
enum NetStatus {
    NET_SUCEESS,
    NET_ERROR,
    NOT_NET,
    NET_FAILURE
};

/*模擬網絡請求*/
void requestHttp(char* url, void(*callBack)(enum NetStatus status,char* res)) {
    printf("請求地址:%s\n", url);
    printf("請求網絡....\n");
    Sleep(2000);
    enum NetStatus status = NET_SUCEESS;
    char* res = "如果 愛情是一場花火 ,一閃即逝的花火,我也要去追求\n";
    callBack(status, res);
}

/*網絡回調函數*/
void callBackHttp(enum NetStatus status, char* res) {
    switch (status)
    {
    case NET_SUCEESS:
        printf("網絡數據:\n%s", res);
        break;
    case NET_ERROR:
        printf("請求網絡錯誤\n");
        break;
    case NOT_NET:
        printf("沒有網絡\n");
        break;
    case NET_FAILURE:
        printf("請求網絡失敗\n");
        break;
    default:
        printf("未知錯誤\n");
        break;
    }
}

/*枚舉示例*/
void useEnum() {
    enum NetStatus status = NET_FAILURE;

    printf("枚舉中元素的值:%d\n", status);

    char* url = "http://www.zhuyongit.com";
    requestHttp(url, callBackHttp);
}

我們模擬了網絡請求的幾種情況 , 成功 , 失敗 , 錯誤等等 , 通過枚舉將這些情況列舉出來 ,然后通過網絡回調函數傳遞到網絡處理函數 , 通過switch分支語句來進行不同網絡狀態的判斷 。

在jni.h頭文件中 , 我們也可以見到類似的應用:

typedef enum jobjectRefType {
    JNIInvalidRefType = 0,
    JNILocalRefType = 1,
    JNIGlobalRefType = 2,
    JNIWeakGlobalRefType = 3
} jobjectRefType;

使用枚舉來標識對象引用的類型 , 本地引用,全局引用,弱引用,等等 ,因為我們在使用jni調取java對象的時候 , java虛擬機并沒有將引用數加1 , 所以我們需要用過加強引用類型 , 來保證jni引用的java對象,不被虛擬機回收掉 。

在IT的路上 , 山路崎嶇 , 山崖陡峭 , 自學如在荊棘滿布的叢林中 , 披荊斬棘 , 在渾濁的河流中 , 摸著石頭過河 。何以保證我們走的是正確的方向 , 長沙動腦學院 , 老司機眾多 , 功力深厚 , 開車穩當 , 都是互聯網老兵 , 他們是IT路上的探頭燈 , 幫你指明方向 , 帶你超神 , 他們的宗旨是:做一家受人尊敬的企業,做一位受人尊敬的老師【動腦學院】。 --- 特約贊助

Android程序員學C系列:
C語言基礎及指針①
C語言基礎及指針②之指針內存分析
C語言基礎及指針③函數與二級指針
C語言基礎及指針④函數指針
C語言基礎及指針⑤動態內存分配
C語言基礎及指針⑥字符操作
C語言基礎及指針⑦結構體與指針
C語言基礎及指針⑧文件IO
C語言基礎及指針⑨聯合體與枚舉
C語言基礎及指針⑩預編譯及jni.h分析

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容