標籤:
今天要講的是C++範圍運算子"::",強制類型轉換的擴充,C++中相對於C中malloc和free函數的運算子new和delete,以及C++對C的一個重要擴充:引用(reference);這也是C++對C語言的非物件導向特性擴充系列的最後一節。
1.如果有兩個同名變數,一個是全域的,一個是局部的,那麼局部的變數在其範圍擁有較高的優先權,全域變數則被屏蔽。那如果我希望在局部變數的範圍裡使用全域變數怎麼辦,這時就要用到::範圍運算子了。比如:
1 #include<iostream>
2
3 usingnamespace std;
4
5 int x;
6
7 int main()
8
9 {
10
11 int x;
12
13 x=50;
14
15 ::x=100;
16
17 cout<<"局部變數x="<<x<<endl;
18
19 cout<<"全域變數x="<<::x<<endl;
20
21 return0;
22
23 }
結果:
2.在C語言中有強制類型的轉換比如:int x=1;double y=(double)x;而C++不但支援這種格式,還提供了一種類似於函數格式的轉換:int x=1;double y=double(x);
3.C中的malloc和free函數被用於動態分配記憶體和釋放動態分配的記憶體,而在C++裡,不但保留了這兩個函數,另外使用運算子new和delete來更好地進行記憶體的分配和釋放。記憶體配置的基本形式:指標變數名=new 類型,如:int *x;x=new int;或char *chr;chr=new char;釋放記憶體(delete 指標變數名):delete x;delete chr;雖然new和delete的功能和malloc和free相似,但是前者有幾個優點:(1)new可以根據資料類型自動計算所要分配的記憶體大小,而malloc必須使用sizeof函數來計算所需要的位元組;(2)new能夠自動返回正確類型的指標,而malloc的傳回值一律為void*,必須在程式中進行強制類型轉換;
new可以為數組動態分配記憶體空間如:int *array=new int[10]或int *xyz=new int[8][9][10];釋放時用delete []array和delete []xyz;另外new可以在給簡單變數分配記憶體的同時初始化,比如int *x=new int(100);但不
能對資料進行初始化;有時候沒有足夠的記憶體滿足分配要求,則有些編譯系統將會返回null 指標NULL,比如:
1 #include <iostream>
2
3 usingnamespace std;
4 int main()
5 {
6 int*x;
7 x=newint;
8 if(!x)
9 {
10 cout<<"分配記憶體失敗!"<<endl;
11 return1;
12 }
13 *x=10;
14 cout<<*x;
15 delete x;
16 return0;
17 }
4.接下來詳細地說一下C++的引用(reference),先解釋一下,什麼是引用?打個比方,一個人可能有三四個名字,但這三四個名字所做的事,其實就是那一個人所做的。引用就是給變數起了個別名罷了。它的格式:類型 &引用名=以定義的變數名;比如:
1 #include <iostream>
2
3 usingnamespace std;
4 int main()
5 {
6 int x=100;
7 int&y=x;
8 x=50;
9 cout<<"x="<<x<<endl;
10 cout<<"y="<<y<<endl;
11
12 y=0;
13 cout<<"x="<<x<<endl;
14 cout<<"y="<<y<<endl;
15
16 return0;
17 }
結果:
實際上,引用與其所代表的變數共用同一個記憶體單元,系統部位引用另外分配儲存空間,編譯系統使引用和其代表的變數具有相同地址。
1 #include <iostream>
2
3 usingnamespace std;
4 int main()
5 {
6 int x=100;
7 int&y=x;
8 x=50;
9 cout<<"變數x的地址:"<<&x<<endl;
10 cout<<"引用y的地址:"<<&y<<endl;
11 return0;
12 }
結果:
發現其實引用就那麼回事,但是也有幾個注意點:(1)在聲明引用時,必須立即對它進行初始化,不能聲明完後在賦值:如int x=10;int &y;y=x;(2)引用的類型必須和給其賦值的變數的類型相同,不可以這樣:int x;double &y=x;(3)為引用提供的值,可以是變數也可以是引用:int x=5;int &y=x;int &z=y;(4)引用在初始化後不能再被重新聲明為另一個變數的引用:int x,y;int &z=x;z=&y;
其實引用主要的用途就在於作為函數的參數,回顧一下,以前在C中傳遞函數參數有兩種情況,分別是"傳值調用"和"傳址調用",前者傳遞是單向的,後者則為雙向,而引用作為函數參數傳遞,則是"傳址調用",它和C中指標作為參數傳遞的效果是一致的,只不過它不用像指標一樣,需要交間接引用運算子"*";舉個例子,比較一下這兩種方法:
1 #include <iostream>
2
3 usingnamespace std;
4 void swap(int*x,int*y)
5 {
6 int temp;
7 temp=*x;
8 *x=*y;
9 *y=temp;
10 }
11
12 void swap(int&x,int&y)
13 {
14 int temp;
15 temp=x;
16 x=y;
17 y=temp;
18 }
19 int main()
20 {
21 int i=10,j=5;
22 cout<<"i="<<i<<" j="<<j<<endl;
23 swap(&i,&j);
24 cout<<"i="<<i<<" j="<<j<<endl;
25 swap(i,j);
26 cout<<"i="<<i<<" j="<<j<<endl;
27 return0;
28 }
結果:
對於引用,還有點小小的細節要說一下:(1)不能建立引用數組,比如:int a[4]="abcd";int &araay[4]=a;(2)不能建立引用的引用,不能建立指向引用的指標,比如:int x=50;int &&y=x;int &z=x;int *p=z;(3)可以把引用的地址賦給指標;(4)可以用const對引用加以限定,不允許改變引用的值,比如:int x=10;const int &t=x;t=5,但是x=5卻可以,此時x和t都等於5;(5)引用運算子和地址操作符雖然都是&,但是引用的話,只是在聲明時才用,而其它場合使用&都是地址操作符!比如:int x=5;int &y=x;y=10;int *z=&y//&為地址操作符;cout<<&z//&為地址操作符;
最後,我們還是用一個例子來總結一下今天所講的內容(開發工具:vs2010):
1 #include "stdafx.h"
2 #include <iostream>
3
4 usingnamespace std;
5
6 int x=10;//全域變數
7 void swap(int*x,int*y)//指標類型的參數
8 {
9 int temp;
10 temp=*x;
11 *x=*y;
12 *y=temp;
13 }
14
15 void swap(int&x,int&y)//帶有參考型別的參數
16 {
17 int temp;
18 temp=x;
19 x=y;
20 y=temp;
21 }
22 int main()
23 {
24 double*y=newdouble(5.55);//new動態分配記憶體空間,位元組大小和double類型所佔位元組一樣,並初始化值
25 int x=double(*y);//強制類型轉換
26
27 cout<<"局部變數x="<<x<<" 全域變數x="<<::x<<endl;
28 swap(&x,&::x);
29 cout<<"局部變數x="<<x<<" 全域變數x="<<::x<<endl;
30 swap(x,::x);
31 cout<<"局部變數x="<<x<<" 全域變數x="<<::x<<endl;
32
33 delete y;//釋放記憶體空間
34 return0;
35 }
結果:
C++對C語言的非物件導向特性擴充(3)