日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

【C语言】 C 语言 关键字分析 ( 属性关键字 | 常量关键字 | 结构体关键字 | 联合体关键字 | 枚举关键字 | 命名关键字 | 杂项关键字)

發(fā)布時(shí)間:2023/12/18 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【C语言】 C 语言 关键字分析 ( 属性关键字 | 常量关键字 | 结构体关键字 | 联合体关键字 | 枚举关键字 | 命名关键字 | 杂项关键字) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

相關(guān)文章鏈接 :
1.【嵌入式開(kāi)發(fā)】C語(yǔ)言 指針數(shù)組 多維數(shù)組
2.【嵌入式開(kāi)發(fā)】C語(yǔ)言 命令行參數(shù) 函數(shù)指針 gdb調(diào)試
3.【嵌入式開(kāi)發(fā)】C語(yǔ)言 結(jié)構(gòu)體相關(guān) 的 函數(shù) 指針 數(shù)組
4.【嵌入式開(kāi)發(fā)】gcc 學(xué)習(xí)筆記(一) - 編譯C程序 及 編譯過(guò)程
5.【C語(yǔ)言】 C 語(yǔ)言 關(guān)鍵字分析 ( 屬性關(guān)鍵字 | 常量關(guān)鍵字 | 結(jié)構(gòu)體關(guān)鍵字 | 聯(lián)合體關(guān)鍵字 | 枚舉關(guān)鍵字 | 命名關(guān)鍵字 | 雜項(xiàng)關(guān)鍵字)


文章目錄

  • 一. 屬性關(guān)鍵字 (auto | static | register)
    • 1. auto 關(guān)鍵字
      • (1) auto 關(guān)鍵字說(shuō)明 ( 默認(rèn)屬性 | 聲明棧存儲(chǔ) | 只能修飾局部變量 [ 全局變量在全局區(qū)存儲(chǔ) , auto 在棧內(nèi)存中 ] )
      • (2) auto 關(guān)鍵字 代碼示例 ( 不能修飾全局變量 | 錯(cuò)誤示例 )
      • (3) auto 關(guān)鍵代碼示例 ( 正確用法 )
    • 2. static 關(guān)鍵字
      • (1) static 關(guān)鍵字說(shuō)明 ( ① 聲明靜態(tài)屬性 存儲(chǔ)于靜態(tài)區(qū) [ 修飾局部變量 ] | ② 文件作用域限定符 [ 修飾全局變量 和 函數(shù) ] )
      • (2) static 關(guān)鍵字 代碼示例 ( 修飾局部變量 )
      • (3) static 關(guān)鍵字 代碼示例 ( 限定變量和方法 作用域 )
    • 3. register 關(guān)鍵字
      • (1) register關(guān)鍵字說(shuō)明 ( 聲明寄存器存儲(chǔ) ( 不確定 ) | 適用前提 ① 值符合CPU要求 ② 不能用 & 取地址 , & 只能取內(nèi)存地址 不能取 CPU 地址 )
      • (2) register 關(guān)鍵字代碼示例 ( 不能修飾全局變量 | 錯(cuò)誤示例 )
      • (3) register 關(guān)鍵字代碼示例 ( 不能獲取register變量地址 | 錯(cuò)誤示例 )
    • 4. 屬性關(guān)鍵字綜合示例
  • 二. 其它關(guān)鍵字 ( goto | void | extern | sizeof)
    • 1. goto 關(guān)鍵字 ( 不建議使用 )
    • 2. void 關(guān)鍵字
      • (1) void 關(guān)鍵字說(shuō)明 ( 修飾 返回值 和 參數(shù) | 本質(zhì) 代表 沒(méi)有 )
      • (2) void * 指針介紹 ( 被賦值 [ 左值 ] 時(shí)可以被賦值為任意指針類型變量 | 右值 賦值給其它類型變量時(shí) 需要將 void* 指針強(qiáng)轉(zhuǎn)為被賦值的類型 )
      • (3) void * 指針 代碼示例 ( 實(shí)現(xiàn) memset 方法 )
    • 3. extern 關(guān)鍵字
      • (1) extern 關(guān)鍵字說(shuō)明 ( 聲明外部文件的 變量 和 函數(shù) | 設(shè)置編譯方式 C++ 中 命令編譯器 以 標(biāo)準(zhǔn) C 規(guī)范編譯 變量 和 函數(shù) )
      • (2) extern 引用外部文件示例 ( 聲明外部變量 : extern 類型 變量名稱; | 聲明外部函數(shù) : extern 返回值類型 函數(shù)名稱 ( 參數(shù)列表 ) ; )
      • (3) extern 關(guān)鍵字代碼示例 ( 編譯方式 )
    • 4. sizeof 關(guān)鍵字
      • (1) sizeof 關(guān)鍵字說(shuō)明 ( 本質(zhì) 不是函數(shù) 是 編譯器 指示符 | 編譯過(guò)程中得到結(jié)果 | 計(jì)算變量 或 類型 占用內(nèi)存大小 )
  • 三. 常量 和 易變 關(guān)鍵字 ( const | volatile )
    • 1. const 關(guān)鍵字 簡(jiǎn)介
      • (1) const 關(guān)鍵字 簡(jiǎn)介 ( 左數(shù)右指 | 修飾制度變量 | 生成常量符號(hào)表 )
      • (2) const 關(guān)鍵字 代碼示例 ( const 常量不能被賦值 | 錯(cuò)誤示例)
      • (3) const 關(guān)鍵字 代碼示例 ( 通過(guò)指針修改const常量 : 獲取 const 變量的地址, 并改變?cè)摰刂返闹?)
      • (4) const 關(guān)鍵字 代碼示例 ( 修飾指針 | 錯(cuò)誤示例 )
      • ( 5 ) const 關(guān)鍵字 代碼示例 ( 修飾返回值 )
    • 2. volatile 關(guān)鍵字 簡(jiǎn)介
      • (1) volatile 關(guān)鍵字 簡(jiǎn)介 ( 告訴編譯器 每次去內(nèi)存中取變量值 | )
      • (2) volatile 關(guān)鍵字 代碼示例
  • 四. 結(jié)構(gòu)體 聯(lián)合體 關(guān)鍵字 ( struct | union )
    • 1. struct 關(guān)鍵字
      • (1) 結(jié)構(gòu)體定義 使用 ( ① 結(jié)構(gòu)體定義 : struct 結(jié)構(gòu)體名稱 {}; | ② 結(jié)構(gòu)體變量聲明 : struct 結(jié)構(gòu)體名 變量名 ; | ③ 定義結(jié)構(gòu)體同時(shí)聲明結(jié)構(gòu)體變量 : struct 結(jié)構(gòu)體名稱 {} 變量名 ; | ④ 結(jié)構(gòu)體定義別名 : typedef struct 結(jié)構(gòu)體名稱 {} 別名名稱; 聲明變量 : 別名名稱 變量名稱 ; [ 定義一個(gè)別名后, ] | ⑤ 結(jié)構(gòu)體定義別名省略結(jié)構(gòu)體名稱 : typedef struct {} 別名名稱; 聲明變量 : 別名名稱 變量名稱 ; )
      • (2) struct 結(jié)構(gòu)體大小
      • (3) struct 結(jié)構(gòu)體實(shí)現(xiàn)柔性數(shù)組
      • (4) 柔性數(shù)組 代碼示例 ( 處理斐波那契數(shù)列 )
    • 3. union 聯(lián)合體 關(guān)鍵字
      • (1) struct 和 union 的區(qū)別 ( struct 為每個(gè)元素分配獨(dú)立空間 | union 只為最大的元素分配內(nèi)存空間 所有元素共享該空間 )
      • (2) union 聯(lián)合體注意事項(xiàng) ( 受大小端影響 )
  • 五. 枚舉 關(guān)鍵字 ( enum )
    • 1. enum 關(guān)鍵字
      • (1) enum 枚舉關(guān)鍵介紹 ( 定義常量 | 只能定義 int 類型 )
      • (2) enum 枚舉代碼示例
      • (3) enum 和 define 區(qū)別 ( #define 編譯時(shí)進(jìn)行替換 | enum 是常量值 )
    • 2. typedef 關(guān)鍵字
      • ( 1 ) typedef 關(guān)鍵字介紹 ( 給已有類型重新命名 | 沒(méi)有新類型 | 無(wú)法擴(kuò)展 )





一. 屬性關(guān)鍵字 (auto | static | register)


每個(gè)C語(yǔ)言變量都有自己的屬性.
定義變量時(shí)可以在變量前加上 “屬性關(guān)鍵字” 來(lái)為變量定義屬性.
auto 關(guān)鍵字 : auto 是C語(yǔ)言變量的默認(rèn)屬性, 所有的局部變量都被編譯器默認(rèn)為 auto 屬性. 存儲(chǔ)在棧中.
static 關(guān)鍵字 : 聲明靜態(tài), 限定作用域. 存儲(chǔ)在靜態(tài)存儲(chǔ)區(qū).
register關(guān)鍵字 : 聲明存儲(chǔ)在 CPU 寄存器中. 存儲(chǔ)在CPU寄存器中.


1. auto 關(guān)鍵字


(1) auto 關(guān)鍵字說(shuō)明 ( 默認(rèn)屬性 | 聲明棧存儲(chǔ) | 只能修飾局部變量 [ 全局變量在全局區(qū)存儲(chǔ) , auto 在棧內(nèi)存中 ] )


auto 關(guān)鍵字 :

  • 1.C語(yǔ)言默認(rèn)屬性 : 如果一個(gè)變量前沒(méi)有寫(xiě)明屬性, 那就是默認(rèn)為 auto 的屬性;
  • 2.聲明棧存儲(chǔ) : 使用auto修飾的變量, 會(huì)默認(rèn)存儲(chǔ)在程序的棧中.
  • 3.只能修飾局部變量 : auto 關(guān)鍵字只能修飾局部變量, 修飾全局變量編譯時(shí)會(huì)報(bào)錯(cuò).

>**auto不能修飾全局變量** : auto 關(guān)鍵字不能修飾全局變量, 因?yàn)?***auto 修飾的變量存儲(chǔ)在棧內(nèi)存中, 全局變量存儲(chǔ)在全局區(qū), 此時(shí)出現(xiàn)了沖突***. 如果使用auto修飾全局變量, 編譯時(shí)會(huì)報(bào)錯(cuò).

