专注收集记录技术开发学习笔记、技术难点、解决方案
网站信息搜索 >> 请输入关键词:
您当前的位置: 首页 > C语言

一个奇怪的指针有关问题.难道不能修改传入指针的值么

发布时间:2011-06-28 12:12:40 文章来源:www.iduyao.cn 采编人员:星星草
一个奇怪的指针问题...难道不能修改传入指针的值么?
在写一个栈的东西,在销毁的时候有点小问题
#define POSITION int
#define SIZE_T int
#define ELEMTYPE char
#define BUTTOM -1
struct stStack {
POSITION top;
ELEMTYPE *buffer;
SIZE_T MAXNUM;
SIZE_T length;
};
typedef struct stStack *PSeqStack;

如果这样写:
int destroy(PSeqStack *pstack)
{
if (*pstack==NULL) return 0;
if ((*pstack)->buffer==NULL)
{
free(*pstack);
return 1;
}
free((*pstack)->buffer);
free(*pstack);
*pstack=NULL;
return 1;
}

int main()
{
PSeqStack stack=createEmptyStack(5);
destroy(&stack);
printStack(stack);
system("pause");
return 0;
}

这样写是完全没问题的
但是——
int destroy(PSeqStack pstack)
{
if (pstack==NULL) return 0;
if ((pstack)->buffer==NULL)
{
free(pstack);
return 1;
}
free((pstack)->buffer);
free(pstack);
pstack=NULL;
return 1;
}

int main()
{
PSeqStack stack=createEmptyStack(5);
destroy(stack);
printStack(stack);
system("pause");
return 0;
}
这样在printStack(stack);的时候就会出错
通过调试,发现stack的值居然还不为NULL!但是如果用第一个的话就可以。
请大神来解释下好么?

------解决方案--------------------
如果函数原型为
int destroy(PSeqStack pstack);

当你调用
destroy(stack);

的时候,只是把stack的值赋给了形参pstack。。也就是说pstack是stack的副本。。它们共同都指向了你要free的那个对象。。
然后在destroy中,你把对象free了,把pstack赋值为NULL,但这并没有改变stack的值,它依然指向你已经free掉的那个对象。。
------解决方案--------------------
引用:
Quote: 引用:

唉,初学者百分之百分在这个问题上绊倒,而且在此之前他们都相信自己掌握了传值和传地址,殊不知......

嗯嗯,主要是对这个概念理解的的确不够深入,请问传入数组的时候是传入同一个指针么?

你需要了解的是指针本身也是一个变量,其值是一个地址,注意这个地址是指针指向变量的地址,不是指针自己变量的地址,所以如果以指针作函数参数,那么形参和实参都是一个地址,都指向同一个变量(被实参指针指向的变量),可以通过这个地址改变被指向变量的值,但若你修改形参指针本身的值,实参指针并不会得到修改,因为实参指针与形参指针是两个不同的变量,占据不同的内存位置,只不过传入参数时使这两个变量具有相同的值(被指向变量的地址)。
所以,如果你想修改一个变量,请传递此变量的地址(指针)。如果你想修改一个指针本身,请传递此指针的地址,也就是指针的指针,即二级指针。
------解决方案--------------------
计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构……

对学习编程者的忠告:
眼过千遍不如手过一遍!
书看千行不如手敲一行!
手敲千行不如单步一行!
单步源代码千行不如单步对应汇编一行!

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

想要从本质上理解C指针,必须学习汇编以及C和汇编的对应关系。
从汇编的角度理解和学习C语言的指针,原本看似复杂的东西就会变得非常简单!
指针即地址。“地址又是啥?”“只能从汇编语言和计算机组成原理的角度去解释了。”
但我又不得不承认:
 有那么些人喜欢或者适合用“先具体再抽象”的方法学习和理解复杂事物;
 而另一些人喜欢或者适合用“先抽象再具体”的方法学习和理解复杂事物。
而我本人属前者。

这辈子不看内存地址和内存值;只画链表、指针示意图,画堆栈示意图,画各种示意图,甚至自己没画过而只看过书上的图……能从本质上理解指针、理解函数参数传递吗?本人深表怀疑!
这辈子不种麦不收麦不将麦粒拿去磨面;只吃馒头、吃面条、吃面包、……甚至从没看过别人怎么蒸馒头,压面条,烤面包,……能从本质上理解面粉、理解面食吗?本人深表怀疑!!
友情提示:
信息收集于互联网,如果您发现错误或造成侵权,请及时通知本站更正或删除,具体联系方式见页面底部联系我们,谢谢。

其他相似内容:

热门推荐: