1. 程式人生 > >C語言中的32個關鍵字及部分講解

C語言中的32個關鍵字及部分講解

說起c語言中的關鍵字,大家印象最深的可能就是int,double等定義一個數據變數時所使用的關鍵字了。但是除了這些資料型別的關鍵字還有哪些呢?for?while?沒錯,這些確實都是,但是並沒有一個系統的總結。本文筆者就將就c語言學習中所遇到的共計32個關鍵字進行整理。請善用搜索功能。

首先是對關鍵字的羅列以及相應的簡介:

auto                    宣告自動變數 預設時編譯器預設為auto    

int                       宣告整形變數

double                宣告雙精度變數

long                    宣告長整形變數

char                    宣告字元型變數

float                    宣告浮點型變數

short                    宣告短整型變數

signed                宣告有符號型別變數

unsigned            宣告無符號型別變數

struct                  宣告結構體變數

union                  宣告聯合體(聯合資料)變數

enum                  宣告列舉變數

static                   宣告靜態變數

switch                 用於開關語句   

case                    開關語句的分支

default                開關語句中的“預設”分支

break                  跳出當前迴圈

register                宣告暫存器變數

const                    宣告只讀變數(常變數)

volatile                說明變數在程式執行中可能會被隱式地改變

typedef                給資料型別取別名

extern                  宣告變數是從其他檔案中引用來的

return                   子程式返回語句(引數可有可無)

void                      宣告函式無返回值或無引數,宣告空型別指標

continue                結束當前迴圈並開啟下一輪迴圈

do                          迴圈語句的迴圈體

while                      迴圈語句的迴圈條件  

if                            條件語句

else                        條件語句的否定分支

for                         迴圈語句

goto                      無條件跳轉語句  

sizeof                    計算物件所佔記憶體空間大小

篇幅問題,無法進行挨個講解,同時也不一定會根據上述順序進行分析,請見諒。

1.auto

    該關鍵字通常情況下都可以無視,而且平常它並不是特別常見。(說是不常見,只是我們看不到而已,並非是不常用的意思。)

    C語言作為一門面向過程的語言必然會出現許多的函式塊。在每個函式模組中宣告的變數即區域性變數,也有另一個名字,就叫做:自動變數。  

     例:(在一個函式中)int a = 10;

                等價於

                auto int a = 10;

auto的出現也就意味著當前變數是一個區域性變數,會在記憶體棧上分配,從而更高效的利用記憶體。

2.register

    被register修飾的變數叫做暫存器變數,顧名思義,該變數是直接儲存在CPU的內部暫存器中的,訪問速度和記憶體中的資料必不可同日而語。具體應用場景比如有一個很大的迴圈,其中有幾個需要頻繁操作的變數,這時使用register進行修飾將大大提高效率。

    但是即使強如register也是有著自己的限制的,必須是暫存器所接受的型別才能被修飾,即register變數必須是一個單個的值,而且他的長度也要小於等於整形的長度。register變數雖說並不是每時每刻都在暫存器中,最後也是要寫入記憶體的,但是我們也並不能保證某個時刻它就在記憶體裡,所以我們也不能對register變數取地址。

3.static

    靜態關鍵字static在c語言中主要有兩個作用,在C++中獲得了擴充套件(第三個作用),不過這不在本文的討論範圍內。

作用一:修飾變數

變數分為區域性變數和全域性變數,修飾後也就對應兩種靜態變數。他們都儲存在記憶體的靜態區。

    靜態區域性變數:

    在函式中定義的靜態區域性變數則只有該函式可以使用,其他函式不得使用。同時由於它和靜態全域性變數都存在於記憶體的靜態區中而非棧中,所以函式結束之後值也不會銷燬,函式下次執行時會繼續使用這個值,這是非常重要的特性。

    靜態全域性變數:

    該種變數的作用域僅限於被定義的檔案中(從定義之處開始到當前檔案結尾),而且在其他檔案中即使使用extern關鍵字也不能使用。在當前檔案中,靜態全域性變數定義之處之前的程式碼行也同樣不能直接使用它,需要使用extern關鍵字才能使用。所以一般我們都將靜態全域性變數定義在檔案的頂端。

