C++学习笔记 简单部分
C++?數(shù)據(jù)類型
- 使用變量來存儲各種信息,變量保留的是它所存儲的值的內(nèi)存位置。這意味著,當創(chuàng)建一個變量時,就會在內(nèi)存中保留一些空間。這段內(nèi)存空間可以用于存儲各種數(shù)據(jù)類型(比如字符型、寬字符型、整型、浮點型、雙浮點型、布爾型等)的信息,操作系統(tǒng)會根據(jù)變量的數(shù)據(jù)類型,來分配內(nèi)存和決定在保留內(nèi)存中存儲什么。
- typedef short int wchar_t;因此?wchar_t 實際上的空間是和 short int 一樣。?
-
一些基本類型可以使用一個或多個類型修飾符進行修飾:
- signed
- unsigned
- short
- long
typedef 聲明
- 您可以使用?typedef?為一個已有的類型取一個新的名字。下面是使用 typedef 定義一個新類型的語法:
- typedef type newname;
- typedef int feed;給int給一個別名,feed
枚舉類型
- 枚舉類型(enumeration)是C++中的一種派生數(shù)據(jù)類型,它是由用戶定義的若干枚舉常量的集合。
- 如果一個變量只有幾種可能的值,可以定義為枚舉(enumeration)類型。所謂"枚舉"是指將變量的值一一列舉出來,變量的值只能在列舉出來的值的范圍內(nèi)。創(chuàng)建枚舉,需要使用關鍵字?enum。枚舉類型的一般形式為:
- 如果枚舉沒有初始化, 即省掉"=整型常數(shù)"時, 則從第一個標識符開始。例如,下面的代碼定義了一個顏色枚舉,變量 c 的類型為 color。最后,c 被賦值為 "blue"。
- ?默認情況下,第一個名稱的值為 0,第二個名稱的值為 1,第三個名稱的值為 2,以此類推。但是,您也可以給名稱賦予一個特殊的值,只需要添加一個初始值即可。例如,在下面的枚舉中,green?的值為 5。
- 在這里,blue?的值為 6,因為默認情況下,每個名稱都會比它前面一個名稱大 1,但 red 的值依然為 0。
C++變量的類型
Extern?
- 當使用多個文件且只在其中一個文件中定義變量時(定義變量的文件在程序連接時是可用的),變量聲明就顯得非常有用。可以使用?extern?關鍵字在任何地方聲明一個變量。雖然可以在 C++ 程序中多次聲明一個變量,但變量只能在某個文件、函數(shù)或代碼塊中被定義一次。?
C++ 中的左值(Lvalues)和右值(Rvalues)
C++ 中有兩種類型的表達式:
- 左值(lvalue):指向內(nèi)存位置的表達式被稱為左值(lvalue)表達式。左值可以出現(xiàn)在賦值號的左邊或右邊。
- 右值(rvalue):術語右值(rvalue)指的是存儲在內(nèi)存中某些地址的數(shù)值。右值是不能對其進行賦值的表達式,也就是說,右值可以出現(xiàn)在賦值號的右邊,但不能出現(xiàn)在賦值號的左邊。
變量是左值,因此可以出現(xiàn)在賦值號的左邊。數(shù)值型的字面值是右值,因此不能被賦值,不能出現(xiàn)在賦值號的左邊。下面是一個有效的語句:int g = 20;
C++?變量作用域
作用域是程序的一個區(qū)域,一般來說有三個地方可以定義變量:
- 在函數(shù)或一個代碼塊內(nèi)部聲明的變量,稱為局部變量。
- 在函數(shù)參數(shù)的定義中聲明的變量,稱為形式參數(shù)。
- 在所有函數(shù)外部聲明的變量,稱為全局變量。
初始化局部變量和全局變量
- 當局部變量被定義時,系統(tǒng)不會對其初始化,必須自行對其初始化。定義全局變量時,系統(tǒng)會自動初始化為下列值:
?整數(shù)變量
- 整數(shù)常量也可以帶一個后綴,后綴是 U 和 L 的組合,U 表示無符號整數(shù)(unsigned),L 表示長整數(shù)(long)。后綴可以是大寫,也可以是小寫,U 和 L 的順序任意。?
字符常量
- 字符常量是括在單引號中。如果常量以 L(僅當大寫時)開頭,則表示它是一個寬字符常量(例如 L'x'),此時它必須存儲在?wchar_t?類型的變量中。否則,它就是一個窄字符常量(例如 'x'),此時它可以存儲在?char?類型的簡單變量中。
- 字符常量可以是一個普通的字符(例如 'x')、一個轉(zhuǎn)義序列(例如 '\t'),或一個通用的字符(例如 '\u02C0')。
- 在 C++ 中,有一些特定的字符,當它們前面有反斜杠時,它們就具有特殊的含義,被用來表示如換行符(\n)或制表符(\t)等。下表列出了一些這樣的轉(zhuǎn)義序列碼:
定義常量
在 C++ 中,有兩種簡單的定義常量的方式:
- 使用?#define?預處理器。
- 使用?const?關鍵字。
C++ 中的類型限定符
類型限定符提供了變量的額外信息。?
C++?存儲類
- auto
- register
- static
- extern
- mutable
- thread_local (C++11)
auto 存儲類
- 自 C++ 11 以來,auto?關鍵字用于兩種情況:聲明變量時根據(jù)初始化表達式自動推斷該變量的類型、聲明函數(shù)時函數(shù)返回值的占位符。C++98標準中auto關鍵字用于自動變量的聲明,但由于使用極少且多余,在C++11中已刪除這一用法。
- 根據(jù)初始化表達式自動推斷被聲明的變量的類型,如:
register 存儲類
- register?存儲類用于定義存儲在寄存器中而不是 RAM 中的局部變量。這意味著變量的最大尺寸等于寄存器的大小(通常是一個詞),且不能對它應用一元的 '&' 運算符(因為它沒有內(nèi)存位置)。
- 寄存器只用于需要快速訪問的變量,比如計數(shù)器。還應注意的是,定義 'register' 并不意味著變量將被存儲在寄存器中,它意味著變量可能存儲在寄存器中,這取決于硬件和實現(xiàn)的限制。
static 存儲類
- static?存儲類指示編譯器在程序的生命周期內(nèi)保持局部變量的存在,而不需要在每次它進入和離開作用域時進行創(chuàng)建和銷毀。因此,使用 static 修飾局部變量可以在函數(shù)調(diào)用之間保持局部變量的值。
- static 修飾符也可以應用于全局變量。當 static 修飾全局變量時,會使變量的作用域限制在聲明它的文件內(nèi)。
- 在 C++ 中,當 static 用在類數(shù)據(jù)成員上時,會導致僅有一個該成員的副本被類的所有對象共享。
extern 存儲類
- extern?存儲類用于提供一個全局變量的引用,全局變量對所有的程序文件都是可見的。當您使用 'extern' 時,對于無法初始化的變量,會把變量名指向一個之前定義過的存儲位置。
- 當您有多個文件且定義了一個可以在其他文件中使用的全局變量或函數(shù)時,可以在其他文件中使用?extern?來得到已定義的變量或函數(shù)的引用。可以這么理解,extern?是用來在另一個文件中聲明一個全局變量或函數(shù)。
- extern 修飾符通常用于當有兩個或多個文件共享相同的全局變量或函數(shù)的時候
mutable 存儲類
- mutable?說明符僅適用于類的對象,這將在本教程的最后進行講解。它允許對象的成員替代常量。也就是說,mutable 成員可以通過 const 成員函數(shù)修改。
thread_local 存儲類
- 使用 thread_local 說明符聲明的變量僅可在它在其上創(chuàng)建的線程上訪問。 變量在創(chuàng)建線程時創(chuàng)建,并在銷毀線程時銷毀。 每個線程都有其自己的變量副本。
- thread_local 說明符可以與 static 或 extern 合并。
- 可以將 thread_local 僅應用于數(shù)據(jù)聲明和定義,thread_local 不能用于函數(shù)聲明或定義。
- 以下演示了可以被聲明為 thread_local 的變量:
C++?運算符
運算符是一種告訴編譯器執(zhí)行特定的數(shù)學或邏輯操作的符號。C++ 內(nèi)置了豐富的運算符,并提供了以下類型的運算符:
- 算術運算符
- 關系運算符
- 邏輯運算符
- 位運算符
- 賦值運算符
- 雜項運算符
C++ 教程
C++ 教程C++ 簡介C++ 環(huán)境設置C++ 基本語法C++ 注釋C++ 數(shù)據(jù)類型C++ 變量類型C++ 變量作用域C++ 常量C++ 修飾符類型C++ 存儲類C++ 運算符C++ 循環(huán)C++ 判斷C++ 函數(shù)C++ 數(shù)字C++ 數(shù)組C++ 字符串C++ 指針C++ 引用C++ 日期 & 時間C++ 基本的輸入輸出C++ 數(shù)據(jù)結(jié)構
C++?面向?qū)ο?/h2>
C++ 類 & 對象C++ 繼承C++ 重載運算符和重載函數(shù)C++ 多態(tài)C++ 數(shù)據(jù)抽象C++ 數(shù)據(jù)封裝C++ 接口(抽象類)
C++?高級教程
C++ 文件和流C++ 異常處理C++ 動態(tài)內(nèi)存C++ 命名空間C++ 模板C++ 預處理器C++ 信號處理C++ 多線程C++ Web 編程
C++?資源庫
C++ STL 教程C++ 標準庫C++ 有用的資源C++ 實例
?C++ 存儲類
C++ 循環(huán)?
C++?運算符
運算符是一種告訴編譯器執(zhí)行特定的數(shù)學或邏輯操作的符號。C++ 內(nèi)置了豐富的運算符,并提供了以下類型的運算符:
- 算術運算符
- 關系運算符
- 邏輯運算符
- 位運算符
- 賦值運算符
- 雜項運算符
本章將逐一介紹算術運算符、關系運算符、邏輯運算符、位運算符、賦值運算符和其他運算符。
算術運算符
下表顯示了 C++ 支持的算術運算符。
假設變量 A 的值為 10,變量 B 的值為 20,則:
| + | 把兩個操作數(shù)相加 | A + B 將得到 30 |
| - | 從第一個操作數(shù)中減去第二個操作數(shù) | A - B 將得到 -10 |
| * | 把兩個操作數(shù)相乘 | A * B 將得到 200 |
| / | 分子除以分母 | B / A 將得到 2 |
| % | 取模運算符,整除后的余數(shù) | B % A 將得到 0 |
| ++ | 自增運算符,整數(shù)值增加 1 | A++ 將得到 11 |
| -- | 自減運算符,整數(shù)值減少 1 | A-- 將得到 9 |
實例
請看下面的實例,了解 C++ 中可用的算術運算符。
復制并粘貼下面的 C++ 程序到 test.cpp 文件中,編譯并運行程序。
實例
#include <iostream> using namespace std; int main() { int a = 21; int b = 10; int c; c = a + b; cout << "Line 1 - c 的值是 " << c << endl ; c = a - b; cout << "Line 2 - c 的值是 " << c << endl ; c = a * b; cout << "Line 3 - c 的值是 " << c << endl ; c = a / b; cout << "Line 4 - c 的值是 " << c << endl ; c = a % b; cout << "Line 5 - c 的值是 " << c << endl ; int d = 10; // 測試自增、自減 c = d++; cout << "Line 6 - c 的值是 " << c << endl ; d = 10; // 重新賦值 c = d--; cout << "Line 7 - c 的值是 " << c << endl ; return 0; }
當上面的代碼被編譯和執(zhí)行時,它會產(chǎn)生以下結(jié)果:
Line 1 - c 的值是 31 Line 2 - c 的值是 11 Line 3 - c 的值是 210 Line 4 - c 的值是 2 Line 5 - c 的值是 1 Line 6 - c 的值是 10 Line 7 - c 的值是 10關系運算符
下表顯示了 C++ 支持的關系運算符。
假設變量 A 的值為 10,變量 B 的值為 20,則:
| == | 檢查兩個操作數(shù)的值是否相等,如果相等則條件為真。 | (A == B) 不為真。 |
| != | 檢查兩個操作數(shù)的值是否相等,如果不相等則條件為真。 | (A != B) 為真。 |
| > | 檢查左操作數(shù)的值是否大于右操作數(shù)的值,如果是則條件為真。 | (A > B) 不為真。 |
| < | 檢查左操作數(shù)的值是否小于右操作數(shù)的值,如果是則條件為真。 | (A < B) 為真。 |
| >= | 檢查左操作數(shù)的值是否大于或等于右操作數(shù)的值,如果是則條件為真。 | (A >= B) 不為真。 |
| <= | 檢查左操作數(shù)的值是否小于或等于右操作數(shù)的值,如果是則條件為真。 | (A <= B) 為真。 |
實例
請看下面的實例,了解 C++ 中可用的關系運算符。
復制并黏貼下面的 C++ 程序到 test.cpp 文件中,編譯并運行程序。
實例
#include <iostream> using namespace std; int main() { int a = 21; int b = 10; int c ; if( a == b ) { cout << "Line 1 - a 等于 b" << endl ; } else { cout << "Line 1 - a 不等于 b" << endl ; } if ( a < b ) { cout << "Line 2 - a 小于 b" << endl ; } else { cout << "Line 2 - a 不小于 b" << endl ; } if ( a > b ) { cout << "Line 3 - a 大于 b" << endl ; } else { cout << "Line 3 - a 不大于 b" << endl ; } /* 改變 a 和 b 的值 */ a = 5; b = 20; if ( a <= b ) { cout << "Line 4 - a 小于或等于 b" << endl ; } if ( b >= a ) { cout << "Line 5 - b 大于或等于 a" << endl ; } return 0; }
當上面的代碼被編譯和執(zhí)行時,它會產(chǎn)生以下結(jié)果:
Line 1 - a 不等于 b Line 2 - a 不小于 b Line 3 - a 大于 b Line 4 - a 小于或等于 b Line 5 - b 大于或等于 a邏輯運算符
下表顯示了 C++ 支持的關系邏輯運算符。
假設變量 A 的值為 1,變量 B 的值為 0,則:
| && | 稱為邏輯與運算符。如果兩個操作數(shù)都非零,則條件為真。 | (A && B) 為假。 |
| || | 稱為邏輯或運算符。如果兩個操作數(shù)中有任意一個非零,則條件為真。 | (A || B) 為真。 |
| ! | 稱為邏輯非運算符。用來逆轉(zhuǎn)操作數(shù)的邏輯狀態(tài)。如果條件為真則邏輯非運算符將使其為假。 | !(A && B) 為真。 |
實例
請看下面的實例,了解 C++ 中可用的邏輯運算符。
復制并黏貼下面的 C++ 程序到 test.cpp 文件中,編譯并運行程序。
實例
#include <iostream> using namespace std; int main() { int a = 5; int b = 20; int c ; if ( a && b ) { cout << "Line 1 - 條件為真"<< endl ; } if ( a || b ) { cout << "Line 2 - 條件為真"<< endl ; } /* 改變 a 和 b 的值 */ a = 0; b = 10; if ( a && b ) { cout << "Line 3 - 條件為真"<< endl ; } else { cout << "Line 4 - 條件不為真"<< endl ; } if ( !(a && b) ) { cout << "Line 5 - 條件為真"<< endl ; } return 0; }
當上面的代碼被編譯和執(zhí)行時,它會產(chǎn)生以下結(jié)果:
Line 1 - 條件為真 Line 2 - 條件為真 Line 4 - 條件不為真 Line 5 - 條件為真位運算符
位運算符作用于位,并逐位執(zhí)行操作。&、 | 和 ^ 的真值表如下所示:
| 0 | 0 | 0 | 0 | 0 |
| 0 | 1 | 0 | 1 | 1 |
| 1 | 1 | 1 | 1 | 0 |
| 1 | 0 | 0 | 1 | 1 |
假設如果 A = 60,且 B = 13,現(xiàn)在以二進制格式表示,它們?nèi)缦滤?#xff1a;
A = 0011 1100
B = 0000 1101
-----------------
A&B = 0000 1100
A|B = 0011 1101
A^B = 0011 0001
~A? = 1100 0011
下表顯示了 C++ 支持的位運算符。假設變量 A 的值為 60,變量 B 的值為 13,則:
| & | 如果同時存在于兩個操作數(shù)中,二進制 AND 運算符復制一位到結(jié)果中。 | (A & B) 將得到 12,即為 0000 1100 |
| | | 如果存在于任一操作數(shù)中,二進制 OR 運算符復制一位到結(jié)果中。 | (A | B) 將得到 61,即為 0011 1101 |
| ^ | 如果存在于其中一個操作數(shù)中但不同時存在于兩個操作數(shù)中,二進制異或運算符復制一位到結(jié)果中。 | (A ^ B) 將得到 49,即為 0011 0001 |
| ~ | 二進制補碼運算符是一元運算符,具有"翻轉(zhuǎn)"位效果,即0變成1,1變成0。 | (~A ) 將得到 -61,即為 1100 0011,一個有符號二進制數(shù)的補碼形式。 |
| << | 二進制左移運算符。左操作數(shù)的值向左移動右操作數(shù)指定的位數(shù)。 | A << 2 將得到 240,即為 1111 0000 |
| >> | 二進制右移運算符。左操作數(shù)的值向右移動右操作數(shù)指定的位數(shù)。 | A >> 2 將得到 15,即為 0000 1111 |
實例
請看下面的實例,了解 C++ 中可用的位運算符。
復制并黏貼下面的 C++ 程序到 test.cpp 文件中,編譯并運行程序。
實例
#include <iostream> using namespace std; int main() { unsigned int a = 60; // 60 = 0011 1100 unsigned int b = 13; // 13 = 0000 1101 int c = 0; c = a & b; // 12 = 0000 1100 cout << "Line 1 - c 的值是 " << c << endl ; c = a | b; // 61 = 0011 1101 cout << "Line 2 - c 的值是 " << c << endl ; c = a ^ b; // 49 = 0011 0001 cout << "Line 3 - c 的值是 " << c << endl ; c = ~a; // -61 = 1100 0011 cout << "Line 4 - c 的值是 " << c << endl ; c = a << 2; // 240 = 1111 0000 cout << "Line 5 - c 的值是 " << c << endl ; c = a >> 2; // 15 = 0000 1111 cout << "Line 6 - c 的值是 " << c << endl ; return 0; }
當上面的代碼被編譯和執(zhí)行時,它會產(chǎn)生以下結(jié)果:
Line 1 - c 的值是 12 Line 2 - c 的值是 61 Line 3 - c 的值是 49 Line 4 - c 的值是 -61 Line 5 - c 的值是 240 Line 6 - c 的值是 15賦值運算符
下表列出了 C++ 支持的賦值運算符:
| = | 簡單的賦值運算符,把右邊操作數(shù)的值賦給左邊操作數(shù) | C = A + B 將把 A + B 的值賦給 C |
| += | 加且賦值運算符,把右邊操作數(shù)加上左邊操作數(shù)的結(jié)果賦值給左邊操作數(shù) | C += A 相當于 C = C + A |
| -= | 減且賦值運算符,把左邊操作數(shù)減去右邊操作數(shù)的結(jié)果賦值給左邊操作數(shù) | C -= A 相當于 C = C - A |
| *= | 乘且賦值運算符,把右邊操作數(shù)乘以左邊操作數(shù)的結(jié)果賦值給左邊操作數(shù) | C *= A 相當于 C = C * A |
| /= | 除且賦值運算符,把左邊操作數(shù)除以右邊操作數(shù)的結(jié)果賦值給左邊操作數(shù) | C /= A 相當于 C = C / A |
| %= | 求模且賦值運算符,求兩個操作數(shù)的模賦值給左邊操作數(shù) | C %= A 相當于 C = C % A |
| <<= | 左移且賦值運算符 | C <<= 2 等同于 C = C << 2 |
| >>= | 右移且賦值運算符 | C >>= 2 等同于 C = C >> 2 |
| &= | 按位與且賦值運算符 | C &= 2 等同于 C = C & 2 |
| ^= | 按位異或且賦值運算符 | C ^= 2 等同于 C = C ^ 2 |
| |= | 按位或且賦值運算符 | C |= 2 等同于 C = C | 2 |
實例
請看下面的實例,了解 C++ 中可用的賦值運算符。
復制并黏貼下面的 C++ 程序到 test.cpp 文件中,編譯并運行程序。
實例
#include <iostream> using namespace std; int main() { int a = 21; int c ; c = a; cout << "Line 1 - = 運算符實例,c 的值 = : " <<c<< endl ; c += a; cout << "Line 2 - += 運算符實例,c 的值 = : " <<c<< endl ; c -= a; cout << "Line 3 - -= 運算符實例,c 的值 = : " <<c<< endl ; c *= a; cout << "Line 4 - *= 運算符實例,c 的值 = : " <<c<< endl ; c /= a; cout << "Line 5 - /= 運算符實例,c 的值 = : " <<c<< endl ; c = 200; c %= a; cout << "Line 6 - %= 運算符實例,c 的值 = : " <<c<< endl ; c <<= 2; cout << "Line 7 - <<= 運算符實例,c 的值 = : " <<c<< endl ; c >>= 2; cout << "Line 8 - >>= 運算符實例,c 的值 = : " <<c<< endl ; c &= 2; cout << "Line 9 - &= 運算符實例,c 的值 = : " <<c<< endl ; c ^= 2; cout << "Line 10 - ^= 運算符實例,c 的值 = : " <<c<< endl ; c |= 2; cout << "Line 11 - |= 運算符實例,c 的值 = : " <<c<< endl ; return 0; }
當上面的代碼被編譯和執(zhí)行時,它會產(chǎn)生以下結(jié)果:
Line 1 - = 運算符實例,c 的值 = 21 Line 2 - += 運算符實例,c 的值 = 42 Line 3 - -= 運算符實例,c 的值 = 21 Line 4 - *= 運算符實例,c 的值 = 441 Line 5 - /= 運算符實例,c 的值 = 21 Line 6 - %= 運算符實例,c 的值 = 11 Line 7 - <<= 運算符實例,c 的值 = 44 Line 8 - >>= 運算符實例,c 的值 = 11 Line 9 - &= 運算符實例,c 的值 = 2 Line 10 - ^= 運算符實例,c 的值 = 0 Line 11 - |= 運算符實例,c 的值 = 2雜項運算符
下表列出了 C++ 支持的其他一些重要的運算符。
| sizeof | sizeof 運算符返回變量的大小。例如,sizeof(a) 將返回 4,其中 a 是整數(shù)。 |
| Condition ? X : Y | 條件運算符。如果 Condition 為真 ? 則值為 X : 否則值為 Y。 |
| , | 逗號運算符會順序執(zhí)行一系列運算。整個逗號表達式的值是以逗號分隔的列表中的最后一個表達式的值。 |
| .(點)和 ->(箭頭) | 成員運算符用于引用類、結(jié)構和共用體的成員。 |
| Cast | 強制轉(zhuǎn)換運算符把一種數(shù)據(jù)類型轉(zhuǎn)換為另一種數(shù)據(jù)類型。例如,int(2.2000) 將返回 2。 |
| & | 指針運算符 &?返回變量的地址。例如 &a; 將給出變量的實際地址。 |
| * | 指針運算符 *?指向一個變量。例如,*var; 將指向變量 var。 |
- sizeof(data type);
- Exp1?Exp2:Exp3;
- 表達式1,表達式2? ?先求解表達式 1,再求解表達式 2。整個逗號表達式的值是表達式 2 的值。最右邊的那個表達式的值將作為整個逗號表達式的值,其他表達式的值會被丟棄。
-
.(點)運算符和 ->(箭頭)運算符用于引用類、結(jié)構和共用體的成員。點運算符應用于實際的對象。箭頭運算符與一個指向?qū)ο蟮闹羔樢黄鹗褂谩?/p>
(.)點運算符
下面的代碼把值 "zara" 賦給對象 emp 的?first_name?成員:
strcpy(emp.first_name, "zara");(->)箭頭運算符
如果 p_emp 是一個指針,指向類型為 Employee 的對象,則要把值 "zara" 賦給對象 emp 的?first_name?成員,需要編寫如下代碼:
strcpy(p_emp->first_name, "zara");-> 稱為箭頭運算符,它是由一個減號加上一個大于號組成。
簡而言之,訪問結(jié)構的成員時使用點運算符,而通過指針訪問結(jié)構的成員時,則使用箭頭運算符。
強制類型轉(zhuǎn)換負號
-
const_cast<type> (expr):?const_cast 運算符用于修改類型的 const / volatile 屬性。除了 const 或 volatile 屬性之外,目標類型必須與源類型相同。這種類型的轉(zhuǎn)換主要是用來操作所傳對象的 const 屬性,可以加上 const 屬性,也可以去掉 const 屬性。
-
dynamic_cast<type> (expr):?dynamic_cast 在運行時執(zhí)行轉(zhuǎn)換,驗證轉(zhuǎn)換的有效性。如果轉(zhuǎn)換未執(zhí)行,則轉(zhuǎn)換失敗,表達式 expr 被判定為 null。dynamic_cast 執(zhí)行動態(tài)轉(zhuǎn)換時,type 必須是類的指針、類的引用或者 void*,如果 type 是類指針類型,那么 expr 也必須是一個指針,如果 type 是一個引用,那個 expr 也必須是一個引用。
-
reinterpret_cast<type> (expr):?reinterpret_cast 運算符把某種指針改為其他類型的指針。它可以把一個指針轉(zhuǎn)換為一個整數(shù),也可以把一個整數(shù)轉(zhuǎn)換為一個指針。
-
static_cast<type> (expr):?static_cast 運算符執(zhí)行非動態(tài)轉(zhuǎn)換,沒有運行時類檢查來保證轉(zhuǎn)換的安全性。例如,它可以用來把一個基類指針轉(zhuǎn)換為派生類指針。
取地址運算符號
- C++ 提供了兩種指針運算符,一種是取地址運算符 &,一種是間接尋址運算符 *。?
- 指針是一個包含了另一個變量地址的變量,可以把一個包含了另一個變量地址的變量說成是"指向"另一個變量。變量可以是任意的數(shù)據(jù)類型,包括對象、結(jié)構或者指針。
-
取地址運算符 &
& 是一元運算符,返回操作數(shù)的內(nèi)存地址。例如,如果 var 是一個整型變量,則 &var 是它的地址。該運算符與其他一元運算符具有相同的優(yōu)先級,在運算時它是從右向左順序進行的。
您可以把 & 運算符讀作"取地址運算符",這意味著,&var?讀作"var 的地址"。
間接尋址運算符 *
第二個運算符是間接尋址運算符 *,它是 & 運算符的補充。* 是一元運算符,返回操作數(shù)所指定地址的變量的值。
請看下面的實例,理解這兩種運算符的用法。
- #include <iostream>using namespace std;int main ()
{int var;int *ptr;int val;var = 3000;// 獲取 var 的地址ptr = &var;// 獲取 ptr 的值val = *ptr;cout << "Value of var :" << var << endl;cout << "Value of ptr :" << ptr << endl;cout << "Value of val :" << val << endl;return 0;
}
//Value of var :3000
//Value of ptr :0xbff64494
//Value of val :3000
?
C++ 中的運算符優(yōu)先級
| 后綴? | () [] -> . ++ - - ? | 從左到右? |
| 一元? | + - ! ~ ++ - - (type)* & sizeof? | 從右到左? |
| 乘除? | * / %? | 從左到右? |
| 加減? | + -? | 從左到右? |
| 移位? | << >>? | 從左到右? |
| 關系? | < <= > >=? | 從左到右? |
| 相等? | == !=? | 從左到右? |
| 位與 AND? | &? | 從左到右? |
| 位異或 XOR? | ^? | 從左到右? |
| 位或 OR? | |? | 從左到右? |
| 邏輯與 AND? | &&? | 從左到右? |
| 邏輯或 OR? | ||? | 從左到右? |
| 條件? | ?:? | 從右到左? |
| 賦值? | = += -= *= /= %=>>= <<= &= ^= |=? | 從右到左? |
| 逗號? | ,? | 從左到右? |
循環(huán)
| while 循環(huán) | 當給定條件為真時,重復語句或語句組。它會在執(zhí)行循環(huán)主體之前測試條件。 |
| for 循環(huán) | 多次執(zhí)行一個語句序列,簡化管理循環(huán)變量的代碼。 |
| do...while 循環(huán) | 除了它是在循環(huán)主體結(jié)尾測試條件外,其他與 while 語句類似。 |
| 嵌套循環(huán) | 您可以在 while、for 或 do..while 循環(huán)內(nèi)使用一個或多個循環(huán)。 |
循環(huán)控制語句
| break 語句 | 終止?loop?或?switch?語句,程序流將繼續(xù)執(zhí)行緊接著 loop 或 switch 的下一條語句。 |
| continue 語句 | 引起循環(huán)跳過主體的剩余部分,立即重新開始測試條件。 |
| goto 語句 | 將控制轉(zhuǎn)移到被標記的語句。但是不建議在程序中使用 goto 語句。 |
判斷語句
| if 語句 | 一個?if 語句?由一個布爾表達式后跟一個或多個語句組成。 |
| if...else 語句 | 一個?if 語句?后可跟一個可選的?else 語句,else 語句在布爾表達式為假時執(zhí)行。 |
| 嵌套 if 語句 | 您可以在一個?if?或?else if?語句內(nèi)使用另一個?if?或?else if?語句。 |
| switch 語句 | 一個?switch?語句允許測試一個變量等于多個值時的情況。 |
| 嵌套 switch 語句 | 您可以在一個?switch?語句內(nèi)使用另一個?switch?語句。 |
函數(shù)的參數(shù)
| 傳值調(diào)用 | 該方法把參數(shù)的實際值賦值給函數(shù)的形式參數(shù)。在這種情況下,修改函數(shù)內(nèi)的形式參數(shù)對實際參數(shù)沒有影響。 |
| 指針調(diào)用 | 該方法把參數(shù)的地址賦值給形式參數(shù)。在函數(shù)內(nèi),該地址用于訪問調(diào)用中要用到的實際參數(shù)。這意味著,修改形式參數(shù)會影響實際參數(shù)。 |
| 引用調(diào)用 | 該方法把參數(shù)的引用賦值給形式參數(shù)。在函數(shù)內(nèi),該引用用于訪問調(diào)用中要用到的實際參數(shù)。這意味著,修改形式參數(shù)會影響實際參數(shù)。 |
Lambda 函數(shù)與表達式
- C++11 提供了對匿名函數(shù)的支持,稱為 Lambda 函數(shù)(也叫 Lambda 表達式)。
- Lambda 表達式把函數(shù)看作對象。Lambda 表達式可以像對象一樣使用,比如可以將它們賦給變量和作為參數(shù)傳遞,還可以像函數(shù)一樣對其求值。
- Lambda 表達式本質(zhì)上與函數(shù)聲明非常類似。Lambda 表達式具體形式如下
- 如果沒有返回值,可以表示為:
在一個更為復雜的例子中,返回類型可以被明確的指定如下:
[](int x, int y) -> int { int z = x + y; return z + x; }- 本例中,一個臨時的參數(shù) z 被創(chuàng)建用來存儲中間結(jié)果。如同一般的函數(shù),z 的值不會保留到下一次該不具名函數(shù)再次被調(diào)用時。如果 lambda 函數(shù)沒有傳回值(例如 void),其返回類型可被完全忽略。在Lambda表達式內(nèi)可以訪問當前作用域的變量,這是Lambda表達式的閉包(Closure)行為。 與JavaScript閉包不同,C++變量傳遞有傳值和傳引用的區(qū)別。可以通過前面的[]來指定:
- 另外有一點需要注意。對于[=]或[&]的形式,lambda 表達式可以直接使用 this 指針。但是,對于[]的形式,如果要使用 this 指針,必須顯式傳入:
C++ 隨機數(shù)
- 在許多情況下,需要生成隨機數(shù)。關于隨機數(shù)生成器,有兩個相關的函數(shù)。一個是?rand(),該函數(shù)只返回一個偽隨機數(shù)。生成隨機數(shù)之前必須先調(diào)用?srand()?函數(shù)。
- 下面是一個關于生成隨機數(shù)的簡單實例。實例中使用了?time()?函數(shù)來獲取系統(tǒng)時間的秒數(shù),通過調(diào)用 rand() 函數(shù)來生成隨機數(shù):
C++數(shù)組詳解
| 多維數(shù)組 | C++ 支持多維數(shù)組。多維數(shù)組最簡單的形式是二維數(shù)組。 |
| 指向數(shù)組的指針 | 您可以通過指定不帶索引的數(shù)組名稱來生成一個指向數(shù)組中第一個元素的指針。 |
| 傳遞數(shù)組給函數(shù) | 您可以通過指定不帶索引的數(shù)組名稱來給函數(shù)傳遞一個指向數(shù)組的指針。 |
| 從函數(shù)返回數(shù)組 | C++ 允許從函數(shù)返回數(shù)組。 |
C++?傳遞數(shù)組給函數(shù)
方式 1
形式參數(shù)是一個指針:
void myFunction(int *param) { . . . }方式 2
形式參數(shù)是一個已定義大小的數(shù)組:
void myFunction(int param[10]) { . . . }方式 3
形式參數(shù)是一個未定義大小的數(shù)組:
void myFunction(int param[]) { . . . }C++?從函數(shù)返回數(shù)組
- C++ 不允許返回一個完整的數(shù)組作為函數(shù)的參數(shù)。但是,可以通過指定不帶索引的數(shù)組名來返回一個指向數(shù)組的指針。如果想要從函數(shù)返回一個一維數(shù)組,必須聲明一個返回指針的函數(shù),如下:
- int * myFunction() { . . . }
- 另外,C++ 不支持在函數(shù)外返回局部變量的地址,除非定義局部變量為?static?變量。
C++?字符串
| 1 | strcpy(s1, s2); 復制字符串 s2 到字符串 s1。 |
| 2 | strcat(s1, s2); 連接字符串 s2 到字符串 s1 的末尾。 |
| 3 | strlen(s1); 返回字符串 s1 的長度。 |
| 4 | strcmp(s1, s2); 如果 s1 和 s2 是相同的,則返回 0;如果 s1<s2 則返回值小于 0;如果 s1>s2 則返回值大于 0。 |
| 5 | strchr(s1, ch); 返回一個指針,指向字符串 s1 中字符 ch 的第一次出現(xiàn)的位置。 |
| 6 | strstr(s1, s2); 返回一個指針,指向字符串 s1 中字符串 s2 的第一次出現(xiàn)的位置。 |
C++中使用指針
| C++ Null 指針 | C++ 支持空指針。NULL 指針是一個定義在標準庫中的值為零的常量。 |
| C++ 指針的算術運算 | 可以對指針進行四種算術運算:++、--、+、- |
| C++ 指針 vs 數(shù)組 | 指針和數(shù)組之間有著密切的關系。 |
| C++ 指針數(shù)組 | 可以定義用來存儲指針的數(shù)組。 |
| C++ 指向指針的指針 | C++ 允許指向指針的指針。 |
| C++ 傳遞指針給函數(shù) | 通過引用或地址傳遞參數(shù),使傳遞的參數(shù)在調(diào)用函數(shù)中被改變。 |
| C++ 從函數(shù)返回指針 | C++ 允許函數(shù)返回指針到局部變量、靜態(tài)變量和動態(tài)內(nèi)存分配。 |
- C++ 不支持在函數(shù)外返回局部變量的地址,除非定義局部變量為?static?變量。
C++ 引用 vs 指針
引用很容易與指針混淆,它們之間有三個主要的不同:
- 不存在空引用。引用必須連接到一塊合法的內(nèi)存。
- 一旦引用被初始化為一個對象,就不能被指向到另一個對象。指針可以在任何時候指向到另一個對象。
- 引用必須在創(chuàng)建時被初始化。指針可以在任何時間被初始化。
C++?日期 & 時間
- C++ 標準庫沒有提供所謂的日期類型。C++ 繼承了 C 語言用于日期和時間操作的結(jié)構和函數(shù)。為了使用日期和時間相關的函數(shù)和結(jié)構,需要在 C++ 程序中引用 <ctime> 頭文件。
- 有四個與時間相關的類型:clock_t、time_t、size_t?和?tm。類型 clock_t、size_t 和 time_t 能夠把系統(tǒng)時間和日期表示為某種整數(shù)。
- 結(jié)構類型?tm?把日期和時間以 C 結(jié)構的形式保存,tm 結(jié)構的定義如下:
| 1 | time_t time(time_t *time); 該函數(shù)返回系統(tǒng)的當前日歷時間,自 1970 年 1 月 1 日以來經(jīng)過的秒數(shù)。如果系統(tǒng)沒有時間,則返回 -1。 |
| 2 | char *ctime(const time_t *time); 該返回一個表示當?shù)貢r間的字符串指針,字符串形式?day month year hours:minutes:seconds year\n\0。 |
| 3 | struct tm *localtime(const time_t *time); 該函數(shù)返回一個指向表示本地時間的?tm?結(jié)構的指針。 |
| 4 | clock_t clock(void); 該函數(shù)返回程序執(zhí)行起(一般為程序的開頭),處理器時鐘所使用的時間。如果時間不可用,則返回 -1。 |
| 5 | char * asctime ( const struct tm * time ); 該函數(shù)返回一個指向字符串的指針,字符串包含了 time 所指向結(jié)構中存儲的信息,返回形式為:day month date hours:minutes:seconds year\n\0。 |
| 6 | struct tm *gmtime(const time_t *time); 該函數(shù)返回一個指向 time 的指針,time 為 tm 結(jié)構,用協(xié)調(diào)世界時(UTC)也被稱為格林尼治標準時間(GMT)表示。 |
| 7 | time_t mktime(struct tm *time); 該函數(shù)返回日歷時間,相當于 time 所指向結(jié)構中存儲的時間。 |
| 8 | double difftime ( time_t time2, time_t time1 ); 該函數(shù)返回 time1 和 time2 之間相差的秒數(shù)。 |
| 9 | size_t strftime(); 該函數(shù)可用于格式化日期和時間為指定的格式。 |
C++?基本的輸入輸出
- C++ 的 I/O 發(fā)生在流中,流是字節(jié)序列。如果字節(jié)流是從設備(如鍵盤、磁盤驅(qū)動器、網(wǎng)絡連接等)流向內(nèi)存,這叫做輸入操作。如果字節(jié)流是從內(nèi)存流向設備(如顯示屏、打印機、磁盤驅(qū)動器、網(wǎng)絡連接等),這叫做輸出操作。
| <iostream> | 該文件定義了?cin、cout、cerr?和?clog?對象,分別對應于標準輸入流、標準輸出流、非緩沖標準錯誤流和緩沖標準錯誤流。 |
| <iomanip> | 該文件通過所謂的參數(shù)化的流操縱器(比如?setw?和?setprecision),來聲明對執(zhí)行標準化 I/O 有用的服務。 |
| <fstream> | 該文件為用戶控制的文件處理聲明服務。我們將在文件和流的相關章節(jié)討論它的細節(jié)。 |
標準輸入流(cin)
標準錯誤流(cerr)
#include <iostream>using namespace std;int main( ) {char str[] = "Unable to read....";cerr << "Error message : " << str << endl; }標準日志流(clog)
- 預定義的對象?clog?是?iostream?類的一個實例。clog 對象附屬到標準錯誤設備,通常也是顯示屏,但是?clog?對象是緩沖的。這意味著每個流插入到 clog 都會先存儲在緩沖區(qū),直到緩沖填滿或者緩沖區(qū)刷新時才會輸出。
- clog?也是與流插入運算符 << 結(jié)合使用的,如下所示:
輸入輸出流中的函數(shù)(模板)
#include <iostream> #include <iomanip> using namespace std; int main() {cout<<setiosflags(ios::left|ios::showpoint); // 設左對齊,以一般實數(shù)方式顯示cout.precision(5); // 設置除小數(shù)點外有五位有效數(shù)字 cout<<123.456789<<endl;cout.width(10); // 設置顯示域?qū)?0 cout.fill('*'); // 在顯示區(qū)域空白處用*填充cout<<resetiosflags(ios::left); // 清除狀態(tài)左對齊cout<<setiosflags(ios::right); // 設置右對齊cout<<123.456789<<endl;cout<<setiosflags(ios::left|ios::fixed); // 設左對齊,以固定小數(shù)位顯示cout.precision(3); // 設置實數(shù)顯示三位小數(shù)cout<<999.123456<<endl; cout<<resetiosflags(ios::left|ios::fixed); //清除狀態(tài)左對齊和定點格式cout<<setiosflags(ios::left|ios::scientific); //設置左對齊,以科學技術法顯示 cout.precision(3); //設置保留三位小數(shù)cout<<123.45678<<endl;return 0; } setiosflags(ios::fixed) 固定的浮點顯示 setiosflags(ios::scientific) 指數(shù)表示 setiosflags(ios::left) 左對齊 setiosflags(ios::right) 右對齊 setiosflags(ios::skipws 忽略前導空白 setiosflags(ios::uppercase) 16進制數(shù)大寫輸出 setiosflags(ios::lowercase) 16進制小寫輸出 setiosflags(ios::showpoint) 強制顯示小數(shù)點 setiosflags(ios::showpos) 強制顯示符號| boolalpha | 可以使用單詞”true”和”false”進行輸入/輸出的布爾值. |
| oct | 用八進制格式顯示數(shù)值. |
| dec | 用十進制格式顯示數(shù)值. |
| hex | 用十六進制格式顯示數(shù)值. |
| left | 輸出調(diào)整為左對齊. |
| right | 輸出調(diào)整為右對齊. |
| scientific | 用科學記數(shù)法顯示浮點數(shù). |
| fixed | 用正常的記數(shù)方法顯示浮點數(shù)(與科學計數(shù)法相對應). |
| showbase | 輸出時顯示所有數(shù)值的基數(shù). |
| showpoint | 顯示小數(shù)點和額外的零,即使不需要. |
| showpos | 在非負數(shù)值前面顯示”+(正號)”. |
| skipws | 當從一個流進行讀取時,跳過空白字符(spaces, tabs, newlines). |
| unitbuf | 在每次插入以后,清空緩沖區(qū). |
| internal | 將填充字符回到符號和數(shù)值之間. |
| uppercase | 以大寫的形式顯示科學記數(shù)法中的”e”和十六進制格式的”x”. |
| boolalpha | 啟用boolalpha標志 | √ | √ |
| dec | 啟用dec標志 | √ | √ |
| endl | 輸出換行標示,并清空緩沖區(qū) | ? | √ |
| ends | 輸出空字符 | ? | √ |
| fixed | 啟用fixed標志 | ? | √ |
| flush | 清空流 | ? | √ |
| hex | 啟用 hex 標志 | √ | √ |
| internal | 啟用 internal 標志 | ? | √ |
| left | 啟用 left 標志 | ? | √ |
| noboolalpha | 關閉boolalpha 標志 | √ | √ |
| noshowbase | 關閉showbase 標志 | ? | √ |
| noshowpoint | 關閉showpoint 標志 | ? | √ |
| noshowpos | 關閉showpos 標志 | ? | √ |
| noskipws | 關閉skipws 標志 | √ | ? |
| nounitbuf | 關閉unitbuf 標志 | ? | √ |
| nouppercase | 關閉uppercase 標志 | ? | √ |
| oct | 啟用 oct 標志 | √ | √ |
| right | 啟用 right 標志 | ? | √ |
| scientific | 啟用 scientific 標志 | ? | √ |
| showbase | 啟用 showbase 標志 | ? | √ |
| showpoint | 啟用 showpoint 標志 | ? | √ |
| showpos | 啟用 showpos 標志 | ? | √ |
| skipws | 啟用 skipws 標志 | √ | ? |
| unitbuf | 啟用 unitbuf 標志 | ? | √ |
| uppercase | 啟用 uppercase 標志 | ? | √ |
| ws | 跳過所有前導空白字符 | √ |
| resetiosflags(long f) | 關閉被指定為f的標志 | √ | √ |
| setbase(int base) | 設置數(shù)值的基本數(shù)為base | ? | √ |
| setfill(int ch) | 設置填充字符為ch | ? | √ |
| setiosflags(long f) | 啟用指定為f的標志 | √ | √ |
| setprecision(int p) | 設置數(shù)值的精度(四舍五入) | ? | √ |
| setw(int w) | 設置域?qū)挾葹閣 | ? | √ |
C++?數(shù)據(jù)結(jié)構
- C/C++ 數(shù)組允許定義可存儲相同類型數(shù)據(jù)項的變量,但是結(jié)構是 C++ 中另一種用戶自定義的可用的數(shù)據(jù)類型,它允許您存儲不同類型的數(shù)據(jù)項。
- 結(jié)構用于表示一條記錄,假設您想要跟蹤圖書館中書本的動態(tài),您可能需要跟蹤每本書的下列屬性:
訪問結(jié)構成員
- 為了訪問結(jié)構的成員,我們使用成員訪問運算符(.)。成員訪問運算符是結(jié)構變量名稱和我們要訪問的結(jié)構成員之間的一個句號。
- 下面的實例演示了結(jié)構的用法:
結(jié)構體作為函數(shù)的參數(shù)
#include <iostream> #include <cstring>using namespace std; void printBook( struct Books book );// 聲明一個結(jié)構體類型 Books struct Books {char title[50];char author[50];char subject[100];int book_id; };int main( ) {Books Book1; // 定義結(jié)構體類型 Books 的變量 Book1Books Book2; // 定義結(jié)構體類型 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 信息printBook( Book1 );// 輸出 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; }指向結(jié)構的指針
- 可以定義指向結(jié)構的指針,方式與定義指向其他類型變量的指針相似,如下所示:
- 現(xiàn)在,您可以在上述定義的指針變量中存儲結(jié)構變量的地址。為了查找結(jié)構變量的地址,請把 & 運算符放在結(jié)構名稱的前面,如下所示:
- 為了使用指向該結(jié)構的指針訪問結(jié)構的成員,您必須使用 -> 運算符,如下所示:
typedef 關鍵字
下面是一種更簡單的定義結(jié)構的方式,您可以為創(chuàng)建的類型取一個"別名"。例如:
typedef struct Books {char title[50];char author[50];char subject[100];int book_id; }Books; 現(xiàn)在,您可以直接使用 Books 來定義 Books 類型的變量,而不需要使用 struct 關鍵字。下面是實例:Books Book1, Book2; 您可以使用 typedef 關鍵字來定義非結(jié)構類型,如下所示:typedef long int *pint32;pint32 x, y, z; x, y 和 z 都是指向長整型 long int 的指針。?
總結(jié)
以上是生活随笔為你收集整理的C++学习笔记 简单部分的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用C++的方式实现AES算法
- 下一篇: C++primer第九章 顺序容器 9.