最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

C語(yǔ)言編程:最常見 7 道C語(yǔ)言面試題,還是有不少人弄不明白?

2022-01-17 17:47 作者:C語(yǔ)言編程__Plus  | 我要投稿

C語(yǔ)言是一門面向結(jié)構(gòu)化的高級(jí)編程語(yǔ)言(也有人認(rèn)為它是中級(jí)語(yǔ)言),用于通用編程需求。基本上,C語(yǔ)言是其基本語(yǔ)法和庫(kù)函數(shù)的集合,因此程序員定義自己的函數(shù)并且將其包含在C語(yǔ)言庫(kù)中也是很方便的。


C語(yǔ)言的主要用途是編寫其他編程語(yǔ)言的編譯器、操作系統(tǒng)、文本編輯器、后臺(tái)服務(wù)程序、驅(qū)動(dòng)程序、數(shù)據(jù)庫(kù)、腳本語(yǔ)言的解釋器,以及其他各種實(shí)用的程序。

C語(yǔ)言甚至能夠編寫自己的編譯器。

如果讀者對(duì)C語(yǔ)言感興趣,并且希望得到一份C語(yǔ)言程序員的工作,那么下面這 7 道面試題將會(huì)非常有趣。

問(wèn)題1,C語(yǔ)言的顯著特點(diǎn)是什么?

可移植。C語(yǔ)言是一種與平臺(tái)無(wú)關(guān)的編程語(yǔ)言,不使用平臺(tái)依賴庫(kù)的C語(yǔ)言程序可以輕易移植到各種平臺(tái)。模塊化。我們能夠輕易的將一個(gè)非常大的C語(yǔ)言項(xiàng)目拆分成若干個(gè)小的模塊,并逐個(gè)實(shí)現(xiàn),最終組合解決該大項(xiàng)目。靈活。C語(yǔ)言給與程序員最大的自由,因此只要某種代碼C語(yǔ)言的語(yǔ)法沒有禁止,程序員就可使用。也即所謂的“法無(wú)禁止即可行”。


問(wèn)題2,什么是C語(yǔ)言中的“懸空指針”?

C語(yǔ)言中的指針可以指向一塊內(nèi)存,如果這塊內(nèi)存稍后被操作系統(tǒng)回收(被釋放),但是指針仍然指向這塊內(nèi)存,那么,此時(shí)該指針就是“懸空指針”。下面這段C語(yǔ)言代碼是一個(gè)例子,請(qǐng)看:

void *p = malloc(size);

assert(p);

free(p); // 現(xiàn)在 p 是“懸空指針”

C語(yǔ)言中的“懸空指針”會(huì)引發(fā)不可預(yù)知的錯(cuò)誤,而且這種錯(cuò)誤一旦發(fā)生,很難定位。這是因?yàn)樵?free(p) 之后,p 指針仍然指向之前分配的內(nèi)存,如果這塊內(nèi)存暫時(shí)可以被程序訪問(wèn)并且不會(huì)造成沖突,那么之后使用 p 并不會(huì)引發(fā)錯(cuò)誤。

最難調(diào)試的 bug 總是不能輕易復(fù)現(xiàn)的 bug,對(duì)不?

所以在實(shí)際的C語(yǔ)言程序開發(fā)中,為了避免出現(xiàn)“懸空指針”引發(fā)不可預(yù)知的錯(cuò)誤,在釋放內(nèi)存之后,常常會(huì)將指針 p 賦值為 NULL:

void *p = malloc(size);

assert(p);

free(p);

// 避免“懸空指針”

p = NULL;

這么做的好處是一旦再次使用被釋放的指針 p,就會(huì)立刻引發(fā)“段錯(cuò)誤”,程序員也就能立刻知道應(yīng)該修改C語(yǔ)言代碼了。


問(wèn)題3,C語(yǔ)言中的“野指針”是什么?

“懸空指針”是指向被釋放內(nèi)存的指針,“野指針”則是不確定其具體指向的指針?!耙爸羔槨弊畛?lái)自于未初始化的指針,例如下面這段C語(yǔ)言代碼:

void *p;// 此時(shí) p 是“野指針”

因?yàn)椤耙爸羔槨笨赡苤赶蛉我鈨?nèi)存段,因此它可能會(huì)損壞正常的數(shù)據(jù),也有可能引發(fā)其他未知錯(cuò)誤,所以C語(yǔ)言中的“野指針”危害性甚至比“懸空指針”還要嚴(yán)重。在實(shí)際的C語(yǔ)言程序開發(fā)中,定義指針時(shí),一般都要盡量避免“野指針”的出現(xiàn)(賦初值):

void *p = NULL;

void *data = malloc(size);

問(wèn)題4,C語(yǔ)言中的 static 函數(shù)有什么用?

相信讀者在不少的C語(yǔ)言項(xiàng)目中看到類似于下面這樣的 static 函數(shù),為什么使用 static 關(guān)鍵字修飾函數(shù)呢?這么做有什么用呢?

static void foo(){ ...}

稍大的C語(yǔ)言項(xiàng)目中一般都會(huì)出現(xiàn)這樣的 static 函數(shù)(靜態(tài)函數(shù)),C語(yǔ)言中的靜態(tài)函數(shù)最主要的特點(diǎn)就在于其作用域——僅限所述文件。例如在 fun.c 文件中定義的 static 函數(shù),不能在如 main.c 等其他文件中使用。

讀者可以嘗試使用 extern 關(guān)鍵字引入其他文件中定義的 static 函數(shù)。

C語(yǔ)言中 static 函數(shù)的這個(gè)特性使得它常常被定義在 .h 文件中,一般和 inline 關(guān)鍵字一起使用,以獲得 define 函數(shù)式宏定義類似的高效率。


問(wèn)題5,C語(yǔ)言中的“循環(huán)”數(shù)據(jù)類型是指什么?

所謂的“循環(huán)”數(shù)據(jù)類型,其實(shí)就是某種類型的數(shù)據(jù)溢出后,又從頭開始存儲(chǔ)。一個(gè)典型的例子是 unsigned char 變量若已經(jīng)等于 255,仍然對(duì)其加 1,那么該變量就會(huì)溢出從頭開始,也即等于零:

unsigned char a = 255;

a = a+1;// a 等于 0

unsigned char 型變量 a 是無(wú)符號(hào)的 8 位整數(shù),它能表示的最大值是 8 個(gè)位全為 1,也即 0xff=255,若此時(shí)再對(duì)其加一,將得到 0x100。a 只索引 8 位,也即 0x100 中的 0x00=0。

C語(yǔ)言中的 int,long,short 等類型也有類似的“循環(huán)”特性,該特性不會(huì)引發(fā)語(yǔ)法編譯錯(cuò)誤,因此較難判斷這些類型的變量是否溢出。而C語(yǔ)言中的 float,double 類型則沒有“循環(huán)”特性,因此實(shí)際C語(yǔ)言程序開發(fā)中一個(gè)常用的檢查整型數(shù)據(jù)是否溢出的技巧,就是借助于 float 和 double 類型的,這一點(diǎn)在我之前的文章中說(shuō)過(guò),感興趣的讀者可以看看。

問(wèn)題6,C語(yǔ)言中的頭文件有什么用?

一般C語(yǔ)言程序項(xiàng)目中的頭文件后綴名都為 .h,h 是 header 的縮寫。頭文件的使用一般和 #include 結(jié)合使用,例如在 main.c 文件中寫下:

#include "header.h"

意味著在該處將 header.h 中的內(nèi)容展開到此。所以C語(yǔ)言中的頭文件中一般包含程序需要使用的函數(shù)定義和原型,也可以包含相關(guān)的數(shù)據(jù)結(jié)構(gòu)類型定義。

這里再啰嗦下“在該處將 header.h 中的內(nèi)容展開到此”的含義——假如 header.h 頭文件中的內(nèi)容是:

// header.h 頭文件

printf("hello world\n");

那么,在其他文件中寫下

#include "header.h"就等價(jià)于

// header.h 頭文件

