Back to Study material
C PPS

UNIT 5

STRUCTURE AND POINTERS

 


Structure

A structure can be considered as a template used for defining a collection of variables under a single name. Structures help programmers to group elements of different data types into a single logical unit (Unlike arrays which permit a programmer to group only elements of same data type).

  • Why Use Structures

         Ordinary variables can hold one piece of information

         arrays can hold a number of pieces of information of the same data type.

For example, suppose you want to store data about a book. You might want to store its name (a string), its price (a float) and number of pages in it (an int).

If data about say 3 such books is to be stored, then we can follow two approaches:

  • Construct individual arrays, one for storing names, another for storing prices and still another for storing number of pages.
  • Use a structure variable.

Suppose we want to create a employee database. Then, we can define a structure

calledemployee with three elements id, name and salary. The syntax of this structure is as

follows:

struct employee  

{   int id;  

    char name[50];  

    float salary;  

};

Note:

  • Struct keyword is used to declare structure.
  • Members of structure are enclosed within opening and closing braces.
  • Usually structure type declaration appears at the top of the source code file, before any variables or functions are defined or maintained in separate header file.
  • Declaration of Structure reserves no space.
  • It is nothing but the “ Template / Map / Shape ” of the  structure .
  • Memory is created , very first time when the variable is created / Instance is created.
  • Structure variable declaration:

We can declare the variable of structure in two ways

  1. Declare the structure inside main function
  2. Declare the structure outside the main function.

1. Declare the structure inside main function

Following example show you, how structure variable is declared inside main function

struct employee  

{  

 int id;  

 char name[50];  

 float salary;  

};  

int main()

{

struct employee e1, e2; 

return 0;

}

In this example the variable of structure employee is created inside main function that e1 ,e2.

2. Declare the structure outside main function

Following example show you, how structure variable is declared outside the main function

 

struct employee  

{  

 int id;  

 char name[50];  

 float salary;  

}e1,e2;  

 

  • Memory allocation for structure

Memory is allocated to the structure only when we create the variable of structure.

Consider following example

 

 

 

  • Structure Initialization

1. When we declare a structure, memory is not allocated for un-initialized variable.

2. Let us discuss very familiar example of structure student , we can initialize structure variable

in different ways –

Way 1 : Declare and Initialize

Struct student

{

char name[20];

int roll;

float marks;

}std1 = { "Poonam",89,78.3 };

In the above code snippet, we have seen that structure is declared and as soon as after declaration we

have initialized the structure variable.

std1 = { "Poonam",89,78.3 }

This is the code for initializing structure variable in C programming

Way 2 : Declaring and Initializing Multiple Variables

struct student

{

char name[20];

int roll;

float marks;

}

std1 = {"Poonam" ,67, 78.3};

std2 = {"Vishal",62, 71.3};

In this example, we have declared two structure variables in above code. After declaration of variable we have initialized two variable.

std1 = {"Poonam" ,67, 78.3};

std2 = {"Vishal",62, 71.3};

 

Way 3 : Initializing Single member

struct student

{

int mark1;

int mark2;

int mark3;

} sub1={67};

Though there are three members of structure,only one is initialized , Then remaining two members

are initialized with Zero. If there are variables of other data type then their initial

values will be –

Data Type Default value if not initialized

integer 0

float 0.00

char NULL

Way 4 : Initializing inside main

struct student

{

int mark1;

int mark2;

int mark3;

};

void main()

{

struct student s1 = {89,54,65};

- - - - --

- - - - --

- - - - --

};

When we declare a structure then memory won’t be allocated for the structure. i.e only writing below

declaration statement will never allocate memory

struct student

{

int mark1;

int mark2;

int mark3;

};

We need to initialize structure variable to allocate some memory to the structure.

struct student s1 = {89,54,65};

Pointers

The pointer in C language is a variable which stores the address of another variable. This variable can be of type int, char, array, function, or any other pointer. ... int n = 10; int* p = &n; // Variable p of type pointer is pointing to the address of the variable n of type integer.

One of the vital and heavily used feature ‘C’ is pointer. Most of the other programming languages also support pointers but only few of them use it freely. Support pointers but only few of them use it freely.

When we declare any variable in C language, there are three things associated with that variable.

 1. Data type of variable : Data type defines the type of data that variable can hold. Data type tells compiler about the amount of memory allocate to the variable.

 2. Address of Variable : Address of variable represent the exact address of memory location which is allocated to variable.

 3. Value of variable : It is the value of variable which is store at the address of memory location allocated to variable.

Example :int     n = 5;

In the above example ‘int’ is the data type which tells compiler to allocate 2 bytes of memory to variable ‘n’.

Once the variable is declare compiler allocated two bytes of memory to variable ‘n’. Suppose the address of that memory location is 1020. At the address of memory location 1020 the value 5 is store.

Memory map for above declaration is as follows.

use of &,/and ‘*’ operator

Consider the following program.

 #include<stdio.h>

 #include<conio.h>

 void main()

 {

  inta,b,c,

  printf (“Enter two numbers”);

  scanf (“%d%d”, &a,&b);

  c=a+b;

  printf(“/n Addition is %d”, C);

  printf(“/n Address of variable C is %d”, &C);

  getch ();

 }

