Функция не возвращает значения правильного массива - PullRequest
1 голос
/ 14 февраля 2020

Я начал изучать функции в C.

У меня есть задача преобразовать числа из имперских в метри c, которые содержатся в 2d массиве.

Массив:

{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 return SortedArray[DATA_ROWS] = find_function(MixedData);

find_function logi c:

0 - это показатель системного значения metri c, а 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 - среднее значение. Затем распечатайте их. И тут возникает проблема.

Вызов функции без возврата total_AVG(SortedArray); с скопированным массивом SortedArray[DATA_ROWS]

Просто для проверки сделал printf и получил это:

-1.#R
0.00
0.00
0.00
0.00
0.00
0.00

Вроде как my SortedArray[DATA_ROWS] не скопировал во вторую функцию total_AVG

Указатели идут в следующем задании, поэтому по временной шкале задания я не могу их использовать * (и даже если Я мог бы, я не знаю, как их еще использовать) *

Подскажите, пожалуйста, что я делаю не так.

NB: Некоторые комментарии и переменные , которые не используются только старые, когда я пытался исправить свой код. И еще мне нужно только понять, почему SortedArray[DATA_ROWS] не скопировал во вторую функцию total_AVG. Все дальнейшие логи c будут исправлены после решения этой проблемы.

Спасибо! И извините за сломанный Engli sh!

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

Ответы [ 3 ]

1 голос
/ 14 февраля 2020

Массивы НЕ назначаются в C. C11 Standard - 6.3.2.1 Другие операнды - L-значения, массивы и указатели функций (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." Массив НЕ является lvalue;

Для заполнения массива необходимо итерируйте элементы и присвойте значения отдельным элементам или скопируйте блок памяти в ваш массив, содержащий значения для ваших элементов, с помощью memcpy, et c ..

Далее, с помощью double SortedArray[DATA_ROWS]; Вы не можете вернуть локально объявленный массив из функции. Когда функция возвращается, стек функций (содержащий ваш массив) уничтожается (освобождается для повторного использования). Вы должны либо передать свой SortedArray в качестве параметра в find_function и заполнить значения массива, переданного из main(), либо вы должны выделить хранилище для значений и вернуть Pointer выделенному блок памяти, хранящий ваши значения в main(). Это ваши два варианта.


Перестановка вашего кода

Глядя на ваш код и то, что вы пытаетесь сделать, кажется, вам нужно:

  • объявить double total = 0; в main()
  • вам нужно изменить объявление для функции поиска, чтобы оно принимало SortedArray в качестве параметра, например

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

  • вам нужно объявить еще double total; (или любое другое имя по вашему выбору) в find_function() и что total - это то, что вы хотите вернуть find_function() присваивать total, объявленному в main(), тем самым предоставляя его значение, например,

    total = find_function (MixedData, SortedArray);
    
  • Необходимо изменить объявление для total_AVG(), чтобы оно принимало SortedArray передается find_function() и заполняется там функцией total_AVG() в качестве параметра вместе с total, возвращаемым из find_function(), например

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

Пример Use / Outp ut

Запуск скомпилированной программы дает следующее:

$ ./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: Я не проверял этот вывод на правильность - что я оставляю для Вы, но на первый взгляд - это выглядит разумно, исходя из того, что делает ваш код)

Дайте мне знать, если у вас есть какие-либо вопросы о внесенных изменениях.

0 голосов
/ 14 февраля 2020

Вы определили функцию:

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) { /*...*/ }

или вы можете использовать динамические c выделения памяти .. в случае, если вы хотите вернуть базовый адрес из функции.

0 голосов
/ 14 февраля 2020

Вы не можете использовать массивы, подобные этому

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];
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...