摘要: C++語言中的引用概念與&和*運算是幾個相關(guān)的概念。如何用簡明、準(zhǔn)確的語言講解引用概念和相關(guān)的運算,讓學(xué)習(xí)者容易理解記憶,我們一直在探討。本文用例題和實驗來驗證有關(guān)概念,講清楚這些概念的關(guān)系。
關(guān)鍵詞:引用;指針;&運算;*運算
中圖分類號:TP311 文獻標(biāo)識碼:A 文章編號:1009-3044(2018)28-0277-02
本文通過返回可以被賦值的左值(變量或?qū)ο螅┑葞讉€例子,對引用概念進行辨析。講清楚變量的引用、返回引用的函數(shù),&運算,*運算等。希望對于學(xué)習(xí)C++的人有所幫助。
1 變量的引用
引用是給已經(jīng)存在的變量指定一個別名,相當(dāng)于給一個人起外綽號。是一種使用已經(jīng)定義了的變量的方法。引用不分配新的存儲空間、不產(chǎn)生新變量。別名也是該變量空間的名字。并且這個別名不能再作為其他變量的名字或別名。
引用方法的一般格式是:
<類型名><&引用名> = <被引用的已經(jīng)存在的變量名>;
其中<類型名> 要與 <被引用的已經(jīng)存在的變量名>的類型保持一致。&在此是起標(biāo)識作用。聲明引用時必須同時對其進行初始化,即上面的格式中不能少項。
例題1(本文所有例題都在VC++2017下實驗驗證)
#include
using namespace std;
int main(int argc, char *argv[])
{double p = 3.14;
cout <<"被重新賦值前p="<< p << endl;
double &bp; = p; //A行,聲明bp為p的別名。
//double &bp2; = p;//同一個變量,起2個別名。
//double &bp2; = bp;//變量的別名的別名。
bp = 3.14159;
cout <<"被重新賦值p="<< p << endl;
cout <<"bp="<< bp << endl;
cout <<"&p;="<<&p; << endl;
cout <<"&bp;="<<&bp; << endl; //B行
//cout <<"&bp2;="<<&bp2; << endl;
system("pause");
}
運行結(jié)果:
被重新賦值前p=3.14
被重新賦值p=3.14159
bp=3.14159
&p;=0097F828
&bp;=0097F828
其中p和bp的地址值都是0097F828相等,說明引用沒有分配新的存儲空間。
思考題1:如果在例題1的//A行后加double &bp2;=p; //B行后加cout<<"&bp2;="<<&bp2;< 答:說明同一個變量可以有多個別名。 思考題2:如果在例題1的//A行后加行改為double &bp2;=bp; 程序還能運行說明了什么? 答:說明可以給變量p的別名bp再指定別名bp2。 函數(shù)的引用參數(shù)就是變量的引用。如: void swap(int &a;,int &b;){…};int main( ){int x=1,y=2; swap(x, y); …}語句swap(x, y);可以看成swap(int &a;=x, int &b;=y);在swap開辟的新工作區(qū)中把a和b分別作為主函數(shù)中變量x和變量y的別名。對象也可以作為函數(shù)的引用參數(shù)。 關(guān)于引用的說明: (1)變量的引用名不能再做其他變量的引用名。 (2)引用只是說明,沒有定義新變量。 (3)引用僅在說明時帶有&,使用引用名不能再帶&。 (4)函數(shù)參數(shù)的引用名,可以返回多個值。 (5)被引用的必須是左值。即可以被賦值的變量或?qū)ο蟆?/p> (6)引用與被引用變量類型必須相同。 (7)不允許對void類型進行引用。如萬用指針變量void *kk。 (8)不能建立引用的數(shù)組。int a[10]; int &ra;[10] = a或a[10];都是非法的。 (9)引用不能用類型來初始化。如:int&h;=int; (10)沒有空引用。如: int &rn;=NULL;錯誤。 2 用返回引用或指針的函數(shù)實現(xiàn)左值 函數(shù)返回值分為:值,引用,指針三種。c沒有引用類型。返回引用做左值可以實現(xiàn)連續(xù)賦值運算。 例題2:對于基本類型用返回引用的函數(shù)實現(xiàn)連續(xù)賦值 #include using namespace std; int& test() { int *b = new int(); *b = 2; return *b; delete b;//此語句沒有被執(zhí)行,不能清理int *b = new int();產(chǎn)生的垃圾。 } int main(int argc, char *argv[]) { int a; a = test() += test() += 1; cout <<"a="<< a << endl;
system("pause");
}
運行結(jié)果:
a=5
本例做適當(dāng)修改后,可以驗證返回指針也可以實現(xiàn)連續(xù)賦值。
例題2用基本類型返回引用會帶來一個問題,那就是語句return *b之后,無法實現(xiàn)清理退出被調(diào)函數(shù)int& test()之后,語句int *b = new int();產(chǎn)生的垃圾。
用返回基本類型引用的函數(shù)實現(xiàn)左值,在主調(diào)函數(shù)中一般要定義一個同類型的變量保存結(jié)果。a = test() += test() += 1;雖然實現(xiàn)了連續(xù)賦值,但不符合賦值習(xí)慣。
變量的引用是C++中新添加的概念。在C++中返回引用的函數(shù)、返回的是左值即主動對象本身,可以進行連續(xù)賦值。
例題3:用類返回引用的成員函數(shù)實現(xiàn)賦值運算。
#include
#include
using namespace std;
class String
{
protected:
int Length; // 字符串的長度
char *Strp; // 指向字符串的指針
public:
String(){ Strp =NULL; Length=0; }
String(const char *s);
String(const String &);
~String()
{
if (Strp) delete[] Strp;
}
void Show()
{
if (Strp) cout << Strp << '\n';
}
int GetLen() { return Length; }
String &operator;=(String &);
};
String::String(const char *s)
{
if (s)
{
Length = strlen(s);
Strp = new char[Length+1];
strcpy_s(Strp,strlen(s)+1, s);
//要注意字符串s不可太長。
}
else
{
Strp=NULL; Length=0;
}
}
String::String(const String &s;)
{
Length=s.Length;
if (s.Strp)
{
Strp = new char[Length+1];
strcpy_s(Strp, strlen(s.Strp) + 1, s.Strp);
}
else Strp=NULL;
}
String & String::operator = (String &s;)
{
if (this == &s;) return *this;
if (Strp) delete[] Strp;
Length = s.Length;
if (s.Strp)
{
Strp = new char[Length + 1];
strcpy_s(Strp, s.Length+1,s.Strp);
}
else Strp=NULL;
return *this;
}
int main(void)
{
String s1("C++程序設(shè)計 "), s2;
String s3("學(xué)生學(xué)習(xí).");
s1.Show();
s2.Show();
s3.Show();
s2 = s1;// 測試運算符"="
s1.Show();
s2.Show();
s3.Show();
String s6="C++ programming! ";
s1 = s2 = s6;
s1.Show();
s2.Show();
s3.Show();
system("pause");
return 0;
}
程序運行結(jié)果:
C++程序設(shè)計
學(xué)生學(xué)習(xí).
C++程序設(shè)計
C++程序設(shè)計
學(xué)生學(xué)習(xí).
C++ programming!
C++ programming!
學(xué)生學(xué)習(xí).
例題3中,返回引用的作左值使用,返回語句一定是:return *this;實際上返回的是主動對象本身。賦值號重載,實現(xiàn)了符合基本類型傳統(tǒng)的連續(xù)完美賦值運算s1 = s2 = s6。
3 引用運算符&與取地址運算符&、指針運算符*的關(guān)系
在定義引用的語句中&是引用聲明符號。使用變量時&出現(xiàn)在變量左側(cè)是取地址運算符、使指針升一級。&的另一個含義是按位與運算。在指針變量的定義中*號是類型的一部分,即表明定義的是指針變量。使用指針變量時在指針變量左側(cè)的*號把指針降一級、表示指針變量所指的變量、這叫間接訪問變量。*號的另一個用法是乘法。取地址運算符&和間接訪問運算符*是互逆的運算。
4 結(jié)束語
有關(guān)引用當(dāng)然還有好多問題需要討論,指針運算更是用法繁多,限于篇幅,不再展開討論。
參考文獻:
[1] https://blog.csdn.net/cnsword/article/details/7256821.
[2] 王玉山.一個難于理解的C++函數(shù)指針問題[J].山東工業(yè)技術(shù),2014(20).
[3]http://www.360doc.com/content/15/1025/10/26795867_508195623.shtml.
[4] 王玉山.C++程序設(shè)計語言的實踐教學(xué)建設(shè)[J].中小企業(yè)管理與科技,2017(1).
[5] 王珊珊,臧冽,張志航.C++程序設(shè)計教程(第3版)[M].機械工業(yè)出版社,2016.
【通聯(lián)編輯:光文玲】