麻烦看看这个为啥会无限循环
用C语言实现的舞伴配对问题,为什么会无限循环?#include<stdio.h>
#include<stdlib.h>
#define size 50
typedef struct
{
char name;
char male;
}people;
typedef struct
{
people* ren;
int front,rear;
}S;
void init(S* st)
{
st->ren=(people *)malloc(size*sizeof(people));
st->front=st->rear=0;//初始化顺序栈
}
int full(S* st)//判断队列是否满
{
if(((st->rear)+1)%size==st->front)
return 1;
return -1;
}
int empty(S* st)//判断队列是否为空
{
if(st->rear==st->front)
return -1;
else return 1;
}
int enter(S* st,people person)//插入元素
{
if(full(st))
{
printf("队列已满\n");
return 1;
}
st->ren=person;
st->rear=(st->rear+1)%size;
return -1;
}
int pop(S* st,people* person)
{
if(!empty(st))
{
printf("空\n");
return -1;
}
*person=st->ren;
st->front=(st->front+1)%size;
return 1;
}
people gethead(S Q)
{//返回Q的队头元素,不修改队头指针
if(Q.front!=Q.rear) //队列非空
return Q.ren; //返回队头元素的值,队头指针不变
}
void dance(people dancers[],int n)
{
S man,woman;
people person;
init(&man);
init(&woman);
int i;
for(i=0;i<n;i++)
{
if(dancers.male=='F')
{
enter(&woman,dancers);
}
if(dancers.male=='M')
{
enter(&man,dancers);
}
else
printf("性别输入错误:%s %c\n",dancers.name,dancers.male);
}
printf("舞伴配对如下\n");
while(empty(&man)&&empty(&woman))
{
pop(&woman,&person);
printf("%s女士与",person.name);
pop(&man,&person);
printf("%s男士配对\n",person.name);
}
if(empty(&man))
{
person=gethead(man);
printf("%s男士将在下一轮第一个获得匹配机会\n",person.name);
}
if(empty(&woman))
{
person=gethead(woman);
printf("%s女士将在下一轮第一个获得匹配机会\n",person.name);
}
}
int main()
{
int n,i;
people wuzhe;
printf("请输入等待的总人数\n");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("请输入第%d位舞者的姓名和性别,用空格隔开(F表示女,M表示男)\n",i+1);
scanf("%s %c",&wuzhe.name,&wuzhe.male);
}
dance(wuzhe,n);
return 0;
}
感谢 队列满和队列空的判断逻辑问题:full 函数返回 1 表示满,但是判断条件应返回非0值表示真(在 C 中常用),return -1 会被认为是假,这与预期相反。
empty 函数逻辑也是反的,return -1 表示队列为空时实际应返回真(1),但返回了假(-1)。
pop 函数中的逻辑错误:在检查队列是否空时,empty(st) 应该返回 1 时表示空,但是您的代码中使用了 !empty(st) 表示队列为空。
男女判断和性别输入错误处理逻辑错误:当性别为男('M')时,应该只进入男队列逻辑分支,但是代码当前会继续检查性别输入错误的逻辑。
修正后的部分关键代码:
int full(S* st) {
return (st->rear + 1) % size == st->front;
}
int empty(S* st) {
return st->rear == st->front;
}
int enter(S* st, people person) {
if (full(st)) {
printf("队列已满\n");
return 1;// 队列满时返回1
}
st->ren = person;
st->rear = (st->rear + 1) % size;
return 0;// 插入成功返回0
}
int pop(S* st, people* person) {
if (empty(st)) {
printf("空\n");
return 0;// 队列空时返回0
}
*person = st->ren;
st->front = (st->front + 1) % size;
return 1;// 弹出成功返回1
}
// 修改舞伴配对逻辑
void dance(people dancers[], int n) {
S man, woman;
people person;
init(&man);
init(&woman);
int i;
for (i = 0; i < n; i++) {
if (dancers.male == 'F') {
enter(&woman, dancers);
} else if (dancers.male == 'M') {
enter(&man, dancers);
} else {
printf("性别输入错误:%s %c\n", dancers.name, dancers.male);
}
}
printf("舞伴配对如下\n");
while (!empty(&man) && !empty(&woman)) {
pop(&woman, &person);
printf("%s女士与", person.name);
pop(&man, &person);
printf("%s男士配对\n", person.name);
}
if (!empty(&man)) {
person = gethead(man);
printf("%s男士将在下一轮第一个获得匹配机会\n", person.name);
}
if (!empty(&woman)) {
person = gethead(woman);
printf("%s女士将在下一轮第一个获得匹配机会\n", person.name);
}
}
代码修正了队列判断逻辑,并调整了条件判断,以确保程序逻辑正确且不会陷入无限循环。
同时,确保了性别错误的逻辑仅在真正输入错误时才触发。 6666 在您提供的代码中,存在几个问题可能导致无限循环或其他逻辑错误:
1. **性别标识问题**:在`people`结构体中,`male`被定义为`char`类型,但在`main`函数中输入性别时,却使用`%c`格式符,这可能不会影响无限循环,但可能不是最恰当的数据类型选择,建议使用`char`数组或枚举类型来存储性别。
2. **队列实现问题**:在`enter`和`pop`函数中,队列的`front`和`rear`指针操作是正确的,但逻辑判断似乎有误。在`full`函数中,您应该返回0表示队列满,而不是1;在`empty`函数中,返回-1表示队列不为空,这可能与您的预期逻辑相反。
3. **`dance`函数中的逻辑问题**:在`dance`函数的循环条件中,您使用了`while(empty(&man)&&empty(&woman))`,这个条件只有在两个队列都为空时才会停止循环。但是,如果您希望配对舞伴,您应该在至少有一个队列不为空时继续循环。正确的条件应该是`while(!empty(&man) || !empty(&woman))`。
4. **`gethead`函数的实现问题**:在`gethead`函数中,您直接返回了队头元素的值。但是,如果队列是空的,这将返回一个未定义的值。建议添加一个检查,以确保队列不为空。
5. **内存分配问题**:在`init`函数中,为`ren`分配内存时使用了`malloc`,但在程序结束时并没有释放这块内存。虽然这不会导致无限循环,但最好的做法是在使用完内存后释放它,以避免内存泄漏。
6. **输入验证问题**:在`main`函数中,当读取舞者姓名和性别时,如果用户输入的性别不是`M`或`F`,程序会继续执行,但会调用错误的逻辑分支。建议添加输入验证来确保性别输入正确。
7. **`scanf`的使用问题**:在`main`函数中,使用`scanf`读取`wuzhe.name`时,由于`name`是`char`数组,应该使用`%s`格式符,并且`scanf`的参数应该是`wuzhe.name`的地址,即`&wuzhe.name`。
修正后的`main`函数中的`scanf`调用应该如下所示:
```c
scanf("%s %c", wuzhe.name, &wuzhe.male);
```
修正后的`dance`函数循环条件应该是:
```c
while(!empty(&man) || !empty(&woman))
```
确保对这些潜在问题进行修复后,程序应该能够正常运行并避免无限循环。
页:
[1]