作用二:修飾函式

在函式前面加上static使得函式成為靜態函式。這時該函式的作用域則僅限於本檔案中,所以又成為內部函式。這樣做的好處是不同的人編寫不同的函式時這樣不用擔心自己的函式與他人編寫的重名。

4.基本資料型別-----short int long char float double

需要注意的是在32位系統上,short佔2個位元組,int和long都是4個位元組,char是1個位元組,只有double和longlong是8位元組。當然在不同系統上也有差異,需要自己用sizeof進行測試。

5.sizeof

首先有一個問題:sizeof是函式還是關鍵字呢?

有人可能看見sizeof後面加上了一對括號,認為它是函式。其實sizeof(i) 和 sizeof i (竟然可以這樣用?)效果是一樣的,結果也是一樣沒有任何問題。那麼sizeof(int) 和 sizeof int也是一樣的嗎?答案是否定的,因為sizeof int 根本就無法通過編譯。從前面一個例子我們瞭解了沒有括號也能完成功能說明它並不是一個函式!毫無疑問它是一個關鍵字,那麼sizeof int是什麼意思?在int資料型別前加一個關鍵字,類比下來就好像double int型別的變數一樣,這是個什麼變數?

所以一般來說,sizeof在計算變數所佔空間大小的時候可以去掉括號,但計算型別大小的時候不能省略。在此處省略也只是wile讓大家明白它不是一個函式,平常我們使用的時候還是乖乖的把括號寫上吧:P

6.signed和unsigned關鍵字

相信大家平常也沒少見這兩個關鍵字,但大多數人對其不甚瞭解。

他們的中文名字是有符號型別和無符號型別。涉及到變數的正負問題。我們都知道一個變數的最高位是符號位,unsigned型別則是將這個最高位也用於表示資料了,所以unsigned型別都是從0開始到某個正數的範圍。signed型別和auto類似,也是平常我們看不到但是預設預設情況都認為一個變數是signed型別的。

7.goto關鍵字

建議禁用。雖然它可以靈活跳轉,但它明顯破壞了結構化的設計風格。

8.void關鍵字

首先問大家一個問題:在c語言中如果定義一個函式,不給返回型別,例如:

add (int a, int b)

{

    return a+b;

}

這麼做的結果是什麼呢?返回值是不是void型別?還是說根本無法通過編譯呢?

答案是,編譯可以通過,但返回值型別並不是你所想的void而是int。

還有另一個問題:定義一個void型別的變數的話,編譯器會給他分配多大的記憶體呢?

