
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, cons 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 指针本身也是变量,如果要改变指针自身的值,就需要引用,仅改变指针指向变量的值,指针按照值传递就可以了 |
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 |