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