如果你接觸過OOP語言(例如java c#等)一定對抽象類這個概念不陌生。抽象類能定義一個例項嗎?明顯不能,因為它強調的是一個“抽象”的概念,那必然是不能存在的,void也是同理,是不允許定義void型別的變數的。

9.const

這個關鍵字非常重要,有許多人對它的理解都有錯誤。先來看一句話。

                        被const修飾的變數叫做常量。

這句話對嗎?加上const確實不能直接修改它的值了,這不是和常量一樣嗎?

這麼說是不準確的。該值在編譯的時候不能被使用,因為這時編譯器並不知道它儲存的內容。因此和常量還是有小小的區別的,也許叫做只讀變數比較好。

具體驗證:請看如下程式碼。

const int MAX = 100;

int Array[MAX];

這串程式碼在.cpp檔案中可以順利執行,但是在.c檔案中不可行。證明了這個MAX它其實還是一個變數,絕非常量。由於c++對const進行了擴充套件使得在.cpp檔案中這些程式碼成為可行。

前面我們說到它叫做只讀變數是因為編譯期間它的值不被編譯器所知道,這是怎麼回事呢?

編譯器通常不給只讀變數分配儲存空間,而是直接將他們儲存在符號表裡。它就成為了一個編譯期間的值,沒有了儲存和讀記憶體的操作,效率變得很高。

關於const修飾物件的問題

先看下面這些程式碼:

const int *p;                //p的指向可以改變,但是指標p指向的物件的記憶體不能改變。

int const *p;                //同上

int *const p;                //p的指向不可以改變,但是指標p指向的物件的記憶體可以改變。

const int* const p;      //p的值和p指向的物件都不可改變。

分辨這些情況,只需要首先將資料型別遮蔽(把int不看,編譯器解析的時候也是這麼做的),我們看const離哪個近他就修飾誰。

10.volatile

和const類似,它也是一種型別修飾符。不過我們可能覺得它很陌生,因為它並不那麼常見(其實在linux和c++中還是很常見的)。該關鍵字表示他所修飾的變數是一個極易被未知因素所改變的,編譯器則對訪問該程式碼不再進行優化,從而提供對特殊地址的穩定訪問。具體例子如下:

int i = 10;  

int j = i;          //(1)    

int k = i;         //(2)

通常情況編譯器會對程式碼進行優化:在(1)(2)這兩條語句中,i並未做左值。此時編譯器就認為i的值沒有改變,所以在語句(1)將i從記憶體中取出賦給j之後這個值並未被丟掉,而是直接繼續給k賦值了。編譯器不會再生成從記憶體中再次取出i的值的程式碼,這樣就提高了效率,也就是所謂的優化。

接下來再看下面的程式碼:

volatile i = 10;

int j = i;            //(3)

int k = i;           //(4)

這樣的話,(4)語句則會再次從記憶體中i的地址中讀取一次值賦給k。省去了優化的步驟,實現了穩定的訪問。

11.extern

extern可以置於變數和函式之前,來表示這個函式或者變數有可能是來自別的檔案的,在這裡進行了引用(當然有一種特殊情況,就是我們在上面講過的本檔案中在靜態全域性變數前的程式碼行若想使用這個變數,也得使用extern來引用)

12.struct

struct即是我們所說的結構體。他將一些相關聯的資料打包成一個整體,方便使用。其實它的概念通俗的來說,就像OOP語言中的類一樣,只不過我們的結構體裡沒有函式,只有各種“屬性”或者“欄位”。:P

(PS:C語言中只能包含資料,C++中可以包含成員函式,和class更加相似。)

說到結構體,最折磨人的就是它的大小問題。首先我們先解決空結構體的大小問題。普通結構體的大小涉及到記憶體對齊,我將在我的另一篇部落格中進行整理。

大小是0嗎?

很遺憾,大小是1。如果定義一個空結構體,把它看成一個模子,模子當然不能為0。編譯器認為任何一種資料型別都有其大小,同樣它也認為任何一個結構體都是有大小的,哪怕它是空的。

13.union關鍵字

union,即聯合體。它和struct非常相像,但是含義卻有較大的差別。

我們知道,struct結構體的大小是考慮到其中每個成員後,經過記憶體對齊而產生的。而union則只是維護足夠的空間(成員中大小最大的資料型別)來放置多個數據成員的一種,而並非給每個成員都配置空間。所有的成員都有相同的起始地址。

一個形象的比喻:struct就像是一個大別墅,每個成員都有自己的房子,大家都在裡面住也沒任何問題;而union就比較可憐了,只有一個房間,大小夠成員中最胖的那個住進去,但是同時只能有一個人在裡面住。

union主要的用處就是壓縮空間。如果一些資料不可能在同一時間被用到,則他們可以寫進同一個union裡面。

14.enum 列舉型別

一般它的定義如下:

enum enum_type_name

{

    ENUM_CONST_1,

    ENUM_CONST_2,

    ......

    ENUM_CONST_n

}enum_variable_name;

其中裡面的例如ENUM_CONST_1就是我們常說的列舉常量。

需要注意的一點是,enum中的常量可以賦值,但是如果你不給它賦值則會從被賦了初值的那個常量開始依次加1.如果沒有給賦任何值,則從第一個值開始自動賦0,往後每個變數都自增1.

至於enum的大小,你在使用它的時候它的型別就已經確定了,這時大小你自己心裡也就有數了。

enum可以一次定義大量相關的常量,而且使用方便。

15.typedef關鍵字

有許多人對這個關鍵字的認知是:定義一個*新的*資料型別。因為type是型別,def是define定義的意思,連在一起不就是定義型別的意思嗎?

又是典型的望文生義慘案,看來不只是中國成語,英文單詞也有這樣的問題啊www

它的真正作用是:給一個已經存在的資料型別(注意,不是變數)取一個別名.它的主要用處就是,取了別名之後我們可以更清楚的一眼看懂這個資料型別的含義。常見的使用場合就是結構體定義的時候。

typedef struct Student

{

    //code..

}stu,*stu_p;

此時結構體Student 就有了別名stu,即

struct Student stu1 == stu stu1;

struct Student* stu2 == stu_p stu2 == stu * stu2;

現在我們順便回顧一下以前的知識:

const stu_p stu3;

stu_p const stu4;

這兩句的const分別修飾的是誰呢?

答案是stu3和stu4.因為我們說了typedef的含義是,給*資料型別*起一個別名。所以stu_p不單單是一個指標,而是一個數據型別。const在判斷時會自動忽略資料型別,所以自然它也就被當作不存在啦。

相關推薦

C言中32關鍵字部分講解

說起c語言中的關鍵字,大家印象最深的可能就是int,double等定義一個數據變數時所使用的關鍵字了。但是除了這些資料型別的關鍵字還有哪些呢?for?while?沒錯,這些確實都是,但是並沒有一個系統的總結。本文筆者就將就c語言學習中所遇到的共計32個關鍵字進行整理。請善用搜

C言中32關鍵字

auto 區域性變數(自動儲存) break無條件退出程式最內層迴圈 case   switch語句中選擇項 char單位元組整型資料 const定義不可更改的常量值 continue中斷本次迴圈,並轉向下一次迴圈 default switch語句中的預設選擇項 do  用於構成do.....while迴圈語

c語言的32關鍵字和9控制語句

com nbsp 自動變 typedef void unsigned c語言 分享 signed C的32個關鍵字 auto :聲明自動變量 一般不使用double :聲明雙精度變量或函數int: 聲明整型變量或函數struct:聲明結構體變量或函數break:跳出當前循環

c言中32為地址型別轉換為64位整數型別

uint64_t idt_operand = ((sizeof(idt) - 1) | ((uint64_t)(uint32_t)idt << 16)); idt是陣列名,也就是結構陣列型別的指標。static struct gate_desc idt[IDT

C語言的32關鍵字,9種控制語句,34種運算子

32個關鍵字: char,int,short,long,float,double signed,unsigned auto,register,extern,static,volatile,const if,else,do,while,for,goto,switch,case

C言中static的作用C語言中使用靜態函式有何好處

在C語言中,static的字面意思很容易把我們匯入歧途,其實它的作用有三條,分別是: 一是隱藏功能,對於static修飾的函式和全域性變數而言 二是保持永續性功能,對於static修飾的區域性變數而言。 三是因為存放在靜態區,全域性和區域性的static修飾的變數,都預設初始化為0 下面我逐一給

C語言的32關鍵字

6個變數記憶體管理修飾符 auto register static extern volatile const 12個數據型別 void char short int long float double signed unsigned enum struct union

C言中,static關鍵字舉例——全域性static變數

C語言中,可以在全域性作用域中使用static關鍵字:被static關鍵字修飾的變數或函式,僅在本".c檔案"中可見,而在其他".c檔案"中,不可見。例如,在t1.c中的全域性作用域,定義static函式func,則在t2.c中,無法使用t1.c中定義的func函式,即使在

【好程式設計師筆記分享】—— C言中的extern關鍵字

C語言中的extern關鍵字不僅可以用變數還可以用於函式。當用於函式時,表示宣告函式,引用別人的“外部函式”;當用於變數時,表示宣告一個已經定義過的變數,必須結合定義變數使用。下面我們先來看一個extern用於函式的例子。 先來看一下檔案結構: test.c中的程式碼如下

整理C言中32關鍵字

auto :宣告自動變數 一般不使用 double :宣告雙精度變數或函式 int: 宣告整型變數或函式 struct:宣告結構體變數或函式 break:跳出當前迴圈 else :條件語句否定分支(與 if 連用) long :宣告長整型變數或函式     switch :用於開關語句  case:開關語句分

C言中static關鍵字的作用

編譯 size lac 所有 指針 變量 運行時 http 多個 在C語言中static的作用如下 第一、在修飾變量的時候,static修飾的靜態局部變量只執行一次,而且延長了局部變量的生命周期,直到程序運行結束以後才釋放。 第二、static修飾全局變量的時候,這個全局變

C言中,當計算字符數組長度時,用sizeof 和strlen 的原理兩者的區別

指針 data- 編譯器 tracking 行處理 ews csdn 編譯 分配 字符數組的長度計算:必須以終止符’\0‘作為邊界,但對字符數組賦值時,有兩種方式: 1:定義時用字符初始化 (1)char chs[7] = {‘a‘, ‘c‘, ‘0‘, ‘z‘, ‘3

C言中volatile關鍵字的作用

本文為轉載總結文章:點選進入原地址 用volatile修飾變數的時候,意指系統總是重新從它所在的記憶體讀取資料。遇到這個關鍵字宣告的變 量,編譯器對訪問該變數的程式碼就不再進行優化,從而可以提供對特殊地址的穩定訪問。 舉一個容易理解的例子: volatile int i=10;

C言中const關鍵字

關鍵字const用來定義常量,如果一個變數被const修飾,那麼它的值就不能再被改變,我想一定有人有這樣的疑問,C語言中不是有#define嗎,幹嘛還要用const呢,我想事物的存在一定有它自己的道理,所以說const的存在一定有它的合理性,與預編譯指令相比,const修飾符有以下的優點

C言中static關鍵字的作用詳解

在C語言中,static的字面意思很容易把我們匯入歧途,其實它的作用有三條。 (1)先來介紹它的第一條也是最重要的一條:隱藏。 當我們同時編譯多個檔案時,所有未加static字首的全域性變數和函式都具有全域性可見性。為理解這句話,我舉例來說明。我們要同時編譯兩個原始檔,一個是a.c,另一個是

c言中external,static關鍵字用法

static用法: 在C中,static主要定義全域性靜態變數、定義區域性靜態變數、定義靜態函式。 1、定義全域性靜態變數:在全域性變數前面加上關鍵字static,該全域性變數變成了全域性靜態變數。全域性靜態變數有以下特點。 a.在全域性區分配記憶體。 b.如果沒有初始化,其預設值為

c言中static關鍵字用法詳解

概述 static關鍵字在c語言中比較常用,使用恰當能夠大大提高程式的模組化特性,有利於擴充套件和維護。 但是對於c語言初學者,static由於使用靈活,並不容易掌握。本文就static在c語言中的應用進行總結,供參考使用。錯漏之處,請不吝指正。 在程

C言中const關鍵字的用法

關鍵字const用來定義常量,如果一個變數被const修飾,那麼它的值就不能再被改變,我想一定有人有這樣的疑問,C語言中不是有#define嗎,幹嘛還要用const呢,我想事物的存在一定有它自己的道理,所以說const的存在一定有它的合理性,與預編譯指令相比

C言中strlen求字串長度,求字元陣列長度(空字元,數字0,字元0,陣列部分初始化)

如下字元陣列or字串,用strlen函式求長度各是多少? char * p = "abc" 與 char a[] = "abc"兩種形式並不同,這在我另一篇博文中有提到。 char * str1 = "abc";

年齡與疾病、成績判斷C言中if else 的簡單應用

年齡與疾病 描述 某醫院想統計一下某項疾病的獲得與否與年齡是否有關,需要對以前的診斷記錄進行整理。 輸入 共2行,第一行為過往病人的數目n(0 < n <= 100),第二行為每個病人患病時的年齡。 輸出 每個年齡段(分四段:18以下,1