关于C/C++ 指针类型的疑问。

![图片说明](https://img-ask.csdn.net/upload/201710/22/1508687842_258506.jpg

我的疑问在于,既然有了
typedef struct TNode *Position;
typedef Position BinTree;
那么 BinTree 就是一种指针了吧。或者说由BinTree定义出来的变量就是一个指针?(我不知道啊,我理解的是)
在主函数传递一个 BinTree的指针过去(区别于传递变量,只是在不同地址赋值相同) 加上引用又有什么作用呢?
在Create函数里面 也是对BT指针进行的操作啊。
指针本质上不就是一个地址么?传送地址 与在Creat函数里面对这个地址的操作 加引用又有什么作用呢?
(然而经过我多次测试 必须加这个 & 引用的,不然是不对的。)
很是困惑啊。

同样还有一个 在链表的,是一样的情况。
图片说明

既然typedef struct LNode {
ElemType data;
LNode * next;
}LNode, *LinkList;

那么 LinkList 就是 struct LNode 的一个指针类型啊,本质上就一个指针。
int ListCreate_L(LinkList &L) {
L = (LNode *)malloc(sizeof(LNode));
L = (LNode *)malloc(sizeof(LNode));
还有这句话 说明L 就是一个指针啊,
而在函数头上 却对 L 前面加个了 &(引用),不明白为什么这样操作。
(也经过多次测试了,不加这个&也是不对的)。

呜呜呜呜。。求解啊。

3个回答

你看下下面的知识,再想想看。。。

要点:每块申请的内存都有它固定的首地址,而我们要做的就是将这个首地址告诉这个“外部指针”,但是这个“外部指针”必须满足以下其中一个条件

(1)传递的是指针的引用

(2)传递的是指针的指针

为什么直接传递指针不可以呢?我们看一个示例:

class A {
public:
A() { cout << "A" << endl; }
~A() { cout << "~A" << endl; }
};

class Ex_AA {
public:
A _a;
};

void init(Ex_AA aa) {

}

int main(void)

{

Ex_AA aa;
init(aa);

}

输出:

A
~A
~A
请按任意键继续. . .
这就是我们常说的值传递了,从上面可以看到调用过程中会产生一个A的副本,结束后A的副本会释放掉。

所以如果是直接传递指针,调用完成后这个指针变量(也就是原指针变量的副本)会释放掉它所存储的地址信息,申请的内存地址仍然没有传递出去!

qq_37337190
Leslie__Chin 所以按照我现在的理解,若是Creat以后,任何其他的操作 不论是修改还是删除 不加引用都是没有问题了吧,只要主函数里面的L不是NULL就行?不知道这个延伸的对不对?
接近 3 年之前 回复
qq_37337190
Leslie__Chin 哇 我终于懂了。我从一开始就进入了一个误区,我始终认为主函数传递过去了L,我认为L已经存在了,要对L进行空间分配,其实主函数里面的L啥都没有是个NULL,Creat给创造了一个地址,并且分配了该地址内存,要做的是把Creat函数里面malloc得到的地址传递出去。谢谢老哥这几天的帮助。
接近 3 年之前 回复
JasBin2008
JasBin2008 回复Leslie__Chen:返回时在堆里分配的内存还在,必须delete或free释放掉,可以理解为“买的快递还在,快递员把地址给弄丢了”
接近 3 年之前 回复
qq_37337190
Leslie__Chin 哎 我又突然想起来, 在你给我写的例子上 void init(Ex_AA, &aa) 这样的话 就没有那个副本 也就只调用一个析构函数了吧?
接近 3 年之前 回复
qq_37337190
Leslie__Chin 我看了好几遍应该是看懂了,如果应用到最初例子上面的话、是不是可以这样理解:在退出Creat函数返回主函数之前的的一切操作都是合理的,但是在返回时,会把当前函数的L 还有L存储的指针物理内存上的内容也一并抹去了?这样理解对么?
接近 3 年之前 回复
qq_37337190
Leslie__Chin 强无敌。多谢老哥了。
接近 3 年之前 回复

掉用的地方:
ListCreate_L(L); ----原L的地址,假设L的地址为0x12345678

掉用的函数:
int ListCreate_L(LinkList L) ----这里的L是原L的一个副本,假设此处L的地址为0x87654321
{
L = (LNode *)malloc(sizeof(LNode)); ---给L申请了内存
} -----出了大括号,申请的内存还存在,,但存储指针L的地址0x87654321将被释放掉。原L的地址0x12345678仍然为NULL!!!

用法:使用指针的引用或指针的指针来申请内存
int ListCreate_L(LinkList &L) ----这里仍然为0x12345678
{
}

int ListCreate_L(LinkList *L)
{
LinkList *LL = *L; ----同样为0x12345678
}

qq_37337190
Leslie__Chin 回复布莱特桑尼: 哇 老哥看看楼下 。
接近 3 年之前 回复
JasBin2008
JasBin2008 调用。。。写错了。。。
接近 3 年之前 回复

我基本看懂了你想表达的意思了。可是还存在一些疑问。
L的存储地址变了,可是L本身的数据不应该变的吧?
就像传递一个整数a,会开辟新的空间,赋值为a,。
那么在开辟新的物理地址存储L所对应的指针(地址)的数值大小也是相同的啊,对这个地址的操作就可以完成任务啊?
这是我的理解,(肯定是有问题),但是我不知道错在哪里。

我的理解的一个小例子;图片说明
int a = 5;
int *p1 = &a;
int *p2 = p1;

 p1  p2 是存在不同的两个地址上,但是他们存的数字(一个int类型的指针)应该是相同的啊。
 为什么同样的赋值操作,就不适应于上面最初的问题了呢?
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问