面試常見問題之C語言與C++的區(qū)別問題
C和C++的區(qū)別
- C語言是一種結(jié)構(gòu)化語言,其偏重于數(shù)據(jù)結(jié)構(gòu)和算法,屬于過程性語言
- C++是面向?qū)ο蟮木幊陶Z言,其偏重于構(gòu)造對(duì)象模型,并讓這個(gè)模型能夠契合與之對(duì)應(yīng)的問題。其本質(zhì)區(qū)別是解決問題的思想方法不同
- 雖然在語法上C++完全兼容C語言,但是兩者還是有很多不同之處。下面將詳細(xì)講解C和C++不同之處的常見考題
關(guān)鍵字static在C和C++區(qū)別
C和C++中都有關(guān)鍵字static關(guān)鍵字,那么static關(guān)鍵字在C和C++中的使用有什么區(qū)別?請(qǐng)簡(jiǎn)述之。
分析問題:在C中,用static修飾的變量或函數(shù),主要用來說明這個(gè)變量或函數(shù)只能在本文件代碼塊中訪問,而文件外部的代碼無權(quán)訪問。并且static修飾的變量存放在段存儲(chǔ)區(qū)。主要有以下兩種用途。
1. 定義局部靜態(tài)變量
- 局部靜態(tài)變量存儲(chǔ)在靜態(tài)存儲(chǔ)區(qū),在程序運(yùn)行期間都不會(huì)釋放,只在聲明時(shí)進(jìn)行初始化,而且只能初始化一次,如果沒有初始化,其自動(dòng)初始化為0或空字符。具有局部變量的“記憶性”和生存周期“全局性”特點(diǎn)。
- 局部變量的“記憶性”是指在兩次函數(shù)調(diào)用時(shí),第二次調(diào)用開始時(shí),變量能夠保持上一次調(diào)用結(jié)束數(shù)的值。如下例:
#include <stdio.h> //20210520 公眾號(hào):C語言與CPP編程 void staticShow() { static int a=10; printf("a=%d\n",a); a += 10; } int main() { for(int i=0;i<4;i++) { staticShow(); } return 0; }
運(yùn)行結(jié)果
利用生存周期的“全局性”,可以改善函數(shù)返回指針的問題,局部變量的問題在于當(dāng)函數(shù)退出時(shí)其生存周期結(jié)束。而利用static修飾的局部變量卻可以延長(zhǎng)其生存期。如下所示:
#include <stdio.h> #include <string.h> //202105205 公眾號(hào):C語言與CPP編程 char *p = NULL; char *helloToStr(char *b) { static char a[50]; a[0]='H'; a[1]='E'; a[2]='L'; a[3]='L'; a[4]='O'; strcpy(a+5,b); p=a; return a; }; int main(void) { printf("%s\n",helloToStr("yang")); strcpy(p+5,"song"); printf("%s\n",p); strcpy(p+5,"zhang"); printf("%s\n",p); strcpy(p+5,"wang"); printf("%s\n",p); return 0; }
運(yùn)行結(jié)果
2.限定訪問區(qū)域
被static修飾的變量、函數(shù)只能被同一文件內(nèi)的代碼段訪問。在此static不再表示存儲(chǔ)方式,而是限定作用范圍。如下所示:
//Test1.cpp static int a; int b; extern void fun1() { ...... } static void fun1() { ...... } //Test2.cpp extern int a; //錯(cuò)誤,a是static類型,無法在Test2.cpp文件中使用 extern int b; //使用Test1.cpp中定義的全局變量 extern void fun1(); //使用Test1.cpp中定義的函數(shù) extern void fun2(); //錯(cuò)誤,無法使用Test1.cpp文件中static函數(shù)
在C++中除了上述的兩種常用方法外還有另外一種使用方法:定義靜態(tài)成員變量和靜態(tài)成員函數(shù)。靜態(tài)成員變量或靜態(tài)成員函數(shù)表示其不屬于任何一個(gè)類實(shí)例,是類的所有類實(shí)例所共有的。如下所示:
#include <iostream.h> #include <string.h> class A { public: static int a; static int geta(); int b; int getb(); }; int A::a=100; int A::geta() { return a; } int A::getb() { return b; } int main(void) { A m,n; m.b=90; cout<<m.geta()<<endl; cout<<m.getb()<<endl; cout<<m.a<<endl; n.a=33; n.b=44; cout<<m.geta()<<endl; cout<<m.getb()<<endl; cout<<m.a<<endl; return 0; }
運(yùn)行結(jié)果
答案
在C中static用來修飾局部靜態(tài)變量和外部靜態(tài)變量、函數(shù)。而C++中除了上述功能外,還用來定義類的成員變量和函數(shù),即靜態(tài)成員和靜態(tài)成員函數(shù)。
注意:編程時(shí)static的記憶性和全局性的特點(diǎn)可以使在不同時(shí)期調(diào)用的函數(shù)進(jìn)行通信,傳遞信息,而C++的靜態(tài)成員則可以在多個(gè)對(duì)象實(shí)例間進(jìn)行通信,傳遞信息。
結(jié)構(gòu)體在C語言和C++的區(qū)別
分析問題:在C中,結(jié)構(gòu)體是一種簡(jiǎn)單的復(fù)合型數(shù)據(jù),由若干個(gè)基本類型數(shù)據(jù)或復(fù)合類型數(shù)據(jù)組合而成。而在C++結(jié)構(gòu)體中,還可以聲明函數(shù)。如下所示:
#include <iostream.h> struct A { public: int a; int gata() { return a; } }; int main(void) { m.a=50; cout<<m.gata()<<endl; return 0; }
輸出結(jié)果:50
但是這種用法看起來有點(diǎn)不倫不類,這是C到C++過渡的遺留問題
答案
- C語言的結(jié)構(gòu)體是不能有函數(shù)成員的,而C++的類可以有。
- C語言結(jié)構(gòu)體中數(shù)據(jù)成員是沒有private、public和protected訪問限定的。而C++的類的成員有這些訪問限定(在C++中結(jié)構(gòu)體的成員也是有訪問權(quán)限設(shè)定的,但是類成員的默認(rèn)訪問屬性是private,而結(jié)構(gòu)體的默認(rèn)訪問屬性是public)。
- C語言的結(jié)構(gòu)體是沒有繼承關(guān)系的,而C++的類卻有豐富的繼承關(guān)系。
說明:雖然C的結(jié)構(gòu)體和C++的類有很大的相似度,但是類是實(shí)現(xiàn)面向?qū)ο蟮幕A(chǔ)。而結(jié)構(gòu)體只可以簡(jiǎn)單地理解為類的前身。
C中malloc和C++的new區(qū)別
分析問題:malloc、free與new、delete都是用來動(dòng)態(tài)申請(qǐng)內(nèi)存和釋放內(nèi)存的。不同點(diǎn)如下:
- malloc、free是標(biāo)準(zhǔn)庫函數(shù),new、delete則是運(yùn)算符。malloc、free在C、C++中都可使用,而new、delete只屬于C++。
- malloc要指定申請(qǐng)內(nèi)存的大小,其申請(qǐng)的只是一段內(nèi)存空間。而new不必指定申請(qǐng)內(nèi)存的大小,建立的是一個(gè)對(duì)象。
- new、delete在申請(qǐng)非內(nèi)部數(shù)據(jù)類型的對(duì)象時(shí),對(duì)象在創(chuàng)建的同時(shí)會(huì)自動(dòng)執(zhí)行構(gòu)造函數(shù),在消亡時(shí)會(huì)自動(dòng)執(zhí)行析構(gòu)函數(shù),這不在編譯器的控制之內(nèi),所以malloc、free無法實(shí)現(xiàn)。
- new返回的是某種數(shù)據(jù)類型的指針,而malloc返回的是void型指針。
- 由于new、delete是運(yùn)算符,可以重載,不需要頭文件的支持,而malloc、free是庫函數(shù),可以覆蓋,并且要包含相應(yīng)的頭文件。
答案
- new、delete是操作符,可以重載,只能在C++中使用。
- malloc、free是函數(shù),可以覆蓋,C、C++中都可以使用。
- new可以調(diào)用對(duì)象的構(gòu)造函數(shù),對(duì)應(yīng)的delete調(diào)用相應(yīng)的析構(gòu)函數(shù)。
- malloc僅僅分配內(nèi)存,free僅僅回收內(nèi)存,并不執(zhí)行構(gòu)造和析構(gòu)函數(shù)。
- new、delete返回的是某種數(shù)據(jù)類型指針,malloc、free返回的是void指針。
注意:malloc申請(qǐng)的內(nèi)存空間要用free釋放,而new申請(qǐng)的內(nèi)存空間要用delete釋放,不能混用。因?yàn)閮烧邔?shí)現(xiàn)的機(jī)理不同。
C++引用和C的指針有何區(qū)別
分析問題:引用就是變量或?qū)ο蟮膭e名,它不是值,不占據(jù)存儲(chǔ)空間,其只有聲明沒有定義。在C++中引用主要用于函數(shù)的形參和函數(shù)返回值。
1、作為函數(shù)的參數(shù)
當(dāng)函數(shù)的返回值多于一個(gè)時(shí),可以使用指針實(shí)現(xiàn)。如下所示:
void swap(int *a, int *b) { int temp; temp = *a; *a = *b; *b = temp; } int main(void) { int a=10,b=5; cout<<"Before change:"<< a<<""<<b<<endl; swap(&a,&b); cout<<"After change:"<< a<<""<<b<<endl; return 0; }
輸出結(jié)果:
Before change: 10 55
After change: 55 10
雖然上述代碼實(shí)現(xiàn)了多個(gè)返回值的功能,但是函數(shù)的語法相對(duì)傳值方式比較麻煩。在函數(shù)中使用指針?biāo)笇?duì)象的數(shù)值時(shí),必須在指針前加上*,如上例中的的swap函數(shù)頻繁使用了“*a”、“*b”,如此不僅書寫麻煩,還不利于閱讀,并且容易產(chǎn)生錯(cuò)誤。在函數(shù)調(diào)用時(shí)也容易產(chǎn)生誤解,如上述代碼main函數(shù)中swap(&a, &b),看起來好像是交換了兩個(gè)變量的地址似的。而用引用實(shí)現(xiàn)swap函數(shù),如下所示:
void swap(int &a, int &b) { int temp; temp = a; a = b; b = temp; } int main(void) { int a=10,b=5; cout<<"Before change:"<< a<<""<<b<<endl; swap(a,b); cout<<"After change:"<< a<<""<<b<<endl; return 0; }
可以看出用引用實(shí)現(xiàn)swap函數(shù)比指針實(shí)現(xiàn)要簡(jiǎn)潔,調(diào)用也顯得更加合乎情理。
2、引用作為函數(shù)的返回值
在大多數(shù)情況下可以被指針替代,但是遇到構(gòu)造函數(shù)和操作符重載函數(shù)的“形式自然”的問題時(shí),是不能被指針替代的。指針和引用功能相似,但是在操作時(shí)卻有很多不同的地方,如指針的操作符是“*”和“->”,而引用常用的操作符是“.”。在使用時(shí)還要注意以下幾點(diǎn):
指針可不初始化且初始化的時(shí)候,可以指向一個(gè)地址,也可以為空。引用必須初始化且只能初始化為另一個(gè)變量,如下:
int a=1024; int *p=&a; int &b=a;
引用之間的賦值和指針之間的賦值不同。指針賦值如下:
int a=1,b=2; int *p1=&a, *p2=&b;
這時(shí)執(zhí)行p1=p2;后,p1原來指向的對(duì)象v1的值并沒有改變,而p1被賦值為p2所指向的對(duì)象,如下圖:
指針間賦值
引用賦值如下:
int a=1,b=2; int &v1=a, &v2=b;
這時(shí)執(zhí)行r1= r2;改變的是v1,將r 2指向的對(duì)象的值賦值給v1,而不是引用r1本身。賦值之后,兩個(gè)引用還是指向各自的原來對(duì)象,如圖下圖。
引用間賦值
指針可以被重新賦值以指向另一個(gè)不同的對(duì)象。但是引用則總是指向在初始化時(shí)被指定的對(duì)象,以后不能改變。如下所示:
int a=1; int b=2; int &v1=a; //v1引用a string *pi = &a; //pi指向a v1=b; //v1仍舊引用a,但是a現(xiàn)在的值是2; pi=&b; //pi指向b,a沒有改變
答案
- 指針和引用主要有以下區(qū)別:
- 引用必須被初始化,但是不分配存儲(chǔ)空間。指針不聲明時(shí)初始化,在初始化的時(shí)候需要分配存儲(chǔ)空間。
- 引用初始化以后不能被改變,指針可以改變所指的對(duì)象。
不存在指向空值的引用,但是存在指向空值的指針。
注意:引用作為函數(shù)參數(shù)時(shí),會(huì)引發(fā)一定的問題,因?yàn)樽屢米鳛閰?shù),目的就是想改變這個(gè)引用所指向地址的內(nèi)容,而函數(shù)調(diào)用時(shí)傳入的是實(shí)參,看不出函數(shù)的參數(shù)是正常變量,還是引用,因此可能會(huì)引發(fā)錯(cuò)誤。所以使用時(shí)一定要小心謹(jǐn)慎。
關(guān)于c語言與c++面試筆試題,最近文章《為各位學(xué)弟學(xué)妹整理的C語言/C++相關(guān)筆試面試題》,也整理了一份30多頁的PDF:
以上就是面試常見問題之C語言與C++的區(qū)別問題的詳細(xì)內(nèi)容,更多關(guān)于C語言與C++區(qū)別的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
詳解C++調(diào)用Python腳本中的函數(shù)的實(shí)例代碼
這篇文章主要介紹了C++調(diào)用Python腳本中的函數(shù) ,需要的朋友可以參考下2018-11-11C++中inet_pton、inet_ntop函數(shù)的用法
這篇文章主要介紹了C++中inet_pton、inet_ntop函數(shù)的用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08數(shù)據(jù)結(jié)構(gòu)與算法中二叉樹子結(jié)構(gòu)的詳解
這篇文章主要介紹了數(shù)據(jù)結(jié)構(gòu)與算法中二叉樹子結(jié)構(gòu)的詳解的相關(guān)資料,需要的朋友可以參考下2017-04-04使用C語言求解撲克牌的順子及n個(gè)骰子的點(diǎn)數(shù)問題
這篇文章主要介紹了使用C語言求解撲克牌的順子及n個(gè)骰子的點(diǎn)數(shù)問題的方法,解答實(shí)例主要為了突出解題的算法,需要的朋友可以參考下2016-03-03