1. 程式人生 > >C和C++區別與特點

C和C++區別與特點

1、函式傳指標和傳引用的區別? 
1>指標定義時可以不初始化,但引用不行; 
2>引用只能和一個實體結合,而指標可和多個實體結合; 
3>自加減意義不同。指標的++表示指標向後偏移型別個位元組,而引用則是+1,–類似; 
4>sizeof求值的意義不同。Sizeof(指標)是指標所佔的位元組數,32位平臺下為4,64位平臺下為8(陣列名除外),sizeof(引用)是指引用所指實體型別的大小; 
5>沒有空引用,但是有空指標; 
6>有多級指標,但沒有多級引用; 
7>引用比指標用起來更安全,不用判空。 
注意:指標也可以進行引用

2、C++中的封裝:

 
隱藏物件的屬性和實現細節,僅僅對外提供公開介面和物件進行互動,將資料和操作資料的方法進行有機結合。

3、必須在建構函式的成員初始化列表中進行初始化的資料成員: 
引用資料成員、const資料成員、類型別成員(該類沒有預設的建構函式)。

4、面向物件與面向過程的區別? 
面向過程程式設計方法採用函式(或過程)來描述對資料的操作,但又將函式與其操作的資料分離開來。 
面向物件程式設計方法是將資料和物件的操作封裝在一起,作為一個整體來處理。 
面向過程程式設計以過程為中心,難於維護。 
面向物件程式設計以資料為中心,資料相對功能而言,有較強的穩定性,因此更易於維護。

5、static關鍵字

 
static可修飾區域性變數、全域性變數和函式。 
在修飾全域性的變數和函式時:在檔案作用域中使用可改變連結屬性,僅在當前檔案中可以使用。 
修飾區域性變數時: 
1.在靜態區開闢; 
2.生命週期為整個函式的執行時間; 
3.預設初始化為0; 
4.變數具有記憶作用,即每次儲存上一次呼叫後的值; 
5.在函式第一次呼叫時建立,建構函式只調用一次。 
修飾類的成員變數和函式: 
靜態成員為所有物件所共享,不屬於某個例項 
類靜態成員即可用類名::靜態成員或者物件(.靜態成員函式)來訪問 
類靜態成員變數必須在類內宣告類外定義,定義時不新增static關鍵字 
類的靜態成員函式沒有預設的this指標,因此在它裡面不能使用任何非靜態成員 
靜態成員和類的普通成員一樣,也有public、protected、private3種訪問級別,也可以具有返回值,const修飾符等引數。

6、malloc、free和new、delete的區別: 
malloc、free為函式,new、delete為操作符; 
malloc的引數為要申請的位元組數,new直接跟型別; 
malloc的返回值為void*,並且返回時需要判空,new不需要判空,申請空間失敗時會直接拋異常; 
new申請單個型別的空間時可對其進行初始化,同時還可以陣列空間; 
malloc、free呼叫時不會呼叫建構函式和解構函式,但new、delete會; 
new的底層會呼叫malloc,delete的底層會呼叫free。 
1.operator new/operator delete、 operator new[]/operator delete[] 和 malloc/free用法一樣。 
2. 他們只負責分配空間/釋放空間,不會呼叫物件建構函式/解構函式來初始化/清理物件。 
3. 實際operator new和operator delete只是malloc和free的一層封裝

7、定位new表示式 
是在已分配的原始記憶體空間中呼叫建構函式初始化一個物件。 
new (place_address) type 
new (place_address) type(initializer-list) 
place_address必須是一個指標,initializer-list是型別的初始化列表。

8、sizeof 和 strlen的區別? 
Sizeof用來求取型別或變數所佔的位元組數,strlen則用來求取字串的長度,不包括’\0’; 
Sizeof 求字元個數時會包含‘\0’,strlen 不會; 
Sizeof(陣列名)陣列名代表整個陣列的大小,strlen(陣列名)代表陣列首元素的地址; 
Sizeof(型別),sizeof(變數),sizeof 變數,strlen()必須加括號; 
Sizeof在編譯時求位元組數,strlen在執行時才計算; 
Sizeof+(型別或變數),strlen(字串地址)。

