Tag Archive | Programming

C programming: multiple function, multiple source code and multi-dimensional array

This will be another technical note, so I don’t need to search for the solution again in the future. It is frustrating that the solution to a particular technical problem often are hard to find on the internet. It seems to me that a lot of people are asking, a lot are answering, but there isn’t a good systematic categorization to make finding the relevant solution easier.

Multiple function program

In the case where the program is long and complicated, but tend to repeating computing the same function, what can be done is we can write the repeating function and call it whenever we needed it. This reduce the tedious work of typing the same thing over and over again in the code.

A function  needs two things, the argument(s) and the return value. This is why the function itself has a type according to the value they return. The function, like variables, also needs to be declared before it can be called by the main function. (Just think about how would you know the phone number of a particular person whom you don’t know the person’s face or name!) If there is only one source file, declaring the function can be done in two ways:

1. function is declared and written before main function

#include <stdio.h>
#include <math.h>

double power_series(int d, /*order to truncate the series*/
double x)
{
double return=0;
int i=0;
for(i=0;i<=d;i++){
result=result+pow(x,i);
}
return(result);
}

int main(){
double result=0;
int d=4;
double x=3;
result=power_series(d,x);
return(0);

}

2. function is declared before the main function but written after the main function

#include <stdio.h>
#include <math.h>

double power_series(int d, double x); /*declaration of function*/<

int main(){
double result=0;
int d=4;
double x=3;
result=power_series(d,x);
return(0);

}
/*detail of the function*/
double power_series(int d, /*order to truncate the series*/
double x)
{
double return=0;
int i=0;
for(i=0;i<=d;i++){
result=result+pow(x,i);
}
return(result);
}

Similar principle goes for function on a different source file, the function must be declared before it can be called. Let’s say, we created source files called main.c for the main function and series.c for containing calculation of series. To link this together, we need a header called series.h to be added to both main.c and series.c. This header will contain all the necessary libraries and declaration of functions in series.c.

main.c series.h series.c
#include <stdio.h>
#include <series.h>
int main(){}
#include <math.h>
double series(int d, double x);
#include <series.h>double series(int d, double x){

}

Passing Array as Argument

The function can take as much argument as is needed, but can only return only one value. In a lot of cases, we need a function that can return multiple values of the calculation, an array of it even. To by pass the limitation of function return, we can instead instruction the function to place the value into a particular memory which is associated with a variable in the main function. What the function would need is a pointer to where they should place the function which can be passed into the function by

double power_series(int d, double x, double* y); /*passing location of y*/.

To pass the location to the function in, we use

power_series(d,x,&y); /*y is the variable that will hold the result from the function*/.

To assign the value to y inside the functions, we need to refer to *y instead of y.

Passing and array into the function is done on the same principle. When writing

power_series(d,x,y[ ]); /*passing y as array*/,

the function is receiving the pointer for array y[ ] which has to be a one-dimensional array (as limited as it is). The good thing is the handling of the array is easy in the function as it can just treat it as a variable. The problem, however, is when the array of more than one dimension has to be passed into the function.

A way to get around this we have to look at how an array is constructed in the memory. The elements of an array is stored consecutive to one another. In two-dimensional array, for example, will be stored as

|A[0][0]|A[0][1]|A[0][2]|A[1][0]|A[1][1]|A[1][2]|….

To access the element is then to call the correct value in the correct position which follows the relation

A[i][j]=*(A[i]+j).

This means in order to pass an array, only an address to an element in the array is needed regardless of the size and dimension of the array. So what we send into the function is then

power_series(d,x,&y[0][0]);

To assign value to the element of the array in the function is then

*(y+10)=result; /*assigning value to the 11th element of the array*/.

One thing to be careful about is how to address row and column. It is best to pass the dimensions of the array into the function in order to allow the computation of row and column.

Passing the array in this manner can also be used for structures. The difference is that the component has to be specified like this

(*(y+10)).component1=result;

The parenthesis before .component1 is absolutely essential to address the component correctly.

For further reading, see the reference.

References

1. 2D Arrays & pointer to a pointer(**): http://www.cs.cmu.edu/~ab/15-123S09/lectures/Lecture%2006%20-%20%20Pointer%20to%20a%20pointer.pdf

2. Pointers and Structures: http://www.taranets.net/cgi/ts/1.37/ts.ws.pl?w=329;b=282