16.7 – Functions and struct

by subbu on September 20, 2014

Here in this session we will see how a struct variable and the address of a struct variable are send as arguments. We will also see how a struct variable and the address of struct variable can be returned from a function.

Sending struct variable as argument

One of the main reasons of using struct type is to send all the details of a single entity as single group rather sending multiple values to a function

While sending a struct variable as argument, we specify the name of struct variable as actual argument and another struct variable is defined as a formal argument, so that, all the members of actual argument will be assigned to the formal argument.

It is important to note that sending struct variable as argument follows pass-by-value rather pass-by-reference. So the change in the members of formal argument will not change in the values of actual argument.

While sending a struct variable as argument make sure that, the type of formal argument must be the type of actual argument (struct type) and struct definition must be visible to both the calling and called by function

struct book
{
 char name[50];
 char author[50];
 char publisher[50];
 float price;
};
void display(struct book);
int main()
{
 struct book x={"Let us C","Kanithkar","BpB",275};
 display(x);
 return 0;
}
void display(struct book a) /* members of x would be assigned to a */
{
 printf("Book Name:%s",a.name);
 printf("\nAuthor: %s",a.author);
 printf("\nPublisher: %s",a.publisher);
 printf("\nPrice:%f",a.price);
}

Output:
Book Name:Let us c
Author: Kanithkar
Publisher: BpB
Price:275.000000

Example explained:
Here the struct variable “x” is send as an argument to the function display().
All the members of “x” are assigned to the formal argument “a”

Sending the address of a struct variable

Like a struct variable, even we can send the address of a struct variable as argument to a function but the formal argument must be a pointer to the struct variable, so that the formal argument can access and modify the details of actual argument using indirection that is either by using *. or -> operators.

#include<stdio.h>
#define PI 3.14
struct circle
{
 int rad;
 float area,cir;
};
void calculate(struct circle*);
int main()
{
 struct circle x;
 printf("Enter the radios:");
 scanf("%d",&x.rad);
 calculate(&x);             /* sending the address of struct variable */
 printf("Area of circle %f",x.area);
 printf("\nCircumference of circle %f",x.cir);
 return 0;
}
void calculate(struct circle *p) /* pointer to struct variable */
{
 p->area=PI*(p->rad)*(p->rad);
 p->cir=2*PI*(p->rad);
}

Execution:
Enter the radios: 17
Area of circle 907.460022
Circumference of circle 106.760002

Example explained:

Pointer to struct variable

“x.rad” is accepted from the keyboard
The address of “x” is send to the function calculate().
Using pointer “p” we could directly access the members of “x” using -> operator.

Sending the array of struct variables

Like a struct variable, even we can send an array of struct type as argument. Here we specify the name of array as actual argument and the same type of struct array as a formal argument.

#include<stdio.h>
#include<math.h>
struct point
{
 int x;
 int y;
};
float distance(struct point[]);
int main()
{
 struct point a[]={{3,5},{6,8}}; /* Array of points */
 float d;
 d=distance(a); /* sending array as argument */
 printf("Distance among two points: %f",d);
 return 0;
}
float distance(struct point f[]) /* struct type array as a formal argument */
{
 /* (f[0].x,[0].y) and (f[1].x,f[1].y) are two points like (x1,y1) and (x2,y2) */
 float t=sqrt(pow(f[1].x-f[0].x,2)+pow(f[1].y-f[0].y,2));
 return t;
}

Output
Distance among two points: 4.242640
As we know, the name of array gives the address of array, we can also define a struct type pointer as a formal argument.
So, the above function distance() can be also defined as

float distance(struct point *f)
{
 float t=sqrt(pow(f[1].x-f[0].x,2)+pow(f[1].y-f[0].y,2));
 return t;
}

Returning a struct variable

Like any variable, even a struct variable can be returned from a function

#include<stdio.h>
#include<math.h>
struct point
{
 int x;
 int y;
};
struct point getpoint();
int main()
{
 struct point p;
 p=getpoint();
 printf("x=%d\ny=%d",p.x,p.y);
 return 0;
}
struct point getpoint()
{
 struct point a={43,56};
 return a;  /* returning the struct variable */
}

Output
x=43
y=56

In the above example “a” is a struct point type of variable initialized with {43,56}. It’s value is being returned and assigned to “p” which is of same struct point type in main()

Returning the address of a struct variable

We can return the address of a struct variable to the calling function so that the calling function can access the struct variable of called by function using indirection.

#include<stdio.h>
#include<math.h>
struct point
{
 int x;
 int y;
};
struct point* getref();
int main()
{
 struct point *p;
 p=getref();
 printf("x=%d\ny=%d",p->x,p->y);
 return 0;
}
struct point* getref()
{
 struct point a={43,56};
 return &a;  /* returning the address of local variable */
}
$gcc –o demo demo.c
demo.c in function 'getref'
demo.c : Warning : function returns address of local variable
$./demo
x=43
y=56

Here the program is successfully executed but, compiler is throwing a warning because the local variable “a” belongs to getref() will be de-allocated once the execution of function is completed and return to the main().

It can be rectified by defining the local variable as static so that, the scope of struct variable will be extended along the program. To get rid of warning, we can define the function as

struct point* getref()
{
  static struct point a={43,56};
  return &a;  /* returning the address of local variable */
}

Previous post:

Next post: