未初始化化的指针为什么可以赋值给指针的引用?

时间:2021-09-23 19:47:58

#include<iostream>
using namespace std;
void test(int *&p)
{
p = new int;
*p = 5;
}
int main()
{
int *a;
test(a);
cout << *a << endl;
return 0;
}

上面代码没问题,把函数声明改为如下形式:

void test(int *p)
{
p = new int;
*p = 5;
}

编译能通过,但是运行时会出错

11 个解决方案

#1


题目后面写错了
上面代码没问题,把函数声明改为如下形式:

void test(int *p)
{
    p = new int;
    *p = 5;
}

#2


指针本身绑定为引用,那么函数内对指针的修改就会反应到实参
p = new int; //p最开始是实参的值,未初始化,现在申请一个空间并把地址赋值给p

但是第二段代码,p是通过值传递,那么函数内会拷贝一个临时的副本假设为_p,_p = new int
而实参a的值并没有被修改,依然是未初始化时候的值(理论上是任意值),所以外部访问它指向的内存,可能造成程序崩溃

你题目所描述的问题,跟普通引用是一样的道理,一个同样类型的数据是可以绑定到该类型的引用或者const引用(隐式转换)

#3



#include<iostream>
using namespace std;
void test(int *&p)
{
    p = new int;
    *p = 5;
}
int main()
{
    int *a;
    test(a);
    return 0;
}

我把输出语句去掉,上面这段代码运行时也出错。

#4


#include<iostream>
using namespace std;
void test(int *&p)
{
    p = new int;
    *p = 5;
}
int main()
{
    int *a;
    test(a);
    return 0;
}


这段代码我在visual studio 下测试运行正常,
能发一下报的什么错吗?

#5


未初始化的指针不能使用!

这是理解题目的关键。

#6




#include<iostream>
using namespace std;
void test(int *&p)
{
p = new int;
*p = 5;
}
int main()
{
int *a;
test(a);//调用完这个函数后,a已经被赋值了(test函数中new操作符)
cout << *a << endl;//可以取a指针的内容
return 0;
}





void test(int *p)//这里p是传值的形式到test,
{
p = new int;//虽然new了空间,但test外在的实参无法获取到这个new的空间
*p = 5;
}

#7


你需要传递指针的引用到函数中

否则参数是按值传递,也就是说函数中形参只是外面实参的复制品

你在函数中new得到的地址只给了一个复制的指针,原指针并没有改变

#8


未初始化化的指针为什么可以赋值给指针的引用?理解讨论之前请先学会如何 观察

计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构……

对学习编程者的忠告:
未初始化化的指针为什么可以赋值给指针的引用?多用小脑和手,少用大脑、眼睛和嘴,会更快地学会编程!
眼过千遍不如手过一遍!
书看千行不如手敲一行!
手敲千行不如单步一行!
单步源代码千行不如单步Debug版对应汇编一行!
单步Debug版对应汇编千行不如单步Release版对应汇编一行!
不会单步Release版对应汇编?在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有,然后在IDE中运行。(一般人我不告诉他! 未初始化化的指针为什么可以赋值给指针的引用?

单步类的实例“构造”或“复制”或“作为函数参数”或“作为函数返回值返回”或“参加各种运算”或“退出作用域”的语句对应的汇编代码几步后,就会来到该类的“构造函数”或“复制构造函数”或“运算符重载”或“析构函数”对应的C/C++源代码处。

VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。

#9


http://edu.csdn.net/course/detail/2344 C语言指针与汇编内存地址-一.代码要素

#10


引用 4 楼 fight_in_dl 的回复:
#include<iostream>
using namespace std;
void test(int *&p)
{
    p = new int;
    *p = 5;
}
int main()
{
    int *a;
    test(a);
    return 0;
}


这段代码我在visual studio 下测试运行正常,
能发一下报的什么错吗?

test定义改成void test(int *p)就会报错

#11


你可以理解为int *&p只是将形参绑定到实参,并没有 使用实参的值,而int *p需要将实参的值复制给形参,因此 使用了实参的值

#1


题目后面写错了
上面代码没问题,把函数声明改为如下形式:

void test(int *p)
{
    p = new int;
    *p = 5;
}

#2


指针本身绑定为引用,那么函数内对指针的修改就会反应到实参
p = new int; //p最开始是实参的值,未初始化,现在申请一个空间并把地址赋值给p

但是第二段代码,p是通过值传递,那么函数内会拷贝一个临时的副本假设为_p,_p = new int
而实参a的值并没有被修改,依然是未初始化时候的值(理论上是任意值),所以外部访问它指向的内存,可能造成程序崩溃

你题目所描述的问题,跟普通引用是一样的道理,一个同样类型的数据是可以绑定到该类型的引用或者const引用(隐式转换)

#3



#include<iostream>
using namespace std;
void test(int *&p)
{
    p = new int;
    *p = 5;
}
int main()
{
    int *a;
    test(a);
    return 0;
}

我把输出语句去掉,上面这段代码运行时也出错。

#4


#include<iostream>
using namespace std;
void test(int *&p)
{
    p = new int;
    *p = 5;
}
int main()
{
    int *a;
    test(a);
    return 0;
}


这段代码我在visual studio 下测试运行正常,
能发一下报的什么错吗?

#5


未初始化的指针不能使用!

这是理解题目的关键。

#6




#include<iostream>
using namespace std;
void test(int *&p)
{
p = new int;
*p = 5;
}
int main()
{
int *a;
test(a);//调用完这个函数后,a已经被赋值了(test函数中new操作符)
cout << *a << endl;//可以取a指针的内容
return 0;
}





void test(int *p)//这里p是传值的形式到test,
{
p = new int;//虽然new了空间,但test外在的实参无法获取到这个new的空间
*p = 5;
}

#7


你需要传递指针的引用到函数中

否则参数是按值传递,也就是说函数中形参只是外面实参的复制品

你在函数中new得到的地址只给了一个复制的指针,原指针并没有改变

#8


未初始化化的指针为什么可以赋值给指针的引用?理解讨论之前请先学会如何 观察

计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构……

对学习编程者的忠告:
未初始化化的指针为什么可以赋值给指针的引用?多用小脑和手,少用大脑、眼睛和嘴,会更快地学会编程!
眼过千遍不如手过一遍!
书看千行不如手敲一行!
手敲千行不如单步一行!
单步源代码千行不如单步Debug版对应汇编一行!
单步Debug版对应汇编千行不如单步Release版对应汇编一行!
不会单步Release版对应汇编?在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有,然后在IDE中运行。(一般人我不告诉他! 未初始化化的指针为什么可以赋值给指针的引用?

单步类的实例“构造”或“复制”或“作为函数参数”或“作为函数返回值返回”或“参加各种运算”或“退出作用域”的语句对应的汇编代码几步后,就会来到该类的“构造函数”或“复制构造函数”或“运算符重载”或“析构函数”对应的C/C++源代码处。

VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。

#9


http://edu.csdn.net/course/detail/2344 C语言指针与汇编内存地址-一.代码要素

#10


引用 4 楼 fight_in_dl 的回复:
#include<iostream>
using namespace std;
void test(int *&p)
{
    p = new int;
    *p = 5;
}
int main()
{
    int *a;
    test(a);
    return 0;
}


这段代码我在visual studio 下测试运行正常,
能发一下报的什么错吗?

test定义改成void test(int *p)就会报错

#11


你可以理解为int *&p只是将形参绑定到实参,并没有 使用实参的值,而int *p需要将实参的值复制给形参,因此 使用了实参的值