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:
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.