printf("hello world\n");


問(wèn)題7,C語(yǔ)言中的指針可以做加法運(yùn)算嗎?

C語(yǔ)言中的指針包含地址詳細(xì)信息,一般是不可以直接做加法運(yùn)算的,例如下面這段C語(yǔ)言代碼:

void *p1 = (void *)1;

void *p2 = (void *)2;

// 下面是非法的

void *p = p1+p2;

讀者可自行嘗試,指針 p1 和指針 p2 是無(wú)法直接相加的,否則編譯器就會(huì)報(bào)錯(cuò)。但是如果想對(duì)指針 p1 和 p2 的地址值相加,可以將其強(qiáng)制轉(zhuǎn)換為整數(shù)類型,例如:

void *p1 = (void *)1;

void *p2 = (void *)2;

long p = (long)p1 + (long)p2;

應(yīng)該確保強(qiáng)制轉(zhuǎn)換的整數(shù)類型寬度大于指針類型寬度,否則可能會(huì)因?yàn)閿?shù)值截?cái)鄬?dǎo)致得到錯(cuò)誤的結(jié)果。

雖然C語(yǔ)言中的指針不能直接與指針相加,但是卻可以與其他整數(shù)相加,例如下面這段C語(yǔ)言代碼:

char *p1 = (char *)1;

char *p = p1+1;

指針p1 指向地址 1,因此指針 p 指向地址 2,這沒什么好說(shuō)的。但是,讀者應(yīng)該注意下面這樣的“陷阱”:

int *p1 = (int *)1;

int *p = p1+1;

與上面的C語(yǔ)言代碼例子相比,這里僅僅將 char 換成 int。那么,指針 p 指向哪個(gè)地址呢?編寫打印代碼:

int *p1 = (int *)1;

int *p = p1+1;

printf("p1=%p, p=%p\n", p1, p);

編譯并執(zhí)行上面這段C語(yǔ)言代碼,會(huì)發(fā)現(xiàn)輸出如下:

p1=0x1, p=0x5

可見,“1+1”并不等于 2,而是等于 5 了。這其實(shí)是因?yàn)镃語(yǔ)言中的指針是有其自己的含義的,不同的指針類型索引內(nèi)存的大小也往往不同,我的機(jī)器上 int 類型占用 4 個(gè)字節(jié)內(nèi)存空間,因此指針 p1+1 實(shí)際上是往后移動(dòng)了 4 個(gè)字節(jié)。

讀者可自行將 int 換成其他類型試試。

小結(jié)

本節(jié)列舉的 7 個(gè)C語(yǔ)言問(wèn)題其實(shí)屬于C語(yǔ)言的基本語(yǔ)法和特點(diǎn),如果能夠熟練掌握,相信對(duì)找到一份相關(guān)的工作是有幫助的。

另外,對(duì)于編程方面,學(xué)習(xí)C/C++編程或者工作想提升的伙伴,如果你想更好的提升你的編程能力幫助你提升水平!筆者這里或許可以幫到你~

微信公眾號(hào):C語(yǔ)言編程學(xué)習(xí)基地

C語(yǔ)言零基礎(chǔ)入門教程(83集全)

歡迎轉(zhuǎn)行和學(xué)習(xí)編程的伙伴,利用更多的資料學(xué)習(xí)成長(zhǎng)比自己琢磨更快哦!



C語(yǔ)言編程:最常見 7 道C語(yǔ)言面試題,還是有不少人弄不明白?的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
申扎县| 湟中县| 河间市| 石嘴山市| 荥经县| 曲松县| 天祝| 昭苏县| 乐亭县| 长丰县| 琼海市| 南皮县| 铁岭县| 南通市| 神农架林区| 湖口县| 晋中市| 门源| 永德县| 海安县| 天津市| 区。| 陇川县| 常德市| 马鞍山市| 福贡县| 宁明县| 泾阳县| 鸡东县| 新源县| 诏安县| 巴塘县| 玉田县| 大厂| 六盘水市| 阿图什市| 东城区| 扎赉特旗| 新化县| 保山市| 永昌县|