简体   繁体   中英

Function doesn't return right array's values

I've started learning functions in C.

I have a task to convert numbers from imperial to metric, which are contained in the 2d Array.

Array:

{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] 

So I am calling function with double return SortedArray[DATA_ROWS] = find_function(MixedData);

find_function logic:

0 is an indicator of the metric system value and 1 is an indicator of imperial system value, i is a row indexer and j is a column indexer.

So when for cycles find out that column value is 0 or 1 they save [j-1](an actual value that we need) into SortedArray .

It also converts value if finds out that column value is 1 SortedArray[i] = MixedData[i][j-1]*CONSTANT;

Just for a check, I did printf to see if values are correct and correctly converted if needed. I got this output:

1300.00
2198.00
1301.69
2103.00
962.24
338.83
3204.00

So, seems like correct, but in Task I have another task - use 2 functions to solve this task. I've decided to make another function, which will sum all values in SortedArray[DATA_ROWS] and then calculate avg - average. Then print them out. And here comes the problem.

Calling function with no return total_AVG(SortedArray); with copied array SortedArray[DATA_ROWS]

Just to check made a printf and got this:

-1.#R
0.00
0.00
0.00
0.00
0.00
0.00

It seems like my SortedArray[DATA_ROWS] did not copy into the second function total_AVG

Pointers are coming in the next task, so according to task's timeline I can't use them * (and even if I could, I have no idea how to use them still)*

Can you please tell me, what I am doing wrong.

NB: Some comments and variables, which are not used just old ones, when I tried to correct my code. And also I only need to understand why SortedArray[DATA_ROWS] did not copy into second function total_AVG . All further logic will be corrected after solving this problem.

Thank you! And sorry for broken English!

CODE:

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

Arrays are NOT assignable in 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." An array is NOT an lvalue;

In order to fill an array you have to iterate over the elements and assign values to the individual elements, or copy a block of memory to your array containing the values for your elements with memcpy , etc..

Further, with double SortedArray[DATA_ROWS]; you cannot return a locally declared array from a function. When the function returns, the function stack (containing your array) is destroyed (released for re-used). You must either pass your SortedArray as a parameter to find_function and fill the values of the array passed from main() there, or you must allocate storage for the values and return a Pointer to the allocated block of memory holding your values to main() . Those are your two-options.


Rearranging Your Code

Looking at your code and what you are attempting to do, it appears you need to:

  • declare double total = 0; in main()
  • you need to change the declaration for the find function so it takes SortedArray as a parameter, eg

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

  • you need to declare another double total; (or any other name you choose) in find_function() and that total is what you want to return from find_function() to assign to the total declared in main() thereby providing its value, eg

    total = find_function (MixedData, SortedArray);
  • You need to change the declaration for total_AVG() so it takes the SortedArray passed to find_function() and filled there to the total_AVG() function as a parameter, along with the total returned from the find_function() eg

    void total_AVG (double *SortedArray, double total);

With that, and uncommenting the calculations and getting rid of the unused variables in your code, you could do:

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

Example Use/Output

Running the compiled program yields the following:

$ ./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

( note: I have not validated this output for correctness -- that I leave to you, but at a quick glance -- it looks reasonable based on what your code does)

Let me know if you have any questions about the changes made.

You cant use arrays like this

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

You can pass it as parameter to function. like below.

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

The function you've defined is:

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

It's return type is double whereas you're trying to return an array, assays can't be returned liked nor can be assigned.

return SortedArray[DATA_ROWS]; 

Here you're trying to access the element which is equal to length, it's wrong. What you can do is, pass array as function parameter (or as a pointer) and return void. ie:

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

or you may use dynamic memory allocations.. in case you want to return the base address from the function.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM