Module 5 - Strings - Pointers - Structure - PDF
Module 5 - Strings - Pointers - Structure - PDF
1
What is a Structure?
Used for handling a group of logically
related data items
Examples:
Student name, roll number, and marks
Real part and complex part of a complex number
3
Contd.
The individual members can be ordinary
variables, pointers, arrays, or other structures
(any data type)
The member names within a particular
structure must be distinct from one another
A member name can be the same as the
name of a variable defined outside of the
structure
Once a structure has been defined, the
individual structure-type variables can be
declared as:
struct tag var_1, var_2, …, var_n;
4
Example
A structure definition
struct student {
char name[30];
int roll_number;
int total_marks;
char dob[10];
};
A new data-type
5
A Compact Form
It is possible to combine the declaration of the
structure with that of the structure variables:
struct tag {
member 1;
member 2;
:
member m;
} var_1, var_2,…, var_n;
7
Example: Complex number addition
void main()
{
struct complex
{
float real;
float cmplex;
} a, b, c;
9
Arrays of Structures
Once a structure has been defined, we can
declare an array of structures
struct student class[50];
type name
a.real=1.0; a.imag=2.0;
b.real=-3.0; b.imag=4.0;
12
Parameter Passing in a
Function
Structure variables can be passed as parameters like
any other variables. Only the values will be copied
during function invocation
tmp=a;
a=b;
b=tmp;
} 13
Returning structures
It is also possible to return structure values from a
function. The return data type of the function should
be as same as the data type of the structure itself
struct complex add(struct complex a, struct complex b)
{
struct complex tmp;
_COMPLEX a, b, c;
16
Note: typedef is not restricted to just structures,
can define new types from any existing type
Example:
typedef int INTEGER
Defines a new type named INTEGER from the
known type int
Can now define variables of type INTEGER which
will have all properties of the int type
INTEGER a, b, c;
17
The earlier program using typedef
typedef struct{
float real;
float imag;
} _COMPLEX;
tmp = a;
a = b;
b = tmp;
}
18
Contd.
void print (_COMPLEX a)
{
printf("(%f, %f) \n",a.real,a.imag);
}
void main()
{
_COMPLEX x={4.0,5.0}, y={10.0,15.0};
print(x); print(y);
swap(x,y);
print(x); print(y);
} swap.c 19
Output:
(4.000000, 5.000000)
(10.000000, 15.000000)
(4.000000, 5.000000)
(10.000000, 15.000000)
20
Structures and Functions
A structure can be passed as argument to
a function
A function can also return a structure
21
Example: complex number addition
void main()
{
_COMPLEX a, b, c;
scanf(“%f %f”, &a.real, &a.imag);
scanf(“%f %f”, &b.real, &b.imag);
c = add (a, b) ;
printf(“\n %f %f”, c,real, c.imag);
}
_COMPLEX add(_COMPLEX x, _COMPLEX
y)
{
_COMPLEX t;
POINTERS
Pointers are variables that hold address of another variable of same data type. Pointers are
one of the most distinct and exciting features of C language. It provides power and flexibility to
the language. Although pointer may appear little confusing and complicated in the beginning, but
trust me its a powerful tool and handy to use once its mastered.
Benefit of using pointers
Pointers are more efficient in handling Array and Structure.
Pointer allows references to function and thereby helps in passing of function as
arguments to other function.
It reduces length and the program execution time.
It allows C to support dynamic memory management.
Concept of Pointer
Whenever a variable is declared, system will allocate a location to that variable in the
memory, to hold value. This location will have its own address number. Let us assume that
system has allocated memory location 80F for a variable a. int a = 10 ;
The value 10 can be accessed by either using the variable name a or the address
80F.Since the memory addresses are simply numbers they can be assigned to some other
variable. The variable that holds memory address are called pointer variables. A pointer
variable is therefore nothing but a variable that contains an address, which is a location of
another variable. Value of pointer variable will be stored in another memory location.
Array Representation
Here variable arr will give the base address, which is a constant pointer pointing to
the element, arr[0]. Therefore arr is containing the address of arr[0] i.e 1000.
We can declare a pointer of type int to point to the array arr.
int *p;
p = arr;
or p = &arr[0]; //both the statements are equivalent.
Now we can access every element of array arr using p++ to move from one element to another.
NOTE : You cannot decrement a pointer once incremented. p-- won't work.
Pointer to Array
As studied above, we can use a pointer to point to an Array, and then we can use
that pointer to access the array. Lets have an example,
Array of Pointers
Array of pointers can also be declared. Pointers are very helpful in handling character
array with rows of varying length.
char *name[3]={
"Adam",
"chris",
"Deniel"
};
//Now see same array without using pointer
char name[3][20]= {
"Adam", "chris",
"Deniel"
};
The above figure shows the array of pointers used to store the character arrays. The
pointers hold the address of each of the string. Each pointer will point to the first character of
their respective strings.
Pointer to a Pointer
Just as we have pointers to int, float or char, we can also have pointers to pointers. This is
because, a pointer is also a variable. Hence, we can always have another variable (pointer) which
can contain the address of the pointer variable.
EX:
int a = 10; // integer variable
int *p; // pointer to an integer
int **q; // pointer to a pointer to an integer
p = &a;
q = &p;
The above shows a 2-level indirection, however, there is no limit as to how many levels of
indirection we can use.
Here,
3000 2000 10
During compilation, the compiler will allocate 10 memory locations for the variable ‘a’ and once
defined cannot be changed. During execution we cannot have more than 10 data items, and if we
use 3 locations, another 7 locations are wasted.
1. malloc
Description: This function allocates and reserves a block of memory, specified in bytes and
returns a pointer to the first byte of the allocated space.
Syntax:
ptr = (datatype *) malloc (size);
Where - ptr is a pointer of type datatype
- datatype can be any of the basic data type or user defined data type.
- size is the number of bytes required.
Example: ptr = ( int * ) malloc ( sizeof ( int ) );
On successful execution of this statement, a memory space equivalent to size of int is
reserved and the address of the first byte of the memory allocated is assigned to the pointer
ptr of type int.
Return Value – On success, it returns a pointer of type void to the newly allocated block of
memory. On failure i.e. if the specified size of memory is not available, it returns NULL.
3. realloc
Description – This function is used to alter the size of the previously allocated space which
is allocated either by using malloc or calloc function.
Syntax:
ptr = (datatype *) realloc (ptr, size);
Where - ptr is the starting address of allocated memory obtained previously by calling
malloc, calloc, or realloc functions.
- size is the number of bytes required for reallocation. The size specified may be
larger or smaller than the previously allocated memory.
Example:
If the original allocation is done by the statement
ptr = malloc(size);
Then reallocation of space may be done by the statement
ptr = realloc(ptr, newsize)
In case of realloc( ), the contents of the old block will be copied into the newly
allocated space and so, this function guarantees that the earlier contents are not lost.
4. free
Description – This function de-allocates (frees) the allocated block of memory which is
allocated by using the functions malloc( ), calloc( ) or realloc( ).
Syntax:
free(ptr);
Where ptr is a pointer to a memory block which has already been created by invoking one of
the 3 functions malloc( ), calloc( ) or realloc( ).
Return Value – None.
1. Memory Leakage
This is a problem where in a part of the memory is reserved but is not accessible to any of the
applications.
Example: Consider the following program segment.
main ( )
{
int *a;
a = (int *)malloc(sizeof (int) );
2. Dangling Pointer
Any pointer pointing to a destroyed object or which does not contain a valid address is called
a dangling pointer.
Example: Consider the following program segment
main ( )
{
int *a;
a =(int *)malloc(sizeof(int));
*a=20;
…….
…….
free(a);
}
Here, if we de-allocate the memory for the variable ‘a’ using free(a), the memory location
pointing to by it is returned to the free pool. Now the pointer variable ‘a’ can be used, but the
contents pointed by that cannot be used, because the pointer variable ‘a’ does not contain a
valid address now and is called a dangling pointer.
Sl
Static Memory Allocation Dynamic Memory Allocation
no.
Memory is allocated during compilation Memory is allocated during run time.
1
time.
The size of the allocated memory space is The size of the allocated memory space is
2 fixed and it cannot be altered during not fixed and it can be altered (increased /
execution. decreased) during execution.
This type of memory allocation can be used This type of memory allocation can be used
3
in applications where the data size is fixed in applications where the storage
6) Program to find the sum of positive and negative numbers out of ‘n’ elements using
dynamic arrays.
#include<stdio.h>
main()
{
int i,n,*a,psum,nsum;
printf("enter the number of elements \n");
scanf("%d",&n);
a=(int*)malloc(n*sizeof(int));
printf("enter the elements\n");
for(i-0;i<n;i++)
{
scanf("%d",a+i);
}
psum=0;
nsum=0;
for(i=0;i<n;i++)
{
if(*(a+i)>0)
{
psum=psum+*(a+i);
If we frequently allocate the memory space,then it is better to use functions as below where n is
number of items.
Functions to allocate memory for integers, floats, chars and double
int* MALLOC_FLOAT(int n)
{
float *x;
x=(float*)malloc(n*sizeof(float));
if(x==NULL)
{
printf(“Insufficient memory\n”);
int* MALLOC_CHAR(int n)
{
char *x;
x=(char*)malloc(n*sizeof(char));
if(x==NULL)
{
printf(“Insufficient memory\n”);
exit(0);
}
return x;
}
4) Allocating memory for double values
int* MALLOC_DOUBLE(int n)
{
double *x;
x=(double*)malloc(n*sizeof(double));
if(x==NULL)
{
printf(“Insufficient memory\n”);
exit(0);
}
return x;
}
The above functions have to be invoked appropriately as shown below:
above segment allocate 5 locations to store integer values. consider size of integer is 2 bytes so,
total 5*2 =10 bytes allocates for 5 integer values.
float *p;
p=MALLOC_FLOAT(n);
char *p;
p=MALLOC_CHAR(n);
It is not possible to write generalized function to allocate memory for n elements of any data type
in C. But it’s possible to write a generalized macro in place of generalized function.
Macro to allocate memory for one or more items of any data type using malloc
#define MALLOC(p,n,type) \
p=(type*)malloc(n*sizeof(type)); \
if(p==NULL) \
{ \
printf(“Insufficient memory\n”); \
exit(0); \
NOTE:
The symbol \ is an instruction given to the preprocessor that all the lines following \ are
continuation of the first line of that macro definition.
#include<stdio.h>
#define MALLOC(p,n,type) \
p=(type*)malloc(n*sizeof(type)); \
if(p==NULL) \
{ \
printf(“Insufficient memory\n”); \
exit(0); \
}
main()
{
int *p1,*p2;
int sum;
MALLOC(p1,1,int);
MALLOC(p2,1,int);
*p1=10;
*p2=20;
sum=*p1+*p2;
printf(“%d+%d=%d\n”,*p1,*p2,sum);
}
Macro to reallocate memory for one or more items of any data type using realloc
a[0]
a[1]
a[2]
The element a[i][j] is found by first accessing the pointer in a[i]. This gives the address of the
zero th element of row ‘i’ of the array. Then by adding ‘j’ to this pointer the address of the j th
element of row ‘i’ is found
This means,
The expression *(a + i) + j points to the jth element in the ith row i.e. *(a + i) + j = &a[i][j]
The expression *( *(a + i) + j ) gives the value of the element in i th row and jth column i.e.
*( *(a + i) + j ) = a[i][j].
A 2-dimensional array with 3 rows and 5mcolumns can be created by allocating the memory
dynamically in two stages.
Stage 1: Allocate memory for specified number of row pointers.
Example: allocate memory for 3 row pointers using: MALLOC(x,3,int*);
Pictorial representation is shown below
In general
MALLOC(x,rows,int*); //rows-represents number of rows in a two dimensional array
Stage 2: Allocate memory for each row with specified number of column .
Example: Allocate memory for 5 columns with respect to row x[0],x[1] and x[2] using
MALLOC() three times as shown below.
[0] [1] [2] [3] [4]
X[0]
X[1]
X[2]
3-rows 5-columns
X[3][5]
}
}
printf(“The entered the elements are\n”);
for( i = 0; i < rows ; i + + )
{
for( j = 0; j < columns ; j + + )
{
printf(“%d \t”, *( *(a + i) + j ) ); // printf(“%d \t”, a[i][j] );
}
printf(“\n”);
}
free(a);
}