网站首页  词典首页

请输入您要查询的论文:

 

标题 C++函数返回可以被赋值的左值与&和*运算辨析
范文

    摘要: C++语言中的引用概念与&和*运算是几个相关的概念。如何用简明、准确的语言讲解引用概念和相关的运算,让学习者容易理解记忆,我们一直在探讨。本文用例题和实验来验证有关概念,讲清楚这些概念的关系。

    关键词:引用;指针;&运算;*运算

    中图分类号:TP311 文献标识码:A 文章编号:1009-3044(2018)28-0277-02

    本文通过返回可以被赋值的左值(变量或对象)等几个例子,对引用概念进行辨析。讲清楚变量的引用、返回引用的函数,&运算,*运算等。希望对于学习C++的人有所帮助。

    1 变量的引用

    引用是给已经存在的变量指定一个别名,相当于给一个人起外绰号。是一种使用已经定义了的变量的方法。引用不分配新的存储空间、不产生新变量。别名也是该变量空间的名字。并且这个别名不能再作为其他变量的名字或别名。

    引用方法的一般格式是:

    <类型名><&引用名> = <被引用的已经存在的变量名>;

    其中<类型名> 要与 <被引用的已经存在的变量名>的类型保持一致。&在此是起标识作用。声明引用时必须同时对其进行初始化,即上面的格式中不能少项。

    例题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");

    }

    运行结果:

    被重新赋值前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。

    函数的引用参数就是变量的引用。如: 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开辟的新工作区中把a和b分别作为主函数中变量x和变量y的别名。对象也可以作为函数的引用参数。

    关于引用的说明:

    (1)变量的引用名不能再做其他变量的引用名。

    (2)引用只是说明,没有定义新变量。

    (3)引用仅在说明时带有&,使用引用名不能再带&。

    (4)函数参数的引用名,可以返回多个值。

    (5)被引用的必须是左值。即可以被赋值的变量或对象。

    (6)引用与被引用变量类型必须相同。

    (7)不允许对void类型进行引用。如万用指针变量void *kk。

    (8)不能建立引用的数组。int a[10]; int &ra;[10] = a或a[10];都是非法的。

    (9)引用不能用类型来初始化。如:int&h;=int;

    (10)没有空引用。如: int &rn;=NULL;错误。

    2 用返回引用或指针的函数实现左值

    函数返回值分为:值,引用,指针三种。c没有引用类型。返回引用做左值可以实现连续赋值运算。

    例题2:对于基本类型用返回引用的函数实现连续赋值

    #include

    using namespace std;

    int& test()

    {

    int *b = new int();

    *b = 2;

    return *b;

    delete b;//此语句没有被执行,不能清理int *b = new int();产生的垃圾。

    }

    int main(int argc, char *argv[])

    {

    int a;

    a = test() += test() += 1;

    cout <<"a="<< a << endl;

    

    

    

    system("pause");

    }

    运行结果:

    a=5

    本例做适当修改后,可以验证返回指针也可以实现连续赋值。

    例题2用基本类型返回引用会带来一个问题,那就是语句return *b之后,无法实现清理退出被调函数int& test()之后,语句int *b = new int();产生的垃圾。

    用返回基本类型引用的函数实现左值,在主调函数中一般要定义一个同类型的变量保存结果。a = test() += test() += 1;虽然实现了连续赋值,但不符合赋值习惯。

    变量的引用是C++中新添加的概念。在C++中返回引用的函数、返回的是左值即主动对象本身,可以进行连续赋值。

    例题3:用类返回引用的成员函数实现赋值运算。

    #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++程序设计 "), s2;

    String s3("学生学习.");

    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;

    }

    程序运行结果:

    C++程序设计

    学生学习.

    C++程序设计

    C++程序设计

    学生学习.

    C++ programming!

    C++ programming!

    学生学习.

    例题3中,返回引用的作左值使用,返回语句一定是:return *this;实际上返回的是主动对象本身。赋值号重载,实现了符合基本类型传统的连续完美赋值运算s1 = s2 = s6。

    3 引用运算符&与取地址运算符&、指针运算符*的关系

    在定义引用的语句中&是引用声明符号。使用变量时&出现在变量左侧是取地址运算符、使指针升一级。&的另一个含义是按位与运算。在指针变量的定义中*号是类型的一部分,即表明定义的是指针变量。使用指针变量时在指针变量左侧的*号把指针降一级、表示指针变量所指的变量、这叫间接访问变量。*号的另一个用法是乘法。取地址运算符&和间接访问运算符*是互逆的运算。

    4 结束语

    有关引用当然还有好多问题需要讨论,指针运算更是用法繁多,限于篇幅,不再展开讨论。

    参考文献:

    [1] https://blog.csdn.net/cnsword/article/details/7256821.

    [2] 王玉山.一个难于理解的C++函数指针问题[J].山东工业技术,2014(20).

    [3]http://www.360doc.com/content/15/1025/10/26795867_508195623.shtml.

    [4] 王玉山.C++程序设计语言的实践教学建设[J].中小企业管理与科技,2017(1).

    [5] 王珊珊,臧冽,张志航.C++程序设计教程(第3版)[M].机械工业出版社,2016.

    【通联编辑:光文玲】

    

    

随便看

 

科学优质学术资源、百科知识分享平台,免费提供知识科普、生活经验分享、中外学术论文、各类范文、学术文献、教学资料、学术期刊、会议、报纸、杂志、工具书等各类资源检索、在线阅读和软件app下载服务。

 

Copyright © 2004-2023 puapp.net All Rights Reserved
更新时间:2025/3/10 18:48:58