C++学习_第1章_从C到C++
一、引用的概念和應(yīng)用
?1.引用的概念
下面寫法定義了一個引用,并將其初始化為引用某個變量。類型名 & 引用名 = 某變量名;int n = 4;int & r = n; // r引用了n,r的類型是 int & 某個變量的引用,等價于這個變量,相當于該變量的一個別名。代碼示例:
// 課堂練習 # include <iostream> using namespace std;int main(void) {int n = 7;int & r = n;r = 4;cout<<r<<" "<<n<<endl; // 輸出 4 4 n = 5;cout<<r<<" "<<n<<endl; // 輸出 5 5 return 0; }注意點: 1. 定義引用時一定要將其初始化為引用某個變量。
2. 初始化以后,從一而終,不會再引用別的變量。
3. 引用只能引用變量,不能引用常量和表達式。
代碼示例:
// 課堂練習 # include <iostream> using namespace std;int main(void) {double a = 4, b = 5;double & r = a; // r引用 a double & p = r; // 這時候 p 也引用了 ap = 10;cout<<a<<" "<<r<<" "<<p; // 輸出 10 10 10 r = b; // 這句話并不代表r重新引用b,而是把 b值賦值給r cout<<a<<" "<<r<<" "<<p; // 輸出 5 5 5 return 0; }課堂習題:
下面程序片段輸出結(jié)果是什么?int a = 1,b = 2;int & r = a;r = b;r = 7;cout << a << endl;2. 引用應(yīng)用的簡單示例
2.1?引用作為函數(shù)的參數(shù)
C語言中如何交換兩個整型變量的值? void swap(int * a, int * b) {int temp;temp = *a; *a=*b; *b=temp; } int n1, n2; swap(&n1, &n2); // n1 n2 的值被交換有了C++的引用:void swap(int & a, int & b) {int temp;temp = a; a=b; b=temp; } int n1, n2; swap(n1, n2); // n1 n2 的值被交換2.2 引用作為函數(shù)的返回值
// 課堂練習 # include <iostream> using namespace std; int n = 4; int & SetValue() {return n; } int main(void) {SetValue() = 40; // 將40的值賦值給SetValue()函數(shù)的返回n cout<<n; // 輸出40 return 0; }2.3 常引用
定義引用時,前面加const關(guān)鍵字,即為“常引用” int n; const int & r = n; // r 的類型是const int & 不能通過常引用去修改其引用內(nèi)容。 int n = 100; const int & r = n; r = 200; // 編譯錯 n = 300; // 沒問題2.4 常引用和非常引用的轉(zhuǎn)換
const T & 和 T & 是不同的類型! T &類型的引用或者T類型的變量可以用來初始化const T &類型的引用。而const T類型的常變量和const T &類型的引用則 不能用來初始化T &類型的引用,除非強制類型轉(zhuǎn)化。二、const關(guān)鍵字
?0) 定義常引用 (在引用處已經(jīng)講過,不再贅述)
1) 定義常量
const int MAX_VAL = 23; const double Pi = 3.14; const char * SCHOOL_NAME = "PKU";2) 定義常量指針
A) 不能通過常量指針修改其指向內(nèi)容
int n, m; const int * p = &n; * p = 5; // 試圖通過指針修改指向內(nèi)容, 編譯出錯 n = 4; // ok 指向的內(nèi)容本身是可以修改的 p = &m; // ok 常量指針的指向可以發(fā)生變化B) 不能把常量指針賦值給非常量指針,反過來可以
const int * p; // 常量指針 int * q; // 非常量指針 p = q; // ok q = p; // error 企圖把常量指針賦值給非常量指針 q = (int *)p; //ok 強制類型轉(zhuǎn)化C) 函數(shù)參數(shù)為常量指針時,可避免函數(shù)內(nèi)部不小心改變參數(shù)指針所指地方的內(nèi)容
// 課堂練習 # include <iostream> # include <string.h> using namespace std;void MyPrintf(const char * p) {strcpy(p,"123"); // 編譯出錯 // 因為strcpy()函數(shù)的第一個參數(shù)是 char * 非常量指針// 而定義的 P 是一個常量指針,所以,賦值過程會報錯 printf("%s",p); // ok }int main(void) {char ch[5] = {"0123"};const char * q = ch;MyPrintf(q);return 0; }課堂習題:
下面說法哪種是對的? A) 常引用所引用的變量,其值不能被修改 B) 不能通過常量指針,去修改其指向的變量 C) 常量指針一旦指向某個變量,就不能再指向其他變量 D) 以上都不對三、動態(tài)內(nèi)存分配
1. 用new運算符實現(xiàn)動態(tài)內(nèi)存分配
1.1) 用new 分配一個變量
P = new T; T 是任意的類型名,P是類型為T * 的指針。 動態(tài)分配出一片大小為sizeof(T)字節(jié)的內(nèi)存空間,并且將該內(nèi)存空間的起始地址賦值給P。代碼示例:
// 課堂練習 # include <iostream> using namespace std;int main(void) {int * p;p = new int; // 給P指針分配內(nèi)存*p = 5;cout<<*p;return 0; }課堂習題:
表達式 “new int”的返回值類型是: A) int B) int * C) int & D) void1.2) 分配一個數(shù)組
P = new T[N]; T: 任意類型名 P: 類型為T * 的指針 N:要分配的數(shù)組元素的個數(shù) 動態(tài)分配出一片大小為N*sizeof(T)字節(jié)的內(nèi)存空間,并且將該內(nèi)存空間的起始地址賦值給P。代碼示例:
// 課堂練習 # include <iostream> using namespace std;int main(void) {int * p;p = new int[20];p[10] = 5;cout<<p[10]; // 輸出5 return 0; }1.3) new 運算符的返回值類型
new T; new T[N]; 均返回T*類型2. 用delete運算符釋放動態(tài)分配的內(nèi)存
2.1) 用new 動態(tài)分配的內(nèi)存空間,一定要用delete運算符進行釋放
delete 指針; // 該指針必須指向new出來的空間 int * p = new int; * p = 5; delete p; delete p; // error,不能delete兩次代碼示例:
// 課堂練習 # include <iostream> using namespace std;int main(void) {int * p = new int;*p = 5;cout<<*p<<endl; // 輸出5 delete p;cout<<*p<<endl; // 輸出結(jié)果不為 5,空間已經(jīng)被釋放 return 0; }2.2) 用delete釋放動態(tài)分配的數(shù)組,要加 []
delete [] 指針; // 該指針必須指向new出來的數(shù)組 int * p = new int[20]; p[0] = 1; delete [] p;代碼示例:
// 課堂練習 # include <iostream> using namespace std;int main(void) {int * p = new int[20];p[10] = 5;cout<<p[10]<<endl; // 輸出5 printf("%p\n",p[10]); // 輸出p[10]的地址 delete [] p; cout<<p[10]<<endl; // 輸出5,空間已經(jīng)被釋放 printf("%p\n",p[10]); // 輸出p[10]的地址delete [] p; // 再次delete編譯不會報錯,但是程序無法繼續(xù)執(zhí)行 cout<<p[10]<<endl; // 無輸出printf("%p\n",p[10]); // 無輸出return 0; }課堂習題:
下面小段程序,哪個是正確的: A) char * p = new int; p = 'a'; delete p; B) int *p = new int[25]; p[10] = 100; delete p; C) char * p = new char[10]; p[0] = 'K'; delete [] p; D) 都不對?四、動態(tài)內(nèi)存分配
1. 內(nèi)聯(lián)函數(shù)?
?函數(shù)調(diào)用是有時間開銷的。
如果函數(shù)本身只有幾條語句,執(zhí)行非常快,而且函數(shù)被反復(fù)執(zhí)行很多次,相比之下調(diào)用函數(shù)所產(chǎn)生的這個開銷就會顯得比較大。
為了減少函數(shù)調(diào)用的開銷,引入了內(nèi)聯(lián)函數(shù)機制。
編譯器處理對內(nèi)聯(lián)函數(shù)的調(diào)用語句時,是將整個函數(shù)的代碼插入到調(diào)用語句處,而不會產(chǎn)生調(diào)用函數(shù)的語句。
在函數(shù)定義前加“inline”關(guān)鍵字,即可定義內(nèi)聯(lián)函數(shù)
inline int Max(int a,int b) {if( a > b) return a;return b; }2. 函數(shù)重載
一個或多個函數(shù),名字相同,然而參數(shù)個數(shù)或參數(shù)類型不相同,這叫做函數(shù)的重載。
以下三個函數(shù)是重載關(guān)系: int Max(double f1,double f2) { } int Max(int n1,int n2) { } int Max(int n1,int n2,int n3) { }函數(shù)重載使得函數(shù)命名變得簡單。編譯器根據(jù)調(diào)用語句的中的實參的個數(shù)和類型判斷應(yīng)該調(diào)用哪個函數(shù)。
具體使用:
(1) int Max(double f1,double f2) { } (2) int Max(int n1,int n2) { } (3) int Max(int n1,int n2,int n3) { } Max(3.4,2.5); //調(diào)用 (1) Max(2,4); //調(diào)用 (2) Max(1,2,3); //調(diào)用 (3) Max(3,2.4); //error,二義性3. 函數(shù)的缺省參數(shù)
C++中,定義函數(shù)的時候可以讓最右邊的連續(xù)若干個參數(shù)有缺省值,那么調(diào)用函數(shù)的時候,若相應(yīng)位置不寫參數(shù),參數(shù)就是缺省值。
void func( int x1, int x2 = 2, int x3 = 3){ } func(10 ) ; //等效于 func(10,2,3) func(10,8) ; //等效于 func(10,8,3) func(10, , 8) ; //不行,只能最右邊的連續(xù)若干個參數(shù)缺省函數(shù)參數(shù)可缺省的目的在于提高程序的可擴充性。
即如果某個寫好的函數(shù)要添加新的參數(shù),而原先那些調(diào)用該函數(shù)的語句,未必需要使用新增的參數(shù),那么為了避免對原先那些函數(shù)調(diào)用語句的修改,就可以使用缺省參數(shù)。
課堂例題:
下面說法正確的是: A) 多個重載函數(shù)的參數(shù)個數(shù)必須不同。 B) 兩個函數(shù),參數(shù)表相同,返回值類型不同,它們是重載關(guān)系。 C) 調(diào)用一個第二個和第三個參數(shù)都有有缺省值的函數(shù)時,可以不寫第二個實參而寫第三個實參。 D) 使用內(nèi)聯(lián)函數(shù)的目的是提高程序的運行速度。RRR
轉(zhuǎn)載于:https://www.cnblogs.com/Robin5/p/11231930.html
總結(jié)
以上是生活随笔為你收集整理的C++学习_第1章_从C到C++的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: P1-0:项目框架搭建
- 下一篇: MVC 无法将带 [] 的索引应用于“S