#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引用(隐式转换)
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得到的地址只给了一个复制的指针,原指针并没有改变
否则参数是按值传递,也就是说函数中形参只是外面实参的复制品
你在函数中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执行停在该断点处的时候。
计算机组成原理→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执行停在该断点处的时候。
#10
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引用(隐式转换)
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得到的地址只给了一个复制的指针,原指针并没有改变
否则参数是按值传递,也就是说函数中形参只是外面实参的复制品
你在函数中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执行停在该断点处的时候。
计算机组成原理→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
test定义改成void test(int *p)就会报错
#11
你可以理解为int *&p只是将形参绑定到实参,并没有
使用实参的值,而int *p需要将实参的值复制给形参,因此
使用了实参的值。