【问题标题】:process exits prematurely C programming进程过早退出 C 编程
【发布时间】:2020-12-29 23:28:46
【问题描述】:

有一部分程序要求用户输入 YN 然后当我选择 N 时循环返回,否则它将结束while循环并继续。当我第一次选择 Y 时,程序运行正常,但是当我选择 N 然后在我的程序退出后选择 Y 时,即使它确实如此没有遇到来自 main 的 return 关键字 它以垃圾return 值退出。它停在system("cls");。谁能告诉我这段代码有什么问题。笔记: Statistician 是我用 typedef 创建的整数指针类型。而且,我还在 survey.h 文件中声明了 SIZE 变量

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

【问题讨论】:

标签: c return main


【解决方案1】:

可能还有其他问题(我不会仔细研究),但您肯定需要解决:

   while(item > 9 || item < 1)
    {
        scanf("%d", &item);
    }

如果 scanf 匹配零个项目,那么这是一个无限循环,scanf 重复返回 0,读取相同的数据并且不更改 item。您必须始终检查 scanf 返回的值。

【讨论】:

    【解决方案2】:

    这是一个严重的错误:

    realloc(answer, *SIZE);
    

    您没有保存返回值,因此您丢失了分配的内存。此外,您忘记了对象的大小。

    原则上你应该这样做

    Statistician tmp = realloc(answer, *SIZE * sizeof(int));
    if (tmp == NULL)
    {
        // Error handling
        // or just
        exit(1);
    }
    answer = tmp;
    

    但是,这并不完全有帮助。问题是它只会改变函数内部answer 的值,而不会改变@987654324 的值@在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;
    }
    

    【讨论】:

    • 我尝试在 main 中打印“arr”,它仍然有效,因为 Statistician 是一个指针。我已经在 survey.h 中写过了。 typedef int* Statistician;。另外,我已经初始化了choice 并将while 更改为do...while。它仍然在 main 中的 system("cls"); 处停止。
    • @Hans 不,arr in main 不能用您的代码更改。所以你的realloc 永远不会出现在main 中。 arrint* 没关系。
    猜你喜欢
    • 2013-07-03
    • 1970-01-01
    • 2015-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-22
    • 1970-01-01
    相关资源
    最近更新 更多