C/C++經(jīng)典面試題(附答案)

面試題1:變量的聲明和定義有什么區(qū)別
為變量分配地址和存儲(chǔ)空間的稱為定義,不分配地址的稱為聲明。一個(gè)變量可以在多個(gè)地方聲明,但只能在一個(gè)地方定義。加入extern修飾的是變量的聲明,說(shuō)明此變量將在文件以外或在文件后面部分定義。
說(shuō)明:很多時(shí)候一個(gè)變量,只是聲明,不分配內(nèi)存空間,知道具體使用時(shí)才初始化,分配內(nèi)存空間,如外部變量。
面試題2:sizeof和strlen的區(qū)別
sizeof是一個(gè)操作符,strlen是庫(kù)函數(shù)。
sizeof的參數(shù)可以是數(shù)據(jù)的類型,也可以是變量,而strlen只能以結(jié)尾為‘\0‘的字符串作參數(shù)。
編譯器在編譯時(shí)就計(jì)算出了sizeof的結(jié)果。而strlen函數(shù)必須在運(yùn)行時(shí)才能計(jì)算出來(lái)。并且sizeof計(jì)算的是數(shù)據(jù)類型占內(nèi)存的大小,而strlen計(jì)算的是字符串實(shí)際的長(zhǎng)度。
數(shù)組做sizeof的參數(shù)不退化,傳遞給strlen就退化為指針了。
注意:有些是操作符看起來(lái)像是函數(shù),而有些函數(shù)名看起來(lái)又像操作符,這類容易混淆的名稱一定要加以區(qū)分,否則遇到數(shù)組名這類特殊數(shù)據(jù)類型作參數(shù)時(shí)就很容易出錯(cuò)。最容易混淆為函數(shù)的操作符就是sizeof。
說(shuō)明:指針是一種普通的變量,從訪問(wèn)上沒(méi)有什么不同于其他變量的特性。其保存的數(shù)值是個(gè)整型數(shù)據(jù),和整型變量不同的是,這個(gè)整型數(shù)據(jù)指向的是一段內(nèi)存地址。
面試題3:寫一個(gè)“標(biāo)準(zhǔn)”宏MIN
#define min(a,b) ((a)<=(b)?(a):(b))
面試題4:一個(gè)指針可以是volatile嗎?
可以,因?yàn)橹羔樅推胀ㄗ兞恳粯?,有時(shí)也有變化程序的不可控性。常見例:子中斷服務(wù)子程序修改一個(gè)指向一個(gè)buffer的指針時(shí),必須用volatile來(lái)修飾這個(gè)指針。
面試題5:a 和 &a 有什么區(qū)別請(qǐng)寫出以下代碼的打印結(jié)果,主要目的是考察a和&a的區(qū)別。
#include<stdio.h> int main( void ) { int a[5]={1,2,3,4,5}; int *ptr=(int *)(&a+1); printf("%d,%d",*(a+1),*(ptr-1)); return 0; }
輸出結(jié)果:2,5。
想過(guò)為啥結(jié)果是2和5么,*(a+1)這個(gè)比較簡(jiǎn)單,很好理解,就是取數(shù)組a的首地址的下一個(gè)值;數(shù)組名a可以作數(shù)組的首地址,而&a是數(shù)組的指針,指針ptr指向數(shù)組地址的下一塊空間,通過(guò)*(ptr-1)就可獲取數(shù)組的最后一個(gè)值。思考,將原式的int *ptr=(int *)(&a+1);改為int *ptr=(int *)(a+1);時(shí)輸出結(jié)果將是什么呢?
面試題6:簡(jiǎn)述C、C++程序編譯的內(nèi)存分配情況
C、C++中內(nèi)存分配方式可以分為三種:
(1)從靜態(tài)存儲(chǔ)區(qū)域分配:
內(nèi)存在程序編譯時(shí)就已經(jīng)分配好,這塊內(nèi)存在程序的整個(gè)運(yùn)行期間都存在。速度快、不容易出錯(cuò),因?yàn)橛邢到y(tǒng)會(huì)善后。例如全局變量,static變量等。
(2)在棧上分配:
在執(zhí)行函數(shù)時(shí),函數(shù)內(nèi)局部變量的存儲(chǔ)單元都在棧上創(chuàng)建,函數(shù)執(zhí)行結(jié)束時(shí)這些存儲(chǔ)單元自動(dòng)被釋放。棧內(nèi)存分配運(yùn)算內(nèi)置于處理器的指令集中,效率很高,但是分配的內(nèi)存容量有限。
(3)從堆上分配:
即動(dòng)態(tài)內(nèi)存分配。程序在運(yùn)行的時(shí)候用malloc或new申請(qǐng)任意大小的內(nèi)存,程序員自己負(fù)責(zé)在何時(shí)用free或delete釋放內(nèi)存。動(dòng)態(tài)內(nèi)存的生存期由程序員決定,使用非常靈活。如果在堆上分配了空間,就有責(zé)任回收它,否則運(yùn)行的程序會(huì)出現(xiàn)內(nèi)存泄漏,另外頻繁地分配和釋放不同大小的堆空間將會(huì)產(chǎn)生堆內(nèi)碎塊。
一個(gè)C、C++程序編譯時(shí)內(nèi)存分為5大存儲(chǔ)區(qū):堆區(qū)、棧區(qū)、全局區(qū)、文字常量區(qū)、程序代碼區(qū)。
面試題7:簡(jiǎn)述strcpy sprintf與mencpy的區(qū)別
三者主要有以下不同之處:
(1)操作對(duì)象不同,strcpy的兩個(gè)操作對(duì)象均為字符串,sprintf的操作源對(duì)象可以是多種數(shù)據(jù)類型,目的操作對(duì)象是字符串,memcpy 的兩個(gè)對(duì)象就是兩個(gè)任意可操作的內(nèi)存地址,并不限于何種數(shù)據(jù)類型。
(2)執(zhí)行效率不同,memcpy最高,strcpy次之,sprintf的效率最低。
(3)實(shí)現(xiàn)功能不同,strcpy主要實(shí)現(xiàn)字符串變量間的拷貝,sprintf主要實(shí)現(xiàn)其他數(shù)據(jù)類型格式到字符串的轉(zhuǎn)化,memcpy主要是內(nèi)存塊間的拷貝。
說(shuō)明:strcpy、sprintf與memcpy都可以實(shí)現(xiàn)拷貝的功能,但是針對(duì)的對(duì)象不同,根據(jù)實(shí)際需求,來(lái)選擇合適的函數(shù)實(shí)現(xiàn)拷貝功能。還有一個(gè)高效的安全的函數(shù)就是memmove,有興趣的朋友可以查閱相關(guān)資料學(xué)習(xí)
面試題8:鏈表與數(shù)組的區(qū)別
數(shù)組和鏈表有以下幾點(diǎn)不同:
(1)存儲(chǔ)形式:數(shù)組是一塊連續(xù)的空間,聲明時(shí)就要確定長(zhǎng)度。鏈表是一塊可不連續(xù)的動(dòng)態(tài)空間,長(zhǎng)度可變,每個(gè)結(jié)點(diǎn)要保存相鄰結(jié)點(diǎn)指針。
(2)數(shù)據(jù)查找:數(shù)組的線性查找速度快,查找操作直接使用偏移地址。鏈表需要按順序檢索結(jié)點(diǎn),效率低。
(3)數(shù)據(jù)插入或刪除:鏈表可以快速插入和刪除結(jié)點(diǎn),而數(shù)組則可能需要大量數(shù)據(jù)移動(dòng)。
(4)越界問(wèn)題:鏈表不存在越界問(wèn)題,數(shù)組有越界問(wèn)題。
說(shuō)明:在選擇數(shù)組或鏈表數(shù)據(jù)結(jié)構(gòu)時(shí),一定要根據(jù)實(shí)際需要進(jìn)行選擇。數(shù)組便于查詢,鏈表便于插入刪除。數(shù)組節(jié)省空間但是長(zhǎng)度固定,鏈表雖然變長(zhǎng)但是占了更多的存儲(chǔ)空間。
面試題9:簡(jiǎn)述隊(duì)列和棧的異同
隊(duì)列和棧都是線性存儲(chǔ)結(jié)構(gòu),但是兩者的插入和刪除數(shù)據(jù)的操作不同,隊(duì)列是“先進(jìn)先出”,棧是“后進(jìn)先出”。
注意:區(qū)別棧區(qū)和堆區(qū)。堆區(qū)的存取是“順序隨意”,而棧區(qū)是“后進(jìn)先出”。棧由編譯器自動(dòng)分配釋放 ,存放函數(shù)的參數(shù)值,局部變量的值等。其操作方式類似于數(shù)據(jù)結(jié)構(gòu)中的棧。堆一般由程序員分配釋放, 若程序員不釋放,程序結(jié)束時(shí)可能由OS回收。分配方式類似于鏈表。
它與本題中的堆和棧是兩回事。堆棧只是一種數(shù)據(jù)結(jié)構(gòu),而堆區(qū)和棧區(qū)是程序的不同內(nèi)存存儲(chǔ)區(qū)域。
面試題10:編碼實(shí)現(xiàn)直接插入排序
直接插入排序編程實(shí)現(xiàn)如下:
#include <stdio.h> int main() { int i,temp,p; int array[10] = {2,6,1,9,4,7,5,8,3,0}; printf("Display this array:\n"); for(i=0;i<10;i++) { printf("%d ",array[i]); } for(i=1;i<10;i++) { temp = array[i]; p = i-1; while(p >= 0 && temp < array[p]) { array[p+1] = array[p]; p--; } array[p+1] = temp; } printf("\n"); printf("After sorting,this array is:\n"); for(i=0;i<10;i++) { printf("%d ",array[i]); } printf("\n"); return 0; }
面試題11:編碼實(shí)現(xiàn)冒泡排序
冒泡排序編程實(shí)現(xiàn)如下:
#include <stdio.h> #define LEN 10 int main() { int a,i,j; int ARRAY[10]={23,1,4,9,6,17,24,56,98,72}; printf("\n"); printf("Display this array:\n"); for(a=0;a<10;a++) { printf("%d ",ARRAY[a]); } printf("\n"); for(j=0;j<10;j++) { for(i=0;i<LEN-j-1;i++) { int temp; if(ARRAY[i]>ARRAY[i+1]) { temp=ARRAY[i+1]; ARRAY[i+1]=ARRAY[i]; ARRAY[i]=temp; } } } printf("\nAfter sorting,the array is:\n"); for(a=0;a<LEN;a++) { printf("%d ",ARRAY[a]); } printf("\n"); return 0; }
面試題12:編碼實(shí)現(xiàn)直接選擇排序
選擇排序?qū)崿F(xiàn)代碼如下:
#include <stdio.h> int main() { int i,j,t; int array[10]={2,7,1,8,5,9,3,4,0,6}; printf("\nDisplay this array:\n"); for(i=0;i<10;i++) { printf("%d ",array[i]); } printf("\n"); for(i=1;i<=9;i++) { int t = i-1; for(j=i;j<10;j++) { if(array[j]<array[t]) { t=j; } } if(t!=(i-1)) { int temp = 0; temp=array[i-1]; array[i-1]=array[t]; array[t]=temp; } } printf("After sorting,this array is:\n"); for(i=0;i<10;i++) { printf("%d ",array[i]); } printf("\n"); return 0; }
注:對(duì)比冒泡排序和選擇排序之間的區(qū)別
區(qū)別在于:冒泡算法,每次比較如果發(fā)現(xiàn)較小的元素在后面,就交換兩個(gè)相鄰的元素。而選擇排序算法的改進(jìn)在于:先并不急于調(diào)換位置,先從A[1]開始逐個(gè)檢查,看哪個(gè)數(shù)最小就記下該數(shù)所在的位置P,等一躺掃描完畢,再把A[P]和A[1]對(duì)調(diào),這時(shí)A[1]到A[10]中最小的數(shù)據(jù)就換到了最前面的位置
所以,選擇排序每掃描一遍數(shù)組,只需要一次真正的交換,而冒泡可能需要很多次。比較的次數(shù)是一樣的。
面試題13:typedef和define有什么區(qū)別
(1)用法不同:typedef用來(lái)定義一種數(shù)據(jù)類型的別名,增強(qiáng)程序的可讀性。define主要用來(lái)定義常量,以及書寫復(fù)雜使用頻繁的宏。
(2)執(zhí)行時(shí)間不同:typedef是編譯過(guò)程的一部分,有類型檢查的功能。define是宏定義,是預(yù)編譯的部分,其發(fā)生在編譯之前,只是簡(jiǎn)單的進(jìn)行字符串的替換,不進(jìn)行類型的檢查。
(3)作用域不同:typedef有作用域限定。define不受作用域約束,只要是在define聲明后的引用都是正確的。
(4)對(duì)指針的操作不同:typedef和define定義的指針時(shí)有很大的區(qū)別。
注意:typedef定義是語(yǔ)句,因?yàn)榫湮惨由戏痔?hào)。而define不是語(yǔ)句,千萬(wàn)不能在句尾加分號(hào)。
面試題14:關(guān)鍵字const是什么
const用來(lái)定義一個(gè)只讀的變量或?qū)ο?。主要?yōu)點(diǎn):便于類型檢查、同宏定義一樣可以方便地進(jìn)行參數(shù)的修改和調(diào)整、節(jié)省空間,避免不必要的內(nèi)存分配、可為函數(shù)重載提供參考。
說(shuō)明:const修飾函數(shù)參數(shù),是一種編程規(guī)范的要求,便于閱讀,一看即知這個(gè)參數(shù)不能被改變,實(shí)現(xiàn)時(shí)不易出錯(cuò)。
面試題15:static有什么作用
static在C中主要用于定義全局靜態(tài)變量、定義局部靜態(tài)變量、定義靜態(tài)函數(shù)。在C++中新增了兩種作用:定義靜態(tài)數(shù)據(jù)成員、靜態(tài)函數(shù)成員。
注意:因?yàn)閟tatic定義的變量分配在靜態(tài)區(qū),所以其定義的變量的默認(rèn)值為0,普通變量的默認(rèn)值為隨機(jī)數(shù),在定義指針變量時(shí)要特別注意。
面試題16:extern有什么作用
extern標(biāo)識(shí)的變量或者函數(shù)聲明其定義在別的文件中,提示編譯器遇到此變量和函數(shù)時(shí)在其它模塊中尋找其定義。
面試題17:簡(jiǎn)述指針常量與常量指針區(qū)別
指針常量是指定義了一個(gè)指針,這個(gè)指針的值只能在定義時(shí)初始化,其他地方不能改變。其實(shí)指針常量是唯一的,即NULL;常量指針是指定義了一個(gè)指針,這個(gè)指針指向一個(gè)只讀的對(duì)象,不能通過(guò)常量指針來(lái)改變這個(gè)對(duì)象的值。
指針常量強(qiáng)調(diào)的是指針的不可改變性,而常量指針強(qiáng)調(diào)的是指針對(duì)其所指對(duì)象的不可改變性。
注意:無(wú)論是指針常量還是常量指針,其最大的用途就是作為函數(shù)的形式參數(shù),保證實(shí)參在被調(diào)用函數(shù)中的不可改變特性。
面試題18:如何避免“野指針”
“野指針”產(chǎn)生原因及解決辦法如下:
(1)指針變量聲明時(shí)沒(méi)有被初始化。解決辦法:指針聲明時(shí)初始化,可以是具體的地址值,也可讓它指向NULL。
(2)指針 p 被 free 或者 delete 之后,沒(méi)有置為 NULL。解決辦法:指針指向的內(nèi)存空間被釋放后指針應(yīng)該指向NULL。
(3)指針操作超越了變量的作用范圍。解決辦法:在變量的作用域結(jié)束前釋放掉變量的地址空間并且讓指針指向NULL。
注意:“野指針”的解決方法也是編程規(guī)范的基本原則,平時(shí)使用指針時(shí)一定要避免產(chǎn)生“野指針”,在使用指針前一定要檢驗(yàn)指針的合法性。
面試題19:用C編寫一個(gè)死循環(huán)程序
while() { }
其實(shí)還有
for(;;)
說(shuō)明:很多種途徑都可實(shí)現(xiàn)同一種功能,但是不同的方法時(shí)間和空間占用度不同,特別是對(duì)于嵌入式軟件,處理器速度比較慢,存儲(chǔ)空間較小,所以時(shí)間和空間優(yōu)勢(shì)是選擇各種方法的首要考慮條件。
面試題20:編碼實(shí)現(xiàn)某一變量某位清0或置1
給定一個(gè)整型變量a,寫兩段代碼,第一個(gè)設(shè)置a的bit 3,第二個(gè)清a的bit 3,在以上兩個(gè)操作中,要保持其他位不變。
筆者認(rèn)為,在對(duì)ARM寄存器操作時(shí)會(huì)經(jīng)常用到這一塊,所以要注意這塊:
#define BIT3 (0x1 << 3 ) Satic int a; //設(shè)置a的bit 3: void set_bit3( void ) { a |= BIT3; //將a第3位置1 } //清a的bit 3 void set_bit3( void ) { a &= ~BIT3; //將a第3位清零 }
說(shuō)明:在置或清變量或寄存器的某一位時(shí),一定要注意不要影響其他位。所以用加減法是很難實(shí)現(xiàn)的。
還有一個(gè)就是保留某位:
//保留第k位 void set_bit3(void) { a &= BIT3; }
面試題21:a=3,b=5,不用第三變量temp,對(duì)a和b的值進(jìn)行交換
如果有第三者temp,a和b交換非常方便:
temp = a; a = b; b =temp;
若無(wú)temp,可以這樣做:
a = a + b; b = a - b; a = a - b;
當(dāng)然,我們可以利用C語(yǔ)言的位運(yùn)算符:
a = 3;b = 5; a ^= b; b ^= a; a ^= b;
原理是a ^ b ^ b = = a; a ^ b == b ^ a;
面試題22:宏定義的用法,看下面這個(gè)程序,求出結(jié)果
#include <stdio.h> #define S(a,b) a*b int main(void) { int n = 3; int m = 5; printf("%d",S(n+m,m+n)); return 0; }
這道題容易出現(xiàn)的錯(cuò)誤結(jié)果是64,得到這個(gè)結(jié)果肯定是這樣理解的(3+5)*(5+3)。其實(shí)并不是,大家要理解宏定義的概念,宏定義只是簡(jiǎn)單的符號(hào)替換,而不做其他處理,所以這里得到的結(jié)果是
3+5*5+3=31.
大家看看運(yùn)行結(jié)果:
$ gcc -o 1 1.c
$ ./1
31
要想得到正確結(jié)果,應(yīng)該怎么樣呢?應(yīng)該這樣改,define s(a,b) (a)*(b),這樣才是正確結(jié)果;
$ gcc -o 1 1.c
$ ./1
64
大家記住這句話,宏定義只是簡(jiǎn)單的符號(hào)替換!
面試題23:
C語(yǔ)言中,運(yùn)算對(duì)象必須是整型數(shù)的運(yùn)算符的有()
A、% B、/ C、%和/ D、*
答案:A
取余對(duì)象必須是整數(shù)型
面試題24:
以下程序執(zhí)行的結(jié)果是:
#include <stdio.h>] #define N 2 #define M N+1 #define NUM (M+1)*M/2 int main() { printf("%d",NUM); }
A、5 B、6 C、8 D、9
答案:C
注意宏定義的使用,此處NUM = (3+1)*2+1/2 為8
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
- 這篇文章主要介紹了騰訊公司c++面試小結(jié),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2020-03-02
- 這篇文章主要介紹了 C++ 面試題目(整理自??途W(wǎng)),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2020-02-13
華為校招 C++崗面試經(jīng)歷總結(jié)【筆試+一面+二面+Offer】
這篇文章主要介紹了華為校招 C++崗面試經(jīng)歷,總結(jié)分析了華為校招C++崗位的筆試題,以及一面、二面到最終拿到Offer的經(jīng)歷與相關(guān)經(jīng)驗(yàn)感想,需要的朋友可以參考下2019-11-28- 這篇文章主要介紹了C++面試常見算法題與參考答案,總結(jié)分析了C++面試中遇到的常見算法題與相應(yīng)的參考答案,需要的朋友可以參考下2019-11-20
- 這篇文章主要介紹了C++必備面試題與參考答案,結(jié)合大量經(jīng)典實(shí)例總結(jié)分析了C++面試過(guò)程中經(jīng)常遇到的各種概念、原理、算法相關(guān)問(wèn)題及參考答案,需要的朋友可以參考下2019-10-31
- 這篇文章主要介紹了C/C++求職者必備的20道面試題與參考答案,總結(jié)分析了C/C++相關(guān)的常見概念、原理、知識(shí)點(diǎn)與注意事項(xiàng),需要的朋友可以參考下2019-10-10
騰訊的外包c(diǎn)++面試經(jīng)歷總結(jié)
這篇文章主要介紹了騰訊的外包c(diǎn)++面試經(jīng)歷,總結(jié)記錄了一次騰訊C++面試的經(jīng)歷,包括面試的流程、面試題目與相應(yīng)的參考答案,需要的朋友可以參考下2019-09-29- 這篇文章主要介紹了阿里面試必會(huì)的20道C++面試題與參考答案,涉及C++指針、面向?qū)ο?、函?shù)等相關(guān)特性與使用技巧,需要的朋友可以參考下2019-09-26
- 這篇文章主要介紹了經(jīng)典C++筆試題目與參考答案,總結(jié)分析了C++常見的各種面試題目,包含C++常見知識(shí)點(diǎn)、技術(shù)難點(diǎn)、算法等,需要的朋友可以參考下2019-09-10
- 這篇文章主要介紹了華為筆試算法面試題與參考答案,結(jié)合實(shí)例形式分析了基于C++的字符串轉(zhuǎn)換、判斷、排序等算法相關(guān)操作技巧,需要的朋友可以參考下2019-09-05