存儲(chǔ)類型說(shuō)明 : C 語(yǔ)言中的變量存儲(chǔ) 由上到下順序 : 棧區(qū)(stack) -> 堆區(qū)(heap) -> 全局區(qū) -> 字符常量區(qū) -> 代碼區(qū)



(2) auto 關(guān)鍵字 代碼示例 ( 不能修飾全局變量 | 錯(cuò)誤示例 )


auto 關(guān)鍵字只能修飾局部變量, 修飾全局變量會(huì)報(bào)錯(cuò) :

  • 1.代碼 : test_1.c .
#include<stdio.h>//使用auto修飾全局變量,編譯時(shí)直接報(bào)錯(cuò),因?yàn)閍uto代表存儲(chǔ)在棧中, 全局變量存儲(chǔ)在全局區(qū), 因此auto只能修飾局部變量, 這里出現(xiàn)錯(cuò)誤, 直接注釋掉. auto int global_auto = 0;
  • 2.編譯結(jié)果 : 提示全局變量不能使用 auto 關(guān)鍵字聲明.


(3) auto 關(guān)鍵代碼示例 ( 正確用法 )


正確使用 auto 關(guān)鍵字 :

  • 1.代碼 :
#include<stdio.h>//使用auto修飾全局變量,編譯時(shí)直接報(bào)錯(cuò),因?yàn)閍uto代表存儲(chǔ)在棧中, 全局變量存儲(chǔ)在全局區(qū), 因此auto只能修飾局部變量, 這里出現(xiàn)錯(cuò)誤, 直接注釋掉. //auto int global_auto = 0; int global_auto = 0;//該聲明合法 int main() {//auto 關(guān)鍵字只能修飾局部變量, 不能修飾全局變量auto int auto_variable = 0;//獲取局部變量的地址,該地址是棧內(nèi)存地址printf("%0X\n", &auto_variable);return 0; }
  • 2.執(zhí)行結(jié)果 : 打印出了棧內(nèi)存中的地址.



2. static 關(guān)鍵字


(1) static 關(guān)鍵字說(shuō)明 ( ① 聲明靜態(tài)屬性 存儲(chǔ)于靜態(tài)區(qū) [ 修飾局部變量 ] | ② 文件作用域限定符 [ 修飾全局變量 和 函數(shù) ] )


static 關(guān)鍵字兩大作用 :

  • 1.靜態(tài)屬性 : static 修飾局部變量 指明變量是靜態(tài)的, 該變量存儲(chǔ)在程序靜態(tài)區(qū).
  • 2.作用域限定符 : static 作為 文件作用域限定符.

static 修飾局部變量(聲明靜態(tài)存儲(chǔ)區(qū)) :

  • 1.作用 : 說(shuō)明該局部變量存儲(chǔ)在靜態(tài)存儲(chǔ)區(qū).
  • 2.初始化次數(shù) : 該值只會(huì)***初始化一次***, 之后會(huì)被不斷賦值, 調(diào)用該局部變量所在方法, 每次的值都是上次調(diào)用該方法計(jì)算完畢后的值. 如果是第一次調(diào)用, 那么就初始化這唯一的一次.
  • 3.聲明周期 : 該局部變量的生命周期***從第一次初始化直到程序退出為止***.

static 修飾全局變量和函數(shù)(聲明作用域) :

  • 1.修飾全局變量 : static 如果修飾全局變量, 那么就說(shuō)明該全局變量只能在本文件中使用, 其它文件無(wú)法訪問(wèn).
  • 2.修飾函數(shù) : static 如果修飾函數(shù), 那么該函數(shù)只能

存儲(chǔ)類型說(shuō)明 : C 語(yǔ)言中的變量存儲(chǔ) 由上到下順序 : 棧區(qū)(stack) -> 堆區(qū)(heap) -> 全局區(qū) -> 字符常量區(qū) -> 代碼區(qū)



(2) static 關(guān)鍵字 代碼示例 ( 修飾局部變量 )


static 關(guān)鍵字修飾局部變量, 只初始化一次, 之后每次使用, 都不再進(jìn)行初始化操作.

static 修飾局部變量示例 : 兩個(gè)方法中各有一個(gè)變量, 一個(gè)靜態(tài), 一個(gè)auto, 分別調(diào)用5次方法,進(jìn)行對(duì)比.

  • 1.代碼 :
#include<stdio.h>//定義兩個(gè)函數(shù), 區(qū)別是一個(gè)是 auto 變量, 一個(gè)是 static 變量, 本函數(shù)定義是 auto 變量 void method1() {//每次調(diào)用都調(diào)用該值int local_variable_auto = 0;local_variable_auto ++;printf("%d\n", local_variable_auto); }//定義兩個(gè)函數(shù), 區(qū)別是一個(gè)是 auto 變量, 一個(gè)是 static 變量, 本函數(shù)定義是 static 變量 void method2() {//與method1對(duì)比就是局部變量使用 static 修飾//該變量只初始化一次, 之后調(diào)用, 獲取的值都是上次用完后的值, 即使被賦值很多次, 獲取到的值是最后一次賦值的值.static int local_variable_static = 0;local_variable_static ++;printf("%d\n", local_variable_static); } int main() {//C編譯器中可以不聲明, 默認(rèn)局部變量時(shí) auto 屬性的.auto int i = 0;//調(diào)用五次定義了auto局部變量的值,其中的局部變量每次都初始化for(i = 0; i < 5; i ++){method1();}//調(diào)用五次定義了static局部變量的值,其中的靜態(tài)變量只初始化一次,之后每次都用上一次賦值過(guò)的變量for(i = 0; i < 5; i ++){method2();}return 0; }
  • 2.執(zhí)行結(jié)果 :

