C語言學(xué)習(xí)之關(guān)鍵字的示例詳解
1. 前言
大家好,我是努力學(xué)習(xí)游泳的魚。關(guān)鍵字,這名字一聽,就很關(guān)鍵。而有些關(guān)鍵字,你可能不是很了解,更別談使用。所以,這篇文章將帶你見識(shí)常見的關(guān)鍵字,一起領(lǐng)略它們的風(fēng)采吧。
2. 什么是關(guān)鍵字
C語言提供了豐富的關(guān)鍵字,這些關(guān)鍵字都是語言本身預(yù)先設(shè)定好的,
用戶自己是不能創(chuàng)造關(guān)鍵字的。
大部分關(guān)鍵字會(huì)在其他章節(jié)介紹,這里僅介紹一些稍微有點(diǎn)難度的關(guān)鍵字。
3. extern-聲明外部符號(hào)
extern可以用來聲明外部符號(hào),如外部的全局變量和函數(shù)。
如我們?cè)趖est1.c里定義了全局變量aint a = 2022;
我們想在test2.c里使用,就得先用extern聲明一下extern int a;
注意:一般extern是用來聲明外部的全局變量的。因?yàn)槿绻苯訉慽nt a;就不是聲明了,而是定義,會(huì)直接創(chuàng)建一個(gè)變量a。只有寫extern int a;才是聲明變量a。如果是聲明外部的函數(shù),可以省略掉extern。如直接寫int Add(int, int);和寫extern int Add(int, int);效果是相同的。
4. auto-自動(dòng)
C語言里的局部變量,進(jìn)入局部范圍時(shí)自動(dòng)創(chuàng)建,出局部范圍時(shí)自動(dòng)銷毀。這種自動(dòng)創(chuàng)建,自動(dòng)銷毀的特性,其實(shí)是由于前面省略了關(guān)鍵字auto。比如,int a = 0;其實(shí)編譯器會(huì)處理為auto int a = 0;一般來說,auto會(huì)被省略掉。
5. typedef-類型重定義(類型重命名)
typedef關(guān)鍵字用于給類型起別名,相當(dāng)于起了個(gè)外號(hào)。
比如unsigned int num = 10;如果我們嫌unsigned int這個(gè)類型寫起來太麻煩了,可以給它起個(gè)別名叫做uint:typedef unsigned int uint;這樣上面的代碼就等價(jià)于uint num = 10;
6. register-寄存器
6.1 存儲(chǔ)器
數(shù)據(jù)的存儲(chǔ),需要存儲(chǔ)器。常見的存儲(chǔ)器有:
網(wǎng)盤,硬盤,內(nèi)存,高級(jí)緩存,寄存器。
從左到右,速度越快,從而造價(jià)越高,從而空間越小。
早期,CPU處理的數(shù)據(jù)都來自內(nèi)存。當(dāng)時(shí),CPU的處理速度和內(nèi)存的讀寫速度是差不多的。隨著技術(shù)的迭代,內(nèi)存的讀寫速度逐漸跟不上CPU的處理速度,CPU在很大程度上被閑置了。
于是就有了這么一層設(shè)計(jì)。在內(nèi)存之上設(shè)置讀寫速度更快的高級(jí)緩存和寄存器。CPU從寄存器中拿數(shù)據(jù),與此同時(shí),寄存器從高級(jí)緩存中拿數(shù)據(jù),高級(jí)緩存從內(nèi)存中拿數(shù)據(jù)。如果CPU想要的數(shù)據(jù)在寄存器中沒有,那就直接從高級(jí)緩存中拿數(shù)據(jù),如果還沒有再從內(nèi)存中拿。由于大部分?jǐn)?shù)據(jù)都能在寄存器中命中,整體上,處理數(shù)據(jù)的速度就提升了。
以上,我們能明白一點(diǎn):
寄存器的讀寫速度是非??斓模?/p>
6.2 register關(guān)鍵字的作用
如果我們寫int num = 10;num是放在內(nèi)存中的。如果我們加了個(gè)registerregister int num = 10;此時(shí)register的作用是建議把num放在寄存器中。注意只是建議,實(shí)際是否放在寄存器中取決于編譯器的處理。
7. static-靜態(tài)
在C語言中,static有3種用法,分別修飾局部變量,全局變量和函數(shù)。
1.修飾局部變量-稱為靜態(tài)局部變量
2.修飾全局變量-稱為靜態(tài)全局變量
3.修飾函數(shù)-稱為靜態(tài)函數(shù)
7.1 static修飾局部變量
7.1.1 代碼對(duì)比
下面代碼的輸出結(jié)果是多少呢?
#include <stdio.h> void test() { int a = 5; a++; printf("%d ", a); } int main() { int i = 0; while (i < 10) { test(); i++; } return 0; }
輸出結(jié)果:
10個(gè)6
為什么呢?test函數(shù)被調(diào)用了10次,每次都做了同樣一件事,創(chuàng)建a并初始化為5,a自增變成6,打印a(即6)。本質(zhì)上,每次進(jìn)入test函數(shù)都會(huì)創(chuàng)建a,出test函數(shù)時(shí)都會(huì)銷毀a。這是由于局部變量的特性:進(jìn)入局部范圍創(chuàng)建,出局部范圍銷毀。那么,每次進(jìn)入test函數(shù)創(chuàng)建的都是一個(gè)新的a,和之前創(chuàng)建的a沒有任何關(guān)系。
明白這點(diǎn)后,再看下面這段代碼,輸出的結(jié)果又是多少?
#include <stdio.h> void test() { static int a = 5; a++; printf("%d ", a); } int main() { int i = 0; while (i < 10) { test(); i++; } return 0; }
答案:
輸出6~15。
分析一下:第一次調(diào)用test函數(shù)時(shí)和沒有static相同,創(chuàng)建a并初始化,自增,打?。ù藭r(shí)a是6),但第二次調(diào)用怎么就打印7了呢?這說明,第二次調(diào)用時(shí),a還是上次調(diào)用留下來的6,才會(huì)自增變成7!也就是說,第一次調(diào)用結(jié)束后,a并沒有銷毀,第二次調(diào)用時(shí)依然存在。同理,第二次調(diào)用后a也沒有銷毀,第三次調(diào)用時(shí)a仍是第二次調(diào)用留下來的7,然后自增變成8后打印,以此類推。
static修飾局部變量的時(shí)候,局部變量就變成了靜態(tài)的局部變量,出了局部的范圍,不會(huì)銷毀,下一次進(jìn)入函數(shù)依然存在。
7.1.2 原理分析
內(nèi)存可以分為:棧區(qū),堆區(qū),靜態(tài)區(qū),等等。
棧區(qū)存儲(chǔ)的是局部變量,函數(shù)參數(shù),等等。
堆區(qū)是用來動(dòng)態(tài)內(nèi)存開辟的,與之相關(guān)的函數(shù)有malloc,realloc,calloc和free等等。
靜態(tài)區(qū)存儲(chǔ)的是靜態(tài)變量和全局變量。
靜態(tài)的局部變量出了作用域依然存在,是因?yàn)樗谴鎯?chǔ)在靜態(tài)區(qū)的。
同樣存儲(chǔ)在靜態(tài)區(qū)的全局變量,生命周期也很長。
static修飾局部變量時(shí),實(shí)際改變的是變量的存儲(chǔ)位置,本來一個(gè)局部變量是放在棧區(qū)的,被static修飾后放在了靜態(tài)區(qū),從而導(dǎo)致,出了作用域依然存在,生命周期并沒有結(jié)束。
注意:放在靜態(tài)區(qū)的變量出了作用域不銷毀,相當(dāng)于生命周期變長了,但是作用域并沒有發(fā)生變化,也就是說,靜態(tài)的局部變量仍然只能在它的局部范圍內(nèi)使用!
靜態(tài)區(qū)中的數(shù)據(jù)的生命周期和程序的生命周期是一致的。程序結(jié)束,靜態(tài)數(shù)據(jù)的生命周期也就到了。
7.2 static修飾全局變量
7.2.1 代碼對(duì)比
我們創(chuàng)建兩個(gè)源文件,test1.c和test2.c
在test1.c里定義一個(gè)全局變量g_val
// test1.c int g_val = 2022; // 全局變量,定義在test1.c中
在test2.c內(nèi)部使用這個(gè)全局變量,由于全局變量的作用域是整個(gè)工程,所以可以跨源文件使用。但是在使用前需要使用extern聲明,否則會(huì)報(bào)編譯錯(cuò)誤。
// test2.c extern int g_val; int main() { g_val = 2023; return 0; }
如果我們?cè)趃_val的定義前面加上static會(huì)發(fā)生什么呢?
// test1.c static int g_val = 2022; // 全局變量,定義在test1.c中 // test2.c extern int g_val; int main() { g_val = 2023; return 0; }
此時(shí)會(huì)報(bào)鏈接錯(cuò)誤,因?yàn)間_val是定義在test1.c里的靜態(tài)全局變量,不能在test2.c內(nèi)部使用。看來靜態(tài)的全局變量不能跨文件使用了。
7.2.2 原理分析
一個(gè)全局變量本來是具有外部鏈接屬性的,既能在自己所在的源文件內(nèi)部使用,也能在其他文件內(nèi)部使用。
但是被static修飾之后外部鏈接屬性就變成了內(nèi)部鏈接屬性,只能在自己所在的源文件內(nèi)部使用,不能在其他文件內(nèi)部使用了。
使用上感覺作用域變小了。
7.3 static修飾函數(shù)
7.3.1 代碼對(duì)比
我們?cè)趖est1.c里定義一個(gè)函數(shù)
// test1.c int Add(int x, int y) { return x + y; }
在test2.c內(nèi)部使用,同理要先聲明(此時(shí)可以省略extern),否則會(huì)報(bào)一個(gè)警告。
// test2.c #include <stdio.h> extern int Add(int, int); // extern可以省略 int main() { int sum = Add(10, 20); printf("sum = %d\n", sum); return 0; }
如果在函數(shù)定義前加上static會(huì)發(fā)生什么呢?
// test1.c static int Add(int x, int y) { return x + y; } // test2.c #include <stdio.h> extern int Add(int, int); // extern可以省略 int main() { int sum = Add(10, 20); printf("sum = %d\n", sum); return 0; }
此時(shí)會(huì)報(bào)鏈接錯(cuò)誤,因?yàn)锳dd函數(shù)是定義在test1.c內(nèi)部的靜態(tài)函數(shù),不能在test2.c內(nèi)部使用??磥韘tatic修飾函數(shù)和修飾全局變量類似,靜態(tài)的函數(shù)也不能跨文件調(diào)用。
7.3.2 原理分析
static修飾函數(shù)的作用:一個(gè)函數(shù)本來是具有外部鏈接屬性的,但是被static修飾之后,外部鏈接屬性就變成了內(nèi)部鏈接屬性,這時(shí)這個(gè)函數(shù)只能在自己所在的源文件內(nèi)部使用,其他文件是無法使用的。
使用上的感覺好像是作用域變小了。
到此這篇關(guān)于C語言學(xué)習(xí)之關(guān)鍵字的示例詳解的文章就介紹到這了,更多相關(guān)C語言關(guān)鍵字內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
基于C語言實(shí)現(xiàn)靜態(tài)通訊錄的示例代碼
這篇文章主要為大家詳細(xì)介紹了如何利用C語言實(shí)現(xiàn)一個(gè)簡單的靜態(tài)通訊錄,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)C語言有一定幫助,需要的可以參考一下2022-07-07C++中為什么要使用動(dòng)態(tài)內(nèi)存
大家好,本篇文章主要講的是C++中為什么要使用動(dòng)態(tài)內(nèi)存,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下2022-02-02C語言每日練習(xí)之統(tǒng)計(jì)文本單詞數(shù)及高頻詞
本文文大家準(zhǔn)備了個(gè)C語言練習(xí)題:統(tǒng)計(jì)單詞數(shù)并找出頻率最高的單詞,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)C語言有一定幫助,感興趣的可以了解一下2022-05-05C語言表達(dá)式求值中類型轉(zhuǎn)換和優(yōu)先級(jí)等問題詳解
表達(dá)式求值是一個(gè)常見的問題,可以用C語言實(shí)現(xiàn),下面這篇文章主要給大家介紹了關(guān)于C語言表達(dá)式求值中類型轉(zhuǎn)換和優(yōu)先級(jí)等問題的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-05-05C++中String類的常用接口函數(shù)總結(jié)
這篇文章主要介紹了C++中Stirng類的常用接口函數(shù),文中有詳細(xì)的代碼示例供大家參考,對(duì)我們學(xué)習(xí)C++有一定的幫助,感興趣的同學(xué)可以跟著小編一起來學(xué)習(xí)2023-06-06