麻烦大家看一看这个小程序,我有两点疑问。

时间:2022-04-08 14:15:03
先看一下这个程序:

#include <iostream>

using namespace std;

int main()
{
    //const int i = 0;
    //const int &refi = i;
    //const int *const &ref_pi = &refi;
    
    int i = 0;
    int &refi = i;

    int * const &p_refi = &refi;//指针引用,指向指针的引用 
    int * const &p_i = &i;//指针引用,指向指针的引用 
    //ref_pi = &refj;
    *p_refi = 1;
    cout<<"i is a variable,set i = 0;refi is a reference initalized by i\n"
        <<"and ref_pi is a reference to a reference's pointer. \n"
        <<"It's incorrect that we declare it as 'int *&ref_pi'\n"
        <<"The correct definition is 'int * const &ref_pi'"<<endl;
        
    cout<<"refi                  is "<<refi<<endl;
    cout<<"p_refi                is "<<p_refi<<endl;
    cout<<"p_i                   is "<<p_i<<endl;
    cout<<"The address of   i    is "<<&i<<endl;
    cout<<"The address of p_refi is "<<&p_refi<<endl;
    cout<<"The address of refi   is "<<&refi<<endl;
    cout<<"The address of p_i    is "<<&p_i<<endl;
    
    cout<<"The value of p_refi   is "<<*p_refi<<endl;
    
    system("pause");
    return 0;   
}

然后,大家看下,这是它的运行结果:

麻烦大家看一看这个小程序,我有两点疑问。
{不好意思,我不知道怎么发图片,不过,这个程序运行一下就出来结果了。虽然大家看着不方便,还请大家帮忙解答一下两个疑问:}

1.程序中,我们定义int * const &p_i = &i;,这里,p_i是一个引用,指向的是一个int 型对象的指针,也就是我们开始定义的i的指针,我不明白这里为什么要加上const限定符。虽然说引用一经定义就不能再指向其它对象,但是,我们这样写的时候:
int i = 2;
int &refi = i;
这样,为什么就不用加const呢?

2.程序的运行结果中显示:

refi                  is 1
p_refi                is 0x22ff74
p_i                   is 0x22ff74
The address of   i    is 0x22ff74
The address of p_refi is 0x22ff6c
The address of refi   is 0x22ff74
The address of p_i    is 0x22ff64
The value of p_refi   is 1

这里,我们说refi是指向i的引用,它的内部存放的是一地址,但是,我不明白的是,为什么它的地址和i的地址都是一样的呢、。??


还望高手给解答一下。

8 个解决方案

#1


1.i是变量,可以有别名,&i是个表达式,不是变量,所以……

2.这里,我们说refi是 指向i的引用, 它的内部存放的是一地址

红色部分是楼主想当然,事实不是如此……

#2


1.int * const &p_i = &i;
这个是说你的这个指针引用是个常量,也就是说你的这个指针是不能自加或者自减之类的改变的。加不加const限定符是你的*。
int i = 2; 
int &refi = i; 
同样,这个refi加const就是说这个refi这个引用类型是个常量。
所谓的“引用一经定义就不能再指向其它对象”是当其定义的时候(这时候必须初始化)比如
int &refi = i; 
refi就是i了,以后再使用refi的时候就是使用的i。
在对其赋值的时候,比如:
int c=3;
refi=c;
这里把c赋值给refi,也就是i=c;refi和i的值都变为3了。
2.引用就是个别名。refi就是i的别名,两者就是一个东西。一个东西就一个地址了(其实这就是引用类型和普通类型的区别了)。你的别名叫“大灰狼”,你的家就是“大灰狼”的家,地址是一样的。

#3


2楼说得太对了。

#4


你说的“我们说refi是指向i的引用”
C++Primer上也有事这么说的。我就不喜欢说“指向”,我说的时候就说refi是i的引用。

#5


   第一个问题是这样的:加const说明这是一个指针常量,这个指针中存放的地址只要经过赋值之后就不能再变,但是此指针所指向的值是可以改变的.

  第二个问题是这样的:内存不会为引用开辟新的内存空间,那么自然也就不会为引用分配内存地址,引用只是原来的变量的一个别名,他的地址和为其初始化的变量的地址是一样的

#6


我觉得你应该是在这里理解出现的问题:
1,
int i = 2; 
int &refi = i; 
这样,为什么就不用加const呢? 
【你之前指针加上const是加在*后面,意思就是说这个指针不能再随便指了,而这里引用就像2楼讲的那样,引用已经定义不再指向其他,所以你根本不用加上const,除非你的作用不是为了限制她指向的,你加上const,是为了让i不能再重新赋值,i就是常量2了,不过这样的话,你直接在i上加const不是更意图明显些么】
2,【这个我觉得1喽说的比较清楚些,指针你才说 指向,你那个就是个引用,就是个别名啊,所以当然是一个地址了】

#7