分析 :
調(diào)用5次method1()方法, 每次local_variable_auto 變量都初始化.
調(diào)用5次method2()方法, local_variable_static 變量只初始化一次, 之后每次都沿用上一次的值.



(3) static 關(guān)鍵字 代碼示例 ( 限定變量和方法 作用域 )


static 關(guān)鍵字 限定變量 只能在本代碼中訪問(wèn)被修飾的變量和函數(shù) :

  • 1.代碼1 : 主程序 test_1.c ;
#include<stdio.h>//引用test_2.c 文件中的普通全局變量,該聲明合法. extern int test_2_global;//引用test_2.c 中的靜態(tài)全局變量, 在使用時(shí)會(huì)報(bào)錯(cuò). //extern int test_2_global_static;//引用test_2.c 中的普通函數(shù), 通過(guò)該普通函數(shù)可以獲取test_2.c 中的 test_2_global_static 靜態(tài)變量 extern int method_3();//引用test_2.c 中的靜態(tài)函數(shù), 使用時(shí)會(huì)報(bào)錯(cuò). //extern int method_4();//引用test_2.c 中的普通函數(shù), 通過(guò)該普通函數(shù)可以調(diào)用test_2.c 中的method_4() 靜態(tài)函數(shù) extern int method_5(); int main() {//打印 test_2.c 中的全局變量,查看是否在本文件中引用成功.printf("%d\n", test_2_global);//打印 test_2.c 中的靜態(tài)全局變量, 此時(shí)編譯時(shí)會(huì)報(bào)錯(cuò),這里注釋掉.//printf("%d\n", test_2_global_static);//通過(guò)調(diào)用 method_3() 獲取 test_2.c 中的靜態(tài)全局變量, 打印出該靜態(tài)全局變量的值printf("%d\n", method_3());//無(wú)法調(diào)用 test_2.c 中的靜態(tài)方法, 編譯時(shí)會(huì)報(bào)錯(cuò).//printf("%d\n", method_4());//通過(guò)調(diào)用 method_5, 間接調(diào)用 test_2.c 中的 method_4() 靜態(tài)函數(shù), 獲取該靜態(tài)函數(shù)的值并打印出來(lái).printf("%d\n", method_5());return 0; }
  • 2.代碼2 : 外部文件 test_2.c ;
//普通的全局變量, 其它文件可以引用該變量 int test_2_global = 666; //靜態(tài)全局變量, 同時(shí)限定其作用域是本文件, 不能被外部文件使用. static int test_2_global_static = 444; //通過(guò)調(diào)用該方法, 可以在外部文件訪問(wèn)該方法, 獲取靜態(tài)全局變量的值. int method_3() {return test_2_global_static; }//使用static修飾該方法, 外部文件無(wú)法使用該方法. static int method_4() {return test_2_global_static; }//在普通方法中調(diào)用static修飾的方法, 此時(shí)可以在外部文件中訪問(wèn)該普通方法, 即通過(guò)普通方法調(diào)用 static 方法. int method_5() {return method_4(); }
  • 3.執(zhí)行結(jié)果 : 需要同時(shí)編譯兩個(gè)文件 gcc test_1.c test_2.c ;



3. register 關(guān)鍵字


(1) register關(guān)鍵字說(shuō)明 ( 聲明寄存器存儲(chǔ) ( 不確定 ) | 適用前提 ① 值符合CPU要求 ② 不能用 & 取地址 , & 只能取內(nèi)存地址 不能取 CPU 地址 )


register 關(guān)鍵字說(shuō)明 :

  • 1.作用 : 聲明變量存儲(chǔ)的位置是在 寄存器 中.
  • 2.成功率 : 該關(guān)鍵字只是請(qǐng)求編譯器將該變量存儲(chǔ)在寄存器中, 編譯器不一定會(huì)批準(zhǔn).
  • 3.不能修飾全局變量 : register 修飾全局變量會(huì)報(bào)錯(cuò), 因?yàn)槿肿兞柯暶髦芷谑钦麄€(gè)程序的聲明周期,該周期內(nèi)長(zhǎng)時(shí)間占用 CPU 寄存器明顯不可能, 因此編譯器禁止register修飾全局變量.

register 使用前提 :

  • 1.值符合要求 : 該變量的值必須能夠被 CPU 的寄存器接受.
  • 2.無(wú)法獲取地址 : 取地址運(yùn)算符 & 不能獲取 register 變量地址, & 只是能獲取內(nèi)存地址, 不能獲取 CPU 地址.

使用情況 : 當(dāng)需求是***實(shí)時(shí)性要求效率非常高***時(shí), 就應(yīng)該使用寄存器變量.



(2) register 關(guān)鍵字代碼示例 ( 不能修飾全局變量 | 錯(cuò)誤示例 )


register 不能修飾全局變量 : CPU 寄存器內(nèi)的變量其生命周期不能太長(zhǎng).

  • 1.代碼 : test_1.c ;
#include<stdio.h>//使用register 修飾全局變量,此時(shí)編譯也會(huì)報(bào)錯(cuò),全局變量聲明周期是整個(gè)程序的生命周期,如果將其放入CPU寄存器, //會(huì)導(dǎo)致寄存器占用, 因此編譯器規(guī)定寄存器變量不能是全局變量. 這里將錯(cuò)誤代碼注釋掉. register int global_register = 0;
  • 2.執(zhí)行結(jié)果 : register修飾全局變量報(bào)錯(cuò);


(3) register 關(guān)鍵字代碼示例 ( 不能獲取register變量地址 | 錯(cuò)誤示例 )


register 變量無(wú)法獲取地址 :

  • 1.代碼1 : test_1.c .
#include<stdio.h>int main() {//register 關(guān)鍵字只能修飾局部變量,不能修飾全局變量register int register_variable = 0;//嘗試獲取CPU寄存器的地址, 此時(shí)編譯時(shí)會(huì)報(bào)錯(cuò). 這里注釋掉.printf("%0x\n", &register_variable);return 0; }
  • 2.執(zhí)行結(jié)果 :



4. 屬性關(guān)鍵字綜合示例



屬性關(guān)鍵字綜合示例 :

  • 1.代碼1 : test_1.c;
#include<stdio.h>//使用auto修飾全局變量,編譯時(shí)直接報(bào)錯(cuò),因?yàn)閍uto代表存儲(chǔ)在棧中, 全局變量存儲(chǔ)在全局區(qū), 因此auto只能修飾局部變量, 這里出現(xiàn)錯(cuò)誤, 直接注釋掉. //auto int global_auto = 0; int global_auto = 0;//該聲明合法 //使用register 修飾全局變量,此時(shí)編譯也會(huì)報(bào)錯(cuò),全局變量聲明周期是整個(gè)程序的生命周期,如果將其放入CPU寄存器, //會(huì)導(dǎo)致寄存器占用, 因此編譯器規(guī)定寄存器變量不能是全局變量. 這里將錯(cuò)誤代碼注釋掉. //register int global_register = 0; int global_register = 0;//該聲明合法//定義兩個(gè)函數(shù), 區(qū)別是一個(gè)是 auto 變量, 一個(gè)是 static 變量, 本函數(shù)定義是 auto 變量 void method1() {//每次調(diào)用都調(diào)用該值int local_variable_auto = 0;local_variable_auto ++;printf("%d\n", local_variable_auto); }//定義兩個(gè)函數(shù), 區(qū)別是一個(gè)是 auto 變量, 一個(gè)是 static 變量, 本函數(shù)定義是 static 變量 void method2() {//與method1對(duì)比就是局部變量使用 static 修飾//該變量只初始化一次, 之后調(diào)用, 獲取的值都是上次用完后的值, 即使被賦值很多次, 獲取到的值是最后一次賦值的值.static int local_variable_static = 0;local_variable_static ++;printf("%d\n", local_variable_static); }//引用test_2.c 文件中的普通全局變量,該聲明合法. extern int test_2_global;//引用test_2.c 中的靜態(tài)全局變量, 在使用時(shí)會(huì)報(bào)錯(cuò). //extern int test_2_global_static;//引用test_2.c 中的普通函數(shù), 通過(guò)該普通函數(shù)可以獲取test_2.c 中的 test_2_global_static 靜態(tài)變量 extern int method_3();//引用test_2.c 中的靜態(tài)函數(shù), 使用時(shí)會(huì)報(bào)錯(cuò). //extern int method_4();//引用test_2.c 中的普通函數(shù), 通過(guò)該普通函數(shù)可以調(diào)用test_2.c 中的method_4() 靜態(tài)函數(shù) extern int method_5(); int main() {//auto 關(guān)鍵字只能修飾局部變量, 不能修飾全局變量auto int auto_variable = 0;//static 既可以修飾局部變量(聲明存儲(chǔ)于靜態(tài)存儲(chǔ)區(qū)), 又可以修飾全局變量(文件作用域限定)static int static_variable = 0;//register 關(guān)鍵字只能修飾局部變量,不能修飾全局變量register int register_variable = 0;//獲取局部變量的地址,該地址是棧內(nèi)存地址printf("%0x\n", &auto_variable);//獲取靜態(tài)變量的地址, 該地址是靜態(tài)區(qū)地址printf("%0x\n", &static_variable);//嘗試獲取CPU寄存器的地址, 此時(shí)編譯時(shí)會(huì)報(bào)錯(cuò). 這里注釋掉.//printf("%0x\n", &register_variable);//C編譯器中可以不聲明, 默認(rèn)局部變量時(shí) auto 屬性的.auto int i = 0;//調(diào)用五次定義了auto局部變量的值,其中的局部變量每次都初始化for(i = 0; i < 5; i ++){method1();}//調(diào)用五次定義了static局部變量的值,其中的靜態(tài)變量只初始化一次,之后每次都用上一次賦值過(guò)的變量for(i = 0; i < 5; i ++){method2();}//打印 test_2.c 中的全局變量,查看是否在本文件中引用成功.printf("%d\n", test_2_global);//打印 test_2.c 中的靜態(tài)全局變量, 此時(shí)編譯時(shí)會(huì)報(bào)錯(cuò),這里注釋掉.//printf("%d\n", test_2_global_static);//通過(guò)調(diào)用 method_3() 獲取 test_2.c 中的靜態(tài)全局變量, 打印出該靜態(tài)全局變量的值printf("%d\n", method_3());//無(wú)法調(diào)用 test_2.c 中的靜態(tài)方法, 編譯時(shí)會(huì)報(bào)錯(cuò).//printf("%d\n", method_4());//通過(guò)調(diào)用 method_5, 間接調(diào)用 test_2.c 中的 method_4() 靜態(tài)函數(shù), 獲取該靜態(tài)函數(shù)的值并打印出來(lái).printf("%d\n", method_5());return 0; }
  • 2.代碼2 : test_2.c ;
//普通的全局變量, 其它文件可以引用該變量 int test_2_global = 666; //靜態(tài)全局變量, 同時(shí)限定其作用域是本文件, 不能被外部文件使用. static int test_2_global_static = 444; //通過(guò)調(diào)用該方法, 可以在外部文件訪問(wèn)該方法, 獲取靜態(tài)全局變量的值. int method_3() {return test_2_global_static; }//使用static修飾該方法, 外部文件無(wú)法使用該方法. static int method_4() {return test_2_global_static; }//在普通方法中調(diào)用static修飾的方法, 此時(shí)可以在外部文件中訪問(wèn)該普通方法, 即通過(guò)普通方法調(diào)用 static 方法. int method_5() {return method_4(); }
  • 3.執(zhí)行結(jié)果 :




二. 其它關(guān)鍵字 ( goto | void | extern | sizeof)



1. goto 關(guān)鍵字 ( 不建議使用 )



goto 現(xiàn)狀 (建議禁用) : 一般不使用 goto;

  • 1.對(duì)程序質(zhì)量影響 : 程序中使用的 goto 越多, 代碼質(zhì)量越垃圾;
  • 2.禁用 goto : goto 對(duì)代碼質(zhì)量產(chǎn)生惡劣影響, 高手寫(xiě)代碼一般不使用 goto;
  • 3.后續(xù)高級(jí)語(yǔ)言刪除了 goto : 后續(xù)的 Java 等高級(jí)語(yǔ)言中, 沒(méi)有 goto 關(guān)鍵字;
  • 4.原因 : 破壞了 過(guò)程式 程序順序執(zhí)行 的規(guī)則;



2. void 關(guān)鍵字


(1) void 關(guān)鍵字說(shuō)明 ( 修飾 返回值 和 參數(shù) | 本質(zhì) 代表 沒(méi)有 )


void 關(guān)鍵字作用 : 修飾函數(shù) 返回值 和 參數(shù);

  • 1.修飾返回值 : 函數(shù) 沒(méi)有返回值, 其類型就應(yīng)該寫(xiě)成 void;
  • 2.修飾參數(shù) : 如果函數(shù) 沒(méi)有參數(shù), 即不接收參數(shù), 其參數(shù)類型就寫(xiě)成 void;
  • 3.本質(zhì) : 使用 void 修飾 返回值 和 參數(shù), 其本質(zhì)就代表沒(méi)有;

void 類型大小C語(yǔ)言規(guī)范沒(méi)有規(guī)定, C 語(yǔ)言中是沒(méi)有 void 變量的. 使用sizeof查看void大小, gcc 返回1 這是編譯器廠商給的一個(gè)值, 不是C語(yǔ)言中規(guī)定的.


void 不能修飾變量, 否則會(huì)報(bào)錯(cuò).



(2) void * 指針介紹 ( 被賦值 [ 左值 ] 時(shí)可以被賦值為任意指針類型變量 | 右值 賦值給其它類型變量時(shí) 需要將 void* 指針強(qiáng)轉(zhuǎn)為被賦值的類型 )


void * 指針說(shuō)明 :

  • 1.被賦值的情況(作為左值) : void * 指針作為被賦值對(duì)象, 即在 “=” 左側(cè), 其可以 直接被賦值為任何指針類型變量;
  • 2.賦值給其它指針(作為右值) : void * 賦值給其它類型的指針變量, 需要強(qiáng)制轉(zhuǎn)換為其它類型的指針變量.


(3) void * 指針 代碼示例 ( 實(shí)現(xiàn) memset 方法 )


使用 void * 指針實(shí)現(xiàn) memset 方法示例 :

  • 1.代碼示例 : test_1.c ;
