Transferring Argument’s Address into a Function (call by reference)
Write your own function that changes polar coordinates into Cartesian coordinates, and show how this function is called upon from main program.
#include <math.h>
void cart(float r, float fi, float *x, float *y) {
*x = r*cos(fi); // x address:1244956,value:1245052
//*x address:1245052,value:1.755165
*y = r*sin(fi); // y address:1244960,value:1245048
//*y address:1245048,value:0.958851
}
Main program slice:
float x, y; // x address:1245052,value:?
// y address:1245048,value:?
float fi = 0.5, r = 2; //fi address:1245044,value:0.5
// r address:1245040,value:2
cart(r, fi, &x, &y);
printf("x=%f y=%f",x,y);
// x address:1245052, value:1.755165
// y address:1245048, value:0.958851
Question:
What would happen if the function looked like this?
void cart(float r, float fi, float *x, float *y) {
x = 10000;
*x = r * sin(fi);
*y = r * cos(fi);
}
Important:
Function is able to return single value through its “return” order. In order to return more values (in this case x & y), we can return them through arguments (Call by Reference).
Example:
Write your own function that returns numerator and denominator of a fraction. This fraction is a sum of two fractions, whose two numerators and two denominators are given by user. Function also shortens the fraction if possible, before returning values. Augends numerators and denominators are integers.
(Fraction example: 5/9, Numerator: 5, Denominator: 9)
void addFractions(int nrator1,int denom1,
int nrator2,int denom2,
int *nratorSum,int *denomSum) {
int min, i;
*nratorSum = nrator1*denom2+denom1*nrator2;
*denomSum = denom1*denom2;
min=(*nratorSum<*denomSum) ? *nratorSum : *denomSum;
//testing if numerator and denominator
//are multiples:
if((*nratorSum % min == 0)&&(*denomSum % min==0)){
*nratorSum /= min;
*denomSum /= min;
} else {
//tests if numerator and denominator are
//dividable with same number
i = min / 2;
while ( i >= 2) {
if ((*nratorSum%i == 0)&&(*denomSum%i == 0))
*nratorSum /= i;
*denomSum /= i;
--i;
}
}
}
Main program’s slice (calls function addFractions):
int nrator1, denom1, nrator2, denom2,
int nratorSum, denomSum;
...
addFractions(nrator1, denom1, nrator2,
denom2, &nratorSum, &denomSum);
Function that finds biggest element in real number’s array
Why is flow’s length “length” transferred as function’s argument?
float max(int length, float *p) {
// OR: float max(int length, float p[]) {
float res; int i;
res = p[0];
for (i = 1; i < length; i++)
if (p[i] > res)
res = p[i];
return res;
}
Same problem - solved using pointer’s arithmetic:
float max(int length, float *p) {
float res;
int i;
res = *p;
p++;
for (i = 1; i < length; i++, p++)
if (*p > res)
res = *p;
return res;
}
Important:
Pointer p stores address of the first array element. However, if we shift pointer p inside the function, address of the first array’s element won’t be changed, neither will influent our main program (that calls the function).
Example:
Exam’s results are transferred into a function in a way of array composed of integers (integers represent grades). This array (flow), is consisted of grades 1, 2, 3, 4 and 5. Number of array’s elements is nrGrades. Write your own function that returns most common grade.
int commonGrade(int *flow, int nrGrades) {
int grade[5] = {0}, commonGrade = 0, i;
for(i = 0; i < nrGrades; i++){
grade[flow[i] -1]++;
}
for(i = 1; i < 5; i++){
if(grade[i] > grade[commonGrade]) {
commonGrade = i;
}
}
return commonGrade + 1;
}
Example:
Write your own function that shifts array p (given, integer type) for a number of places. Array p is consisted of N number of elements, and will be shifted left for negative value, or shifted right for positive value (adjustment < N). Empty places are filled with zeroes.
Example of shifting:
shift = 2 and array[10 40 50 60 12]:
Before shifting: [10 40 50 60 12]
Shifted array: [ 0 0 10 40 50]
Solution:
void shiftArray(int *p, int N, int shift) {
int i;
// if shifting right
if (shift > 0 && shift < N) {
for (i = N - 1 - shift; i >= 0; i --)
p[i + shift] = p[i];
for (i = shift - 1; i >= 0; i --)
p[i] = 0;
}
// if shifting left
else if (shift < 0 && -shift < N) {
shift = -shift;
for (i = 0; i <= N - 1 - shift; i++)
p[i] = p[i + shift];
for (i = N - shift; i < N; i++)
p[i] = 0;
}
}
Stack Data Storage with Function call
Every new element is stored on top of the stack. However, compilers often tend to assign lower address to stack’s top, then to stack’s bottom. This results data being stored downwards (from bottom of the stack to lower memory addresses).
Following data is stored to a stack (from higher addresses to lower ones):
- function’s arguments (highest address is assigned to ultimately-right
placed argument)
- returning address
- local variables (highest address is assigned to first declared variable)
Important:
While transferring data to a stack, frames of the stack will be ignored in this tutorial (processor registers). However, some compilers also tend to store these to a stack.
For how many bytes does the stack maximally increase, while executing this block:
...
...
y = f1(10);
...
if the following functions are defined:
long f2(float a, float b) {
return a + b;
}
int f1(char x) {
int i = 4, y;
y = x + 1;
return i * f2(x, y);
}
f1 call: f2 call: STACK’S TOP
(lower addresses)
returning address 2
10 (float) ^
11 (float) / \
11 (int) 11 (int) / \
4 (int) 4 (int) / __ \
returning address 1 returning address 1
10 (char) 10 (char) STACK’S BOTTOM
(higher addresses)
Returning address is data type long.
By calling function f2, stack has increased to its maximal size:
sizeof(char)
+ sizeof(returning address 1)
+ 2 * sizeof(int)
+ 2 * sizeof(float)
+ sizeof(returning address 2)
--------------
= 25 byte
Technorati Tags: Pointer, Argument, Array, Stack, Program, Stacks, Function
This lesson continues teaching about pointers, so be sure first to read Lesson 17: Pointers in C.
http://visualcplus.blogspot.com/2006/03/lesson-17-pointers-in-c.html
A comment I have on your terminology is the use of the word "reference" since this confuses with C++-references (as in pass-by-reference).
can u please help us to make a SOURCE code or a basic program about STACKS AND QUEUES