【问题标题】:Function doesn't return right array's values函数不返回正确数组的值
【发布时间】:2020-02-14 09:18:05
【问题描述】:

我已经开始学习 C 函数了。

我的任务是将数字从英制转换为公制,这些数字包含在二维数组中。

数组:

{1300, 0}  [0][0] [0][1]

{2198, 0}  [1][0] [1][1]

{4199, 1}  [2][0] [2][1]

{2103, 0}  [3][0] [3][1]

{3104, 1}  [4][0] [4][1]

{1093, 1}  [5][0] [5][1]

{3204, 0}  [6][0] [6][1] 

所以我用double 调用函数返回SortedArray[DATA_ROWS] = find_function(MixedData);

find_function 逻辑:

0 是公制值的指示符,1 是英制值的指示符, i 是行索引器,j 是列索引器。

因此,当for 循环发现列值为 0 或 1 时,它们会将 [j-1](我们需要的实际值)保存到 SortedArray

如果发现列值为1 SortedArray[i] = MixedData[i][j-1]*CONSTANT;,它也会转换值

只是为了检查,我做了printf 来查看值是否正确并在需要时正确转换。 我得到了这个输出:

1300.00
2198.00
1301.69
2103.00
962.24
338.83
3204.00

所以,看起来是正确的,但在任务中我有另一个任务 - 使用 2 个函数来解决这个任务。 我决定创建另一个函数,它将 sum 中的所有值 SortedArray[DATA_ROWS] 然后计算 avg - 平均值。 然后将它们打印出来。 问题来了。

使用复制的数组SortedArray[DATA_ROWS]调用不返回total_AVG(SortedArray);的函数

只是检查了printf并得到了这个:

-1.#R
0.00
0.00
0.00
0.00
0.00
0.00

我的SortedArray[DATA_ROWS]好像没有复制到第二个函数total_AVG

指针将在下一个任务中出现,因此根据任务的时间线我无法使用它们 * (即使我可以,我仍然不知道如何使用它们)*

你能告诉我,我做错了什么吗?

注意: 当我尝试更正我的代码时,一些 cmets 和变量不仅仅使用旧的。 而且我只需要了解为什么SortedArray[DATA_ROWS] 没有复制到第二个函数total_AVG。解决此问题后,将更正所有进一步的逻辑。

谢谢!对不起,英语不好!

代码:

#include <stdio.h>
#define DATA_ROWS 7
#define DATA_COLS 2
#define CONSTANT 0.31
#define MAX 3


double find_function(int MixedData[DATA_ROWS][DATA_COLS]);
void total_AVG(double SortedArray[DATA_ROWS]);


int main(void)
{
    int i;
    double SortedArray[DATA_ROWS];


    int MixedData[DATA_ROWS][DATA_COLS] = {
        {1300, 0},//[0][0] [0][1]
        {2198, 0},//[1][0] [1][1]
        {4199, 1},//[2][0] [2][1]
        {2103, 0},//[3][0] [3][1]
        {3104, 1},//[4][0] [4][1]
        {1093, 1},//[5][0] [5][1]
        {3204, 0}};//[6][0] [6][1]

    SortedArray[DATA_ROWS] = find_function(MixedData);
    total_AVG(SortedArray);


    return 0;
}

double find_function(int MixedData[DATA_ROWS][DATA_COLS])
{
    // imperial numbers from source array "mixedData" are 4199,3104,1093;

    int i,j; // indexers
    double SortedArray[DATA_ROWS]; 




    // 7 rows, each row suppose to contain only metric values
    // That means, if second for cycle with j indexer finds 0, it will contain j-1 value for example 1300 in SortedArray
    // If it finds in second for cycle with j indexer 1, it will converte the value from imperial to metric for example 4199*0.31
        /*  {1300, 0}  [0][0] [0][1]
            {2198, 0}  [1][0] [1][1]
            {4199, 1}  [2][0] [2][1]
            {2103, 0}  [3][0] [3][1]
            {3104, 1}  [4][0] [4][1]
            {1093, 1}  [5][0] [5][1]
            {3204, 0}  [6][0] [6][1] */


    // Probably problem in "double SortedArray and int MixedData"
    for(i=0;i<DATA_ROWS;i++)
    {
        for(j=0;j<DATA_COLS;j++)
        {
            if(MixedData[i][j]==0)                                               
            {
                SortedArray[i] = MixedData[i][j-1];
            }
            else if(MixedData[i][j]==1)
            {
                SortedArray[i] = MixedData[i][j-1]*CONSTANT;

            }
        }
    }
    for(i=0;i<DATA_ROWS;i++)
    {
        //total += SortedArray[i];
        printf("%.2lf\n", SortedArray[i]);
    }

    return SortedArray[DATA_ROWS];
}