#include<stdio.h> //實(shí)現(xiàn) memset 函數(shù), 下面是memset函數(shù)的內(nèi)容. //void *memset(void *s, int ch, size_t n); //函數(shù)解析:將s中當(dāng)前位置后面的n個(gè)字節(jié) (typedef unsigned int size_t )用 ch 替換并返回 s //memset:作用是在一段內(nèi)存塊中填充某個(gè)給定的值,它是對(duì)較大的結(jié)構(gòu)體或數(shù)組進(jìn)行清零操作的一種最快方法//實(shí)現(xiàn)方法 : //1.接收參數(shù) : void *s 內(nèi)存地址, int ch 每個(gè)字節(jié)賦值內(nèi)容, int size 替換的字節(jié)個(gè)數(shù). //2.算法實(shí)現(xiàn) : for 循環(huán)實(shí)現(xiàn)設(shè)置 //3.返回值 : void * void * memset(void *p, char v, int size) {//接收一個(gè)任意的內(nèi)存地址值(任意類型的指針變量)void * ret = p;//將 void * 強(qiáng)制轉(zhuǎn)換為 char *char * dest = (char*)p;int i = 0;for(i = 0; i < size; i ++){//使用 char 類型指針, 依次將之后的字節(jié)每個(gè)設(shè)置成 vdest[i] = v;}return ret; }int main() {//定義一個(gè)數(shù)組, 之后我們將使用自定義的memset方法重置數(shù)組中的內(nèi)容int array[5] = {1, 2, 3, 4, 5};//循環(huán)控制變量int i = 0;//打印數(shù)組的原始值for(i = 0; i < 5; i ++){printf("%d\n", array[i]);}//調(diào)用自己定義的memset函數(shù)清空數(shù)組內(nèi)容memset(array, 0, sizeof(array));//打印數(shù)組經(jīng)過(guò)memset重置后的數(shù)值for(i = 0; i < 5; i ++){printf("%d\n", array[i]);}//定義long類型測(cè)試long l = 66666;printf("%ld\n", l); //打印值memset(&l, 0, sizeof(l)); //重置long變量printf("%ld\n", l); //再次打印重置后的值return 0; }
  • 2.執(zhí)行結(jié)果 :



3. extern 關(guān)鍵字


(1) extern 關(guān)鍵字說(shuō)明 ( 聲明外部文件的 變量 和 函數(shù) | 設(shè)置編譯方式 C++ 中 命令編譯器 以 標(biāo)準(zhǔn) C 規(guī)范編譯 變量 和 函數(shù) )


extern 關(guān)鍵字說(shuō)明 :

  • 1.主要作用 : 聲明外部文件中定義的 變量 和 函數(shù);
  • 2.設(shè)置編譯方式 : 有些 C ++ 編譯器 和 一些 變種 C 編譯器 編譯變量 和 函數(shù)時(shí)有時(shí)不遵守標(biāo)準(zhǔn)C 規(guī)范, 通過(guò) extern 關(guān)鍵字可以***命令編譯器以 標(biāo)準(zhǔn)C 規(guī)范編譯 變量和函數(shù)***.
extern "C" {... }

(2) extern 引用外部文件示例 ( 聲明外部變量 : extern 類型 變量名稱; | 聲明外部函數(shù) : extern 返回值類型 函數(shù)名稱 ( 參數(shù)列表 ) ; )


extern 引用外部文件 :

  • 1.代碼示例1 : test_1.c ;
#include <stdio.h>//引用外部文件 test_2.c 中定義的全局變量 extern int test_2_a;//引用外部文件 test_2.c 中定義的方法 extern int test_2_get_min(int a, int b);int main() {//調(diào)用外部變量 test_2_a, 并打印出其值printf("%d\n", test_2_a);//調(diào)用外部函數(shù) test_2_get_min , 并打印結(jié)果printf("%d\n", test_2_get_min(666, 888));return 0; }
  • 2.代碼示例2 : test_2.c ;
//test_2.c 中定義的全局變量 int test_2_a = 666;//test_2.c 中定義的函數(shù) int test_2_get_min(int a, int b) {//返回a和b中較小的值return (a < b) ? a : b; }
  • 3.執(zhí)行結(jié)果 :


(3) extern 關(guān)鍵字代碼示例 ( 編譯方式 )


extern 指定編譯方式代碼示例 :

  • 1.代碼示例 : test_1.c ;
#include <stdio.h>//如果在 gcc 編譯器中, 該用法直接報(bào)錯(cuò) //在 g++ 編譯器中, 該用法有效 extern "C" {int c_get_min(int a, int b){//返回a和b中較小的值return (a < b) ? a : b;} }int main() {//g++ 編譯器中編譯通過(guò)即可執(zhí)行printf("%d\n", c_get_min(666, 888));return 0; }
  • 2.執(zhí)行結(jié)果 :



4. sizeof 關(guān)鍵字


(1) sizeof 關(guān)鍵字說(shuō)明 ( 本質(zhì) 不是函數(shù) 是 編譯器 指示符 | 編譯過(guò)程中得到結(jié)果 | 計(jì)算變量 或 類型 占用內(nèi)存大小 )


sizeof 關(guān)鍵字說(shuō)明 :

  • 1.sizeof 本質(zhì) : sizeof 不是函數(shù), 其本質(zhì)是一個(gè)編譯器的內(nèi)置的指示符;
  • 2.sizeof 確定值的時(shí)機(jī) : sizeof 的實(shí)際值值, 在***編譯的過(guò)程中就已經(jīng)知道了結(jié)果***.
  • 3.sizeof 作用 : 計(jì)算變量或者類型 等實(shí)體 占用內(nèi)存的大小.


###(2) sizeof 關(guān)鍵字 代碼示例 ( 使用方法 )

sizeof 關(guān)鍵字 代碼示例 :

  • 1.代碼示例 :
#include <stdio.h>int main() {int a;//這種sizeof, 將變量放在括號(hào)里, 與函數(shù)調(diào)用類似printf("%ld\n", sizeof(a));//可以不寫(xiě)括號(hào), 也可以打印出 變量 a 的大小, 注意 類型 不能這么寫(xiě)//只有變量可以這么寫(xiě)printf("%ld\n", sizeof a);//可以傳入類型 int, 打印出 int 類型占用內(nèi)存大小printf("%ld\n", sizeof(int));return 0; }
  • 2.執(zhí)行結(jié)果 :




三. 常量 和 易變 關(guān)鍵字 ( const | volatile )



1. const 關(guān)鍵字 簡(jiǎn)介


(1) const 關(guān)鍵字 簡(jiǎn)介 ( 左數(shù)右指 | 修飾制度變量 | 生成常量符號(hào)表 )


const 關(guān)鍵字 說(shuō)明 :

  • 1.const 常量本質(zhì) : const 不是真的常量, 也是一種變量.
  • 2.修飾只讀變量 : const 修飾的變量智能讀取, 不能被賦值, 即不能當(dāng)做左值;
  • 3.占用內(nèi)存 : const 變量也會(huì)占用內(nèi)存中的空間 ;
  • 4.修改const值 : 使用指針可以修改const變量地址中的值.

const 只是針對(duì)編譯器是有用的, 在運(yùn)行的時(shí)候 就沒(méi)有這種約束了, 可以改變其值.


編譯器處理 const 常量過(guò)程 :

  • 1.定義 const 常量 : const int const_variable = 666, 之后編譯器開(kāi)始編譯;
  • 2.生成符號(hào)表 : 編譯器生成一個(gè)符號(hào)表, const_variable 對(duì)應(yīng) int 類型, 值為 666;
常量標(biāo)示符常量類型常量值
const_variableint666

  • 3.編譯器左值判定 : 編譯器查找const常量是否有左值, 如果有報(bào)錯(cuò);
  • 4.編譯器右值判定 : 編譯器查找 const 常量是否當(dāng)做右值,如果出現(xiàn) int a = const_variable, 那么直接將 const_variable 替換為 666; 如果出現(xiàn) int p = (int) &const_variable, 那么不做任何操作;

const 修飾數(shù)組 :

  • 1.只讀數(shù)組 : const 修飾數(shù)組時(shí), 這個(gè)數(shù)組是只讀的, 數(shù)組中的每個(gè)元素都是只讀的, 不能作為左值;
  • 2.const 數(shù)組所在空間不可改變 : 數(shù)組所在的空間是不可更改的, 但是通過(guò)指針是可以修改數(shù)組中每個(gè)元素的值的;

const 修飾指針 : 需要符合下面的規(guī)則 :

