问题描述
有一部分程序会要求用户输入 Y 或 N ,然后在我选择 N 时循环贝克将结束while循环并继续。当我第一次选择 Y 时,程序运行正常,但是当我选择 N 然后在程序退出后选择 Y 时,即使程序运行正常没有遇到主要的return
关键字
并以垃圾值return
退出。它在system("cls");
处停止。谁能告诉我这段代码有什么问题。注意:
Statistician
是我使用typedef创建的整数指针类型。而且,我还在 survey.h 文件
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <math.h>
#include "survey.h"
/* run this program using the console pauser or add your own getch,system("pause") or input loop */
int main(int argc,char *argv[]) {
SIZE = 10;
int c,count = 0,item = 0;
Statistician arr;
float mea,med;
arr = (int*)calloc(10,sizeof(int));
printf("Enter 10 answers\n");
while(count < SIZE) // this is the while loop that loops until Y is chosen by the user in the add function
{
while(item > 9 || item < 1)
{
scanf("%d",&item);
}
++count;
add(arr,&count,&SIZE,item);
item = 0;
}
system("cls");
mea = mean(arr,count);
med = median(arr,count);
printf("mean = %f\n",mea);
printf("median = %f\n",med);
return 0;
}
add()
函数的定义:
void add(Statistician answer,int *count,int *SIZE,int item)
{
int i,j,temp;
bool swapped;
char choice;
answer[*count - 1] = item;
for(i = 0; i < *count - 1; i++)
{
swapped = false;
for(j = 0; j < *count - i - 1; j++)
{
if(answer[j] > answer[j + 1])
{
temp = answer[j];
answer[j] = answer[j + 1];
answer[j + 1] = temp;
swapped = true;
}
}
if(swapped == false)
break;
}
if(*count == *SIZE)
{
printf("Array is full do you want to compute Now?\n");
while(toupper(choice) != 'N' && toupper(choice) != 'Y') // The part where the program ask for Y or N.
{
choice = toupper(getch());
}
if(toupper(choice) == 'Y') // returns without changing the value of SIZE thus ending the while loop at main
{
return;
}
else if(toupper(choice) == 'N') // adds 10 to SIZE thus continuing the while loop in main and returns
{
printf("add another 10 answers\n");
*SIZE += 10;
realloc(answer,*SIZE);
}
}
return;
}
解决方法
可能还有其他问题(我不会仔细看),但是您当然需要修复:
while(item > 9 || item < 1)
{
scanf("%d",&item);
}
如果scanf匹配零项,则这是一个无限循环,其中scanf重复返回0,读取相同的数据,并且不更改item
。您必须始终检查scanf返回的值。
这是一个严重的错误:
realloc(answer,*SIZE);
您不保存返回值,因此丢失了分配的内存。此外,您忘记了对象的大小。
原则上应该这样做
Statistician tmp = realloc(answer,*SIZE * sizeof(int));
if (tmp == NULL)
{
// Error handling
// or just
exit(1);
}
answer = tmp;
但是,这并不能完全解决问题。问题在于,它只会更改函数内部answer
的值,而不会 arr
中的main
。为了更改arr
的值,您必须将arr
的地址传递给函数。与您对SIZE
所做的类似。顺便说一句:为什么您将counter
用作指针?您永远不会在函数中更改它,因此不必传递指针。
您的当前代码也不会初始化choice
。
更改
printf("Array is full do you want to compute now?\n");
while(toupper(choice) != 'N' && toupper(choice) != 'Y') // The part where the program ask for Y or N.
到
printf("Array is full do you want to compute now?\n");
choice = ' ';
while(toupper(choice) != 'N' && toupper(choice) != 'Y') // The part where the program ask for Y or N.
或更好:
printf("Array is full do you want to compute now?\n");
do
{
choice = toupper(getch());
} while(toupper(choice) != 'N' && toupper(choice) != 'Y');
顺便说一句:
因为有了choice = toupper(getch());
,所以不需要toupper(choice) != 'N'
。只需choice != 'N'
所有所说的-为什么要在功能内部 提出问题?如果您在main
中进行操作,您的代码将更加简单。
类似的东西:
int main(void) {
int SIZE = 10;
int c,count = 0,item = 0;
int* arr;
float mea,med;
arr = calloc(10,sizeof(int));
printf("Enter 10 answers\n");
while(count < SIZE)
{
while(item > 9 || item < 1)
{
if (scanf("%d",&item) != 1) exit(1);
}
++count;
add(arr,count,item);
item = 0;
if (count == SIZE)
{
printf("Array is full do you want to compute now?\n");
char choice;
do
{
choice = toupper(getch());
} while(choice != 'N' && choice != 'Y');
if(choice == 'N')
{
printf("add another 10 answers\n");
SIZE += 10;
int* tmp = realloc(arr,SIZE * sizeof *arr);
if (tmp == NULL) exit(1); // or error handling
arr = tmp;
}
}
}
system("cls");
mea = mean(arr,count);
med = median(arr,count);
printf("mean = %f\n",mea);
printf("median = %f\n",med);
return 0;
}
void add(int* answer,int count,int item)
{
int i,j,temp;
bool swapped;
answer[count - 1] = item;
for(i = 0; i < count - 1; i++)
{
swapped = false;
for(j = 0; j < count - i - 1; j++)
{
if(answer[j] > answer[j + 1])
{
temp = answer[j];
answer[j] = answer[j + 1];
answer[j + 1] = temp;
swapped = true;
}
}
if(swapped == false)
break;
}
return;
}