9、debug和release的區別? 
Debug通常稱為除錯版本,它包含除錯資訊,並且不做任何優化,便於程式設計師進行除錯。 
Release稱為釋出版本,它往往進行了各種優化,使得程式在程式碼大小和執行速度上都是最優的,以便使用者很好的使用。

10、區域性性原理 
時間區域性性原理:一個值正在被訪問,那麼近期它有可能再次被訪問; 
空間區域性性原理:一個值正在被訪問,那麼地址與它臨近的值有可能近期再次被訪問。

11、C語言和C++的對比 
1>檔案字尾不同。C語言通常以.c結尾,而C++通常以.cpp結尾 
2>預設返回值不同。如果一個函式沒有指定返回值,則C語言預設返回int型別,C++預設返回void型別 
3>預設引數列表不同。在沒有指定引數列表時,C語言預設可接收任意多個引數,C++預設為void,不接收任何型別的引數 
4>預設引數。C語言的預設引數為int型別,C++為void型別。 
最重要的是解決問題的思想和方法不一樣,C語言是面向過程的,C++是面向物件的。

12、巨集和函式的比較 
這裡寫圖片描述

11、建構函式的特性 
1>建構函式沒有返回值 
2>建構函式有初始化列表但可以不用 
3>建構函式的名字必須與類名相同 
4>在物件被建立時,建構函式被編譯器自動呼叫,且在物件的生命週期內智慧調一次 
5>建構函式可以過載,實參決定了呼叫哪個建構函式 
7>無參建構函式和帶有預設值的建構函式都認為是預設建構函式,且智慧有一個

12、賦值相容規則 
子類物件可以直接賦值給父類物件; 
父類物件不能直接賦值給子類物件; 
父類的指標或引用可以直接指向子類的物件; 
子類的指標或引用不可以直接指向給父類的物件(強轉可以)。

13、多型 
概念:所謂多型性就是指達能夠不同的物件受到不同的訊息時產生不同的動作 
引入:基類的指標或引用指向子類的物件時,它只能訪問派生類中從基類繼承來的成員,而不能訪問派生類的新增成員,引用虛擬函式可解決此問題 
動態繫結條件:基類中的成員函式給成虛擬函式;呼叫虛擬函式時一定要通過基類的指標或引用呼叫;虛擬函式必須在派生類中重寫(同時滿足)。

14、函式過載、同名隱藏、重寫(覆蓋/覆寫) 
函式過載:函式名相同、同一作用域、引數列表不同(型別、個數、順序) 
同名隱藏:一個處於基類,一個處於派生類、函式名相同 
重寫(覆蓋/覆寫):一個處於基類一個處於派生類、都是虛擬函式、函式名相同、引數列表相同、函式的返回值相同(協變除外) 
協變:返回值一個是基類的指標或引用,一個是派生類的指標或引用

15、什麼時候解構函式需要設定為虛擬函式 
在多型的場景下,當一個基類的指標或引用指向一個派生類物件時,由於是基類的指標所以會呼叫基類的解構函式,此時屬於派生類的那部分空間並沒有釋放,因此造成記憶體洩漏,所以這種場景下必須基類的解構函式必須設定為虛擬函式,此時呼叫解構函式的時候就會呼叫派生類的解構函式。

16、編譯器什麼時候會為我們合成預設的建構函式 
1>有一個A類定義有自己的預設建構函式,B類沒有顯示定義自己的建構函式但類中包含A類的物件,此時編譯器會為B類合成預設的建構函式來呼叫A類已有的建構函式。 
2>如果B類和D類處於繼承關係(class D:public B)B類包含自己的預設建構函式,D類無建構函式,此時編譯器會為D類合成預設的建構函式來呼叫B類已有的預設建構函式。 
3>虛擬繼承中,如果派生類沒有顯示的定義自己的建構函式,則編譯器將會給它合成預設的建構函式,並且在構造物件的時候在物件的前4個位元組放入指向虛基表的指標。 
4>多型中,如果基類包含虛擬函式,如果派生類沒有顯示定義建構函式,則編譯器會為其合成預設的建構函式,並且將指向虛表(虛擬函式表)的指標存放在物件的前4個位元組。

