【问题标题】:Function not getting called from the main function未从主函数调用函数
【发布时间】:2020-12-18 22:04:37
【问题描述】:

我非常担心我不了解 C 编程的基本原理。我正在从文本文件中读取数字,我将检查它们是否是素数。然而,问题是IsPrime 函数永远不会被main 函数调用。我尝试将number 变量设置为全局变量和局部变量,但它不起作用。我的基本理解有那么差吗?

从文本文件中读取没有问题。它看起来像这样:

73771782    81296771    79982326    75332246    10128193
81643413    76259734    94432076    50063976    91748657
42311916    -1920042    90747362    53851612    43498487
73193311    96685173    39019033    8630045     17

因为main函数从不调用IsPrime函数,结果是所有数字都打印为is a prime number。

代码如下:

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

int isPrime(int number);

int main(int argc, char **argv) {
    int number = 0;
    int number2 = 0;
    FILE *fp = NULL;
    
    char file_name[] = "C:\\Users\\Erlen\\Desktop\\numbers.txt";
    fp = fopen(file_name, "r"); 
    
    if (fp == NULL) {
        printf("Error opening the file: \n");
        exit(0);
    }
    
    fscanf(fp, "%d", &number);
    
    while (number != number2) {
        if (isPrime(&number) == 1) {
            printf("Number: %d is a prime number \n", number);
        } else {
            printf("The number %d is a prime number \n", number);
        }
        number2 = number;
        fscanf(fp, "%d", &number);
    }
    printf("\n");
    
    return 0;
}

int isPrime(int number) {
    for (int i = 2; i < number; i++) {
        if (number % i == 0) {
            return 0;
        }
    }
    return 1;
}

【问题讨论】:

  • 1st) isPrime(&amp;number) ==> isPrime(number) ... 0th) 打开并注意编译器警告
  • 你的两个分支打印是一个素数。但是你传入了 address,因此它不会改变。事实上,地址很可能不是可以被 4 或 8 整除的素数。
  • 天啊,最后我有点累了。我已经对代码进行了很多更改,但我没有意识到 printf 具有相同的语句。另外,我完全忘记了 & 是用于寻址的。顺便说一句,17 应该是质数。

标签: c function call


【解决方案1】:

您的代码中存在多个问题:

  • 您将number 的地址而不是其值传递给isPrime。
  • 您应该迭代while (fscanf(fp, "%d", &amp;number) == 1) 来处理文件中的所有数字。您当前的循环逻辑很麻烦,如果第一个数字是 0 或文件包含相同的连续数字,则会失败。
  • 在 C 中习惯性地只测试isPrime 的返回值是否非零。
  • 合成数字的消息不正确。
  • 退出状态的约定是非零失败。
  • 你应该取负数的绝对值。
  • 对于不被视为质数的0 和1,您应该返回0。
  • 您可以通过测试i * i &lt;= number 而不是i &lt; number 来提高isPrime 处理大量数字的性能,从而将复杂度降低到O(sqrt(N))。

这是修改后的版本:

#include <stdio.h>

int isPrime(int number);

int main(int argc, char *argv[]) {
    int number;
    FILE *fp;
    char file_name[] = "C:\\Users\\Erlen\\Desktop\\numbers.txt";

    fp = fopen(file_name, "r"); 
    if (fp == NULL) {
        printf("Error opening the file: \n");
        return 1;
    }
    
    while (fscanf(fp, "%d", &number) == 1) {
        if (isPrime(number)) {
            printf("Number %d is a prime number\n", number);
        } else {
            printf("Number %d is a not a prime number\n", number);
        }
    }
    return 0;
}

int isPrime(int number) {
    if (number < 0)
        number = -number;
    if (number < 2)
        return 0;
    for (int i = 2; i < number; i++) {
        if (number % i == 0) {
            return 0;
        }
    }
    return 1;
}

【讨论】:

  • 通过使用 while(fscanf(fp, "%d", &number) == 1 可以避免文本文件中的最后一个数字进入无限循环?我使用了 fscanf(fp, "% d", &number); 在 while 循环之前,我不得不使用 number2 =! number 来避免这种情况的发生。另外,谢谢
  • @Tungstein:测试输入结束的正确方法是使用fscanf() 的返回值,它会告诉您数字是否被转换或失败,无论是因为文件结束还是因为无效输入不会转换为数字。如前所述,测试number != number2是否有误报:如果转换的第一个数字是0,则忽略整个文件,如果连续两个数字相同,则导致循环停止。
  • 这是一个公平的观点。我使用 number != number 2 作为绝望的快速修复,没有考虑如果文本文件中的数字不同的后果。谢谢。
【解决方案2】:

isPrime(&amp;number) 你传递变量number 的地址而不是它的值。改成isPrime(number)

检查scanf的结果。 fscanf(fp, "%d", &amp;number); =>

if(fscanf(fp, "%d", &number) != 1) 
{
    printf("Scanf error\n");
    exit(0);
}

【讨论】:

    猜你喜欢
    • 2012-04-12
    • 2016-05-27
    • 1970-01-01
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-02
    • 1970-01-01
    相关资源
    最近更新 更多