1.c和c++的優缺點解析
c語言屬于面向過程。
優點是:性能比面向對象高,因為類調用時需要執行個體化,開銷比較大,比較消耗資源。
缺點:沒有面向對象易維護、易複用、易擴充
c++屬于面向對象
優點是:易維護、易複用、易擴充,由于面向對象有封裝、繼承、多态性的特性,可以設計出低耦合的系統,使系統更加靈活、更加易于維護
缺點:性能比面向過程低
面向對象程式設計(英語:Object-oriented programming,縮寫:OOP)是一種程式設計範型,同時也是一種程式開發的方法。對象指的是類的執行個體。它将對象作為程式的基本單元,将程式和資料封裝其中,以提高軟體的重用性、靈活性和擴充性
而c++是基于面向對象的語言,因為它包含了c的一部分,而c語言是面向過程。面向對象更符合人類思維模式。
2.函數重載解析
各位應該都知道在c語言中不支援重載,而c++中卻支援重載,這是為什麼呢?接下來我們仔細分析分析。
舉例建立三個檔案:test.h test.c main.c
執行檔案時分為下面四個過程
過程 | 執行的操作 | 生成的檔案 |
---|---|---|
1.預處理 | 展開頭檔案、宏替換、去掉注釋、條件編譯 | test.i main.i |
2.編譯 | 檢查文法詞法并生成彙編代碼 | test.s main.s |
3.彙編 | 彙編代碼變為機器認識的機器碼 | test.0 main.o |
4.連結 | 連結到一起生成可執行程式 | a.out |
這是main.c中的函數
#include"test.h"
void func(int i)
{
count<<i<<endl;
}
int main()
{
func);
func("c");
}
這是test.c的函數
#include"test.h"
void func(char c)
{
count<<"hello world"<<endl;
}
這是test.h函數
#pragma once
#include<stdio.h>
#include<windows.h>
當你這時候編譯時就會出現這種錯誤: fatal error LNK1169: 找到一個或多個多重定義的符号
這就是重定義的錯誤,就算兩個函數參數不一樣,但依然還會重定義,因為在c語言連結時将main.o和test.o 合并時,在兩個檔案中查找func函數,當發現兩個檔案中都有func函數就會産生沖突,因為它是以名字查找的。
而c++是可以重載的
eg:
原函數 | Linux下的反彙編定義的函數名字 |
---|---|
void func(int i) | _Z4funci |
void func(char c) | _Z4funcc |
int max(int a,int b) | _Z3maxii |
double max(double a,double b) | _Z3maxdd |
看上面例子可得:c++ 中底層彙編語言中會将重載函數名映射為傳回類型+函數名+參數清單。這樣c++有同名函數時,連結時隻要參數類型或者順序不一樣就可以調用
3.預設參數解析
c++中的預設參數定義:在聲明函數的某個參數的時候為之指定一個預設值,在調用該 函數的時候如果使用預設值,你就沒必要指定該參數了。
void func2(int x, int y = );//聲明
void func1(int x = , int y = )//定義
{
cout << x << ' ' << y << endl;
}
void func2(int x, int y)
{
cout << x << ' ' << y << endl;
}
void func3(int x = , int y = )
{
cout << x << ' ' << y << endl;
}
int main()
{
func1();
func2();
func3(,);
system("pause");
return ;
}
就像func1在調用時實參為空,這就叫做預設參數,而在定義時有預設參數并且已經給出預設值,函數調用時就可以直接調用。而func2中隻省略了右邊參數y的值,是以實參隻寫了一個參數,func3中實參都寫了,是以調用時就不會用到預設參數的值,如果沒有寫就會直接調用預設參數
預設參數有一下規則:
1.調用時你隻能從最後一個參數開始進行省略,中間不能間斷。
2.預設值必須是常量
3.函數聲明時有預設參數,定義時就不能給出預設參數了,就像func2()一樣
4.預設參數與函數重載一塊使用時就要注意了
如果一組重載函數(可能帶有預設參數)都允許相同實參個數的調用,将會引起調用的二義性。例如:
void func(int x); //重載函數一
void func(int x,int y); //重載函數二,帶有預設參數
void func(int x,int y); //重載函數三,帶有預設參數
func); //error: 到底調用3個重載函數中的哪個?
func) //error:到底調用後面2個重載函數的哪個?
這樣就會出現問題,是以讀者在應用時要特别注意
5.預設值的限定:預設值可以是全局變量、全局常量,甚至是一個函數,但不能是局部變量,局部變量
因為預設參數的函數調用是在編譯時确定的,而局部變量的位置與值在編譯時均無法确定
4.命名空間解析
命名空間:在C++ 中,名稱(name)可以是符号常量、變量、宏、函數、結構、枚舉、類和對象等等。為了避免在大規模程式的設計中,以及在程式員使用各種各樣的C++庫時,這些辨別符的命名發生沖突,标準C++引入了關鍵字namespace(命名空間),這些辨別符的作用域隻在本空間域内有效,進而合理的解決命名沖突。
eg:
namespace n1
{
int a = ;
namespace n2
{
int a = ;
}
}
cout << n1::a << endl;
cout << n1::n2::a << endl;
上面例子說明在不同的命名空間裡可以定義相同的名稱,不會出現命名沖突問題
c++中有一個标準的命名空間
using namespace std;
C++ 庫的所有辨別符都是在std的命名空間中定義的,或者說标準頭檔案(iostream)中的函數、類、對象和類模闆是在命名空間std中定義的。是以在C++程式的一開始,就用using namespace對std進行全局聲明
如果你一開始不寫這個命名空間就會編譯出錯,要麼你就得給是以std命名空間下的成員加上這個eg:
std::cout << n1::a << std::endl;
std::cout << n1::n2::a << std::endl;