【C++】基礎知識篇

1.命名空間
在C++中,標識符(name)可以是符號常量、變量、宏、函數、結構、枚舉、類和對象等。爲了避免在大規模程序設計中以及在程序員使用各種各樣的C++庫時,這些標識符的命名發生衝突,標準C++引入了關鍵字namespace(命名空間),以便更好控制標識符作用域。
定義格式如下:

namespace 命名空間
{
命名空間聲明內容
}

例如:定義兩個命名空間AA1,AA2

#include<iostream>
using namespace std;
namespace AA1
{
    int i;
    void print()
    {
          count<<"AA1"<<end1;
}
namespace AA2
{
    int j;
    void print()
    {
          count<<"AA2"<<end1;
}
int main()
{
     AA1::print();
     AA2::print();
     return 0;
}

using聲明
在C++中,我們可以使用using可以不需要加前綴“namespace_name::”的情況下訪問命名空間中的成員。using聲明同其他聲明一樣有一個作用域,它引入的名字從聲明開始直到其所在的域結束都是可見的。
例如命名空間std,這是最常用的命名空間,標準C++庫中所有的組件都在該命名空間中聲明和定義。
例如:

#include <iostream>
using namespace std;
int main ()
{
     std::cout<<"hello world"<<std::endl;
     return 0;
}

2.C++基本的輸入輸出流
C++的輸入和輸出功能除了支持C語言的輸入/輸出系統外,還可以有iostream庫提供。最常用的輸入/輸出運算符是“>>”和“<<”。
(1)cin:標準輸入的istream類對象,使用戶能夠從終端讀數據,默認鍵盤。
(2)cout:標準輸出的ostream類對象,使用戶能夠從終端寫數據,默認是屏幕。
(3)cerr:標準錯誤的ostream類對象,cerr輸出程序錯誤,默認是屏幕。

#include <iostream>
#include<string>
using namespace std;
int main ()
{
    string s;
    char* p = "abc";
    int i;
    cout<<"Hello world"<<endl ;
    cin>>i;
    count<<"i=\t"<<i<<endl;
    count<<p<<endl;
    cin>>s;
    if(s.empty() == true)
    {
        cerr<<"string s is empty"<<endl;
    }
}

常用的格式流
這裏寫圖片描述

3.重載(C++爲什麼支持重載?)
C++重載:在同一作用域類,一組函數的函數名相同,參數列表不同(個數不同/類型不同),返回值可同可不同
在學習C語言的時候我們不能用下面的方式定義兩個函數:

#include<stdio.h>
void fun(int i)
{
}
void fun(char j)
{

}
int main()
{
    fun(1);
    fun('a');
    return 0;
}

會出現如下的錯誤:
這裏寫圖片描述
而C++可以實現這樣的函數重載,那麼問題來了,爲什麼C++支持函數重載,而C語言不支持呢?
從代碼的編譯到運行,在VS這種編譯器下,它是系統直接完成了翻譯與鏈接,直接生成了運行結果。
編譯器內部完成了翻譯部分:
1.預處理
1)頭文件展開
2)宏的替換
3)去註釋
4)條件編譯
2.編譯過程:將高級語言轉爲彙編語言
3.彙編過程:彙編語言轉爲二進制程序
鏈接部分:所引用的數據鏈接進來
比如一個函數的聲明如下:
void fun(int i);
在c語言中,編譯器在編譯後在庫中的名字爲_fun
在c++中,編譯器在編譯後在庫中的名字爲_function_int
還有一個函數的聲明如下:
void fun(char j);
在c語言中,編譯器在編譯後在庫中的名字爲_fun
在c++中,編譯器在編譯後在庫中的名字爲_function_char
在鏈接時,都是找名字進行鏈接的,就比如以上兩個函數,
在C語言中兩個的名字一樣,就會在鏈接中報錯。
C++中它們的名字不一樣,所以就不會報錯。
4.C++缺省參數
如果函數說明或函數定義中爲形參指定一個默認值,則稱此函數爲帶缺省參數的函數。如果在調用時,指定了形參相對應的實參,則形參使用實參的值。如果未指定相應的實參,則形參使用默認值,這爲函數的使用提供了很大的便利。
例如,函數int可以被說明爲:

void init(int x = 1);

如果調用語句爲init(2),則這個調用語句傳遞給形參的值爲2,如果調用語句爲init( ),則傳遞給形參的值爲1。
如果函數有多個缺省參數,則缺省參數必須是從右向左定義,並且在一個默認參數的右邊不能有未指定缺省參數。
例如:

void fun(int a,int b = 1int c = 4int d = 5);

這個函數聲明語句是正確的,但是下面的聲明語句是錯誤的:

void fun(int a,int b = 1int c,int d);
void fun(int a,int b = 1int c,int d = 5);

缺省參數分爲全缺省參數和半缺省參數,例如:

// 全缺省參數
int Add1 (int a = 0, int b = 0)
{
return a + b;
}
// 半缺省參數
int Add2 (int a, int b = 0)
{
return a + b;
}
void Test ()
{
Add1();
Add1(1);
Add1(1,1);
Add2(2);
Add2(2,2);
}

【注意】
1. 帶缺省值的參數必須放在參數表的最後面。
2. 缺省參數不能同時在函數的聲明和函數定義中出現,二者只能選其一。
3. 缺省值必須是常量或全局變量。
4. 缺省參數必須通過值參或常參傳遞。

5.指針和引用
C語言中函數有兩種傳參的方式:傳值和傳址。
以傳值方式,在函數調用過程中會生成一份臨時變量用形參代替,最終把實參的值傳遞給新分配的臨時變量即形參。它的優點是避免了函數調用的副作用,確無法改變形參的值。如果要改變實參的值,只能通過指針傳遞。

void swap (int *_pleft , int * _pRight)
{
    int iTemp = * _pleft;
    *_pleft = * _pRight;
    *_pRight = iTemp;
}

指針可以解決問題,但不是很形象友好,不安全,因此C++中引入了一種新的符合類型–引用。
引用概念
引用不是新定義一個變量,而是給已存在變量取了一個別名,編譯器不會爲引用變量開闢內存空間,它和它引用的變量共用同一塊內存空間。
定義的格式爲:
類型 &引用變量名 = 已定義過的變量名;
【引用特性】
1. 引用在定義時必須初始化。
2. 一個變量可以有多個引用。
3. 引用一旦綁定了一個實體,就不能再改變爲其他變量的引用。

void Test()
{
   int i = 10;
   int &i1= i;
   int &i2 = i1;
   //int &i3; // 定義引用時必須進行初始化
   int &i5= i;
   int i6 = 20;   
   //&i5 = i6; // 引用一旦定義,就不能夠在改變
}

使用場景
【函數形參】

void swap(int &_iLeft, int &_iRight)
{
int iTemp = _iLeft;
_iLeft = _iRight;
_iRight = iTemp;
}

【返回值】

// 值返回
int Add(int _iLeft, int _iRight)
{
return _iLeft + _iRight;
}
// 引用返回
int& Add(int & _iLeft, int& _iRight)
{
int iResult = _iLeft+_iRight;
return iResult;
}

引用與指針的區別
【相同點】
底層的實現方式相同,都是按照指針的方式來實現的
這裏寫圖片描述
【不同點】

void Test()
{
// 相同點兩者的底層處理方式相同
int iTest0 = 10;
int &iTest1 = iTest0;
int *pTest2 = &iTest0;
// 不同點
// 定義時必須初始化,指針可以不用,正常情況下需初始化爲NULL
int &iTest3;
int *pTest4;
// 引用一旦定義就不能再改變,指針可以
int iTest5 = 20;
int &iTest6 = iTest0;
&iTest5 = iTest5;
int *pTest7 = &iTest0;
pTest7 = &iTest6;
// sizeof
printf( "%d", sizeof (iTest6));
printf( "%d", sizeof (pTest7));
// 自++含義不同
iTest6++;
pTest7++;
// 可以有多級指針,但是沒有多級引用
int &&iTest8;
int **pTest9;
}

總結:
1、引用在定義時必須初始化,指針沒有要求。
2、一旦一個引用被初始化爲指向一個對象,就不能再指向
其他對象,而指針可以在任何時候指向任何一個同類型對象
3、沒有NULL引用,但有NULL指針。
4、在sizeof中含義不同:引用結果爲引用類型的大小,
但指針始終是地址空間所佔字節個數。
5、引用自加改變變量的內容,指針自加改變了指針指向
6、有多級指針,但是沒有多級引用
7、引用比指針使用起來相對更安全

發佈了49 篇原創文章 · 獲贊 28 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章