C++基礎學習筆記(一)
一、簡介
C++ 是一種靜態型別的、編譯式的、通用的、大小寫敏感的、不規則的程式語言,支援過程化程式設計、面向物件程式設計和泛型程式設計。
二、基本語法
1、註釋
#include <iostream> using namespace std; int main() { /* 這是註釋 */ /* C++ 註釋也可以 * 跨行 */ //單行註釋 cout << "Hello World!"; // 輸出 Hello World! //此外,可以使用條件編譯來實現註釋,且可以實現巢狀 #if 0 cout << "我怎麼如此之帥!"; #endif return 0; }
2、資料型別
2.1、基本的內建型別
進行程式設計時,需要用到各種變數來儲存各種資訊。變數保留的是它所儲存的值的記憶體位置。作業系統會根據變數的資料型別,來分配記憶體和決定在保留記憶體中儲存什麼。
型別 | 關鍵字 |
---|---|
布林型 | bool |
字元型 | char |
整型 | int |
浮點型 | float |
雙浮點型 | double |
無型別 | void |
寬字元型 | wchar_t |
修飾符(一些基本型別可以使用一個或多個型別修飾符進行修飾)
- signed
- unsigned
- short
- long
修飾符 signed、unsigned、long 和 short 可應用於整型,signed
型別限定符
限定符 | 含義 |
---|---|
const | const 型別的物件在程式執行期間不能被修改改變。 |
volatile | 修飾符 volatile 告訴編譯器不需要優化volatile宣告的變數,讓程式可以直接從記憶體中讀取變數。對於一般的變數編譯器會對變數進行優化,將記憶體中的變數值放在暫存器中以加快讀寫效率。 |
restrict | 由 restrict 修飾的指標是唯一一種訪問它所指向的物件的方式。只有 C99 增加了新的型別限定符 restrict。 |
型別 | 位 | 範圍 |
---|---|---|
char | 1 個位元組 | -128 到 127 或者 0 到 255 |
unsigned char | 1 個位元組 | 0 到 255 |
signed char | 1 個位元組 | -128 到 127 |
int | 4 個位元組 | -2147483648 到 2147483647 |
unsigned int | 4 個位元組 | 0 到 4294967295 |
signed int | 4 個位元組 | -2147483648 到 2147483647 |
short int | 2 個位元組 | -32768 到 32767 |
unsigned short int | 2 個位元組 | 0 到 65,535 |
signed short int | 2 個位元組 | -32768 到 32767 |
long int | 8 個位元組 | -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 |
signed long int | 8 個位元組 | -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 |
unsigned long int | 8 個位元組 | 0 到 18,446,744,073,709,551,615 |
float | 4 個位元組 | 精度型佔4個位元組(32位)記憶體空間,+/- 3.4e +/- 38 (~7 個數字) |
double | 8 個位元組 | 雙精度型佔8 個位元組(64位)記憶體空間,+/- 1.7e +/- 308 (~15 個數字) |
long double | 16 個位元組 | 長雙精度型 16 個位元組(128位)記憶體空間,可提供18-19位有效數字。 |
wchar_t | 2 或 4 個位元組 | 1 個寬字元 |
2.2、typedef 宣告
//使用 typedef 為一個已有的型別取一個新的名字
typedef type newname;
//例如
typedef int feet;
//用feet建立了一個整型變數 distance
feet distance;
2.3、列舉型別
enum 列舉名{
識別符號[=整型常數],
識別符號[=整型常數],
...
識別符號[=整型常數]
} 列舉變數;
//例如
enum color { red, green, blue } c;
c = blue;
//預設情況下,第一個名稱的值為 0,第二個名稱的值為 1,第三個名稱的值為 2,
//以此類推。但是,您也可以給名稱賦予一個特殊的值,
//比如
enum color { red, green=5, blue };
3、變數的定義
變數定義就是告訴編譯器在何處建立變數的儲存,以及如何建立變數的儲存。
- 變數的名稱可以由字母、數字和下劃線字元組成。
- 必須以字母或下劃線開頭。
- 大小寫敏感:大寫字母和小寫字母是不同的
int i, j, k;
char c, ch;
float f, salary;
double d;
extern int d = 3, f = 5; // d 和 f 的宣告
int d = 3, f = 5; // 定義並初始化 d 和 f
byte z = 22; // 定義並初始化 z
char x = 'x'; // 變數 x 的值為 'x'
//不帶初始化的定義:帶有靜態儲存持續時間的變數會被隱式初始化為 NULL(所有位元組的值都是 0)
//其他所有變數的初始值是未定義的
//正確地初始化變數是一個良好的程式設計習慣,否則有時候程式可能會產生意想不到的結果
左值與右值
C++ 中有兩種型別的表示式:
- 左值(lvalue):指向記憶體位置的表示式被稱為左值(lvalue)表示式。左值可以出現在賦值號的左邊或右邊。
- 右值(rvalue):術語右值(rvalue)指的是儲存在記憶體中某些地址的數值。右值是不能對其進行賦值的表示式,也就是說,右值可以出現在賦值號的右邊,但不能出現在賦值號的左邊。
4、變數作用域
作用域是程式的一個區域,一般來說有三個地方可以定義變數:
- 在函式或一個程式碼塊內部宣告的變數,稱為區域性變數。
- 在函式引數的定義中宣告的變數,稱為形式引數。
- 在所有函式外部宣告的變數,稱為全域性變數。
5、常量
/*
常量是固定值,在程式執行期間不會改變。這些固定的值,又叫做字面量。
常量可以是任何的基本資料型別,可分為整型數字、浮點數字、字元、字串和布林值。
常量就像是常規的變數,只不過常量的值在定義後不能進行修改。
*/
//例如
212 // 合法的
215u // 合法的
0xFeeL // 合法的
078 // 非法的:8 不是八進位制的數字
032UU // 非法的:不能重複字尾
3.14159 // 合法的
314159E-5L // 合法的
510E // 非法的:不完整的指數
210f // 非法的:沒有小數或指數
.e55 // 非法的:缺少整數或分數
定義常量
- 使用 #define 前處理器。
- 使用 const 關鍵字。
#define LENGTH 10
#define WIDTH 5
#define NEWLINE '\n'
const int LENGTH = 10;
const int WIDTH = 5;
const char NEWLINE = '\n';
6、儲存類
儲存類定義 C++ 程式中變數/函式的範圍(可見性)和生命週期
auto 關鍵字用於兩種情況:宣告變數時根據初始化表示式自動推斷該變數的型別、宣告函式時函式返回值的佔位符。
register 儲存類用於定義儲存在暫存器中而不是 RAM 中的區域性變數。這意味著變數的最大尺寸等於暫存器的大小(通常是一個詞),且不能對它應用一元的 '&' 運算子(因為它沒有記憶體位置)。
static 儲存類指示編譯器在程式的生命週期內保持區域性變數的存在,而不需要在每次它進入和離開作用域時進行建立和銷燬。因此,使用 static 修飾區域性變數可以在函式呼叫之間保持區域性變數的值。static 修飾符也可以應用於全域性變數。當 static 修飾全域性變數時,會使變數的作用域限制在宣告它的檔案內。
extern 儲存類用於提供一個全域性變數的引用,全域性變數對所有的程式檔案都是可見的。當您使用 'extern' 時,對於無法初始化的變數,會把變數名指向一個之前定義過的儲存位置。
thread_local 說明符宣告的變數僅可在它在其上建立的執行緒上訪問。 變數在建立執行緒時建立,並在銷燬執行緒時銷燬。 每個執行緒都有其自己的變數副本。
7、運算子
- 算術運算子(+、-、*、/...........)
- 關係運算符( > 、< 、==、!=.................)
- 邏輯運算子(&&、||、!)
- 位運算子(&、|、^、~、>>、<<)
- 賦值運算子
- 雜項運算子(sizeof、條件運算子、成員運算子、指標運算子)
8、迴圈
點選連結檢視每個型別的細節。
迴圈型別 | 描述 |
---|---|
while 迴圈 | 當給定條件為真時,重複語句或語句組。它會在執行迴圈主體之前測試條件。 |
for 迴圈 | 多次執行一個語句序列,簡化管理迴圈變數的程式碼。 |
do...while 迴圈 | 除了它是在迴圈主體結尾測試條件外,其他與 while 語句類似。 |
巢狀迴圈 | 您可以在 while、for 或 do..while 迴圈內使用一個或多個迴圈。 |
9、迴圈控制語句
點選連結檢視每個型別的細節。
控制語句 | 描述 |
---|---|
break 語句 | 終止 loop 或 switch 語句,程式流將繼續執行緊接著 loop 或 switch 的下一條語句。 |
continue 語句 | 引起迴圈跳過主體的剩餘部分,立即重新開始測試條件。 |
goto 語句 | 將控制轉移到被標記的語句。但是不建議在程式中使用 goto 語句。 |
10、條件判斷語句
點選連結檢視每個型別的細節。
語句 | 描述 |
---|---|
if 語句 | 一個 if 語句 由一個布林表示式後跟一個或多個語句組成。 |
if...else 語句 | 一個 if 語句 後可跟一個可選的 else 語句,else 語句在布林表示式為假時執行。 |
巢狀 if 語句 | 您可以在一個 if 或 else if 語句內使用另一個 if 或 else if 語句。 |
switch 語句 | 一個 switch 語句允許測試一個變數等於多個值時的情況。 |
巢狀 switch 語句 | 您可以在一個 switch 語句內使用另一個 switch 語句。 |
11、定義函式
// 函式返回兩個數中較大的那個數
int max(int num1, int num2) ; //函式宣告
//函式宣告會告訴編譯器函式名稱及如何呼叫函式。函式的實際主體可以單獨定義。
int max(int num1, int num2) //函式定義
{
// 區域性變數宣告
int result;
if (num1 > num2)
result = num1;
else
result = num2;
return result;
}
12、函式傳參
有三種向函式傳遞引數的方式
呼叫型別 | 描述 |
---|---|
傳值呼叫 | 該方法把引數的實際值賦值給函式的形式引數。在這種情況下,修改函式內的形式引數對實際引數沒有影響。 |
指標呼叫 | 該方法把引數的地址賦值給形式引數。在函式內,該地址用於訪問呼叫中要用到的實際引數。這意味著,修改形式引數會影響實際引數。 |
引用呼叫 | 該方法把引數的引用賦值給形式引數。在函式內,該引用用於訪問呼叫中要用到的實際引數。這意味著,修改形式引數會影響實際引數。 |
13、引數預設值
#include <iostream>
using namespace std;
int sum(int a, int b=20)
{
int result;
result = a + b;
return (result);
}
int main ()
{
// 區域性變數宣告
int a = 100;
int b = 200;
int result;
// 呼叫函式來新增值
result = sum(a, b);
cout << "Total value is :" << result << endl;
// 再次呼叫函式
result = sum(a);
cout << "Total value is :" << result << endl;
return 0;
}
14、Lambda 函式與表示式
//例如
[](int x, int y){ return x < y ; }
[](int x, int y) -> int { int z = x + y; return z + x; }
[] // 沒有定義任何變數。使用未定義變數會引發錯誤。
[x, &y] // x以傳值方式傳入(預設),y以引用方式傳入。
[&] // 任何被使用到的外部變數都隱式地以引用方式加以引用。
[=] // 任何被使用到的外部變數都隱式地以傳值方式加以引用。
[&, x] // x顯式地以傳值方式加以引用。其餘變數以引用方式加以引用。
[=, &z] // z顯式地以引用方式加以引用。其餘變數以傳值方式加以引用。
15、陣列
多維陣列 | C++ 支援多維陣列。多維陣列最簡單的形式是二維陣列。 |
---|---|
指向陣列的指標 | 您可以通過指定不帶索引的陣列名稱來生成一個指向陣列中第一個元素的指標。 |
傳遞陣列給函式 | 您可以通過指定不帶索引的陣列名稱來給函式傳遞一個指向陣列的指標。 |
從函式返回陣列 | C++ 允許從函式返回陣列。 |
16、字串
//C 風格字串
//C++ 引入的 string 類型別
//C 風格的字串起源於 C 語言,並在 C++ 中繼續得到支援。
//字串實際上是使用 null 字元 \0 終止的一維字元陣列。
char site[7] = {'R', 'U', 'N', 'O', 'O', 'B', '\0'};
char site[] = "RUNOOB";
string str1 = "runoob";
string str2 = "google";
17、指標
指標是一個變數,其值為另一個變數的地址,即記憶體位置的直接地址。就像其他變數或常量一樣,必須在使用指標儲存其他變數地址之前,對其進行宣告。
概念 | 描述 |
---|---|
C++ Null 指標 | C++ 支援空指標。NULL 指標是一個定義在標準庫中的值為零的常量。 |
C++ 指標的算術運算 | 可以對指標進行四種算術運算:++、--、+、- |
C++ 指標 vs 陣列 | 指標和陣列之間有著密切的關係。 |
C++ 指標陣列 | 可以定義用來儲存指標的陣列。 |
C++ 指向指標的指標 | C++ 允許指向指標的指標。 |
C++ 傳遞指標給函式 | 通過引用或地址傳遞引數,使傳遞的引數在呼叫函式中被改變。 |
C++ 從函式返回指標 | C++ 允許函式返回指標到區域性變數、靜態變數和動態記憶體分配。 |
18、引用
引用變數是一個別名,也就是說,它是某個已存在變數的另一個名字。一旦把引用初始化為某個變數,就可以使用該引用名稱或變數名稱來指向變數。
引用很容易與指標混淆,它們之間有三個主要的不同:
- 不存在空引用。引用必須連線到一塊合法的記憶體。
- 一旦引用被初始化為一個物件,就不能被指向到另一個物件。指標可以在任何時候指向到另一個物件。
- 引用必須在建立時被初始化。指標可以在任何時間被初始化。
#include <iostream>
using namespace std;
int main ()
{
// 宣告簡單的變數
int i;
double d;
// 宣告引用變數
int& r = i;
double& s = d;
i = 5;
cout << "Value of i : " << i << endl;
cout << "Value of i reference : " << r << endl;
d = 11.7;
cout << "Value of d : " << d << endl;
cout << "Value of d reference : " << s << endl;
return 0;
}
/**
Value of i : 5
Value of i reference : 5
Value of d : 11.7
Value of d reference : 11.7
*/
概念 | 描述 |
---|---|
把引用作為引數 | C++ 支援把引用作為引數傳給函式,這比傳一般的引數更安全。 |
把引用作為返回值 | 可以從 C++ 函式中返回引用,就像返回其他資料型別一樣。 |
19、資料結構
#include <iostream>
#include <cstring>
using namespace std;
// 宣告一個結構體型別 Books
struct Books
{
char title[50];
char author[50];
char subject[100];
int book_id;
};
int main( )
{
Books Book1; // 定義結構體型別 Books 的變數 Book1
// Book1 詳述
strcpy( Book1.title, "C++ 教程");
strcpy( Book1.author, "Runoob");
strcpy( Book1.subject, "程式語言");
Book1.book_id = 12345;
// 輸出 Book1 資訊
cout << "第一本書標題 : " << Book1.title <<endl;
cout << "第一本書作者 : " << Book1.author <<endl;
cout << "第一本書類目 : " << Book1.subject <<endl;
cout << "第一本書 ID : " << Book1.book_id <<endl;
return 0;
}
//----------------------------------------------------
//typedef 關鍵字為建立的型別取一個"別名"
typedef struct Books
{
char title[50];
char author[50];
char subject[100];
int book_id;
}Books;
Books Book1, Book2;