关于函数传一级指针与二级指针的问题

奋斗小青年 2011-08-05 11:29:03
网上看很多资料,谈到值传递与引用传递。认为指针传递是值传递,传进来的是实参的副本。
比如一个这样的函数 void passParamType(char * p)
{
// p = &全局变量;
//*p = 'a';
}

void passParam2Type(char ** p)
{
//p = &另外的全局变量;
//*p = "mgh";
}
前面两个方法主要涉及到的一级指针与二级指针改变地址与所指向的内容的问题。
当函数传实参进来,比如第一个函数 就好像 p = array; 第二个也一样,其中array是个字符数组。
下面来说说我的想法。 对于两个函数当p = &全局变量,此时很多资料都是说此时操作的是实参的副本对实参没影响,这里我就有点迷糊了,这里干嘛非得扯上实参的副本,还是编译器机制就是这样(PS:编译器机制我不知道)p = &全局变量 这里是对形参重新给予了新的地址,对实参当然没影响。*p 这里倒好理解,形参p指向的实参的地址,*p当然就是实参的内容,因此就可以改变。 求各位麻烦指教下,小弟在此学习了。还望大家多指出我的错误所在。
...全文
470 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
Xomic 2011-08-05
  • 打赏
  • 举报
回复
还是传值,传址,引用的三种调用啊!

传值:实参给形参传值过后,他们再也没有任何瓜葛!

传址:也就是把实参的地址赋给形参(指针),从而间接改变实参的值!

引用:形参是实参的引用,这就是直接操作改变实参的值!

我是这样理解的,如有不妥之处还请高手指点。。。
jernymy 2011-08-05
  • 打赏
  • 举报
回复


void Tst(int *pnData) // pnData为形参,pnData指向nA的地址
{
*pnData = 50;
}

int main(void)
{
int nA = 10;

Tst(&nA); // nA 为实参
return 0;
}
hua_yang 2011-08-05
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 hua_yang 的回复:]
实参和形参的概念再理解一下

形参重新给予了新的地址,//我个人理解形参是函数定义时的一个概念,形式上的参数,代表这个参数的类型。

实际运行时,传入一个指针假如是p,系统会定义个新的指针指向p1,然后将p1=p,函数里通过p1来操作

这就是为什么叫副本
[/Quote]

笔误,应该是:系统会定义个新的指针p1

形参和实参只是概念

实际运行中都是数据的传递,指针的拷贝,指针的副本,叫什么都行

理解内部是怎么工作的就行
赵4老师 2011-08-05
  • 打赏
  • 举报
回复
无汇编,无真相!

VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
想要从本质上理解C指针,必须学习汇编以及C和汇编的对应关系。
从汇编的角度理解和学习C语言的指针,原本看似复杂的东西就会变得非常简单!
指针即地址。“地址又是啥?”“只能从汇编语言和计算机组成原理的角度去解释了。”

提醒:
“学习用汇编语言写程序”

“VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
想要从本质上理解C指针,必须学习C和汇编的对应关系。”
不是一回事!
奋斗小青年 2011-08-05
  • 打赏
  • 举报
回复
那资料上面说的副本难道就是形参?如果是这样,那我所提的问题,就可以攻破了。 期待各位发言
奋斗小青年 2011-08-05
  • 打赏
  • 举报
回复
9楼有点靠近我需要的答案了。再期待,欢迎各位踊跃发言,小弟虚心学习。
奋斗小青年 2011-08-05
  • 打赏
  • 举报
回复
等待我期望的答案。
hua_yang 2011-08-05
  • 打赏
  • 举报
回复
实参和形参的概念再理解一下

形参重新给予了新的地址,//我个人理解形参是函数定义时的一个概念,形式上的参数,代表这个参数的类型。

实际运行时,传入一个指针假如是p,系统会定义个新的指针指向p1,然后将p1=p,函数里通过p1来操作

这就是为什么叫副本
xiaoguangzaia 2011-08-05
  • 打赏
  • 举报
回复
你理解的对的
这个副本是说函数里面的那个参数又重新分配了一块内存用来存储这个指针,只是这个内存里面存放的内容
和实参内存里存放的内容一样(指针的话就是两个指针都指向同一块内存)。
普通的值传递和指针传递都是这样的
但是引用的时候就不会从新分配一块内存了,只是给实参其个别名
johnny_83 2011-08-05
  • 打赏
  • 举报