17、虛表的建立 
基類:按照虛擬函式的宣告順序一次將虛擬函式的地址填入虛表中,最後位置放0 
派生類:先拷貝一份基類的虛表 
如果派生類對基類的某些函式進行重寫,則派生類會將虛表相同便宜位置的函式修改為派生類自己的虛擬函式地址; 
如果派生類新增了不同於基類的虛擬函式,則將其緊放在虛表末尾,最後位置放0

18、STL的6大元件: 
容器、迭代器、演算法、介面卡、空間配置器、仿函式(函式物件)

19、程式的執行過程 
預處理—-編譯—-彙編—-連結—-執行 
預處理:刪除註釋、巨集替換、處理條件編譯、包含標頭檔案、新增行號、檔名等 
編譯 :詞法分析、語法分析、語義分析、優化之後產生相應的彙編程式碼 
彙編:將彙編程式碼程式設計計算機可以執行的二進位制指令 
連結:匯出符號表、地址重定向表、位解決的符號表 
執行:執行程式碼的具體邏輯

20、異常處理 
C語言: 
1>終止程式 
2>返回一個表示錯誤的值,附加錯誤碼 
3>返回一個合法值,讓程式處於某種非法的狀態 
4>呼叫一個預先準備好出現錯誤的情況下呼叫的函式 
5>暴力解決:abort exit 
6>使用goto語句(只能在函式內部跳轉) 
7>setjmp和longjmp組合使用 
C++: 
throw(丟擲異常) try(檢查是否發生異常) catch(處理捕獲的異常)

21、型別轉換 
C語言:隱式型別轉換(如整形提升)和顯示型別轉換(強轉) 
C++:static_cast:用於非靜態型別,類似於隱式型別轉換 
const_cast:去除變數的常屬性,方便賦值 
reinterpret_cast:適用於兩個不同型別之間的轉換(不安全) 
dynamic_cast:用於將父類物件/指標轉換為子類物件/指標,類中必須包含虛擬函式 
Expilicit:防止單引數的建構函式進行飲食型別的轉換 
Volatile:防止編譯器進行優化,保證記憶體的可見性

22、呼叫約定 
這裡寫圖片描述

