01- 從C 到C++

guardwhy發表於2020-12-28

C++的概述

C++語言在c語言的基礎上新增了物件導向程式設計泛型程式設計的支援。c++繼承了c語言高效,簡潔,快速和可移植的傳統。c++語言融合了3種不同的程式設計方式:

c語言代表的過程性語言.
c++在c語言基礎上新增的類代表的面嚮物件語言.
c++模板支援的泛型程式設計。

C語言和C++語言的聯絡

C++語言是在C語言的基礎上,新增了物件導向、模板等現代程式設計語言的特性而發展起來的。兩者無論是從語法規則上,還是從運算子的數量和使用上,都非常相似。

初識C++

程式碼示例

#include <iostream> // 預編譯指令,引入標頭檔案iostream
/**
 * c++第一個源程式
 */
 // 名稱空間
using namespace std;

int main() {
    // cout:標準輸出流物件。
    // endl:重新整理快取區,並且換行
   cout << "Hello, World!" << endl;
    return 0;
}

C++對C的擴充套件

::作用域運算子

程式碼示例

#include <iostream>
/**
 * 雙冒號作用域運算子。
 */
using namespace std;
// 定義全域性變數
int a = 100;

// 宣告函式
void test01()
{
    // 定義區域性變數
    int a = 200;
    cout << "區域性變數:" << a << endl;
    // 如果::前面沒有任何內容,表示代表全域性作用域。
    cout << "全域性變數:" << ::a << endl;
}

int main() {
    // 呼叫函式
    test01();
    return 0;
}

注意

如果::前面沒有任何內容,表示代表全域性作用域。

C++名稱空間

在c++中,名稱(name)可以是符號常量、變數、函式、結構、列舉、類和物件等等。工程越大,名稱互相沖突性的可能性越大。標準C++引入關鍵字namespace(名稱空間/名字空間/名稱空間),可以更好地控制識別符號的作用域。

程式碼示例

#include <iostream>
/**
 * 建立名稱空間
 * @return
 */
 namespace A{
     // 定義變數
     int a = 10;
 }

 namespace B{
     // 定義變數
     int a = 20;
 }
int main()
{
    std::cout << "A::a : " << A::a << std::endl;
    std::cout << "B::a : " << B::a << std::endl;
    return 0;
}

using宣告和使用

程式碼示例

#include <iostream>
/**
 * 使用名稱空間
 */
using namespace std;

// 建立名稱空間stu
namespace stu
{
    void sort()
    {
        cout << "stu" << std::endl;
    }
}
// 使用名稱空間stu
using namespace stu;

// 建立名稱空間stu1
namespace stu1
{
    void sort()
    {
        std::cout << "stu1" << std::endl;
    }
}
// 使用名稱空間stu1
using namespace stu1;

int main()
{
    stu::sort();
    stu1::sort();

    cout << "kobe is mvp" <<endl;

    return 0;
}

全域性變數檢測增強

int a;
// int a = 10; a重定義

函式檢查增強

// 獲取長方形的面積
int getArea(int w, int l){
    return w * l;
}

/**
 * 函式檢測增強  返回值檢測增強  形參型別檢測增強  呼叫時候引數數量檢測增強
 */
 // 宣告test01()函式
void test1(){
    // getArea(10, 12, 13); 引數傳入過多
}

型別轉換檢測加強

/**
 * 型別轉換檢測加強
 * @return
 */
 // 宣告test02()函式
 void test2(){
     // 指標左右型別必須一樣,才能賦值
     int * str = (int *)malloc(sizeof(int)* 8);
 }

結構體的簡化

/**
  * struct增強
  * @return
  */
  // 在C++語言下,可以在結構體中放函式
  struct Student{
      int age;
      void function(){
          age++;
      }
  };

  // 宣告test03()函式
  void test03(){
      // 在C++下面 建立結構體變數的時候,可以簡化關鍵字struct
      Student st;
      st.age = 17;
      st.function();
      cout << "學生的年齡是:" << st.age << endl;
  }

bool資料型別的擴充套件

/**
   * bool資料型別的擴充套件,C++語言下有bool資料型別,代表真和假
   * @return
   */
   bool flag;
   void test04(){
       // bool型別佔用一個位元組
       cout << "bool型別佔用"<< sizeof(bool) << "位元組" << endl;
       // 真 true(1) 假 false(0)
       flag = true;
       cout << flag << endl;
   }

三目運算子增強

/*
* 三目運算子增強
* C++語言下 三目運算子返回的是變數,可以繼續賦值
* @return
*/
void test05(){
       // 定義變數
       int a = 10;
       int b = 20;
       // printf("a > b ? a : b = %d\n", a > b ? a : b);

       (a > b ? a : b) =100; // b = 100   加上括號 保證運算完整性
       cout << "a = " << a << endl; // 10
       cout << "b = " << b << endl; // 100
   }

