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

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