23、const關鍵字 
(1)可以定義const常量,具有不可變性。 
例如:const int Max=100; Max++會產生錯誤; 
(2)便於進行型別檢查,使編譯器對處理內容有更多瞭解,消除了一些隱患。 
例如: void f(const int i) { ………} 編譯器就會知道i是一個常量,不允許修改; 
(3)可以避免意義模糊的數字出現,同樣可以很方便地進行引數的調整和修改。 同巨集定義一樣,可以做到不變則已,一變都變! 
如(1)中,如果想修改Max的內容,只需要:const int Max=you want;即可! 
(4)可以保護被修飾的東西,防止意外的修改,增強程式的健壯性。 還是上面的例子,如果在函式體內修改了i,編譯器就會報錯; 
例如: void f(const int i) { i=10;//error! } 
(5) 可以節省空間,避免不必要的記憶體分配。 例如:

#define PI 3.14159 //常量巨集
const double Pi=3.14159; //此時並未將Pi放入RAM中 ......
double i=Pi; //此時為Pi分配記憶體,以後不再分配!
double I=PI; //編譯期間進行巨集替換,分配記憶體
double j=Pi; //沒有記憶體分配
double J=PI; //再進行巨集替換,又一次分配記憶體!
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

const定義常量從彙編的角度來看,只是給出了對應的記憶體地址,而不是像#define一樣給出的是立即數,所以,const定義的常量在程式執行過程中只有一份拷貝,而#define定義的常量在記憶體中有若干份拷貝。 
(6)提高了效率。 
編譯器通常不為普通const常量分配儲存空間,而是將它們儲存在符號表中,這使得它成為一個編譯期間的常量,沒有了儲存與讀記憶體的操作,使得它的效率也很高。 
C語言和C++ 中const的區別: 
C:const定義變數時變數還是變數,只是它具有了常屬性,不可修改。 
C++:const定義的變數,編譯器認為它時常量。 
驗證:arr[n]在C++中可以,在C語言中不行。

24、struct和class 
struct成員的預設訪問許可權是public,class成員的預設訪問許可權是private。 
預設的繼承訪問許可權:struct是public的,class是private的。

25、模板為什麼不支援分離編譯 
C++編譯器的工作簡介: 
在 C++ 標準中提到,一個編譯單元 [ Translation Unit ] 是指一個.cpp檔案以及它所include的所有.h檔案。.h檔案裡的程式碼將會被擴充套件到包含它的.cpp檔案裡,然後編譯器編譯該.cpp 檔案為一個.obj檔案,後者擁有PE [ Portable Executable,即 Windows 可執行檔案 ] 檔案格式,並且本身包含的就已經是二進位制碼。但是,不一定能夠執行,因為並不保證其中一定有main 函式。當編譯器將一個工程裡的所有.cpp檔案以分離的方式編譯完畢後,再由聯結器 [ linker ] 進行連線成為一個.exe檔案。 
下面給出一個例子說明原因: [將模板和它的實現分離]

//-------------test.h----------------//
template<class T>
class A
{
public:
void f(); //這裡只是個宣告
};
//---------------test.cpp-------------//
#include”test.h”
template<class T>
void A<T>::f() //模板的實現
{
…//do something
}

//---------------main.cpp---------------//
#include”test.h”
int main()
{
A<int> a;//模板的呼叫過程
a. f();//f具有外部屬性
}

在main.cpp中由於編譯時test.h裡的程式碼被展開,所以找到了f的宣告,並同時呼叫它找它的實現程式碼,本來f函式的實現程式碼在test.cpp的檔案裡實現,但由於在test.cpp裡沒有對f函式進行例項化,所以模板並不會為其生成相關程式碼,這就導致了main函式連結時並沒有找到f函式的實現程式碼,因而報出連結錯誤(無法解析的外部符號)。

26、C語言為什麼不支援過載 
因為c++有名命修飾,他會把每一個引數的型別的用一個字串來表示加到函式名上。所以過載的兩個同名函式編譯出來的函式名不同,所以不衝突支援過載。 
c沒有命名修飾,函式叫啥編譯出來只是給函式名前加了下劃線而已,同名函式當然會衝突的,因此不能過載。

相關推薦

CC++區別特點

1、函式傳指標和傳引用的區別?  1>指標定義時可以不初始化,但引用不行;  2>引用只能和一個實體結合,而指標可和多個實體結合;  3>自加減意義不同。指標的++表示指標向後偏移型別個位元組,而引用則是+1,–類似;  4>sizeof求值的意義不同

CC++的聯絡區別

面向過程的思路:分析解決問題所需的步驟,用函式把這些步驟依次實現。 面向物件的思路:把構成問題的事務分解為各個物件,建立物件的目的,不是完成一個步驟,而是描述某個事務在解決整個問題步驟中的行為。 從上述描述可以看出,其實面向物件和麵向過程是兩種思考解決問題的方式,其差異主要在於思考的角度。

C++/C中!~的區別作用

區別: !是邏輯運算子(與||,&&是一類符號),表示邏輯取反,可以把非0值變成0,把0值變為1 ~是位運算子(與|,&是一類符號),表示按位取反,在數值的二進位制表示上,將0變為1,將1變為0 例子: #include<io

C++C語言的區別(二)——動態開闢記憶體的區別new的使用

C++中和C語言中都有動態開闢記憶體的概念,C語言中使用的是庫函式malloc和free,而C++中使用的則是關鍵字new與delete,它們的部分區別如下: 現在我們同時使用兩種方式動態開闢二維陣列a[5][5] C語言: #include <malloc.h> #i

動態建立二維vector陣列 CC++ 及指標引用的區別

二維vectorvector<vector <int> > ivec(m ,vector<int>(n));    //m*n的二維vector動態建立m*n的二維vector方法一:vector<vector <int>

【轉】Visual C++ C++ 有什麽區別

業界 流行 編譯器 gtk+ 語言 開發 多種實現 廠商 計算 有位同學問我“Visual C++和C++有什麽區別?”,這的確是初學者會感到困惑的問題,比較常見。除此之外,還有“先學C++好,還是先學Visual C++好?”,都屬於同樣的概念不明的問題,就比

CC++結構體的區別

mage contain 裏的 clas 存在 prot 使用 構造函數 lai C的結構體內不允許有函數存在,C++允許有內部成員函數,且允許該函數是虛函數。所以C的結構體是沒有構造函數、析構函數、和this指針的。 C的結構體對內部成員變量的訪問權限只能是public

從電梯問題,看cc++之間的區別(有點懂了)錯覺錯覺

命令 上下 能夠 current 表現 靈活 沒有 c++ 16px 磕磕碰碰的也相繼用c和c++構造了不少的電梯了。雖然對自我的表現不滿意,但是總體來說還是有一定的收獲的,對於c和c++之間的區別感覺也摸到了一點點門道了。。。 用c語言構造電梯的步驟: 第一步: 分析這個

c++java區別之彩38平臺出售

substr 高效率 ++ 簡單的 語言 區分 substring 構建 字符串拼接 從概念上講,java字符串就是Unicode字符序列。彩38平臺出售(企 娥:217 1793 408) 1,提取子串 String類提取子串的方法是substring方法

CC++的區別

constexpr rtti 不同 編譯 move val 運行時 編譯器 c++ 1)、標準:分別隸屬於兩個不同的標準委員會。C以C99標準為主流,C11已經發布;C++以C++98/03為主流,C++11/14也日趨流行。 2)、語言本身: 1、C++是面向對象語言,C

cc++的區別(二)

const c語言中const修飾的量為常變數,可以通過一定的方法修改其值,如下程式碼: # include<stdio.h> int main() { const int i = 20; int *p = &i; *p = 30; printf("%d\n",

cc++區別(三)

名稱空間(c++) 示例: fun.h # include<iostream> using namespace std; namespace A { typedef int Int; }; main.cpp # include<iostream> #

C 語言、 C++C #有什麼區別

案例一: 任務:把大象放到冰箱裡。 C 語言、 C++和C 有什麼區別 C: C語言是一個極其高冷的人,因此回答都是冷冷的: 我:你好C語言,我想把大象放到冰箱裡,幫我做好不好? C:好 我:那我們要怎麼做呢? C:猜 我:額。。。是不是應該先創造一隻大象?

CC++的區別:new /delete malloc/free

幕布分享: https://mubu.com/doc/vQfZHGsDG0 動態分配記憶體: 在程式執行中進行的,而不是在編譯就確定的 new 堆上分配記憶體 (1) 開闢T位元組大小空間: Tp =new T; size: sizeof(T)    

C++ ###的區別

##是字串連線 #是字符串化的意思,把#後面的引數轉換成一個字串 例如: #define paster( n ) printf( "token " #n" = %d\n ", token##n )  所以paster(9);就是相當於 printf("token 9 = %d\

CC++的區別(二)

1、引用 引用就是個別名,記憶體單元的別名,底層以指標的方式來支援引用,在引用使用的地方,系統自帶解引用的過程。 int a = 10; int &b = a; a和b是同一個記憶體塊 引用的注意事項: 引用一定要初始化 引用引用的變數要能取地址 引用是

CC++區別

1.const *   和引用& const 常量   常變數 常變數就是不能做左值,其他都和變數性質一樣的。 常量在編譯時候所有用到常量的地方都替換成常量的初始值。 1.C和C++第一個區別: 我們什麼時候要加常引用呢? 很明顯就是在引

C++複習(CC++的區別1)

函式的預設值引數 C語言中沒有帶預設值的函式,C++支援帶預設值的函式 1.預設值的傳入過程   在函式呼叫點,如果沒有傳遞全部的實參,則會預設傳遞預設值作為實參。 2.預設值的賦值   必須從右向左,依次賦值。   預設值只在本檔案有效。   引數預設值在同一

C#C++C語言之間資料型別的對應

一、C#與C++資料型別的對應表  

cc++的區別之const

1.const C++: 在c++中,const定義的是常量,該常量的值是不可以被修改的,編譯時期 該使用該常量的地方直接替換成該常量的值,當然,常量是必須初始化的。 因為編譯時期,使用該常量的地方必須替換成該常量的值,若沒有初始化, 則此常量就是無用的常量 const