void total_AVG(double SortedArray[DATA_ROWS])
{
    double avg,total;
    int i;

    for(i=0;i<DATA_ROWS;i++)
    {
        printf("%.2lf\n", SortedArray[i]);
    }
    //avg = total/DATA_ROWS;
    //printf("Total by every worker: %.2lf\n",total);
    //printf("In average by every worker: %.2lf", avg);

    return;
}

【问题讨论】:

  • SortedArray[i] = MixedData[i][j-1];j=0 时您访问的位置无效。
  • 这里也有SortedArray[DATA_ROWS] = find_function(MixedData);
  • 再次return SortedArray[DATA_ROWS];这里也是。
  • SortedArray[DATA_ROWS] = find_function(MixedData); -> double result = find_function(MixedData);。你的 find 函数应该返回一个双精度。您的大部分困惑来自您尝试“返回数组”。你不能在 C 中这样做。你需要通过指针传递数组。我建议从二维数组退后一步,研究数组如何衰减为指针,以及当您将数组作为函数参数传递时会发生什么。
  • SortedArray[i] = MixedData[i][j-1];j=0 时访问无效位置 * 我有 if else 循环检查标记为 1 的英制数字,当 j = 1 所以如果我在 j = 0 时没有弄错,我有例如 1300 值。而当 j=1 时,它要么是 0 要么是 1。if 它是一个 0,只是保存之前的值 j-1 = j = 0,也就是 1300 到数组中 else if 它是一个 1,只是保存之前的值 j-1 = j = 0,即1300入数组,但先乘以CONSTANT

标签: c arrays function


【解决方案1】:

数组在 C 中不可赋值。C11 Standard - 6.3.2.1 Other Operands - Lvalues, arrays, and function designators(p3) ..."an expression that has type *"array of type"* is converted to an expression with type *"pointer to type"* that points to the initial element of the array object and is not an lvalue." 数组不是左值;

为了填充数组,您必须遍历元素并为各个元素分配值,或者将内存块复制到包含 memcpy 等元素值的数组中。

此外,使用double SortedArray[DATA_ROWS]; 您不能从函数返回本地声明的数组。当函数返回时,函数堆栈(包含您的数组)被销毁(释放以供重复使用)。您必须将 SortedArray 作为参数传递给 find_function 并填充从 main() 传递的数组的值,或者您必须为这些值分配存储空间并返回一个 Pointer 到分配的内存块将您的值保存到main()。这些是您的两个选择。


重新排列您的代码

查看您的代码以及您尝试执行的操作,您似乎需要:

  • main() 中声明double total = 0;
  • 您需要更改 find 函数的声明,以便将 SortedArray 作为参数,例如

    double find_function(int (*MixedData)[DATA_COLS], double *SortedArray)

  • 您需要在find_function() 中声明另一个double total;(或您选择的任何其他名称),并且total 是您想要从find_function() 返回以分配给在main() 中声明的total从而提供其价值,例如

    total = find_function (MixedData, SortedArray);
    
  • 您需要更改total_AVG() 的声明,以便将SortedArray 传递给find_function() 并在那里填充到total_AVG() 函数作为参数,以及从find_function() 返回的total例如

    void total_AVG (double *SortedArray, double total);

这样,取消注释计算并删除代码中未使用的变量,您可以这样做:

#include <stdio.h>

#define DATA_ROWS 7
#define DATA_COLS 2
#define CONSTANT 0.31
#define MAX 3

double find_function (int (*MixedData)[DATA_COLS], double *SortedArray);
void total_AVG (double *SortedArray, double total);

int main(void)
{
    double total = 0;
    double SortedArray[DATA_ROWS] = {0};    /* good idea to initialize arrays zero */


    int MixedData[DATA_ROWS][DATA_COLS] = { {1300, 0},      //[0][0] [0][1]
                                            {2198, 0},      //[1][0] [1][1]
                                            {4199, 1},      //[2][0] [2][1]
                                            {2103, 0},      //[3][0] [3][1]
                                            {3104, 1},      //[4][0] [4][1]
                                            {1093, 1},      //[5][0] [5][1]
                                            {3204, 0} };    //[6][0] [6][1]

    total = find_function (MixedData, SortedArray);
    total_AVG (SortedArray, total);
}