聲明特征
const int* pp指針地址可變 p指針指向的內(nèi)容不可變 (const 在 * 左邊, 數(shù)據(jù)不可變)
int const* pp指針地址可變 p指針指向的內(nèi)容不可變 (const 在 * 左邊, 數(shù)據(jù)不可變)
int* const pp指針地址不可變 p指針指向的內(nèi)容不可變 (const 在 * 右邊, 地址不可變)
const int* const pp指針地址不可變 p指針指向的內(nèi)容不可變 (const 在 * 左邊 和 右邊, 數(shù)據(jù)和地址都不可變)

>**const 修飾指針規(guī)則** : ***左數(shù) 右指 (左邊數(shù)據(jù)是常量, 右邊指針是常量)***; >**左數(shù)** : ***const 出現(xiàn)在 * 左邊時(shí), 指針指向的數(shù)據(jù)為常量***, 指向的數(shù)據(jù)不可改變; >**右指** : ***const 出現(xiàn)在 * 右邊時(shí), 指針地址本身是常量***, 指針地址不可改變;

const 修飾函數(shù)參數(shù) 和 返回值 :

  • 1.const 修飾參數(shù) : 在函數(shù)體內(nèi), 不希望改變參數(shù)的值;
  • 2.const 修飾返回值 : 一般情況下 返回值 使用 const 修飾, 是返回指針, 用于限制 指針指向的內(nèi)容不允許改變 ;


(2) const 關(guān)鍵字 代碼示例 ( const 常量不能被賦值 | 錯(cuò)誤示例)


const 關(guān)鍵字 代碼示例 : const 常量不能被賦值.

  • 1.代碼示例 :
#include <stdio.h>int main() {//定義一個(gè) const 變量, 直接賦值編譯器報(bào)錯(cuò), 但是使用指針改變?cè)摰刂返闹凳强梢缘?const int const_variable = 666;printf("%d\n", const_variable);//const 變量不能被直接賦值, 這樣在編譯的時(shí)候就會(huì)報(bào)錯(cuò)const_variable = 444;printf("%d\n", const_variable);return 0; }
  • 2.執(zhí)行結(jié)果 :

const 常量一旦作為左值, 編譯時(shí)就會(huì)報(bào)錯(cuò)



(3) const 關(guān)鍵字 代碼示例 ( 通過(guò)指針修改const常量 : 獲取 const 變量的地址, 并改變?cè)摰刂返闹?)


const 關(guān)鍵字 代碼示例 : const 常量可以通過(guò)指針修改

  • 1.代碼示例 :
#include <stdio.h>int main() {//定義一個(gè) const 變量, 直接賦值編譯器報(bào)錯(cuò), 但是使用指針改變?cè)摰刂返闹凳强梢缘?const int const_variable = 666;printf("%d\n", const_variable);//const 變量不能被直接賦值, 這樣在編譯的時(shí)候就會(huì)報(bào)錯(cuò), 這里注釋掉//const_variable = 444;//獲取 const 變量的地址, 并改變?cè)摰刂返闹?/span>int* p = (int*) &const_variable;*p = 888;printf("%d\n", const_variable);return 0; }
  • 2.執(zhí)行結(jié)果 :

通過(guò)指針可以修改 const 常量



(4) const 關(guān)鍵字 代碼示例 ( 修飾指針 | 錯(cuò)誤示例 )


const 修飾指針規(guī)則 : 左數(shù)右指;
左數(shù) : const 出現(xiàn)在 * 左邊時(shí), 指針指向的數(shù)據(jù)為常量, 指向的數(shù)據(jù)不可改變;
右指 : const 出現(xiàn)在 * 右邊時(shí), 指針地址本身是常量, 指針地址不可改變;


const 關(guān)鍵字 代碼示例 : 修飾指針

  • 1.代碼示例1 : const 出現(xiàn)在 * 左邊, const int* p = &i;
#include <stdio.h>int main() {//定義普通的變量, 用于取地址用int i = 666;//定義一個(gè) const 在 * 左邊的例子, 意義是 指針指向的內(nèi)容是常量//按照規(guī)則, 指針地址可改變, 指針指向的數(shù)據(jù)不可變const int* p = &i; //指針指向的數(shù)據(jù)不可改變, 這里會(huì)報(bào)錯(cuò)*p = 444;return 0; }

  • 2.代碼示例2 : const 出現(xiàn)在 * 左邊, int const* p = &i;
#include <stdio.h>int main() {//定義普通的變量, 用于取地址用int i = 666;//定義一個(gè) const 在 * 左邊的例子, 意義是 指針指向的內(nèi)容是常量//按照規(guī)則, 指針地址可改變, 指針指向的數(shù)據(jù)不可變int const* p = &i;//指針指向的數(shù)據(jù)不可改變, 這里會(huì)報(bào)錯(cuò)*p = 444;return 0; }

  • 3.代碼示例3 : const 出現(xiàn)在 * 右邊, int* const p = &i;
#include <stdio.h>int main() {//定義普通的變量, 用于取地址用int i = 666;//定義一個(gè) const 在 * 右邊的例子, 意思是 地址是常量//按照規(guī)則, 指針地址不可改變, 指針指向的內(nèi)容可變int* const p = &i;//指針指向的數(shù)據(jù)不可改變, 這里會(huì)報(bào)錯(cuò)p = NULL;return 0; }

  • 4.代碼示例4 : const 同時(shí)出現(xiàn)在 * 左邊 和 右邊, const int* const p = &i;
#include <stdio.h>int main() {//定義普通的變量, 用于取地址用int i = 666;//定義 const 同時(shí)出現(xiàn)在 * 左邊 和 右邊, 則指針的地址 和 指向的數(shù)據(jù)都不可改變const int* const p = &i;//下面的兩個(gè)操作, 一個(gè)是想修改指針地址, 一個(gè)是想修改指針值, 這兩個(gè)都報(bào)錯(cuò).p = NULL;*p = 444;return 0; }



( 5 ) const 關(guān)鍵字 代碼示例 ( 修飾返回值 )


const 關(guān)鍵字 代碼示例 : const 修飾返回值

  • 1.代碼示例 :
#include <stdio.h>//返回的指針 使用 const 修飾, //const 在 指針* 的左邊, 即其指向的內(nèi)容是常量, 不可更改 const int* function() {//聲明靜態(tài)局部變量,該變量只初始化一次, 之后重復(fù)使用static int count = 0;count ++;return &count; }int main() {//使用 const int* 類型才可以接收 返回值是 const int* 類型的返回值//如果沒(méi)有 const 修飾, 會(huì)報(bào)警告const int* p = function();printf("%d\n", *p);return 0; }
  • 2.執(zhí)行結(jié)果 :



2. volatile 關(guān)鍵字 簡(jiǎn)介


(1) volatile 關(guān)鍵字 簡(jiǎn)介 ( 告訴編譯器 每次去內(nèi)存中取變量值 | )


volatile 關(guān)鍵字簡(jiǎn)介 :

  • 1.作用 : 編譯器 警告指示, 告訴編譯器 每次去內(nèi)存中取變量值 , 防止編譯器自己做優(yōu)化, 改變了程序的執(zhí)行邏輯;
  • 2.使用情況 : ① 一個(gè)變量可能被多個(gè)變量同時(shí)訪問(wèn)的情況, ② 變量可能被未知因素更改的情況 ;


(2) volatile 關(guān)鍵字 代碼示例


編譯器優(yōu)化案例 : 有時(shí)我們不需要編譯器的優(yōu)化, 有時(shí)編譯器優(yōu)化完了反而得不到我們想要的執(zhí)行效果 ;

  • 代碼示例說(shuō)明 :
#include <stdio.h> #include <unistd.h> int main() {//value 全程沒(méi)有做過(guò)左值, 值當(dāng)做右值為 a 和 b 賦值用//編譯器會(huì)將 value 當(dāng)做常量, 使用 666 替代 value//如果使用 valatile 修飾value, 在編譯的時(shí)候, 編譯器就不會(huì)進(jìn)行這種替換.int value = 666;//a 和 b 初始值為0int a = 0;int b = 0;//編譯器在編譯時(shí), 直接將 666 賦值給了 aa = value;sleep(1000);//如果在休眠的 1000 ms, //value內(nèi)存值變成了 888, 我們想要的是888, 但是編譯器自作主張將 b 賦值為了 666//這樣就無(wú)法實(shí)現(xiàn)我們想要的意圖b = value;return 0; }



四. 結(jié)構(gòu)體 聯(lián)合體 關(guān)鍵字 ( struct | union )



1. struct 關(guān)鍵字


(1) 結(jié)構(gòu)體定義 使用 ( ① 結(jié)構(gòu)體定義 : struct 結(jié)構(gòu)體名稱 {}; | ② 結(jié)構(gòu)體變量聲明 : struct 結(jié)構(gòu)體名 變量名 ; | ③ 定義結(jié)構(gòu)體同時(shí)聲明結(jié)構(gòu)體變量 : struct 結(jié)構(gòu)體名稱 {} 變量名 ; | ④ 結(jié)構(gòu)體定義別名 : typedef struct 結(jié)構(gòu)體名稱 {} 別名名稱; 聲明變量 : 別名名稱 變量名稱 ; [ 定義一個(gè)別名后, ] | ⑤ 結(jié)構(gòu)體定義別名省略結(jié)構(gòu)體名稱 : typedef struct {} 別名名稱; 聲明變量 : 別名名稱 變量名稱 ; )


結(jié)構(gòu)體定義 :

  • 1.結(jié)構(gòu)體定義最標(biāo)準(zhǔn)方法 : 最基本的方法, 聲明一個(gè)結(jié)構(gòu)體, 使用 struct 結(jié)構(gòu)體名 變量名 來(lái)聲明結(jié)構(gòu)體變量;
//定義結(jié)構(gòu)體 struct Student {char* name;int age; };//聲明結(jié)構(gòu)體變量 struct Student stu;
  • 2.定義結(jié)構(gòu)體同時(shí)聲明結(jié)構(gòu)體變量 : 在定義結(jié)構(gòu)體的大括號(hào)后 寫(xiě)上變量名;
//定義結(jié)構(gòu)體的同時(shí) 聲明結(jié)構(gòu)體變量 struct Student {char* name;int age; }stu;
  • 3.定義結(jié)構(gòu)體同時(shí)聲明變量 但不定義結(jié)構(gòu)體類型名稱 : 定義結(jié)構(gòu)體時(shí)如果不給出結(jié)構(gòu)體的名稱, 那么只能在定義結(jié)構(gòu)體時(shí) 同時(shí) 聲明該變量, 該結(jié)構(gòu)體只有一個(gè)變量;
//定義結(jié)構(gòu)體的同時(shí) 聲明結(jié)構(gòu)體變量, 如果不給出結(jié)構(gòu)體類型名稱, 在別處不能聲明該類型的結(jié)構(gòu)體變量 struct {char* name;int age; }stu;
  • 4.結(jié)構(gòu)體定義別名 : 定義了別名的結(jié)構(gòu)體, 在聲明結(jié)構(gòu)體變量時(shí)可以不適用 struct 關(guān)鍵字;
//定義結(jié)構(gòu)體類型, 并給 _student 定義一個(gè)別名 student typedef struct _student {char* name;int age; }student;//聲明結(jié)構(gòu)體變量 student stu;

-5.定義結(jié)構(gòu)體別名 但是沒(méi)有給出結(jié)構(gòu)體的類型名稱 : 如果使用 typedef 定義了一個(gè)結(jié)構(gòu)體的別名, 那么該結(jié)構(gòu)體可以不定義結(jié)構(gòu)體類型名稱;

//定義結(jié)構(gòu)體類型, 并定義一個(gè)別名 student, 可以不定義結(jié)構(gòu)體的類型名稱 typedef struct {char* name;int age; }student;//聲明結(jié)構(gòu)體變量 student stu;

(2) struct 結(jié)構(gòu)體大小


空結(jié)構(gòu)體占用內(nèi)存大小 :

  • 1.C規(guī)范定義 : C語(yǔ)言規(guī)范中沒(méi)有定義空結(jié)構(gòu)體的大小,不同編譯器有不同的默認(rèn)值0或者1字節(jié);
  • 2.代碼示例 :
#include <stdio.h>//定義一個(gè)空結(jié)構(gòu)體,用來(lái)測(cè)試空結(jié)構(gòu)體的大小 struct A { };int main() {//定義兩個(gè)空結(jié)構(gòu)體變量,打印其大小和地址值struct A a1;struct A a2;//打印空結(jié)構(gòu)體類型大小printf("%ld\n", sizeof(struct A));//打印兩個(gè)空結(jié)構(gòu)體大小 和 空結(jié)構(gòu)體變量地址printf("%ld, %0X\n", sizeof(a1), &a1);printf("%ld, %0X\n", sizeof(a2), &a2);return 0; }
  • 3.執(zhí)行結(jié)果 :

空結(jié)構(gòu)體變量類型大小為0,其變量的大小為0,其地址錯(cuò)位1.



(3) struct 結(jié)構(gòu)體實(shí)現(xiàn)柔性數(shù)組


柔性數(shù)組 :

  • 1.普通數(shù)組 : 在定義的時(shí)候定義數(shù)組的大小,并且在棧上分配內(nèi)存;
  • 2.柔性數(shù)組 : 數(shù)組的大小未知,定義完之后可設(shè)置數(shù)組大小;
  • 3.實(shí)現(xiàn)方式 : 使用結(jié)構(gòu)體實(shí)現(xiàn)柔性數(shù)組.
  • 4.代碼示例 :
#include <stdio.h> #include<stdlib.h>//定義柔性數(shù)組 typedef struct soft_array {int len;int array[]; } soft_array;int main() {//打印 結(jié)構(gòu)體 soft_array 的類型大小, 結(jié)果是4字節(jié)//分析 : int array[] 是一個(gè)未知大小的數(shù)組, 編譯器不知道該數(shù)組多大, 就將該數(shù)組大小當(dāng)做0//sizeof 計(jì)算的 結(jié)構(gòu)體的 4 個(gè)字節(jié)是 int 類型的大小, 后面的 int array[] 只是占位符, 可以分配任意大小的數(shù)組printf("%ld\n", sizeof(soft_array));//為柔性數(shù)組分配內(nèi)存空間, 結(jié)構(gòu)體的基本空間 + 數(shù)組大小soft_array* array = (soft_array*)malloc(sizeof(soft_array) + sizeof(int) * 10);//設(shè)置柔性數(shù)組大小array->len = 10;int i = 0;//以此遍歷為柔性數(shù)組賦值for(i = 0; i < array->len; i ++){array->array[i] = i;}//依次遍歷打印柔性數(shù)組的值for(i = 0; i < array->len; i ++){printf("%d\n", array->array[i]);}return 0; }
  • 5.執(zhí)行結(jié)果 :



(4) 柔性數(shù)組 代碼示例 ( 處理斐波那契數(shù)列 )


柔性數(shù)組使用 :

  • 1.代碼示例 :
