链式队列的一个问题,为什么第一种可以运行,第二种没有报错但是运行会中断?

第一种:
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;

}

6个回答

楼主,你要注意了。对于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的修改。

运行:
图片说明

当然。程序还有一种改法,(只有c++可以,c不可以)就是用引用。

qq_37866775
qq_37866775 又晕了..C那个明白了,但是用引用的时候 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 *& '吗
一年多之前 回复
qq_37866775
qq_37866775 回复: 明白了 谢谢大佬
一年多之前 回复
caozhy
贵阳老马马善福专业维修游泳池堵漏防水工程 Lq qu; init(&qu);因为你并没有一个指针存储的是返回的指针,所以你这么写后面的指针还是错的。你自己调试下就知道了。
一年多之前 回复
qq_37866775
qq_37866775 好像明白点了..好绕啊,那使用引用的时候,void init(Lq * & qu); Lq qu; init(&qu); in_qu(&qu,1); out_qu(&qu);为什么这种方式不对?而Lq qu; Lq * p; p=&qu; init(p);就对了啊
一年多之前 回复
qq_37866775
qq_37866775 好像明白点了..好绕啊,那使用引用的时候void init(Lq * & qu); int main() { Lq qu; init(&qu); in_qu(&qu,1); out_qu(&qu); return 0; }
一年多之前 回复

你说的中断是什么意思,我这里第二种完全就没法运行,你的函数定义有问题,还是说你已经改掉了?麻烦发一下你现在的代码

运行成功的代码2

#include <stdlib.h>
#include <stdio.h>

typedef struct Qnode {//队列结点定义
    int data;
    Qnode * next;
}Qnode;

typedef struct Lq {//链队类型定义
    Qnode * front;
    Qnode * rear;
}Lq;

bool is_empty(Lq *qu) {//判断是否队空
    return qu->front==NULL||qu->rear==NULL;
}

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;
}

int main() {
    Lq qu;
    init(&qu);
    in_qu(&qu,1);
    in_qu(&qu,2);
    in_qu(&qu,3);
    out_qu(&qu);
    out_qu(&qu);
    out_qu(&qu);
    return 0;
}
qq_37866775
qq_37866775 好的,我贴到上面了,麻烦你帮忙看一下吧- -
一年多之前 回复
JonathanYan
JonathanYan 回复: 那你现在的代码是什么,别一句你贴错了就没下文了啊
一年多之前 回复
JonathanYan
JonathanYan 回复: 截图来看,我不知道你是什么问题
一年多之前 回复
qq_37866775
qq_37866775 啊,第二种我贴错了..我有问题的就是你说的这个,我不能运行啊,就是说运行后会输出“初始化成功”,然后就会弹出就会出现由于出现问题,程序停止正常工作
一年多之前 回复

#include
#include

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;

}

图片说明

引用的写法

 #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;

}
qq_37866775
qq_37866775 回复: 。。那我这样写不应该是对的吗void init(Lq * & qu); Lq qu; init(&qu);,qu是一般变量,&qu是指针,然后&qu这个被init函数引用..没毛病啊..
一年多之前 回复
caozhy
贵阳老马马善福专业维修游泳池堵漏防水工程 回复: 如果p是指针,那么&p就是指针的指针,而p是指针,如果p是一般变量,那么&p是指针。
一年多之前 回复
qq_37866775
qq_37866775 回复: 还是稀里糊涂的..抛开这道题int*p=&q,将p作为一个参数传入另一个函数,与,直接将&q作为一个参数传入另一个函数不一样吗
一年多之前 回复
caozhy
贵阳老马马善福专业维修游泳池堵漏防水工程 回复: 引用和取地址是两回事。好比*,它既是乘法,也是取地址,两者没有任何关系哦
一年多之前 回复
qq_37866775
qq_37866775 我知道应该这样写啊,,但就是我刚才问的那样,不明白为什么错了。。你这样定义传到int里是Lq*型的,那我先Lq qu,在直接取地址&qu不也是Lq*型.吗,不看后面的运行结果,就这一句,为什么会报错啊
一年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问