C語言實(shí)例梳理講解常用關(guān)鍵字的用法
一、C語言關(guān)鍵字詳解
1. sizeof
sizeof相信大家并不陌生,其作用就是計算變量所占用的內(nèi)存空間大小。sizeof的用法看著和函數(shù)很相似,但sizeof的真實(shí)身份確是:sizeof既是關(guān)鍵字,也是運(yùn)算符,但不是函數(shù)! 這點(diǎn)需要大家牢記。還有非常重要的一點(diǎn)就是 sizeof中的表示式編譯器不會進(jìn)行編譯處理,其原因就是sizeof是在編譯的時候執(zhí)行的,而C語言的運(yùn)算符計算是在程序運(yùn)行的時候執(zhí)行的,故 sizeof里面的表達(dá)式是不會被執(zhí)行的。下面以一個實(shí)際的程序來為大家演示一下。
源代碼:
#include <stdio.h> int main() { int a = 3, b = 0; b = sizeof(a++); printf("a = %d, b = %d\n", a, b); return 0; }
運(yùn)行結(jié)果:
a = 3, b = 4
看上面的程序就知道,雖然在sizeof表達(dá)式中變量 a 進(jìn)行了自增1操作,但是 ++ 運(yùn)算符是在程序執(zhí)行的時候運(yùn)行的,而sizeof表達(dá)式是在程序編譯的時候運(yùn)行的,所以 ++ 操作并不會被執(zhí)行。
2. const
const關(guān)鍵字的作用就是將變量常量化。大家都知道變量是可以進(jìn)行隨意賦值的,但是常量不可以。而被const修飾的變量是不能夠被賦值的,盡管如此,但是我們依舊有方法可以將其進(jìn)行改變,看下面例子:
源代碼:
#include <stdio.h> int main() { const int a = 3; //a = 4; //程序報錯,因?yàn)樽兞縜被const修飾成只讀的變量了。 int *p = &a; *p = 8; printf("a = %d\n", a); return 0; }
運(yùn)行結(jié)果:
a = 8
上面講到const修飾的變量是不能夠被賦值的,因此程序中注釋的那一行會報錯,這是合理的。在下面我們定義了一個指針指向變量 a ,并且通過指針的方式來改變變量 a 地址里面的內(nèi)容,這樣是合理的。我們可以這樣來理解,首先定義一個變量 a , 那么這個變量 a 是具有可讀可寫屬性的,用 const 對 a 進(jìn)行修飾,可以理解成 const 去掉了變量 a 的寫屬性,只保留了讀屬性,所以不能再對 a 進(jìn)行賦值了。接著我們定義了一個指針變量指向 a 的地址,這個新定義的指針變量沒有被 const 修飾,所以具備可讀可寫屬性,然后通過指針變量來對地址里面的值進(jìn)行操作,相當(dāng)于是間接改變了變量 a 里面的內(nèi)容。所以const的作用可以簡述成一句話,那就是 const修飾誰,誰不能被直接賦值,但是可以通過間接的方式來改變其內(nèi)容。
3. static
static修飾的變量會存儲在靜態(tài)存儲區(qū),靜態(tài)存儲區(qū)默認(rèn)值是0。
static的三個作用:
- static修飾的局部變量只會被初始化一次。
- static修飾的全局變量只能在本文件中被使用,不能在其他文件中使用。
- static修飾的全局函數(shù)只能在本文件中被使用,不能在其他文件中使用。
作用1將在下面的程序示例為大家演示,作用2和作用3將結(jié)合 extern 關(guān)鍵字為大家演示。
源代碼:
#include <stdio.h> void func() { static int a = 2; int b = 2; a++; b++; printf("a = %d, b = %d\n", a, b); } int main() { int i = 0; for(i = 1; i <= 2; i++){ func(); } return 0; }
運(yùn)行結(jié)果:
a = 3, b = 3
a = 4, b = 3
上面程序中,就是調(diào)用了兩次 func() 函數(shù),func() 函數(shù)的功能就是定義兩個變量,并且執(zhí)行加1操作,然后打印輸出。變量 a 因?yàn)楸?static 修飾,所以 a 被存儲在靜態(tài)存儲區(qū),靜態(tài)存儲區(qū)中的內(nèi)容是要等程序結(jié)束完才會被釋放。并且 a 只會在程序第一次進(jìn)來的時候被初始化一次,后續(xù)再進(jìn)來的時候不會再執(zhí)行初始化操作,且保留函數(shù)上一次退出的時候的值。而變量 b 沒有被 static 修飾,所以存儲在棧區(qū),棧區(qū)中的內(nèi)容會在該函數(shù)結(jié)束的時候被回收,所以每次執(zhí)行func() 函數(shù)變量 b 都會被重新賦值。
4. extern
extern一般只有在多文件編程的時候才會被用到,是用來修飾變量或函數(shù)的,并且告訴編譯器,該變量或函數(shù)是在別的文件中被定義的,下面用一個實(shí)例來進(jìn)行具體說明:
文件1源代碼:
int a = 10; int add(int a, int b) { return a+b; }
文件2源代碼:
#include <stdio.h> extern int a; extern int add(int a, int b); int main() { printf("a = %d, sum = %d\n", a, add(10, 20)); }
文件1和文件2同時運(yùn)行結(jié)果:
a = 10, sum = 30
上面程序中在文件2中調(diào)用了文件1的變量和函數(shù),因?yàn)樽兞亢秃瘮?shù)都是在文件1中定義的,所以我們想要引用到文件1中的變量或函數(shù)時就必須要用extern進(jìn)行聲明,否則就會報錯。
假設(shè)我們在文件1中將變量和函數(shù)用static進(jìn)行修飾,文件2不變。
改變后的文件1源代碼
static int a = 10; static int add(int a, int b) { return a+b; }
這個時候再同時運(yùn)行文件1和文件2就會報錯。報錯的原因就是在文件2中找不到變量和函數(shù)。其原因就是被static修飾的變量或函數(shù)只能在該文件中使用。
5. volatile
volatile的作用一句話概述的話就是防止編譯器優(yōu)化。 cpu讀取變量的時候是先從內(nèi)存中讀取到寄存器,再從寄存器中讀取變量的值,但是可能在一些情況下編譯器認(rèn)為某些變量的值沒有發(fā)生變化,因此就省略了從內(nèi)存中讀取變量的操作,直接從寄存器中讀取。但是這些值可能會被外部環(huán)境所改變,比如說是在中斷或者別的線程里面改變,這個時候如果編譯器沒有及時更新變量在寄存器中的值就會導(dǎo)致讀取錯誤。但如果將這個變量用volatile關(guān)鍵字修飾的話就可以保證cpu在讀取變量的時候一定會從內(nèi)存中讀取到寄存器,這樣就可以保證讀取變量的值不出錯。
6. typedef
typedef的作用就是為已有類型取別名,注意typedef只是取別名,而不是創(chuàng)造出一個新的類型。
源代碼:
#include <stdio.h> int main() { typedef int u32; u32 a = 10, b = 20; //等價于 int a = 10, b = 20; printf("a+b = %d\n", a+b); return 0; }
運(yùn)行結(jié)果:
a+b = 30
上面代碼中使用 typedef 將 int 類型取名為 u32,對于編譯器而言,只要是看到 u32 都會默認(rèn)將其轉(zhuǎn)換為 int 。取別名主要是方便我們來寫和閱讀代碼,而并不會說是創(chuàng)造了新類型。
7. enum
enum就是枚舉類型,因?yàn)槲覀冇械淖兞靠赡苋≈捣秶褪悄敲磶讉€值,不會出現(xiàn)別的值。像這種情況下我們就最好使用枚舉類型,注意的是枚舉的值默認(rèn)是從0開始的,后面的值以此增加,如果我們對枚舉變量中某個值進(jìn)行手動賦值,那么被手動賦值的后面那個值會在此基礎(chǔ)上加1。舉個實(shí)例為大家具體講解:
源代碼:
#include <stdio.h> /*0, 1, 2, 3, 4, 5, 6*/ enum weekday{Monday, Tuesday, Wednesday, Thursday, Friday, Staurday, Sunday}; /*0, 1, 5, 6, 7*/ enum num{ONE, TWO, THREE=5, FOUR, FIVE}; int main() { enum weekday day = 3; day = Thursday; enum num number = FIVE; printf("day = %d, number = %d\n", day, number); return 0; }
運(yùn)行結(jié)果:
day = 3, number = 7
8. continue
continue用法兩大注意項(xiàng):
(1)continue只能用在循環(huán)體當(dāng)中。
(2)continue的作用是結(jié)束本次循環(huán),進(jìn)入到下一次循環(huán)。
源代碼:
#include <stdio.h> int main() { int i; int a[5] = {12, 13, 5, 11, 10}; for(i = 0; i < 5; i++){ if(a[i] < 10){ continue; } printf("a[%d] = %d\n", i, a[i]); } return 0; }
運(yùn)行結(jié)果:
a[0] = 12
a[1] = 13
a[3] = 11
a[4] = 10
從上面程序可以看出,a[2] 的結(jié)果是 5,所以結(jié)束本次循環(huán)進(jìn)入下次循環(huán),所以當(dāng) i 的值為 2 的時候不會輸出打印。
9. break
break用法兩大注意項(xiàng):
(1)break只能用于循環(huán)體或 switch…case 語句中。
(2)break的作用是跳出本循環(huán)體外,值得注意的是如果有多層循環(huán)嵌套的話,break是只能跳出它所在的那一層循環(huán)體。
源代碼:
#include <stdio.h> int main() { int i; int a[5] = {12, 13, 5, 11, 10}; for(i = 0; i < 5; i++){ if(a[i] < 10){ break; } printf("a[%d] = %d\n", i, a[i]); } return 0; }
運(yùn)行結(jié)果:
a[0] = 12
a[1] = 13
從上面程序看,a[2] 的結(jié)果是 5,break就直接跳出了循環(huán)體,然后程序就結(jié)束運(yùn)行了。因此從這里就能夠看出continue關(guān)鍵字和break關(guān)鍵字最大的區(qū)別了,這兩個關(guān)鍵字的區(qū)別也是??嫉?,大家可以好好熟悉。
到此這篇關(guān)于C語言實(shí)例梳理講解常用關(guān)鍵字的用法的文章就介紹到這了,更多相關(guān)C語言關(guān)鍵字內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++在成員函數(shù)中使用STL的find_if函數(shù)實(shí)例
這篇文章主要介紹了C++在成員函數(shù)中使用STL的find_if函數(shù)實(shí)例,包括了STL中find_if函數(shù)的具體用法及相關(guān)的完整實(shí)例,非常具有參考借鑒價值,需要的朋友可以參考下2014-10-10C++實(shí)現(xiàn)有向圖鄰接表的構(gòu)建
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)有向圖鄰接表的構(gòu)建,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-04-04VSCode配置C/C++環(huán)境的最新詳細(xì)教程
VisualStudioCode(簡稱VSCode)是Microsoft開發(fā)的代碼編輯器,它支持Windows,Linux和macOS等操作系統(tǒng)以及開源代碼,下面這篇文章主要給大家介紹了關(guān)于VSCode配置C/C++環(huán)境的最新詳細(xì)教程,需要的朋友可以參考下2022-12-12FFmpeg獲取網(wǎng)絡(luò)攝像頭數(shù)據(jù)解碼
這篇文章主要為大家詳細(xì)介紹了FFmpeg獲取網(wǎng)絡(luò)攝像頭數(shù)據(jù)解碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-06-06C++數(shù)據(jù)結(jié)構(gòu)之堆詳解
本文詳細(xì)講解了C++數(shù)據(jù)結(jié)構(gòu)之堆,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-04-04