Above program is the program for addition of two numbers in ‘C’ language. In the sevent instruction of above program we used operator ‘%’ and ‘&’ ‘%d’ is the access specifier which tells compiler to take integer value as ainpute whereas. ‘&a’ tells compile to store the taken value at the address of variable ‘a’.

In the ninth instruction compiler will print me value of ‘C’ so the output of 9th instruction is as follows.

 Addition is 5   [Note : considering a = 2 and b = 3]

In the tenth instruction compiler will print me address of variable C.

So the output of lenth instruction is as follows. Address of variable C is 1020.

Now consider the following program.

 #include<stdio.h>

 #include<conio.h>

 void main()

 {

  inta,b,c;

  printf(“Enter two numbers”);

  scanf(“%d %d”, & a, &b);

  c=a+b;

  printf(“\n Addition is %d”,C);

  printf(“\n Address of variable C is %d”,&C);

  printf(‘\n value of variable C is %d”, *(&C));

  getch();

 }

Now, we all are clear about the output of instruction 9 and 10.

In the 11th instruction, operator *and & is used. ‘*’ operator tells compile to pickup the value which is stored at the address of variable C. So the output of 11th instruction is as follow. Value of variable C is 5 [considering a = 24 b = 3;]

Declaration of Pointer

Pointers are declare with the help of operator ‘*’. ‘*’ is known as ‘value at address’. Pointers are the variables which are used to store the address of another variable As the address of variable is always whole numbers so pointer always contains whole numbers. The declaration of pointer are as follows.

Syntax : Data type * pointer Name.

Example:       int    *I;

Data type defines the type of value defined at the address of pointer variable. In the above example value at the address of ‘I’ is of type integer.

Consider the following program.

 # include<stdio.h>

 # include<conio.h>

 void main()

 {

  int a,b,c;

  int *p,*q,*r;

  p=&a;

  q=&b;

  r=&c;

  printf(“Enter two numbers”);

  scanf(“%d%d,&a,&b);

  c=a + b;

  printf(“\n Address of variable C is %d”,&C);

  printf(“\n Address of variable C is %d,r);

  printf(“\n Address of variable r is %d”,&r);

  printf(“\n value of variable C is %d”,C);

  printf(“\n value of variable C is %d,*^);

  getch ();

 }

 In the above program variable ‘r’ is the integer pointer which holds the address of variable ‘C’

Case 1: In ‘printf’ statement whenever we used (“%d”,r) men me value of r is printed but ‘r’ is holding the address of variable ‘C’. so, address of variable C is copied to the value of ‘r’ and it is printed on output screen

Case 2: Whenever we used (“%d”,&r) in ‘printf’ function men the address of variable ‘r’ is pointed on o/p screen.

Case 3: When we used (“%d”,*r) in pointf function at mat time value which is stored at the address which holds by variable ‘r’ is printed.

Now me variable ‘r’ is holding the address of variable ‘C’. So, the value which is stored at the address of ‘C’ is printed on the output screen.

Consider the following example.

 #include<stdio.h>

 #include<conio.h>

 void main()

 { 

  int a=3;

  int *p;

  p=&a;

  printf(“\n%d”,a);

  printf(“\n%d”,&a);

  printf(“\n%d”,P);

  printf(“\n%d”,&P);

  printf(“\n%d”,*P);

  printf(“\n%d”,*(&a));

 }

Run the above program on the computer system so that you will familiar with the basic use of pointers. Following is the explanation O/p of above program.

  • The first ‘printf’ statement prints the value of ‘C’ ie. 3
  • The second ‘printf’ statement prints the address of ‘a’
  • The third ‘printf’ statement prints me value of ‘p’ ie. the address of ‘a’
  • The forth ‘printf’ statement prints the address of ‘p’
  • The fifth ‘printf’ statement prints the value which is stored at the address holds in ‘p’ ie. 3
  • The sixth ‘printf’ statement prints the value which is stored at the address of ‘a’ ie. 3

Data type of pointer variable can be anything. Such as char *C;

In the above instruction pointer ‘C’ is of type character so the variable ‘C’ can store the address of variable which contains character type of value. Consider the following program.

 #include<stdio.h>

 #include<conio.h>

 void main()

 {

  int I,*ip;

  char C, *cp;

  I = 3;

  ip = & I;

  c=’M’;

  cp=&c;

  printf(“%d”,I);

  printf(“\n%d”,*ip);

  printf(“\n%C;,C);

  printf(“\n%c”, *cp);

  getch();

 }

The output of above program is.

3

3

m

m

Advantages of pointer

1. With the help of pointer, programmer can pass the value to the function by using call be reference.

2. Dynamic memory allocation is positive because of pointer.

3. Pointers are useful in designing linked list and other algorithmic data structure.

4. Faster access of data is positive because of pointer as pointer points to physical memory locations.

 


