c语言指针初探 一 指针与引用(二)

前面我们已经提到过引用,这里我们再深入研究。

一 引用 

引用就是某一(对象)的一个别名,对引用的操作与对变量直接操作完全一样,引用可以看成另一种指针。

int x=10;
int &rx=x;
将引用rx声明为int型变量x的别名,在声明引用时要注意:

(1)一经声明,不能修改,c++不允许在声明完毕后修改引用的值。

(2)声明引用时,必须同时对其初始化,因为  一经声明,不能修改,所以引用的初始化化是必须得。无初始化的引用是无效的。

(3)声明语句中的类型标识符必须与初始值的变量类型一致(特殊情况见后面)。

二  引用的使用限制:

1.不能建立数组的引用。数组是若干个元素所组成的集合,没法建立一个数组的别名。

2.不能声明一个引用的引用。

int & & refNum=num;  //非法
3.声明指向引用的指针

int num=10;
int & *pNum=num; //非法

但是可以声明指针的引用。

#include <iostream>
using namespace std;
int main()
{
    int num=10;
    int *pNum=&num
    int *&refNum=pNum;
    cout<<*refNum<<endl;  //10
    return 0;
}

三 其它

C++程序可以对用new申请的动态无名实体建立一个引用。

#include <iostream>
using namespace std;
int main()
{
    int &refNum=*new int(10);
    cout<<refNum<<endl;  //10
    return 0;
}

在撤销动态内存时,可以用 delete &refNum

#include <iostream>
using namespace std;
int main()
{
    int &refNum=*new int(10);
    delete &refNum;
    return 0;
}
对new申请的动态数组建立引用是非法的。

前面说过声明语句中的类型标识符必须与初始值的变量类型一致,当两者不一样时,有时候聪明的编译器会指出错误,除非引用的是用const修饰的,这种情况下c++将产生临时变量,下面用法是合法的。

#include <iostream>
using namespace std;
int main()
{
    const int & refInt=9;   //去掉const 非法  (常量是不能修改的)
    cout<<refInt<<endl;//9
    int x=10;
    const double & refDouble=x;  //去掉const 非法
    cout<<refDouble<<endl; //10
    return 0;
}
const 修饰的引用是只读的,没法改写。

四 指针与const

用const 修饰符声明的程序实体具有只读性,声明一个指针时,通过在声明语句的不同位置使用const效果是不一样的:

(1)禁止对指针赋值。

(2)禁止通过间接引用(*指针)对指针所指的变量赋值。

(3)即(1)又(2)。

1.禁止改写指针(常量指针或常指针)

在声明一个指针时,如果在*的右边加const修饰符,所声明的指针称为常量指针(常指针)编译器不允许改写指针的值,也就是说,改指针恒指向某个内存地址。

#include <iostream>
using namespace std;
int main()
{
    int num=10,num2=20;
    int * const pNum=&num
    cout<<*pNum<<endl;    //10
    pNum=&num2;   //非法
    return 0;
}
在整个程序执行过程中,pNum的值无法改变,也就是没办法指向其它内存单元,但是可以间接修改变量的值。

#include <iostream>
using namespace std;
int main()
{
    int num=10,num2=20;
    int * const pNum=&num
    cout<<*pNum<<endl;    //10
  //  pNum=&num2;   //非法
    *pNum=0;
    cout<<num<<endl;
    return 0;
}

声明一个常指针时,必须对其进行初始化,因为常指针在声明完成后没有办法修改,未进行初始化的常指针式没有意义的,编译器会报错。

2.禁止改写间接引用

在指针声明时,将const修饰符放在指针类型之前,便无法通过间接引用改写指针所指变量(但是变量直接修改),如:

#include <iostream>
using namespace std;
int main()
{
    int num=5;
    const int *pNum=&num;     //也可以这样写 int const *pNum=&num
    *pNum=10;   //非法
    num=10;
    return 0;
}

3,既禁止改写指针,有禁止改写间接引用

3是上面两种的 ”并集“,那么语法也该是那种的并集-----果然如此

#include <iostream>
using namespace std;
int main()
{
    int num=5,num2=10;
    const int * const pNum=&num
    *pNum=10;   //非法
    pNum=&num2;  //非法
    num=10;
    return 0;
}

五 使用const 提高函数的健壮性

1.用const修饰函数的参数

如果参数做输出用,无论它是什么数据类型,也不论采用指针传递,还是引用传递,都不能加const,否则该参数将失去输出功能啦。

const只能修饰输入参数

(1)例如 StringCopy函数:

void StringCopy(char *strDestination,const *strSource)

其中strSource是输入参数,strDestination是输出参数,给strSource加上const修饰后,如果函数体内的语句试图改动strSource的内容,编译器要报错的。

(2)如果输入参数采用“值传递”由于函数将自动产生临时变量用于复制该参数,所以无需保护。

(3)对于非内部数据类型的参数而言,像 void fun(A a),则应该写成void fun(const A &a),既提高了效率,又安全。但是对于内部数据void fun(int x)就没必要那样写了。

2.用const 修饰函数的返回值

(1)如果给以“指针传递”的方式的函数返回值加const修饰函数返回值(即指针的内容不能被修改,该返回值只能赋给加const 修饰的同类型指针

#include <iostream>
using namespace std;
const int *fun()
{
    int num=3;
    int *pNum=&num
    return pNum;
}
int main()
{
    const int *p=fun();  //去掉const 错误
    cout<<*p<<endl;   //3
    return 0;
}
(2)如果函数返回值采用值传递的方式,加const 修饰没有任何价值。

例如:不要把函数int Fun()写成 const int Fun()。

           不要把函数A Fun() 写成 const A Fun()。

3.const 成员函数

任何不会修改数据成员的函数都应该声明为const ,如果编写const函数时,不慎修改了数据成员,或调用了其他非const成员函数,编译器会指出的。

#include <iostream>
using namespace std;
class fun
{
private:
    int num;
public:
    fun(int Num=0):num(Num)
    {}
    void Add(int elem)
    {
        num+=elem;
    }
    int GetCount() const
    {
        num-=1;     //编译错误
        Add(10);     //编译错误
        return num;
    }
};
int main()
{
    fun f;
    f.Add(10);
    cout<<f.GetCount()<<endl;;
    return 0;
}


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值