#include <stdio.h> #include<stdlib.h>/*柔性數(shù)組實(shí)現(xiàn)斐波那契數(shù)列1. 定義柔性數(shù)組結(jié)構(gòu), typedef struct soft_array 實(shí)現(xiàn);2. 創(chuàng)建柔性數(shù)組, 編寫(xiě)一個(gè)創(chuàng)建函數(shù) create_array() 方法;3. 生成斐波那契數(shù)列, generate_array() 方法;4. 釋放柔性數(shù)組, delete_array() 方法. *///1.定義柔性數(shù)組結(jié)構(gòu)體 typedef struct soft_array {int len;int array[]; } soft_array;//2.創(chuàng)建柔性數(shù)組的函數(shù) soft_array* create_array(int array_size) {soft_array* array = NULL;//數(shù)組大小必須大于0if(array_size > 0){//從堆空間申請(qǐng)一個(gè)柔性數(shù)組內(nèi)存空間array = (soft_array*)malloc(sizeof(*array) + sizeof(*(array->array)) * array_size);array->len = array_size;}return array; }//3.生成斐波那契數(shù)列并放入柔性數(shù)組 void generate_array(soft_array* array) {//傳入的彈性數(shù)組不能為空if(array != NULL){//第一二項(xiàng)為1,后面第三項(xiàng)開(kāi)始就是前兩項(xiàng)之和if(array->len == 1){//數(shù)組大小就1個(gè)直接賦值1array->array[0] = 1;}else if (array->len == 2){//數(shù)組大小2個(gè),這兩個(gè)都賦值1array->array[0] = 1;array->array[1] = 1;}else{//如果超過(guò)2個(gè),前兩個(gè)賦值1,然后依次計(jì)算array->array[0] = 1;array->array[1] = 1;int i = 0;for(i = 2; i < array->len; i ++){array->array[i] = array->array[i - 1] + array->array[i - 2];}}} }//4.刪除柔性數(shù)組 void delete_array(soft_array* array) {//釋放內(nèi)存空間free(array); }int main() {//創(chuàng)建柔性數(shù)組, 為柔性數(shù)組分配內(nèi)存空間, 結(jié)構(gòu)體的基本空間 + 數(shù)組大小soft_array* array = create_array(10);//生成斐波那契數(shù)列generate_array(array);int i = 0;//依次遍歷打印柔性數(shù)組的值for(i = 0; i < array->len; i ++){printf("%d\n", array->array[i]);}//釋放柔性數(shù)組delete_array(array);return 0; }
  • 2.執(zhí)行結(jié)果 :



3. union 聯(lián)合體 關(guān)鍵字


(1) struct 和 union 的區(qū)別 ( struct 為每個(gè)元素分配獨(dú)立空間 | union 只為最大的元素分配內(nèi)存空間 所有元素共享該空間 )


struct 和 union 的區(qū)別 :

  • 1.struct 分配空間 : struct 結(jié)構(gòu)體 為每個(gè)結(jié)構(gòu)體元素分配獨(dú)立的內(nèi)存空間 ;
  • 2.union 分配空間 : union 聯(lián)合體 只為最大的聯(lián)合體元素分配內(nèi)存控件, 所有的元素共享該空間 ;
  • 3.struct union 空間分配示例 :
#include <stdio.h>//結(jié)構(gòu)體需要為所有的元素分配內(nèi)存空間 //該結(jié)構(gòu)體占 8 個(gè)字節(jié)內(nèi)存空間 struct A {int a;int b; };//聯(lián)合體只分配最大元素所占的內(nèi)存空間 //該 聯(lián)合體 占 4 字節(jié) 內(nèi)存空間 union B {int a;int b; };int main() {printf("%ld\n", sizeof(struct A));printf("%ld\n", sizeof(union B));return 0; }
  • 4.執(zhí)行結(jié)果 :



(2) union 聯(lián)合體注意事項(xiàng) ( 受大小端影響 )


union 聯(lián)合體 受大小端 影響 :

  • 1.大端模式 : 低位數(shù)據(jù)放在 高位地址 中;
  • 2.小端模式 : 低位數(shù)據(jù)放在 低位地址 中;

通過(guò) union 判斷系統(tǒng)的大小端 :

  • 1.代碼示例 :
#include <stdio.h>//利用union聯(lián)合體賦值受大小端影響的特性, //判斷當(dāng)前的系統(tǒng)是大端模式還是小端模式 int big_or_small_check() {//定義聯(lián)合體,其中定義int和char類型元素,兩個(gè)元素共用一個(gè)內(nèi)存空間union check_end{int i;char c;} a;//將大空間的int賦值為1a.i = 1;//四個(gè)字節(jié)賦值為1,如果是小端模式,那么高位地址都是0,最低位個(gè)字節(jié)是1//char是占用最低位字節(jié), 如果char 為1,說(shuō)明就是小端模式if(a.c == 1){printf("small end\n");}else{printf("big end\n");}}int main() {big_or_small_check();return 0; }
  • 2.執(zhí)行結(jié)果 :





五. 枚舉 關(guān)鍵字 ( enum )



1. enum 關(guān)鍵字


(1) enum 枚舉關(guān)鍵介紹 ( 定義常量 | 只能定義 int 類型 )


enum 簡(jiǎn)介 :

  • 1.作用 : enum 是自定義類型, 作用是用來(lái)定義常量的 ;
  • 2.定義要求 : enum 只能定義成 int 類型. 不能定義成 浮點(diǎn)型 ;


(2) enum 枚舉代碼示例


enum 枚舉代碼示例 :

  • 1.代碼示例 :
#include <stdio.h>//enum 如果沒(méi)有指明, 默認(rèn)值是從 0 開(kāi)始 //如果沒(méi)有指定值, 那么后面一個(gè)默認(rèn)是在前一個(gè)基礎(chǔ)上加1 //如果顯示的賦值后, 后面的類型依次加 1, 顯示賦值之前的默認(rèn)從 0 開(kāi)始 //枚舉是常量, 不能獲取枚舉的地址 enum color {RED,YELLOW,BLUE = 666,GRAY };int main() {printf("%d\n", RED);printf("%d\n", YELLOW);printf("%d\n", BLUE);printf("%d\n", GRAY);return 0; }
  • 2.執(zhí)行結(jié)果 :


(3) enum 和 define 區(qū)別 ( #define 編譯時(shí)進(jìn)行替換 | enum 是常量值 )


enum 與 define 區(qū)別 :

  • 1.本質(zhì) : #define 是在編譯的時(shí)候進(jìn)行簡(jiǎn)單的替換, enum 枚舉是常量值.
  • 2.能否被調(diào)試 : #define 宏 無(wú)法調(diào)試, enum 可以;
  • 3.類型 : #define 沒(méi)有類型信息, enum 是 有特定的類型 的;
  • 代碼示例 :
#include <stdio.h>#define LEN 888int main() {//在編譯的時(shí)候, #define 定義的 LEN 直接替換成 888 數(shù)字int i = LEN;int array[LEN];return 0; }


2. typedef 關(guān)鍵字


( 1 ) typedef 關(guān)鍵字介紹 ( 給已有類型重新命名 | 沒(méi)有新類型 | 無(wú)法擴(kuò)展 )


typedef 介紹 :

  • 1.作用 : typedef 用于給 存在的數(shù)據(jù)類型 重新命名;
  • 2.沒(méi)有新類型 : typedef 關(guān)鍵字使用, 全程都沒(méi)有產(chǎn)生 新的數(shù)據(jù)類型 ;
  • 3.類型無(wú)法擴(kuò)展 : 不能使用 unsigned 和 signed 等擴(kuò)展 typedef 重命名的類型;

typedef 與 define 區(qū)別 :

  • 1.typedef 本質(zhì) : typedef 是給已有類別重新命名;
  • 2.define 本質(zhì) : define是簡(jiǎn)單的字符串替換, 沒(méi)有類別 類型 等其它含義 ;
  • 3.代碼示例 :
#include <stdio.h>typedef char* PCHAR #define PINT int*int main() {//這里 p1 和 p2 都是 char* 類型PCHAR p1, p2;//這里注意, 編譯時(shí)PINT 會(huì)被替換成 int* p3, p4//注意 *p3 是指針, p4 是 int 類型數(shù)據(jù), int *p3, p4PINT p3, p4;return 0; }

總結(jié)

以上是生活随笔為你收集整理的【C语言】 C 语言 关键字分析 ( 属性关键字 | 常量关键字 | 结构体关键字 | 联合体关键字 | 枚举关键字 | 命名关键字 | 杂项关键字)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。