網(wǎng)站首頁 編程語言 正文
一、C語言關(guān)鍵字詳解
1. sizeof
???????sizeof相信大家并不陌生,其作用就是計(jì)算變量所占用的內(nèi)存空間大小。sizeof的用法看著和函數(shù)很相似,但sizeof的真實(shí)身份確是:sizeof既是關(guān)鍵字,也是運(yùn)算符,但不是函數(shù)! 這點(diǎn)需要大家牢記。還有非常重要的一點(diǎn)就是 sizeof中的表示式編譯器不會(huì)進(jìn)行編譯處理,其原因就是sizeof是在編譯的時(shí)候執(zhí)行的,而C語言的運(yùn)算符計(jì)算是在程序運(yùn)行的時(shí)候執(zhí)行的,故 sizeof里面的表達(dá)式是不會(huì)被執(zhí)行的。下面以一個(gè)實(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í)行的時(shí)候運(yùn)行的,而sizeof表達(dá)式是在程序編譯的時(shí)候運(yùn)行的,所以 ++ 操作并不會(huì)被執(zhí)行。
2. const
???????const關(guān)鍵字的作用就是將變量常量化。大家都知道變量是可以進(jìn)行隨意賦值的,但是常量不可以。而被const修飾的變量是不能夠被賦值的,盡管如此,但是我們依舊有方法可以將其進(jìn)行改變,看下面例子:
源代碼:
#include <stdio.h>
int main()
{
const int a = 3;
//a = 4; //程序報(bào)錯(cuò),因?yàn)樽兞縜被const修飾成只讀的變量了。
int *p = &a;
*p = 8;
printf("a = %d\n", a);
return 0;
}
運(yùn)行結(jié)果:
a = 8
???????上面講到const修飾的變量是不能夠被賦值的,因此程序中注釋的那一行會(huì)報(bào)錯(cuò),這是合理的。在下面我們定義了一個(gè)指針指向變量 a ,并且通過指針的方式來改變變量 a 地址里面的內(nèi)容,這樣是合理的。我們可以這樣來理解,首先定義一個(gè)變量 a , 那么這個(gè)變量 a 是具有可讀可寫屬性的,用 const 對 a 進(jìn)行修飾,可以理解成 const 去掉了變量 a 的寫屬性,只保留了讀屬性,所以不能再對 a 進(jìn)行賦值了。接著我們定義了一個(gè)指針變量指向 a 的地址,這個(gè)新定義的指針變量沒有被 const 修飾,所以具備可讀可寫屬性,然后通過指針變量來對地址里面的值進(jìn)行操作,相當(dāng)于是間接改變了變量 a 里面的內(nèi)容。所以const的作用可以簡述成一句話,那就是 const修飾誰,誰不能被直接賦值,但是可以通過間接的方式來改變其內(nèi)容。
3. static
static修飾的變量會(huì)存儲(chǔ)在靜態(tài)存儲(chǔ)區(qū),靜態(tài)存儲(chǔ)區(qū)默認(rèn)值是0。
static的三個(gè)作用:
- static修飾的局部變量只會(huì)被初始化一次。
- 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ù)的功能就是定義兩個(gè)變量,并且執(zhí)行加1操作,然后打印輸出。變量 a 因?yàn)楸?static 修飾,所以 a 被存儲(chǔ)在靜態(tài)存儲(chǔ)區(qū),靜態(tài)存儲(chǔ)區(qū)中的內(nèi)容是要等程序結(jié)束完才會(huì)被釋放。并且 a 只會(huì)在程序第一次進(jìn)來的時(shí)候被初始化一次,后續(xù)再進(jìn)來的時(shí)候不會(huì)再執(zhí)行初始化操作,且保留函數(shù)上一次退出的時(shí)候的值。而變量 b 沒有被 static 修飾,所以存儲(chǔ)在棧區(qū),棧區(qū)中的內(nèi)容會(huì)在該函數(shù)結(jié)束的時(shí)候被回收,所以每次執(zhí)行func() 函數(shù)變量 b 都會(huì)被重新賦值。
4. extern
???????extern一般只有在多文件編程的時(shí)候才會(huì)被用到,是用來修飾變量或函數(shù)的,并且告訴編譯器,該變量或函數(shù)是在別的文件中被定義的,下面用一個(gè)實(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同時(shí)運(yùn)行結(jié)果:
a = 10, sum = 30
???????上面程序中在文件2中調(diào)用了文件1的變量和函數(shù),因?yàn)樽兞亢秃瘮?shù)都是在文件1中定義的,所以我們想要引用到文件1中的變量或函數(shù)時(shí)就必須要用extern進(jìn)行聲明,否則就會(huì)報(bào)錯(cuò)。
???????假設(shè)我們在文件1中將變量和函數(shù)用static進(jìn)行修飾,文件2不變。
改變后的文件1源代碼
static int a = 10;
static int add(int a, int b)
{
return a+b;
}
???????這個(gè)時(shí)候再同時(shí)運(yùn)行文件1和文件2就會(huì)報(bào)錯(cuò)。報(bào)錯(cuò)的原因就是在文件2中找不到變量和函數(shù)。其原因就是被static修飾的變量或函數(shù)只能在該文件中使用。
5. volatile
???????volatile的作用一句話概述的話就是防止編譯器優(yōu)化。 cpu讀取變量的時(shí)候是先從內(nèi)存中讀取到寄存器,再從寄存器中讀取變量的值,但是可能在一些情況下編譯器認(rèn)為某些變量的值沒有發(fā)生變化,因此就省略了從內(nèi)存中讀取變量的操作,直接從寄存器中讀取。但是這些值可能會(huì)被外部環(huán)境所改變,比如說是在中斷或者別的線程里面改變,這個(gè)時(shí)候如果編譯器沒有及時(shí)更新變量在寄存器中的值就會(huì)導(dǎo)致讀取錯(cuò)誤。但如果將這個(gè)變量用volatile關(guān)鍵字修飾的話就可以保證cpu在讀取變量的時(shí)候一定會(huì)從內(nèi)存中讀取到寄存器,這樣就可以保證讀取變量的值不出錯(cuò)。
6. typedef
???????typedef的作用就是為已有類型取別名,注意typedef只是取別名,而不是創(chuàng)造出一個(gè)新的類型。
源代碼:
#include <stdio.h>
int main()
{
typedef int u32;
u32 a = 10, b = 20; //等價(jià)于 int a = 10, b = 20;
printf("a+b = %d\n", a+b);
return 0;
}
運(yùn)行結(jié)果:
a+b = 30
???????上面代碼中使用 typedef 將 int 類型取名為 u32,對于編譯器而言,只要是看到 u32 都會(huì)默認(rèn)將其轉(zhuǎn)換為 int 。取別名主要是方便我們來寫和閱讀代碼,而并不會(huì)說是創(chuàng)造了新類型。
7. enum
???????enum就是枚舉類型,因?yàn)槲覀冇械淖兞靠赡苋≈捣秶褪悄敲磶讉€(gè)值,不會(huì)出現(xiàn)別的值。像這種情況下我們就最好使用枚舉類型,注意的是枚舉的值默認(rèn)是從0開始的,后面的值以此增加,如果我們對枚舉變量中某個(gè)值進(jìn)行手動(dòng)賦值,那么被手動(dòng)賦值的后面那個(gè)值會(huì)在此基礎(chǔ)上加1。舉個(gè)實(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 的時(shí)候不會(huì)輸出打印。
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ū)別了,這兩個(gè)關(guān)鍵字的區(qū)別也是常考的,大家可以好好熟悉。
原文鏈接:https://blog.csdn.net/liung_/article/details/123015109
相關(guān)推薦
- 2023-10-24 Spring中的@Autowired和@Resource區(qū)別
- 2022-11-14 C++中4種管理數(shù)據(jù)內(nèi)存的方式總結(jié)_C 語言
- 2021-12-15 go?gin+token(JWT)驗(yàn)證實(shí)現(xiàn)登陸驗(yàn)證_Golang
- 2022-04-06 python中matplotlib的顏色以及形狀實(shí)例詳解_python
- 2022-11-02 Flask框架debug與配置項(xiàng)的開啟與設(shè)置詳解_python
- 2022-08-21 golang類型推斷與隱式類型轉(zhuǎn)換_Golang
- 2022-10-02 react函數(shù)組件useState異步,數(shù)據(jù)不能及時(shí)獲取到的問題_React
- 2022-03-15 this.$cookie.set(‘token‘, data.token) token賦值失效
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支