C語言全面細致精講關鍵字的使用
1、switch 深入理解
學習過C語言的小伙伴可能知道,switch 也是選擇結構的一種,是具有判定能力的語法結構,那么他們都必須具備:判定+分支功能!
我們知道 if 可以搭配 else if 或 else 來實現(xiàn)分支功能,那么我們 switch 如何實現(xiàn)分支功能呢?這樣,我們先來看一段代碼:
可能看到這有小伙伴會有疑問,這里為什么把后面case 里面的語句也打印出來了呢???
其實:case 只是提供入口而已,case 并不能實現(xiàn)分支功能,它本身是用來進行判定的!像上面那段代碼,從case 2 進入只要沒有碰到 break 程序就會一直向下執(zhí)行,直到結束 switch !
所以我們要注意,要在每條 case 完成后按需加上 break,所以 break 在 switch 里的作用就相當于分支功能!
推薦寫法:
其實細心的小伙伴發(fā)現(xiàn)了,萬一我們輸入的不是1~5呢?
這里我們就要用到 default 了,在往后寫代碼,我都建議使用switch 時都帶上 default ,并且將 default 寫在最后一個 case 后面,雖然 default 從語法上寫在任何位置都是支持的,但是為了我們的代碼可讀性,能更直觀,建議寫在最后!
例:
int main() { int day = 0; scanf("%d", &day); switch (day) { case 1: printf("星期一\n"); break; case 2: printf("星期二\n"); break; case 3: printf("星期三\n"); break; case 4: printf("星期四\n"); break; case 5: printf("星期五\n"); break; default : printf("輸入錯誤\n"); break; } return 0; }
如果多個不同的 case 匹配,想執(zhí)行同一個語句怎么辦呢?比如說我希望輸入1~5都是工作日,輸入6~7是休息日,推薦寫法:
int main() { int day = 0; scanf("%d", &day); switch (day) { case 1: case 2: case 3: case 4: case 5: printf("工作日\n"); break; case 6: case 7: printf("休息日\n"); break; default: printf("輸入錯誤\n"); break; } return 0; }
2、如何正確的使用 case
現(xiàn)在我們就來學習下使用 case 的細節(jié):
case后面只能是常量整型,或者常量表達式,不能是浮點型,可以是字符型,因為字符本質(zhì)上存儲在內(nèi)存中是它們的ASCII碼,所以是屬于整型家族的!
那么 const 修飾的變量可以放在case后面嗎?
答案是不可以的!為什么不可以呢?因為 const 修飾的變量是常變量,它擁有常量的屬性,但本質(zhì)上還是一個變量!
下面有幾點 case 使用建議給大家:
- 按字母或數(shù)字順序排列各條 case 語句
- 把正常情況放在前面,而把異常情況放在后面(做好注釋)
- 簡化每種情況對應的操作,case語句后面的代碼盡量不要超過20行
- 不要為了使用 case 語句而刻意制造一個變量
- default 子句只用于檢查真正的默認情況
3、循環(huán)語句while for do while深度講解
相信大家學過C語言的對 while for do while 循環(huán)的基本語法肯定是了如指掌了,所以今天我就不帶著大家學習基本語法了,我們直接看流程圖:
我們要注意所有循環(huán)結構的三要素:條件初始化,條件判定,條件更新。
三種循環(huán)死循環(huán)寫法(特殊情況不具備三要素):
我們來看幾個使用循環(huán)語句的注意點:
- 建議寫 for 語句的時候循環(huán)控制變量采用半開半閉取值范圍:比如:for (i = 0; i < 10; ++i),for(i = 0; i <=9; ++i); 我們更推薦第一種寫法,因為循環(huán)次數(shù)明確,便于個數(shù)計算。
- 盡量不要在循環(huán)體內(nèi)修改循環(huán)控制變量,防止循環(huán)失去控制!
- 循環(huán)語句的表達式不能包含任何浮點類型對象,通過上期我們知道,浮點數(shù)在存儲時是會造成精度損失的!
4、continue的作用是什么
我們知道 continue 是用于終止本次循環(huán)的,也就是本次循環(huán)中 continue 后邊的代碼不會再執(zhí)行!
我們分別來演示下三種循環(huán)下 continue 不同的地方:
while:
while 循環(huán)執(zhí)行 continue 是直接跳轉(zhuǎn)到 while 語句的判斷部分,進行下一次循環(huán)的入口判斷。
do while:
do while 循環(huán)執(zhí)行 continue 是直接跳轉(zhuǎn)到 do while 語句下面的判斷部分,進行下一次循環(huán)的入口判斷。
for:
for 循環(huán)執(zhí)行 continue 是直接跳轉(zhuǎn)到 for 語句的條件更新部分,然后再進行下一次循環(huán)的入口判斷。
相信看到這小伙伴們對 continue 的理解更加深刻了,那么接著往后看吧!
5、goto真的沒人用了嗎
可能跟著學校在學習的小伙伴,都沒聽老師講過 goto 語句,那么今天我們就來了解下為什么很少人會用 goto 語句?
goto 語句是c語言給我們提供一個基本的語法結構,給我們提供了代碼跳轉(zhuǎn)的一個能力,對于我們一般的程序員來講,因為太靈活可能會導致我們語句在執(zhí)行的時候它的分支可能會不明確,所以在很多的公司內(nèi)它的編碼規(guī)范當中是禁止使用 goto 語句的,但是如果我們把 goto 語句用好了是會出奇效的今天不講奇效,重點講作用:
goto語句通常會用兩種用法:向下跳轉(zhuǎn),向上跳轉(zhuǎn):
那么我們應該如何看待 goto 呢?
1、有很多公司確實禁止使用 goto,不過,這個問題我們還是靈活對待,goto 在解決很多問題是有奇效的。
2、我們可以認為 goto 使用場景較少,一般不使用。但是必須得知道 goto,需要的時候,也必須會用。
我們來看個例子吧,在 Linux 內(nèi)核源代碼中充滿了大量的goto:
所以說,goto 還是有人用的!
6、void 到底是何方妖怪
我們知道C語言提供了很多種數(shù)據(jù)類型,int,float,char... 大家都知道 void 是空類型,那么首先我們來思考第一個問題,void 可以定義變量嗎?
答案顯然是不可以的! void 的類型大小是不確定的!
經(jīng)過測試,void 在 windows環(huán)境的 vs 編譯器下 sizeof 求出的大小是 0 ,而在 linux 環(huán)境的 gcc 編譯器 sizeof 求出的大小卻是 1 !
既然在 gcc 編譯器求出的大小是1,為什么還是不能定義變量?其實最主要的原因是 void 本身就被編譯器解釋為空類型,強制的不允許定義變量,在語義的級別上就被約束了!
而 void 作為空類型,理論上是不應該開辟空間的,即使開辟了空間,也僅僅作為一個占位符看待!
我們來看 void 的幾個場景:
① void 修飾函數(shù)但是有了返回值:
由上可見,void 修飾的函數(shù)是不能接收返回值的,但是經(jīng)過測試,如果不拿變量接收返回值一樣可以編譯過去,但是不要這樣寫,首先 void 充當占位符,讓我們知道此函數(shù)不需要返回值,再者,可以告知編譯器,這個返回值無法接收!
② void 充當函數(shù)形參列表:
同時我們也能看出來,void 充當函數(shù)形參列表,我們在 vs 環(huán)境下如果強求給函數(shù)傳參是會有警告的,但是編譯仍然能通過,但是如果我們在 Linux 環(huán)境下是會直接報錯的!這個取決于編譯器!
③ void 既然不能定義變量,那么 void* 呢?
首先告訴小伙伴們答案,顯然是可以的!
為什么呢,因為 void* 是指針,指針的大小在任何平臺都是固定的,如果在 32 位的操作系統(tǒng)下指針的大小是 4 個字節(jié),如果在 64 位操作系統(tǒng)下指針的大小是 8 個字節(jié)(在指針章節(jié)我們會詳細講解),不信我們就用 sizeof 求一下指針所占的大?。?/p>
④ void* 可以被任何類型的直接接收,同時 void* 可以接收任意指針類型(常用):
通常我們 void* 會用在庫,系統(tǒng)接的設計上:比如在C中 memset、memcmp 函數(shù)等...
⑤ void* 定義的指針變量可以進行運算操作嗎?
原因:因為一般對指針進行 + 或 - 更多的是衡量一個指針向前或者向后移動步長的問題,而整型指針基本都會指向一個整型變量,所以對它進行 ++ 后一定是跳過一個整型變量指向下一個整型變量,也就是說向后移動 sizeof(int);的大小,而 void* 指針的大小本來就是不明確的!
但是在 Linux 環(huán)境下是可以編譯通過的,因為 Linux 求 sizeof(void);是占 1 個字節(jié)的,所以對 void* 指針進行 ++ -- 是向前或向后移動一個字節(jié),但是在 windows vs 環(huán)境下占 0 字節(jié),無意義的!
根本原因是因為使用的C標準擴展的問題,一句話,大部分編譯器是標準C,而Linux下是擴展C,Linux平臺也能保證標準C的運行,感興趣的小伙伴可以自己去查詢下資料~
最后一點,void* 指針是不能直接解引用的!因為并不知道以什么類型去解釋指向空間里的數(shù)據(jù),也就是說并不知道解引用訪問多少個自己,會直接編譯報錯,在 Linux 環(huán)境下也是一樣的,具體小伙伴的可以自行去測試哦!
只有埋頭,才有出頭!Come on!
到此這篇關于C語言全面細致精講關鍵字的使用的文章就介紹到這了,更多相關C語言關鍵字內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
C++實現(xiàn)LeetCode(151.翻轉(zhuǎn)字符串中的單詞)
這篇文章主要介紹了C++實現(xiàn)LeetCode(151.翻轉(zhuǎn)字符串中的單詞),本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下2021-07-07C++11中的時間庫std::chrono(引發(fā)關于時間的思考)
這篇文章主要介紹了C++11中的時間庫std::chrono(引發(fā)關于時間的思考),本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-04-04C++消息隊列(定義,結構,如何創(chuàng)建,發(fā)送與接收)
這篇文章主要介紹了C++消息隊列(定義,結構,如何創(chuàng)建,發(fā)送與接收),消息隊列是一種先進先出的隊列型數(shù)據(jù)結構,實際上是系統(tǒng)內(nèi)核中的一個內(nèi)部鏈表2022-08-08