【问题标题】:Printing 1D array through loop not working as expected通过循环打印一维数组未按预期工作
【发布时间】:2015-11-13 16:57:02
【问题描述】:

目前,第一个函数info() 可以正常工作并返回整个数组。这似乎也可以传递给kurtosis() 函数,因为我已经测试过每个元素是否在函数中手动打印。但是,当尝试通过循环打印每个元素时,它似乎只在第一次迭代中打印值;对于此后的迭代,它会打印0。奇怪的是,用常数替换 i 时仍然会发生这种情况。

#include <stdio.h>

double * info(){//function for obtaining up to 10 numbers
    int i;
    int x=0;
    double numbers[10];
    for (i = 1; i < 11; i++){
        printf("\nPlease enter value %d:", i);
        scanf("%lf", &numbers[i]);
        x++;//counting number of entries
        if(numbers[i] <0){//stops accepting numbers if user enters negative number
            x--;
            numbers[i] = -1;
            break;
        }
    }
    printf("%d numbers entered.\n", x);
    return numbers;
}
double kurtosis(double * numbers){
    int i, x;   
    double mean, numerator, denominator, sum;

    for (i = 1; i < 11; i = i + 1){ //irrelevant loop; will be used later on
        if (numbers[i] == -1){
        x = i-1;
        break;
        }
    }

    for (i = 1; i < 10; i++){
        printf("%lf\n", numbers[i]);//printing each value in the array
    }   
}

int main(void){
    double * numbers = info();
    double kurtno;
    kurtno = kurtosis(numbers);//passing the array to the kurtosis function
}

【问题讨论】:

    标签: c arrays loops


    【解决方案1】:

    您的代码中存在一些问题。


    double numbers[10];
    

    这是函数info() 的本地数组。函数返回后访问它会调用未定义的行为。


    函数kurtosis()return 类型为double,但没有从kurtosis() 返回。


    如果您尝试在函数kurtosis() 中从info() 访问number[] 数组,那么也会出现错误。

    数组索引总是从0 开始。所以number[10] 的索引从09

    循环for (i = 1; i &lt; 11; i = i + 1) 将访问超出范围的number[10]

    改成

    for (i = 1; i < 10; i = i + 1)
    

    让它发挥作用

    使用malloc()。使用malloc() 分配的内存在函数调用之间保持在范围内。

    double* numbers = malloc(10*sizeof(double));
    

    【讨论】:

    • 还有循环条件。
    • 谢谢,您是否可以推荐另一种方法来返回数组形式 info(),因为这是我找到的唯一方法。
    【解决方案2】:

    您的代码中的主要问题是,在您的函数 info() 中,numbers 是该函数的本地函数。 numbers 从函数调用返回时,其生命周期已过,因此,在调用者中,返回的地址不再有效。通过返回该函数的地址并稍后使用它,您将调用undefined behavior

    另外,正如其他人所提到的,第二个函数缺少返回值。

    然后,循环

     for (i = 1; i < 11; i++)
    

    也是错误的,因为 C 数组具有从 0 开始的索引。循环应该运行

     for (i = 0; i < 10; i++)
    

    【讨论】:

    • 这是我找到的将函数返回主函数的唯一方法,您还有其他建议吗?同样在基于 0 的索引方面,这是我的想法,但它似乎适用于基于 1 的索引。
    • @Ollie 是的,将numbers 设为指针,使用malloc() 动态分配内存,然后您可以从info() 返回numbers
    • @Ollie 还有,似乎工作是UB的众多美女之一@
    • @Ollie 1-based 没问题,问题是它会因为我们的条件访问索引11,这会导致UB。
    • @Ollie 使用malloc() 分配内存的另一种方法是将numbers[] 数组声明为static。但是,这使得函数不可重入 - 每次调用都会覆盖并返回指向同一内存块的指针。如果你确实使用了malloc()(或者更好的calloc()),并返回一个指向动态内存的指针,调用者需要在完成后free()内存。
    【解决方案3】:

    您的第一个函数返回一个作用域在函数块内的局部变量。

    尽管类型为 double,但您的第二个函数不会返回任何内容。

    它们都调用未定义的行为

    添加更多循环条件访问索引越界是 UB 的另一个原因。循环条件应该是i=0 直到i&lt;10(其他人也指出)。

    你能做的是-

    1. 在函数info 中,声明为double * 并为其分配内存。

    2. 将数组从调用函数本身传递给函数info

    【讨论】:

      猜你喜欢
      • 2015-08-12
      • 2018-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-26
      • 1970-01-01
      相关资源
      最近更新 更多