struct PolyNode
{
int coef;
int expon;
PolyNode *Link;
};
typedef PolyNode *Polynomial;
struct PolyQueue
{
Polynominal Front;
Polynominal Rear;
};
typedef PolyQueue *PolyQueuePtrl;
void AddPolyNode(PolyQueuePtrl Ptrl, const int coef, const int expon)
{
Polynominal Temp = new PolyNode;
Temp->coef = coef;
Temp->expon = expon;
Temp->Link = nullptr;
if (Ptrl->Front == nullptr)
Ptrl->Front = Temp;
if (Ptrl->Rear != nullptr)
Ptrl->Rear->Link = Temp;
Ptrl->Rear = Temp;
}
void Attach(Polynomial &rear, const int coef, const int expon)
{
rear->Link = new PolyNode;
rear = rear->Link;
rear->coef = coef;
rear->expon = expon;
rear->Link = nullptr;
}
最近在学习数据结构,在用 C++实现一个队列的时候,有了一个疑问希望能获得各位大佬的解答。我写了两个函数来实现在队列末尾新增一个元素的操作。一个传入的是队列的指针,另外一个传入的是队列里面的 Rear 指针,定义和具体实现在上方代码中,在传入队列指针的时候直接传入即可实现插入的操作,但是在传入 Rear 指针的时候一定要传入 Rear 指针的引用才可以,同样是指针为什么一个传值就可以了,另一个要传引用呢?
1
zjsxwc 2019-07-04 11:55:14 +08:00
|
2
srt180 2019-07-04 11:57:37 +08:00 via iPhone
需要改变入参就引用
|
3
jmc891205 2019-07-04 12:03:25 +08:00
我猜你是插入之后看 ptrl->rear 来检查有没有插入成功
你的 Attach 只传指针进去的时候 插入其实是成功了的 但是 ptrl->rear 没有更新 所以你以为是插入没有成功 |
4
Tony042 OP @zjsxwc 是的,谢谢你,代码是正确的代码,我的意思是,为什么把 Attach 函数第一个参数由&rear 改成 rear 就不对了呢
|
6
Tony042 OP @srt180 但是两个都是指针呀,我目前的理解是传入指针指向的结构体里的指针与传值一样,如需修改得声明饮用,但是传指针的话是不用声明引用就可以直接修改的。
|
7
Tony042 OP @zjsxwc 我贴的代码是正确的代码,但是如果把 void Attach(Polynomial &rear, const int coef, const int expon)这个声明改成 void Attach(Polynomial rear, const int coef, const int expon) 这个函数就不生效了,所以我是想问 rear 和&rear 的区别
|
8
Tony042 OP @jmc891205 对的是这样的,可为什么没更新呢,我通过 attch 函数传入的那个参数值就是 Ptrl->Rear, 比如 Attach ( Ptrl->Rear,3,5)
|
9
zjsxwc 2019-07-04 12:40:15 +08:00
@Tony042
我发的代码里 &rear 改成 rear 后, 仍旧生效。 rear 和&rear 的区别, 简单来说 只是 “副作用”的区别, &引用方式是有副作用的,在子函数里对变量的修改,会影响到外面调用函数里的变量值, 一般&引用方式传值是为了能够返回变量, 比较 C++不能和 golang 那样一次性 return 多个值。 |
10
zjsxwc 2019-07-04 12:41:11 +08:00
“比较 ” ---》 “毕竟”
|
11
Tony042 OP @zjsxwc xi 谢谢您的回复,我运行了您的,如果输出 pqp->rear->coef 的值的话,AttachTest 是不生效的,我在您的代码后面加了一个 cout 输出,请您瞅一下 https://paste.ubuntu.com/p/pzTNnPC74x/
|
12
srt180 2019-07-04 12:46:54 +08:00 via iPhone
@Tony042 指针就是地址,加不加引用代码逻辑都完成了。不同的是加引用的话 attach 函数 rear 的实参变成了入参的 link,不加引用的话 rear 的实参还是入参,相当于对参数而言加了引用就是读写权限,不加就是只读。
AddPolynode 函数不需要引用是因为入参只读了。 |
13
zjsxwc 2019-07-04 12:49:20 +08:00
|
14
Tony042 OP @srt180 谢谢讲解,感觉有点转过来了,AddPolynode 和 Attach 的区别还是在于指针更改了没有,由于 Attach 更改了指针所以要用引用,刚学 C++没多久,遇到指针还是很迷,还好有你们的帮助
|
19
lvdong 2019-07-04 13:00:58 +08:00 1
指针本身也是变量,如果要改变指针自身的值,就需要引用,仅改变指针指向变量的值,指针按照值传递就可以了
|
20
stackexplode 2019-07-04 14:26:36 +08:00
越搞不懂 C++,在学习过程中就越不要用那么多 typedef,什么 Polynomial &,真的非常容易混淆
你参数展开成 PolyNode *& rear,一下就懂了,传进来的是指针的引用,你一旦修改 rear,传进来的指针值就会被修改 如果是 PolyNode * rear,传进来只是一个指针,也就是一个值,修改 rear 就不会对传入方有影响 |
21
b00tyhunt3r 2019-07-04 16:32:51 +08:00
nullptr 是什么?宏吗?
|
22
b00tyhunt3r 2019-07-04 16:37:52 +08:00
@b00tyhunt3r 饿 查了一下原来是 11 的新类型,请问这里为什么不直接用 NULL ?
|
23
jmc891205 2019-07-04 16:47:17 +08:00
|
24
b00tyhunt3r 2019-07-04 17:00:21 +08:00
@jmc891205 这个理解,NULL 相当于还是有个 0 值
但楼主这里用 nullptr 的意义是? |
25
jmc891205 2019-07-04 17:08:50 +08:00
@b00tyhunt3r
意义是养成在所有地方都用 nullptr 抛弃 NULL 的好习惯 |
26
b00tyhunt3r 2019-07-04 18:17:07 +08:00
LZ,你的代码我原样复制在 mac+gcc4.2.1 上跑了一遍,
结果很奇怪,直接报了错 segmentation fault:11, 排查了一下发现是这句的问题: Ptrl->Rear->Link = Temp; 具体来说把 “->Link ”注释掉就好了,应该是直接调用了 link 这个空指针。 你运行没问题吗? 也请大佬帮忙看一下谢谢 @jmc891205 @stackexplode @zjsxwc @srt180 |
27
jmc891205 2019-07-04 19:07:09 +08:00 via iPhone
@b00tyhunt3r 把你调用 lz 函数的代码贴出来
|
28
b00tyhunt3r 2019-07-04 19:30:59 +08:00
#include <iostream>
using namespace std; struct poly { int coef; int expon; poly* link; }; typedef poly* node; struct polyqueue { node front; node rear; }; typedef polyqueue* polyq; void addpoly(polyq q, const int coef, const int expon) { node tmp = new poly; tmp->coef = coef; tmp->expon = expon; tmp->link = nullptr; if(q->front == nullptr) {q->front = tmp;} if(q->rear != nullptr) {q->rear->link = tmp;} q->rear = tmp; } int main() { polyq x=new polyqueue; addpoly(x,1,1); return 0; } @jmc891205 是一样的啊 |
29
jmc891205 2019-07-04 20:22:28 +08:00
@b00tyhunt3r
类成员是指针的话 编译器自动生成的默认构造函数 不保证能正确地初始化他们为 nullptr |
30
Tony042 OP @jmc891205 那为什么这个代码 https://paste.ubuntu.com/p/tD66H7V74M/运行没问题,但 @b00tyhunt3r 的就有问题呢,我在 windows 下用 clang 跑了一遍,遇到的也是相同的情况
|
31
Tony042 OP @b00tyhunt3r 楼里面的大佬说的应该是对的,我在初始化 PolyQueue 类型指针的时候,是调用了另一个函数显示初始化它们为 nullptr,但是我现在也不太明白为什么 https://paste.ubuntu.com/p/tD66H7V74M/这个代码运行起来没问题,而运行你的代码就会 stackfault
|
32
b00tyhunt3r 2019-07-04 21:40:45 +08:00
|
33
jmc891205 2019-07-04 21:46:53 +08:00
|
34
jmc891205 2019-07-04 21:50:29 +08:00
|