double find_function(int (*MixedData)[DATA_COLS], double *SortedArray)
{
    // imperial numbers from source array "mixedData" are 4199,3104,1093;

    int i,j;    // indexers
    double total = 0;

    // Probably problem in "double SortedArray and int MixedData"
    for (i=0;i<DATA_ROWS;i++)
        for (j=0;j<DATA_COLS;j++)
            if (MixedData[i][j]==0)
                SortedArray[i] = MixedData[i][j-1];
            else if (MixedData[i][j]==1)
                SortedArray[i] = MixedData[i][j-1]*CONSTANT;

    for (i=0;i<DATA_ROWS;i++) {
        total += SortedArray[i];
        printf("%.2lf\n", SortedArray[i]);
    }

    return total;
}

void total_AVG (double *SortedArray, double total)
{
    double avg;
    int i;

    for (i=0;i<DATA_ROWS;i++)
        printf("%.2lf\n", SortedArray[i]);

    avg = total/DATA_ROWS;

    printf("Total by every worker: %.2lf\n",total);
    printf("In average by every worker: %.2lf\n", avg);
}

使用/输出示例

运行编译后的程序会产生以下结果:

$ ./bin/sorteddata
1300.00
2198.00
1301.69
2103.00
962.24
338.83
3204.00
1300.00
2198.00
1301.69
2103.00
962.24
338.83
3204.00
Total by every worker: 11407.76
In average by every worker: 1629.68

注意:我还没有验证这个输出的正确性——我把它留给你,但快速浏览一下——根据你的代码所做的,它看起来是合理的)

如果您对所做的更改有任何疑问,请告诉我。

【讨论】:

  • 感谢您的快速响应。指针在下一个讲座和下一个任务中,所以理论上我现在不能使用它们。但这部分对我帮助很大:此外,使用 double SortedArray[DATA_ROWS];您不能从函数返回本地声明的数组。当函数返回时,函数堆栈(包含您的数组)被销毁(释放以供重复使用)。所以我只能使用一个变量而不是数组来保存 find 函数中的数据(SortedArray)?
  • 您可以将数组表示法作为参数重新插入,而不是我使用的指针表示法。它们是相同的C11 Standard - 6.3.2.1 Other Operands - Lvalues, arrays, and function designators(p3) 我现在已经确认了输出——它是正确的。从find_function 中删除数字的(重复)打印,也让你的j 循环for (j=1;j&lt;DATA_COLS;j++),你就完成了。现在,如果你在调用find_function 之后在SortedArray 上使用qsort - 你真的会有SortedArray
  • 谢谢!是的,主要问题只是接收到这个 SortedArray。
【解决方案2】:

你不能使用这样的数组

return SortedArray[DATA_ROWS];
SortedArray[DATA_ROWS] = find_function(MixedData);

您可以将其作为参数传递给函数。如下所示。

find_function(MixedData, SortedArray);

void find_function(int MixedData[DATA_ROWS][DATA_COLS], double SortedArray[DATA_ROWS])
{
// Dont define, use itt from parameter
// double SortedArray[DATA_ROWS];

// ...

// Dont need to return.
// return SortedArray[DATA_ROWS];
}

【讨论】:

  • 谢谢!就像上一个答案一样,我应该将主函数中的 SortedArray[DATA_ROWS] 作为参数提供给 find_function,因为我不能在数组中包含来自它的数据。而且我不能从函数返回本地声明的数组。
【解决方案3】:

你定义的函数是:

double find_function(int MixedData[DATA_ROWS][DATA_COLS]) { }

它的返回类型是double,而您试图返回一个数组,化验不能被喜欢也不能被分配。

return SortedArray[DATA_ROWS]; 

这里你试图访问等于长度的元素,这是错误的。 您可以做的是,将数组作为函数参数(或作为指针)传递并返回 void。 即:

void find_function(int MixedData[DATA_ROWS][DATA_COLS], double* SortedArray) { /*...*/ }

或者你可以使用动态内存分配..如果你想从函数返回基地址。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多