引用 2 楼 yangkunhenry 的回复:
1.int * const &p_i = &i;
这个是说你的这个指针引用是个常量,也就是说你的这个指针是不能自加或者自减之类的改变的。加不加const限定符是你的*。

int i = 2;
int &refi = i;
同样,这个refi加const就是说这个refi这个引用类型是个常量。
所谓的“引用一经定义就不能再指向其它对象”是当其定义的时候(这时候必须初始化)比如
int &refi = i;
refi就是i了,以后再使用refi的时候就是使用的i。
在对其赋值的时候,比如:
int c=3;
refi=c;
这里把c赋值给refi,也就是i=c;refi和i的值都变为3了。
2.引用就是个别名。refi就是i的别名,两者就是一个东西。一个东西就一个地址了(其实这就是引用类型和普通类型的区别了)。你的别名叫“大灰狼”,你的家就是“大灰狼”的家,地址是一样的。


但是不知道你试过没有,不加上这个const它编译 是不通过的。出现的错误是:
error C2440: 'initializing' : cannot convert from 'int *' to 'int *&'

在这里,我再弱的问一句,int * &   和int & *这两个,前一个是一个引用,指向一个int *型对象的引用,后一个是一个地址,是一个int &对象的地址,,这样说,是不是正确?

#8


顶一个先

#1


1.i是变量,可以有别名,&i是个表达式,不是变量,所以……

2.这里,我们说refi是 指向i的引用, 它的内部存放的是一地址

红色部分是楼主想当然,事实不是如此……

#2


1.int * const &p_i = &i;
这个是说你的这个指针引用是个常量,也就是说你的这个指针是不能自加或者自减之类的改变的。加不加const限定符是你的*。
int i = 2; 
int &refi = i; 
同样,这个refi加const就是说这个refi这个引用类型是个常量。
所谓的“引用一经定义就不能再指向其它对象”是当其定义的时候(这时候必须初始化)比如
int &refi = i; 
refi就是i了,以后再使用refi的时候就是使用的i。
在对其赋值的时候,比如:
int c=3;
refi=c;
这里把c赋值给refi,也就是i=c;refi和i的值都变为3了。
2.引用就是个别名。refi就是i的别名,两者就是一个东西。一个东西就一个地址了(其实这就是引用类型和普通类型的区别了)。你的别名叫“大灰狼”,你的家就是“大灰狼”的家,地址是一样的。

#3


2楼说得太对了。

#4


你说的“我们说refi是指向i的引用”
C++Primer上也有事这么说的。我就不喜欢说“指向”,我说的时候就说refi是i的引用。

#5


   第一个问题是这样的:加const说明这是一个指针常量,这个指针中存放的地址只要经过赋值之后就不能再变,但是此指针所指向的值是可以改变的.

  第二个问题是这样的:内存不会为引用开辟新的内存空间,那么自然也就不会为引用分配内存地址,引用只是原来的变量的一个别名,他的地址和为其初始化的变量的地址是一样的

#6


我觉得你应该是在这里理解出现的问题:
1,
int i = 2; 
int &refi = i; 
这样,为什么就不用加const呢? 
【你之前指针加上const是加在*后面,意思就是说这个指针不能再随便指了,而这里引用就像2楼讲的那样,引用已经定义不再指向其他,所以你根本不用加上const,除非你的作用不是为了限制她指向的,你加上const,是为了让i不能再重新赋值,i就是常量2了,不过这样的话,你直接在i上加const不是更意图明显些么】
2,【这个我觉得1喽说的比较清楚些,指针你才说 指向,你那个就是个引用,就是个别名啊,所以当然是一个地址了】

#7


引用 2 楼 yangkunhenry 的回复:
1.int * const &p_i = &i;
这个是说你的这个指针引用是个常量,也就是说你的这个指针是不能自加或者自减之类的改变的。加不加const限定符是你的*。

int i = 2;
int &refi = i;
同样,这个refi加const就是说这个refi这个引用类型是个常量。
所谓的“引用一经定义就不能再指向其它对象”是当其定义的时候(这时候必须初始化)比如
int &refi = i;
refi就是i了,以后再使用refi的时候就是使用的i。
在对其赋值的时候,比如:
int c=3;
refi=c;
这里把c赋值给refi,也就是i=c;refi和i的值都变为3了。
2.引用就是个别名。refi就是i的别名,两者就是一个东西。一个东西就一个地址了(其实这就是引用类型和普通类型的区别了)。你的别名叫“大灰狼”,你的家就是“大灰狼”的家,地址是一样的。


但是不知道你试过没有,不加上这个const它编译 是不通过的。出现的错误是:
error C2440: 'initializing' : cannot convert from 'int *' to 'int *&'

在这里,我再弱的问一句,int * &   和int & *这两个,前一个是一个引用,指向一个int *型对象的引用,后一个是一个地址,是一个int &对象的地址,,这样说,是不是正确?

#8


顶一个先