【问题标题】:How to initialize an array to a non-numeric value如何将数组初始化为非数值
【发布时间】:2013-04-01 04:54:26
【问题描述】:

我正在尝试初始化一个数组,以便我可以使用一个简单的 if 语句来检查一个值是否已放入数组中。

这可能吗?

这是我的代码

double number[1024] = {non-numeric value}
int i = 0;
while(1){
    if (number[i] != non-numeric value){

    printf ("%f", number[i]);
    i++;
}
    else
        break;

}

【问题讨论】:

  • NAN 不是值而是异常(终止状态)
  • 我改了,我的意思是一个非数值,任何计算都无法放入数组中的东西。
  • NAN 是浮点数。
  • @bh3244 您最好创建一个struct optional_number { char has_value; double value; }; 并使用has_value 成员来指示该数组槽是否具有有意义的值。 NaN 可以是计算的结果。
  • 有关 NaN 和 Inf 的更多信息,请参见 stackoverflow.com/questions/1923837/how-to-use-nan-and-inf-in-c

标签: c floating-point


【解决方案1】:

要将数据初始化为 NaN,请使用 <math.h> 中定义的 NAN

#include <math.h>

// initialize to all NaNs
for (int i=0; i<1024; ++i) number[i] = NAN;

要检查 NaN,请使用 &lt;math.h&gt; 中的 isnan

if (!isnan(number[i])) {
    // do something if the value isn’t NaN.
}

【讨论】:

    【解决方案2】:

    使用来自&lt;math.h&gt;NANisnan

        #include <stdio.h>
        #include <math.h>
    
        // ...
    
        #define N 1024
    
        double number[N];
        int i;
    
        for (i = 0; i < N; i++)
            number[i] = NAN; // Produce NaN
    
        //...    
    
        i = 0;
        while (i < N)
        {
            if (!isnan(number[i]))
            {
                printf("%f\n", number[i]);
                i++;
            }
            else
                break;
        }
    

    Live code!

    【讨论】:

    • 执行时会崩溃。
    • @GrijeshChauhan:以前的代码在我的机器上编译。但是我写了一个可移植的代码。更新。
    【解决方案3】:

    试试这个:

    double number[1024];
    int i = 0;
    
    for(i=0 ; i<1024 ; ++i)
        number[i] = NAN;
    
    // while true is bad programming practice, use a for instead
    
    for(i=0 ; i<1024 ; ++i) {
        if(number[i]!=number[i]) 
            printf("%ld",number[i]);
        else break;
    }
    

    【讨论】:

    • 我不会说while true 是不好的编程习惯,而是如果你有一个预定义的终止条件,那么是的,你应该在你使用的循环上有一个条件
    • 为什么while(true) 是不好的做法?也许是,在 this 实例中,但一般来说?
    • 你总是有一个终止循环的条件,它可能取决于循环计算本身,在这种情况下我使用布尔值来退出,这样可以轻松测试并使代码更具可读性(这个可以讨论,但在我的大学普遍接受)
    • NaN 是定义“非数字”的宏,请检查:gnu.org/software/libc/manual/html_node/Infinity-and-NaN.html
    • 宏是NAN,而不是NaN
    【解决方案4】:

    将 NaN 重新定义为“不由用户提供”可能是个坏主意 - 如果用户想要提供 NaN 怎么办?

    考虑使用“可选”数据结构来表示每个数组元素。

    struct optional_double {
        char has_value;
        double value;
    };
    
    struct optional_double number[1024];
    int i;
    
    memset(number, 0, sizeof(number));
    
    // Populate the array with data here.
    
    for (i = 0; number[i].has_value; ++i) {
        printf("%f", number[i].value);
    }
    

    【讨论】:

    • 这不是对 NaN 的再利用;这是它的设计目的之一。
    • @EricPostpischil NaN 在这种情况下可能意味着两件事(用户没有提供值,或者程序通过例如除以零来计算它)对我来说似乎很糟糕。有一个明确的标志可以解决不必要的歧义,表明该值是否存在。 (NaN 可能被视为有效输入!)
    • NaN 专为所有这些而设计。首先,如果您不希望用户输入 NaN,则可以禁止它们。其次,如果您确实希望用户输入 NaN,您可以通过在 NaN 中设置有效负载来区分它们。第三,如果您想将计算期间创建的 NaN 与其他 NaN 区分开来,您可以在 NaN 中设置有效负载或启用异常陷阱。您还可以将 NaN 设置为安静地传播或发出信号。 NaN 就是为此而设计的。
    【解决方案5】:

    我的回答与 cdhowie 的类似,但有一个关键的区别。他是对的-您不应该将 NaN 重新用于表示“未设置”。 (事实上​​,设置一些像 -1234.56789 这样的任意数字比这更安全,因为不太可能有任何东西等于它,而且计算更有可能导致 NaN。)显然,所有 math.h 中都没有定义 NAN文件,但如果它在您的文件中,这是最简单的方法。

    我建议将 NULL 重新用于您的任务。

    您实际上想将您的替身变成Nullable type,那么为什么不实际这样做呢?

    double* numberPointers[1024];
    memset(numberPointers, NULL, 1024 * sizeof(double));
    int i = 0;
    while(1){
        if (numberPointers[i] != NULL){
            printf ("%f", numberPointers[i]);
            i++;
        }
        else {
            break;
        }
    }
    

    其中困难的部分是改变你的计算。而不是像

    void fillArray(double[] number) {
        int i;
        for (i = 0; i < 1024; ++i) {
            number[i] = someCalculation(i);
        }
    }
    

    你需要类似的东西

    void fillArray(double*[] numberPointers) {
        int i;
        double result;
        double* d; 
        for (i = 0; i < 1024; ++i) {
            result = someCalculation(i);
            d = (double*)malloc(sizeof(double));
            *d = result;
            numberPointers[i] = d;
        }
    } 
    

    当然,当你完成后,你需要freenumberPointers 中的所有指针,但这应该很容易:

    int i;
    for (i = 0; i < 1024; ++i) {
        if (numberPointers(i) != NULL) {
            free(numberPointers(i));
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2021-01-23
      • 2020-06-21
      • 1970-01-01
      • 1970-01-01
      • 2017-12-08
      • 1970-01-01
      • 1970-01-01
      • 2014-04-23
      • 2012-10-03
      相关资源
      最近更新 更多