C++ 是一種靜態類型的、編譯式的、通用的、大小寫敏感的、不規則的編程語言,支持過程化編程、面向對象編程和泛型編程。
1.面向對象程序設計:
C++ 完全支持面向對象,包括面向對象開發的四大特性:
- 封裝
- 抽象
- 繼承
- 多態
C++標準庫的組成:
- 核心語言,提供了所有構件塊,包括變量、數據類型和常量等;
- C++ 標準庫,提供了大量的函數,用於操作文件、字符串等;
- 標準模板庫(STL),提供了大量的方法,用於操作數據結構等。
C++ 程序可以定義爲對象的集合,這些對象通過調用彼此的方法進行交互:
- 對象:對象具有狀態和行爲;
- 類:類可以定義爲描述對象行爲/狀態的模板/藍圖;
- 方法:從基本上說,一個方法表示一種行爲。一個類可以包含多個方法。可以在方法中寫入邏輯、操作數據以及執行所有的動作;
- 即時變量:每個對象都有其獨特的即時變量。對象的狀態是由這些即時變量的值創建的。
2.C++基本語法:
- C++數據類型:布爾(bool)/字符型(char)/整型(int)/浮點型(float)/雙浮點型(double)/無類型(void)/寬字符型(wchar_t);
- 一些基本類型可以使用一個或多個類型修飾符進行修飾:signed/unsigned/short/long;
- typedef聲明:可以使用 typedef 爲一個已有的類型取一個新的名字;
typedef type newname;
- 枚舉類型:枚舉類型(enumeration)是C++中的一種派生數據類型,它是由用戶定義的若干枚舉常量的集合。
enum MYCOLOR{
BLUE,
GREE
}color;
- C++變量的聲明:當使用多個文件且只在其中一個文件中定義變量時(定義變量的文件在程序連接時是可用的),使用 extern 關鍵字在任何地方聲明一個變量。
// 變量聲明
extern int a, b;
- 變量的作用域:分爲全局變量/局部變量/形式參數。
- 常量:使用#define 預處理器/使用 const 關鍵字。
#include <iostream>
#define ONE 2
int main() {
std::cout << "helloWorld" << sizeof(char);
const int FRIST = 1;
return 0;
}
- 類型限定符:
const:const 類型的對象在程序執行期間不能被修改改變;
volatile:修飾符 volatile 告訴編譯器不需要優化volatile聲明的變量,讓程序可以直接從內存中讀取變量。對於一般的變量編譯器會對變量進行優化,將內存中的變量值放在寄存器中以加快讀寫效率;
restrict:由 restrict 修飾的指針是唯一一種訪問它所指向的對象的方式。只有 C99 增加了新的類型限定符 restrict。
- 存儲類:存儲類定義 C++ 程序中變量/函數的範圍(可見性)和生命週期。
auto存儲類:auto關鍵字用於兩種情況:聲明變量時根據初始化表達式自動推斷該變量的類型、聲明函數時函數返回值的佔位符。
register存儲類:用於定義存儲在寄存器中而不是 RAM 中的局部變量。這意味着變量的最大尺寸等於寄存器的大小(通常是一個詞),且不能對它應用一元的 '&' 運算符(因爲它沒有內存位置)。
static存儲類:指示編譯器在程序的生命週期內保持局部變量的存在,而不需要在每次它進入和離開作用域時進行創建和銷燬。因此,使用 static 修飾局部變量可以在函數調用之間保持局部變量的值,static 修飾符也可以應用於全局變量。當 static 修飾全局變量時,會使變量的作用域限制在聲明它的文件內。
extern存儲類:用於提供一個全局變量的引用,全局變量對所有的程序文件都是可見的。當使用 'extern' 時,對於無法初始化的變量,會把變量名指向一個之前定義過的存儲位置。
mutable存儲類:僅適用於類的對象,它允許對象的成員替代常量。
thread_local存儲類:聲明的變量僅可在它在其上創建的線程上訪問。 變量在創建線程時創建,並在銷燬線程時銷燬。 每個線程都有其自己的變量副本。
- C++函數:函數是一組一起執行一個任務的語句。每個 C++ 程序都至少有一個函數,即主函數 main() ,所有簡單的程序都可以定義其他額外的函數。
返回類型:一個函數可以返回一個值。不需要返回關鍵字void;
函數名稱:這是函數的實際名稱,函數名和參數列表構成函數簽名;
參數:參數就像是佔位符。當函數被調用時,向參數傳遞一個值,這個值被稱爲實際參數。參數列表包括函數參數的類型、順序、數量。參數是可選的,也就是說,函數可能不包含參數;
函數主體:函數主體包含一組定義函數執行任務的語句。
函數聲明:會告訴編譯器函數名稱及如何調用函數。函數的實際主體可以單獨定義。
調用函數:當程序調用函數時,程序控制權會轉移給被調用的函數。被調用的函數執行已定義的任務,當函數的返回語句被執行時,或到達函數的結束括號時,會把程序控制權交還給主程序。
函數參數:如果函數要使用參數,則必須聲明接受參數值的變量,這些變量稱爲函數的形式參數。形式參數就像函數內的其他局部變量,在進入函數時被創建,退出函數時被銷燬。
參數的傳遞方式:
- 傳值調用:該方法把參數的實際值賦值給函數的形式參數。在這種情況下,修改函數內的形式參數對實際參數沒有影響。
- 指針調用:該方法把參數的地址賦值給形式參數。在函數內,該地址用於訪問調用中要用到的實際參數。這意味着,修改形式參數會影響實際參數。
- 引用調用(引用存儲地址):該方法把參數的引用賦值給形式參數。在函數內,該引用用於訪問調用中要用到的實際參數。這意味着,修改形式參數會影響實際參數。
Lambda函數與表達式:Lambda 表達式把函數看作對象。Lambda 表達式可以像對象一樣使用,比如可以將它們賦給變量和作爲參數傳遞,還可以像函數一樣對其求值。Lambda 表達式本質上與函數聲明非常類似。
- C++數組:存儲一個固定大小的相同類型元素的順序集合。數組是用來存儲一系列數據,但它往往被認爲是一系列相同類型的變量。
聲明數組:需要指定元素的類型和元素的數量;
初始化數組:可以逐個初始化數組,也可以使用一個初始化語句;
訪問數組元素:數組元素可以通過數組名稱加索引進行訪問。元素的索引是放在方括號內,跟在數組名稱的後邊;
多維數組:C++ 支持多維數組。多維數組最簡單的形式是二維數組。
指向數組的指針:把第一個元素的地址存儲在 p 中,就可以使用 *p、*(p+1)、*(p+2) 等來訪問數組元素
double *p;
double balance[10];
p = balance;
傳遞數組給函數:可以通過指定不帶索引的數組名來傳遞一個指向數組的指針,傳數組給一個函數,數組類型自動轉換爲指針類型,因而傳的實際是地址。
從函數返回數組:C++ 不允許返回一個完整的數組作爲函數的參數。但是,您可以通過指定不帶索引的數組名來返回一個指向數組的指針。
- C++字符串:C 風格的字符串起源於 C 語言,並在 C++ 中繼續得到支持。字符串實際上是使用 null 字符 '\0' 終止的一維字符數組。因此,一個以 null 結尾的字符串,包含了組成字符串的字符。C++中string類。
- C++指針:
每一個變量都有一個內存位置,每一個內存位置都定義了可使用連字號(&)運算符訪問的地址,它表示了在內存中的一個地址。指針是一個變量,其值爲另一個變量的地址,即,內存位置的直接地址。就像其他變量或常量一樣,您必須在使用指針存儲其他變量地址之前,對其進行聲明。
指針的使用:定義一個指針變量、把變量地址賦值給指針、訪問指針變量中可用地址的值。
int var = 20; // 實際變量的聲明
int *ip; // 指針變量的聲明
ip = &var; // 在指針變量中存儲 var 的地址
cout << "Value of var variable: ";
cout << var << endl;
// 輸出在指針變量中存儲的地址
cout << "Address stored in ip variable: ";
cout << ip << endl;
// 訪問指針中地址的值
cout << "Value of *ip variable: ";
cout << *ip << endl;
NULL指針:在變量聲明的時候,如果沒有確切的地址可以賦值,爲指針變量賦一個 NULL 值是一個良好的編程習慣。賦爲 NULL 值的指針被稱爲空指針。
int *ptr = NULL;
指針的算術運算:指針是一個用數值表示的地址。因此,可以對指針執行算術運算。
ptr++;//遞增一個指針
ptr--; //遞減一個指針
const int MAX = 3;
int var[MAX] = {10, 100, 200};
int *ptr1;
ptr1 <= &var[MAX - 1]; //指針可以用關係運算符進行比較,如 ==、< 和 >
指針與數組:一個指向數組開頭的指針,可以通過使用指針的算術運算或數組索引來訪問數組;
指針數組:一組存儲同一類型指針的數組
int var[MAX] = {10, 100, 200};
int *ptr[MAX];
for (int i = 0; i < MAX; i++)
{
ptr[i] = &var[i]; // 賦值爲整數的地址
}
for (int i = 0; i < MAX; i++)
{
cout << "Value of var[" << i << "] = ";
cout << *ptr[i] << endl;
}
指向指針的指針(如二級指針):指向指針的指針是一種多級間接尋址的形式,或者說是一個指針鏈。通常,一個指針包含一個變量的地址。當定義一個指向指針的指針時,第一個指針包含了第二個指針的地址,第二個指針指向包含實際值的位置。
int var;
int *ptr;
int **pptr;
var = 3000;
// 獲取 var 的地址
ptr = &var;
// 使用運算符 & 獲取 ptr 的地址
pptr = &ptr;
// 使用 pptr 獲取值
cout << "var 值爲 :" << var << endl;
cout << "*ptr 值爲:" << *ptr << endl;
cout << "**pptr 值爲:" << **pptr << endl;
傳遞指針給函數:傳遞指針給函數,只需要簡單地聲明函數參數爲指針類型即可。
從函數返回指針:必須聲明一個返回指針的函數。
- C++引用:引用變量是一個別名,也就是說,它是某個已存在變量的另一個名字。一旦把引用初始化爲某個變量,就可以使用該引用名稱或變量名稱來指向變量。
引用和指針:不存在空引用,引用必須連接到一塊合法的內存;一旦引用被初始化爲對象就不能指向到另一個對象,指針可以在任何時候指向到另一個對象;引用必須在創建時被初始化,指針可以在任何時候被初始化。
// 聲明簡單的變量
int i;
double d;
// 聲明引用變量
int& r = i;
double& s = d;
- C++數據結構:C/C++ 數組允許定義可存儲相同類型數據項的變量,但是結構是 C++ 中另一種用戶自定義的可用的數據類型,它允許您存儲不同類型的數據項。
定義結構:爲了定義結構,必須使用struct語句。struct語句定義了一個包含多個成員的新的數據類型。
struct Books
{
char title[50];
char author[50];
char subject[100];
int book_id;
} book;
訪問結構成員:爲了訪問結構的成員,我們使用成員訪問運算符(.)。成員訪問運算符是結構變量名稱和我們要訪問的結構成員之間的一個句號。
結構體作爲參數傳遞:把結構作爲函數參數,傳參方式與其他類型的變量或指針類似。
指向結構的指針:
定義指向結構的指針
struct Books *struct_pointer;
存儲變量地址:
struct_pointer = &Book1;
使用指針訪問結構的成員:
struct_pointer->title;
結構體實例:
#include <iostream>
#include <cstring>
using namespace std;
void printBook( struct Books *book );
struct Books
{
char title[50];
char author[50];
char subject[100];
int book_id;
};
int main( )
{
Books Book1; // 定義結構體類型 Books 的變量 Book1
Books Book2; // 定義結構體類型 Books 的變量 Book2
// Book1 詳述
strcpy( Book1.title, "C++ 教程");
strcpy( Book1.author, "Runoob");
strcpy( Book1.subject, "編程語言");
Book1.book_id = 12345;
// Book2 詳述
strcpy( Book2.title, "CSS 教程");
strcpy( Book2.author, "Runoob");
strcpy( Book2.subject, "前端技術");
Book2.book_id = 12346;
// 通過傳 Book1 的地址來輸出 Book1 信息
printBook( &Book1 );
// 通過傳 Book2 的地址來輸出 Book2 信息
printBook( &Book2 );
return 0;
}
// 該函數以結構指針作爲參數
void printBook( struct Books *book )
{
cout << "書標題 : " << book->title <<endl;
cout << "書作者 : " << book->author <<endl;
cout << "書類目 : " << book->subject <<endl;
cout << "書 ID : " << book->book_id <<endl;
}
typedef關鍵字:可以爲創建的類型取一個"別名"。
typedef struct Books //結構體別名爲Book
{
char title[50];
char author[50];
char subject[100];
int book_id;
}Books;
Books Book1, Book2;
//使用 typedef 關鍵字來定義非結構類型
typedef long int *pint32;
pint32 x, y, z;