链式队列的一个问题,为什么第一种可以运行,第二种没有报错但是运行会中断
第一种:typedef struct Qnode//队列结点定义
{
int data;
Qnode * next;
}Qnode;
typedef struct Lq//链队类型定义
{
Qnode * front;
Qnode * rear;
}Lq;
bool is_empty(Lq *qu)//判断是否队空
{
if(qu->front==NULL||qu->rear==NULL)
{
return true;
}
else
return false;
}
void init(Lq * &qu)//初始化
{
qu=(Lq *)malloc(sizeof(Lq));
(*qu).front=(*qu).rear=NULL;
printf("初始化成功!\n");
}
void in_qu(Lq * qu,int a)//入队
{
Qnode *s;
s=(Qnode*)malloc(sizeof(Qnode));
s->next=NULL;
s->data=a;
if(is_empty(qu))
{
qu->front=qu->rear=s;
}
else
{
qu->rear->next=s;
qu->rear=s;
}
return;
}
void out_qu(Lq *qu)//出队
{
Qnode * p;
int a;
if(is_empty(qu))
{
printf("队空不能出队!\n");
return;
}
p=qu->front;
a=qu->front->data;
qu->front=p->next;
if(qu->front==NULL)//即队列中只有一个元素
qu->rear=NULL;
free(p);
printf("出队的元素是:%d\n",a);
return;
}
void out_qu(Lq *qu);
void in_qu(Lq * qu,int a);
bool is_empty(Lq *qu);
void init(Lq * & qu);
int main()
{
Lq qu;
Lq * p;
p=&qu;
init(p);
in_qu(p,1);
out_qu(p);
return 0;
}
第二种:
typedef struct Qnode//队列结点定义
{
int data;
Qnode * next;
}Qnode;
typedef struct Lq//链队类型定义
{
Qnode * front;
Qnode * rear;
}Lq;
bool is_empty(Lq *qu)//判断是否队空
{
if(qu->front==NULL||qu->rear==NULL)
{
return true;
}
else
return false;
}
void init(Lq * &qu)//初始化
{
qu=(Lq *)malloc(sizeof(Lq));
(*qu).front=(*qu).rear=NULL;
printf("初始化成功!\n");
}
void in_qu(Lq * qu,int a)//入队
{
Qnode *s;
s=(Qnode*)malloc(sizeof(Qnode));
s->next=NULL;
s->data=a;
if(is_empty(qu))
{
qu->front=qu->rear=s;
}
else
{
qu->rear->next=s;
qu->rear=s;
}
return;
}
void out_qu(Lq *qu)//出队
{
Qnode * p;
int a;
if(is_empty(qu))
{
printf("队空不能出队!\n");
return;
}
p=qu->front;
a=qu->front->data;
qu->front=p->next;
if(qu->front==NULL)//即队列中只有一个元素
qu->rear=NULL;
free(p);
printf("出队的元素是:%d\n",a);
return;
}
void out_qu(Lq *qu);
void in_qu(Lq * qu,int a);
bool is_empty(Lq *qu);
void init(Lq * & qu);
int main()
{
Lq qu;
init(&qu);
in_qu(&qu,1);
out_qu(&qu);
return 0;
} 呃,有点长……没仔细看
第二种 Lq qu; 本身是一个结构体,不是指针,而你在 init 的时候却把它当指针使用
第一种的 qu 没有实质的作用吧 claws0n 发表于 2018-10-3 23:37
呃,有点长……没仔细看
第二种 Lq qu; 本身是一个结构体,不是指针,而你在 init 的时候却把它当指针使用 ...
第二种里面 直接用&取地址不是一样吗..我看视频的时候记得那老师说指针就是地址- - 我们遇见过 发表于 2018-10-3 23:42
第二种里面 直接用&取地址不是一样吗..我看视频的时候记得那老师说指针就是地址- -
你什么编译器?
typedef struct Qnode//队列结点定义
{
int data;
struct Qnode * next;
}Qnode;
不一样哦,取址只有右值,指针参考的是左值,可以解引用得到右值
指针、取址、数组,很多时候可以互换,但是它们是不一样的东西 claws0n 发表于 2018-10-3 23:58
你什么编译器?
typedef struct Qnode//队列结点定义
{
好晕- -我之前typedef那个是你写的那样定义的,后来看课本里这样定义了就用这个了,我上面那个第二种贴错了,那个编译器会报错,但是
void out_qu(Lq *qu);
void in_qu(Lq * qu,int a);
bool is_empty(Lq *qu);
void init(Lq *qu);
int main()
{
Lq qu;
init(&qu);
in_qu(&qu,1);
out_qu(&qu);
return 0;
}
这个不会报错,但是运行会中断,但是,我把 in 和 out那个注释之后,只有init这一句就不会中断..这种情况他们不是都一样的吗..为什么一个会中断一个不会。。 claws0n 发表于 2018-10-3 23:58
你什么编译器?
typedef struct Qnode//队列结点定义
{
用的vc6.0- -考试要求用这个{:10_266:} 本帖最后由 claws0n 于 2018-10-4 01:21 编辑
我们遇见过 发表于 2018-10-4 00:07
好晕- -我之前typedef那个是你写的那样定义的,后来看课本里这样定义了就用这个了,我上面那个第二种贴错 ...
vc6.0 ...... 加油{:10_250:}
编译器:MinGW GCC 8.10 64位 状态:没问题
编译器:Borland C++ 64位 状态:没问题
编译器:TDM GCC 4.9.264位 状态:没问题
编译器:TDM GCC 4.9.232位 状态:卡……
问题:is_empty 判断错误,去到 else
原因不明{:10_282:}
还是那一句,不是指针就不要当指针用,也许 64 位的指针有 8 个字节,刚好够装你的单一测试数据
@人造人 ,反编译能看出吗? claws0n 发表于 2018-10-4 00:48
vc6.0 ...... 加油
编译器:MinGW GCC 8.10 64位 状态:没问题
编译器:Borland C++ 64位...
其实还有个题,就是我调试的时候也发现那个isempty莫名其妙跳到else了,然后我看答案,答案里那个init里的参数用的引用型,然后用引用型的话...我都不知道咋说了。。就是用引用型的话,主函数里的那个,该传入什么类型啊。。就是说函数定义是void init(Lq * & qu),那么主函数里写成init(&qu)为什么会报错啊,如果函数定义成void init(Lq * qu),主函数里那样写就不会报错。。 claws0n 发表于 2018-10-4 00:48
vc6.0 ...... 加油
编译器:MinGW GCC 8.10 64位 状态:没问题
编译器:Borland C++ 64 ...
人造人 发表于 2018-10-4 01:39
#include <stdio.h>
#include <stdlib.h>
typedef struct Qnode//队列结点定义
{
int data;
Qnode* next;
}Qnode;
typedef struct Lq//链队类型定义
{
Qnode* front;
Qnode* rear;
}Lq;
bool is_empty(Lq *qu)//判断是否队空
{
printf("%d\n", sizeof(qu));
if (qu->front == NULL || qu->rear == NULL)
return true;
else
return false;
}
void init(Lq * qu)//初始化
{
qu = (Lq *)malloc(sizeof(Lq));
(*qu).front = (*qu).rear = NULL;
printf("初始化成功!\n");
}
void in_qu(Lq *qu, int a)//入队
{
Qnode *s;
s = (Qnode*)malloc(sizeof(Qnode));
s->next = NULL;
s->data = a;
printf("in\n");
if (is_empty(qu))
{
printf("2\n");
qu->front = qu->rear = s;
}
else
{
printf("3\n");
qu->rear->next = s;
printf("4\n");
qu->rear = s;
}
printf("in2\n");
return;
}
void out_qu(Lq *qu)//出队
{
Qnode *p;
int a;
if (is_empty(qu))
{
printf("队空不能出队!\n");
return;
}
p = qu->front;
a = qu->front->data;
qu->front = p->next;
if (qu->front == NULL)//即队列中只有一个元素
qu->rear = NULL;
free(p);
printf("出队的元素是:%d\n", a);
return;
}
void out_qu(Lq *qu);
void in_qu(Lq *qu, int a);
bool is_empty(Lq *qu);
void init(Lq *qu);
int main()
{
Lq qu;
init(&qu);
printf("1\n");
in_qu(&qu, 1);
printf("12\n");
out_qu(&qu);
return 0;
} claws0n 发表于 2018-10-4 02:05
#include <stdio.h>
#include <stdlib.h>
typedef struct Qnode//队列结点定义
{
int data;
Qnode* next;
}Qnode;
typedef struct Lq//链队类型定义
{
Qnode* front;
Qnode* rear;
}Lq;
bool is_empty(Lq *qu)//判断是否队空
{
printf("%d\n", sizeof(qu));
if(qu->front == NULL || qu->rear == NULL)
return true;
else
return false;
}
// 初始化
void init(Lq *qu)
{
qu = (Lq *)malloc(sizeof(Lq));
(*qu).front = (*qu).rear = NULL;
printf("初始化成功!\n");
}
void in_qu(Lq *qu, int a)//入队
{
Qnode *s;
s = (Qnode*)malloc(sizeof(Qnode));
s->next = NULL;
s->data = a;
printf("in\n");
if(is_empty(qu))
{
printf("2\n");
qu->front = qu->rear = s;
}
else
{
printf("3\n");
qu->rear->next = s;
printf("4\n");
qu->rear = s;
}
printf("in2\n");
return;
}
void out_qu(Lq *qu)//出队
{
Qnode *p;
int a;
if(is_empty(qu))
{
printf("队空不能出队!\n");
return;
}
p = qu->front;
a = qu->front->data;
qu->front = p->next;
if(qu->front == NULL)//即队列中只有一个元素
qu->rear = NULL;
free(p);
printf("出队的元素是:%d\n", a);
return;
}
void out_qu(Lq *qu);
void in_qu(Lq *qu, int a);
bool is_empty(Lq *qu);
void init(Lq *qu);
int main()
{
Lq qu;
Lq *tmp = &qu;
printf("front:%.8X, rear:%.8X\n", tmp->front, tmp->rear);
init(&qu);
printf("front:%.8X, rear:%.8X\n", tmp->front, tmp->rear);
printf("*******************************\n");
qu.front = NULL;
qu.rear = NULL;
printf("front:%.8X, rear:%.8X\n", tmp->front, tmp->rear);
exit(1);
printf("1\n");
in_qu(&qu, 1);
printf("12\n");
out_qu(&qu);
return 0;
}
front:CCCCCCCC, rear:CCCCCCCC
初始化成功!
front:CCCCCCCC, rear:CCCCCCCC
*******************************
front:00000000, rear:00000000
请按任意键继续. . .
// 初始化
void init(Lq *qu)
{
qu = (Lq *)malloc(sizeof(Lq));
(*qu).front = (*qu).rear = NULL;
printf("初始化成功!\n");
} claws0n 发表于 2018-10-4 02:05
#include <stdio.h>
void Fun1(int *n)
{
n = 0;
}
void Fun2(int *n)
{
*n = 0;
}
int main()
{
int a = 10;
printf("%.8X\n", a);
Fun1(&a);
printf("%.8X\n", a);
printf("\n");
printf("%.8X\n", a);
Fun2(&a);
printf("%.8X\n", a);
return 0;
}
0000000A
0000000A
0000000A
00000000
请按任意键继续. . . claws0n 发表于 2018-10-4 02:05
这个不还是不能运行吗。。可能编译器问题?{:10_266:} 人造人 发表于 2018-10-4 02:28
没看明白..是第一个函数没有改变a吗.. 人造人 发表于 2018-10-4 02:19
这个执行init后front,rear为什么没改变啊..传入的是地址不应该改变了吗.. 看了在csdn别人的解答,感觉相对清楚点吧,但还是没完全搞懂。。。有相同问题的朋友自行理解吧,同时谢谢楼上的两位大佬不辞辛苦大半夜在帮我解答,万分感谢
楼主,你要注意了。对于c++来说,除非传递引用(也就是你所谓正确的方式),否则在函数内修改一个变量,永远无法作用到实参上。
void init(Lq * qu)//初始化
{
qu=(Lq *)malloc(sizeof(Lq));
(*qu).front=(*qu).rear=NULL;
printf("初始化成功!\n");
}
这段代码,你虽然修改了qu,让qu指向你分配的内存。但是退出函数,
init(&qu);
这里的qu并不会改变。
请注意以下两个的区别:
(1)修改一个指针,让它指向另一个地址,这个不会作用到实际参数
(2)通过指针,修改其指向的内容。这个会作用到实际参数指向的内容,因为两者共享的是相同的内容。
因此,如果你要在函数内改变指针指向的内容,那么用指针就可以。要改变指针的指向,让它指向另一个地址,那么必须用指针的指针(2个指针)
此时对于第二个指针,它指向实际的内容,第一个指针,指向第二个指针,而你可以修改第一个指针的指向,从而将第二个指针指向的内容作用到调用者。
修改以后的程序:
#include "stdio.h"
#include "stdlib.h"
typedef struct Qnode//队列结点定义
{
int data;
Qnode * next;
}Qnode;
typedef struct Lq//链队类型定义
{
Qnode * front;
Qnode * rear;
}Lq;
bool is_empty(Lq *qu)//判断是否队空
{
if(qu->front==NULL||qu->rear==NULL)
{
return true;
}
else
return false;
}
void init(Lq ** qu)//初始化
{
*qu=(Lq *)malloc(sizeof(Lq));
(*qu)->front=(*qu)->rear=NULL;
printf("初始化成功!\n");
}
void in_qu(Lq * qu,int a)//入队
{
Qnode * s;
s=(Qnode *)malloc(sizeof(Qnode));
s->next=NULL;
s->data=a;
if(is_empty(qu))
{
qu->front=qu->rear=s;
}
else
{
qu->rear->next=s;
qu->rear=s;
}
return;
}
void out_qu(Lq * qu)//出队
{
Qnode * p;
int a;
if(is_empty(qu))
{
printf("队空不能出队!\n");
return;
}
p=qu->front;
a=qu->front->data;
qu->front=p->next;
if(qu->front==NULL)//即队列中只有一个元素
qu->rear=NULL;
free(p);
printf("出队的元素是:%d\n",a);
return;
}
void out_qu(Lq * qu);
void in_qu(Lq * qu,int a);
bool is_empty(Lq *qu);
void init(Lq * qu);
int main()
{
Lq * qu;
init(&qu);
in_qu(qu,1);
out_qu(qu);
return 0;
}
注意我对main和init的修改。 我们遇见过 发表于 2018-10-4 10:55
看了在csdn别人的解答,感觉相对清楚点吧,但还是没完全搞懂。。。有相同问题的朋友自行理解吧,同时谢谢楼 ...
嗯,合理使用指针。
Lq *qu; //在 main 函数里,这个是重点
因为 void init(Lq **qu); 所以 init(&qu); 如果不是空型,可以用单指针。
之后所有的函数调用,数据类型吻合,都是指针
init 定义对,但声明错了,是双指针。 claws0n 发表于 2018-10-4 11:43
嗯,合理使用指针。
Lq *qu; //在 main 函数里,这个是重点
因为 void init(Lq **qu); 所以 init(&qu); ...
我又有问题了。。这个双指针这个我明白了,但是没明白引用。。
void init(Lq * & qu);
init(&qu);main函数中只运行这一句,这个会直接报错,,错误信息cannot convert parameter 1 from 'struct Lq *' to 'struct Lq *& ',
用这个是正确的Lq qu; Lq * p; p=&qu; init(p);,正确的这个里面不也是 from 'struct Lq *' to 'struct Lq *& '吗,,为什么一个可以一个不可以啊。。 我们遇见过 发表于 2018-10-4 12:57
我又有问题了。。这个双指针这个我明白了,但是没明白引用。。
void init(Lq * & qu);
init(&qu);main ...
你说的是第一种和第二种吗?
数据类型不匹配。第一种正确,p 是指针,你引用了,那个 & 不是取址。
第二种,qu 不是指针,函数不会帮你转 claws0n 发表于 2018-10-4 13:17
你说的是第一种和第二种吗?
数据类型不匹配。第一种正确,p 是指针,你引用了,那个 & 不是取址。
第 ...
不明白...抛开这道题int*p=&q,将p作为一个参数传入另一个函数,与,直接将&q作为一个参数传入另一个函数不一样吗