回复
其实,资料上说的实参的副本这么样得来的。其实指针就是一个变量,这个变量存放另一个变量的地址,不管是普通指针还是二重指针都是一样的这种理解。在函数传参时,采用的是值拷贝,指标变量的值拷贝,还是指针变量,指针变量里的值没有改变,所以它指向的地址也没有改变。引用指针里的地址所在变量,当然是同实参是同一个变量了。修改其值,就是修改实参的值。理解了吗?小弟
奋斗小青年 2011-08-05
  • 打赏
  • 举报
回复
现在我这里谈论的是为啥有的资料为啥是说传递的副本问题,请各位看清我说的话。其实我个人感觉副本这词明显是多余,不知大家有啥看法没,多指点迷津啊 高手们
shishuiruoshang 2011-08-05
  • 打赏
  • 举报
回复
指针传递传副本是说传的是指针所引用内存的副本,就指针值本身而言当然是值传递了
奋斗小青年 2011-08-05
  • 打赏
  • 举报
回复
[Quote=引用楼主 wanyuan19890515 的回复:]
网上看很多资料,谈到值传递与引用传递。认为指针传递是值传递,传进来的是实参的副本。
比如一个这样的函数 void passParamType(char * p)
{
// p = &全局变量;
//*p = 'a';
}

void passParam2Type(char ** p)
{
//p = &另外的全局变量;
/……
[/Quote]

这里 p与*p只执行一个 不是按顺序执行。看来我的表达方式很有问题啊。
bdmh 2011-08-05
  • 打赏
  • 举报
回复
你不能改变 p的指向,但可以改变p地址的实际值
奋斗小青年 2011-08-05
  • 打赏
  • 举报
回复
这里我主要想谈论 指针传递为啥非要说是传递的副本,我这只是个例子,也许不大好。麻烦看下我说的话,也许字太多难看了点
xiaoguangzaia 2011-08-05
  • 打赏
  • 举报
回复
有点看不懂,你在函数里面有p = &全局变量了,那么下面改变*p当然改变的就是这个全局变量了
所以你这个函数根本没必要有参数,参数传进来就被你扔掉了
yah606060 2011-08-05
  • 打赏
  • 举报
回复
#include<iostream>


void passParamType(char * p)// 在使用指针作为参数的时候 其实也做了拷贝 只是这个*p 和原来那个
{ p = new char('d'); // *p 指向的地址相同 而本身指针的值是不同的
*p = 'a';
}



void passParam2Type(char ** p) // 这里的p 是一个指向指针变量的指针 在使用的时候传入的的是指针
{ //是指针变量这个变量本身的地址 而不是指针中的值
// p = 这里能直接用非指针变量赋值的给p
**p = 'a';// *p指向的是 传入指针 不是这个指针的拷贝 所以 **p能 成功赋值
}

int _tmain(int argc, _TCHAR* argv[])
{
char* p = new char('c');

passParamType(p);
std::cout << p << std::endl;

char* p2 = new char('c');
std::cout << &p2 << std::endl;
passParam2Type(&p2);
std::cout << p2 << std::endl;
std::cout << &p2 << std::endl;

char p1 = 'c';
passParamType(&p1);
std::cout << p1 << std::endl;
int i;
std::cin >> i;

}

在使用指针的时候一定要把指针当做是一种变量类型
yah606060 2011-08-05
  • 打赏
  • 举报
回复
#include<iostream>


void passParamType(char * p)// 在使用指针作为参数的时候 其实也做了拷贝 只是这个*p 和原来那个
{ p = new char('d'); // *p 指向的地址相同 而本身指针的值是不同的
*p = 'a';
}



void passParam2Type(char ** p) // 这里的p 是一个指向指针变量的指针 在使用的时候传入的的是指针
{ //是指针变量这个变量本身的地址 而不是指针中的值
// p = 这里能直接用非指针变量赋值的给p
**p = 'a';// *p指向的是 传入指针 不是这个指针的拷贝 所以 **p能 成功赋值
}

int _tmain(int argc, _TCHAR* argv[])
{
char* p = new char('c');

passParamType(p);
std::cout << p << std::endl;

char* p2 = new char('c');
std::cout << &p2 << std::endl;
passParam2Type(&p2);
std::cout << p2 << std::endl;
std::cout << &p2 << std::endl;

char p1 = 'c';
passParamType(&p1);
std::cout << p1 << std::endl;
int i;
std::cin >> i;

}

在使用指针的时候一定要把指针当做是一种变量
奋斗小青年 2011-08-05
  • 打赏
  • 举报
回复
高手们都来发表下看法啊,别那么吝啬嘛
奋斗小青年 2011-08-05
  • 打赏
  • 举报
回复
大家都来发表下看法啥,呵呵
加载更多回复(1)

64,652

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