const關鍵字

C語言中的const的特徵

  1. const修飾的變數是隻讀的, 本質還是變數,不是常量。const修飾的區域性變數在棧上分配空間。
  2. const修飾的全域性變數在只讀儲存區分配空間,const只在編譯期有用,在執行期無用。
  3. const修飾的變數不是真的常量,它只是告訴編譯器該變數不能出現在賦值符號的左邊。

程式碼示例

#include <stdio.h>

int main()
{
    // 定義普通變數
    const int c = 0;
    // 定義指標變數
    int* p = (int*)&c;
    
    printf("hello world...\n");
    
    *p = 5;
    
    printf("c = %d\n", c);
    
    return 0;
}

程式執行結果

結論

C語言中的const使得變數具有隻讀屬性。
const將具有全域性生命週期的變數儲存於只讀儲存區。
const不能定義真正意義上的常量!

C++語言中的const的特徵

C++在C的基礎上的const進行了進化處理。

當碰見const宣告時在符號表中放入常量,編譯過程中若發現使用常量則直接以符號表中的值替換。   

編譯過程中若發現下述情況則給對應的常量分配儲存空間

const常量使用了extern,對const常量使用&操作符。

注意

C+ +編譯器雖然可能為const常量分配空間,但不會使用其儲存空間中的值(相容C語言)。

C++中的const常量

可能分配儲存空間

- 當const常量為全域性,並且需要在其它檔案中使用。
- 當使用&操作符對const常量取地址。

C++中的const常量類似於巨集定義。

constintc= 5; ≈ #define C 5

C++中的const常量在與巨集定義的區別

const常量是由編譯器處理。
編譯器對const常量進行型別檢查和作用域檢查.
巨集定義由前處理器處理,單純的文字替換。

程式碼示例

#include <stdio.h>

void fax()
{   // 定義巨集
    #define a 3

}

// 宣告函式
void gax()
{
    printf("a = %d\n", a);
}

int main()
{   
    // 定義變數
    const int A = 1;
    const int B = 2;
    // 定義陣列
    int array[A + B] = {0};
    int i = 0;
    
    // 遍歷迴圈
    for(i=0; i<(A + B); i++)
    {
        printf("array[%d] = %d\n", i, array[i]);
    }
    
    // 呼叫函式
    fax();
    gax();
    
    return 0;
}

程式執行結果

修改const的值

程式碼示例

#include <cstdlib>
#include <iostream>
using namespace std;

// 定義全域性變數
    const int const_A = 10;
    // 宣告函式
    void test01(){
    	/**
         * 全域性變數受到常量區的保護,無法修改
         */
         
        // const_A = 1000;

        /*
        int* p = (int *)&const_A;
        *p = 100;
        cout << "const_A的值:"<< const_A<< endl;
        */
        
        // 定義區域性變數
        const int const_B = 20;
        /*
        	當對const_B取地址的時候,建立臨時記憶體空間,臨時空間是看不到的。
			int temp = const_B;
			int *p = (int*)&temp
        */
        int *p = (int*)&const_B;
        *p = 200;
        // 輸出結果
        cout << "const_B的值是"<< const_B << endl;
    }
    
int main() {
    printf("hello world!!!\n");
    // 呼叫函式
    test01();
    return 0;
}

程式執行結果

const分配記憶體

程式碼示例

#include <iostream>
/**
 * const在C++下分配記憶體的情況
 */
using namespace std;
// 1.對const修飾的區域性變數取地址,會分配臨時空間
void test01(){
    // 01.定義變數
    const int const_A = 10;
    int *p = (int *)&const_A;
}

// 2.使用變數,初始化const修飾的區域性變數
void test02(){
    // 定義變數
    int a = 10;
    // 會分配記憶體,可以通過間接修改,修改成功.
    const int const_B = a;

    int * p = (int *)&const_B;
    *p = 30;
    // 輸出結果
    cout << "const_B的值:" << const_B << endl;
}

// 3.對於自定義資料型別,也會分配記憶體
struct Person{
    // 定義變數
    string name;
    int age;
};

// 宣告函式
void test03(){
    const Person p1{};
    Person * p = (Person *)&p1;
    p->age = 18;
    p->name = "常山趙子龍";

    // 輸出結果
    cout << "姓名:" << p->name <<endl << "年齡:" << p->age << endl;
}
int main() {
   // 1.呼叫函式
   // test02();
   test03();
    return 0;
}

相關文章