There are 4 main types of preprocessor directives:

  1. Macros
  2. File Inclusion
  3. Conditional Compilation
  4. Other directives

 

  • Macros: Macros are a piece of code in a program which is given some name. Whenever this name is encountered by the compiler the compiler replaces the name with the actual piece of code. The ‘#define’ directive is used to define a macro. Let us now understand the macro definition with the help of a program:

 

#include <stdio.h>

// macro definition

#define LIMIT 5

int main()

{

    for (int i = 0; i < LIMIT; i++) {

        printf("%d \n",i);

    }

    return 0;

}

Output:

0

1

2

3

4

In the above program, when the compiler executes the word LIMIT it replaces it with 5. The word ‘LIMIT’ in the macro definition is called a macro template and ‘5’ is macro expansion.
 

Macros with arguments: We can also pass arguments to macros. Macros defined with arguments works similarly as functions.

#include <stdio.h>

// macro with parameter

#define AREA(l, b) (l * b)

int main()

{

    int l1 = 10, l2 = 5, area;

    area = AREA(l1, l2);

   printf("Area of rectangle is: %d", area);

    return 0;

}


Output:

Area of rectangle is: 50

 

The compiler finds AREA(l, b) in the program it replaces it with the statement (l*b) . The values passed to the macro template AREA(l, b) will also be replaced in the statement (l*b). Therefore AREA(10, 5) will be equal to 10*5.

  • File Inclusion: This type of pre-processor directive tells the compiler to include a file in the source code program. There are two types of files which can be included by the user in the program:
    1. Header File or Standard files: These files contains definition of pre-defined functions like printf(), scanf() etc. These files must be included for working with these functions. Different function is declared in different header files. For example, standard I/O functions are in ‘iostream’ file whereas functions which perform string operations are in ‘string’ file.
      Syntax:

#include< file_name >

where file_name is the name of file to be included. The ‘<‘ and ‘>’ brackets tells the compiler to look for the file in standard directory.

2.     user defined files: When a program becomes extremely large, it is good practice to divide it into smaller files and include whenever needed. These types of files are user defined files.

These files can be included as:

3.     #include"filename"

 

  • Conditional Compilation: Conditional Compilation directives are type of directives which helps to compile a specific portion of the program or to skip compilation of some specific part of the program based on some conditions. This can be done with the help of two pre-processing commands ‘ifdef‘ and ‘endif‘.
    Syntax:
  • #ifdef macro_name
  •     statement1;
  •     statement2;
  •     statement3;
  •     .
  •     .
  •     .
  •     statementN;
  • #endif

If the macro with name as ‘macroname‘ is defined then the block of statements will execute normally but if it is not defined, the compiler will simply skip this block of statements.

  • Other directives: Apart from the above directives there are two more directives which are not commonly used. These are:
    1. #undef Directive: The #undef directive is used to undefine an existing macro. This directive works as:
    2. #undef LIMIT

Using this statement will undefine the existing macro LIMIT. After this statement every “#ifdef LIMIT” statement will evaluate to false.

3.     #pragma Directive: This directive is a special purpose directive and is used to turn on or off some features. This type of directives is compiler-specific, that vary from compiler to compiler.

Some of the #pragma directives are discussed below:

  • #pragma startup and #pragma exit: These directives helps us to specify the functions that are needed to run before program startup( before the control passes to main()) and just before program exit (just before the control returns from main()).
     

#include <stdio.h>

void func1();

void func2();

#pragma startup func1

#pragma exit func2

void func1()

{

    printf("Inside func1()\n");

}

  

void func2()

{

    printf("Inside func2()\n");

}

int main()

{

    void func1();

    void func2();

    printf("Inside main()\n");

    return 0;

}

Output:

Inside func1()

Inside main()

Inside func2()

The above code will produce the output as given below when run on GCC compilers:

Inside main()

This happens because GCC does not supports #pragma startup or exit. However, you can use the below code for a similar output on GCC compilers.

#include <stdio.h>

void func1();

void func2();

void __attribute__((constructor)) func1();

void __attribute__((destructor)) func2();

  

void func1()

{

    printf("Inside func1()\n");

}

void func2()

{

    printf("Inside func2()\n");

}

int main()

{

    printf("Inside main()\n");

    return 0;

}

 

  • #pragma warn Directive: This directive is used to hide the warning message which are displayed during compilation.
    We can hide the warnings as shown below:
    • #pragma warn -rvl: This directive hides those warning which are raised when a function which is supposed to return a value does not returns a value.
    • #pragma warn -par: This directive hides those warning which are raised when a function does not uses the parameters passed to it.
    • #pragma warn -rch: This directive hides those warning which are raised when a code is unreachable. For example: any code written after the return statement in a function is unreachable.

 

References:

  • The C programming language by Dennis Ritchie
  • C programming by K.N. King
  • The Complete Reference C Fourth Edition by Herbert Schilt
  • Computer Fundamentals and Programming in C by Reema Theraja.
  • C in a nutshell by Peter Prinz.

 

 


Index
Notes
Highlighted
Underlined
:
Browse by Topics
:
Notes
Highlighted
Underlined