0% found this document useful (0 votes)
21 views24 pages

Unit 4

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
21 views24 pages

Unit 4

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 24

UNIT IV

PART-A
POINTERS

INTRODUCTION:
The pointer in C language is a variable which stores the address of another variable.
Pointers are used to access memory and manipulate the address. This variable can be of type int,
char, array, function, or any other pointer.

Declaring Pointers (Creating Pointers):

In c programming language, declaration of pointer variable is similar to the creation of normal


variable but the name is prefixed with * symbol.

Syntax: datatype *pointerName ;

Example : int *ptr ;

Initialize a pointer:
After declaring a pointer, we initialize it like standard variables with a variable address. To get
the address of a variable, we use the ampersand (&)operator, placed before the name of a
variable whose address we need.

Syntax: pointer = &variable;

Eg: double a = 10;

double *p;

p = &a;

Program:

#include <stdio.h>

void main()
{

int a=10; //variable declaration

int *p; //pointer variable declaration

p=&a; //store address of variable a in pointer p

printf("Address stored in a variable p is:%x \n",p); //accessing the address

printf("Value stored in a variable p is:%d \n",*p); //accessing the value

getch();

Output:

Address stored in a variable p is: 60ff08

Value stored in a variable p is: 10

POINTERS TO POINTERS:

A pointer to a pointer is a form multiple indirection, or a chain of pointers or double


pointer. Normally, a pointer contains the address of a variable. When we define a pointer to a
pointer, the first pointer contains the address of the second pointer, which points to the location
that contains the actual value as shown below.

A variable that is a pointer to a pointer must be declared as such. This is done by placing an
additional asterisk in front of its name.

Syntax: datatype **pointerName ;

Eg: int **var;

Example Program:

#include <stdio.h>

void main ()

{
int var;

int *ptr;

int **pptr;

var = 3000;

ptr = &var;

pptr = &ptr;

printf("Value of var = %d\n", var );

printf("Value available at *ptr = %d\n", *ptr );

printf("Value available at **pptr = %d\n", **pptr);

getch();

Output:

Value of var = 3000

Value available at *ptr = 3000


Value available at **pptr = 3000

COMPATIBILITY:
Two pointer types with the same type qualifiers are compatible if they point to objects of
compatible types. The composite type for two compatible pointer types is the similarly qualified
pointer to the composite type.
The following example shows compatible declarations for the assignment operation:
float subtotal;
float * sub_ptr;

sub_ptr = &subtotal;
printf("The subtotal is %f\n", *sub_ptr);
The next example shows incompatible declarations for the assignment operation:
double league;
int * minor;
minor = &league; /* error */
Pointers have a type associated with them, such as char, int, float, etc. Each pointer takes on the
attributes of the type to which it refers to in addition to its own attributes.
Compatibility types are:
a) Pointer Size Compatibility
b) Dereference Type Compatibility

c) Casting Pointers

d) Dereference Level Compatibility

a) Pointer Size Compatibility:

 The size of all pointers is the same.


 Every pointer variable holds the address of one memory location in the computer.
 On the other hand, the Size of the variable that the pointer references can be different.
 The pointer also takes the attributes of the type being referenced.
Example: Prints the size of each pointer and the size of each referenced variable
#include <stdio.h>
void main()
{
int a = 10;
int *pa = &a;

char b = 'x';
char *pb = &b;
float c = 10.01;
float *pc = &c;
printf("Pointer Example Program : Print Size of Different types Using sizeof\n");
printf("\n sizeof(a): = %d", sizeof(a));

printf("\n sizeof(*pa): = %d", sizeof(*pa));


printf("\n sizeof(b): = %d", sizeof(b));
printf("\n sizeof(*pb): = %d", sizeof(*pb));
printf("\n sizeof(c): = %d", sizeof(c));
printf("\n sizeof(*pc): = %d", sizeof(*pc));
getch();
}

Output:
Pointer Example Program : Print Size of Different types Using sizeof
sizeof(a) : = 4
sizeof(*pa) : = 4
sizeof(b) : = 1
sizeof(*pb) : = 1
sizeof(c) : = 4

sizeof(*pc) : = 4

b) Dereference Type Compatibility :

 The dereference type is the type of the variable that the pointer is referencing.
 It is invalid to assign a pointer of one type to a pointer of another type.
 A pointer to a char is only compatible with a pointer to a char.
 A pointer to an int is only compatible with a pointer to an int.
 Do not assign a pointer to a char to a pointer to an int.
 The exception to the reference type compatibility rule is the pointer to Void.

c) Casting Pointers:
• The problem of type incompatibility can be solved by using casting.

• An explicit assignment between incompatible pointer types is done by using a cast


operator.
• For example,
pc=(char *)&a; /*pc is a character pointer and a is a integer pointer */

• This converts an integer pointer to a char and assigns the value to pc.

D) Dereference Level Compatibility:

 A pointer to int is not compatible with a pointer-to-pointer to int.


 The pointer to int has a reference type of int, while a pointer-to-pointer to int has a
reference type of pointer to int

L VALUE AND R VALUE:


L-value: An l-value (locator value) represents an object that occupies some identifiable location
in memory. l-value may appear as either left hand or right hand side of an assignment
operator(=). l-value often represents as identifier.
The l-value is one of the following:
1. The name of the variable of any type i.e of integral, floating, pointer, structure, or union
type.
2. A subscript ([ ]) expression int arr[20];
3. A unary-indirection (*) expression. *p = 1;
4. An l-value expression in parentheses. *(p + 2) = 18;
5. A const object
6. The result of indirection through a pointer.
7. The result of member access through pointer(-> or .)

Eg: int a,b;

a = 1;
b = a; // Ok, as l-value can appear on right
9 = a; // Compilation error:
R-value: r-value refers to data value that is stored at some address in memory. A r-value is an
expression that can’t have a value assigned to it, which means r-value can appear on right but not
on left hand side of an assignment operator(=).

Eg: int a = 1, b;
a + 1 = b; // Error, left expression (a + 1) is not variable
1

UNIT IV

PART B

POINTER APPLICATIONS

ARRAYS AND POINTERS IN C:


When an array is declared, compiler allocates sufficient amount of memory to contain all
the elements of the array. Base address i.e address of the first element of the array is also
allocated by the compiler.

Suppose we declare an array arr,

int arr[5] = { 1, 2, 3, 4, 5 };

Assuming that the base address of arr is 1000 and each integer requires two bytes, the five
elements will be stored as follows:

Here variable arr will give the base address, which is a constant pointer pointing to the first
element of the array, arr[0]. Hence arr contains the address of arr[0] i.e 1000.

Hence arr has two purposes

1. It is the name of the array


2. It acts as a pointer pointing towards the first element in the array.

arr is equal to &arr[0] by default

Eg: int *p;

p = arr; // or,

p = &arr[0]; //both the statements are equivalent.

Pointer to Array: We can use a pointer to point to an array, and then we can use that pointer to
access the array elements.
2

#include <stdio.h>

void main()

int i;

int a[5] = {1, 2, 3, 4, 5};

int *p = &a[0]; // same as int*p = a;

for (i = 0; i < 5; i++)

printf("%d", *p);

p++;

getch();

Output:

In the above program, the pointer *p will print all the values stored in the array one by one.

POINTER ARITHMETIC AND ARRAYS:

A pointer in c is an address, which is a numeric value. Therefore, you can perform


arithmetic operations on a pointer just as you can on a numeric value.

Following arithmetic operations are possible on the pointer in C language:

1. Increment
2. Decrement
3. Addition
4. Subtraction
5. Comparison
3

Pointer increment:
Increment operator when used with a pointer variable returns next address pointed by the
pointer. The next address returned is the sum of current pointed address and size of pointer data
type.

Example:

#include <stdio.h>

void main()

int i;

int a[5] = {1, 2, 3, 4, 5};

int *p = &a[0]; // same as int*p = a;

for (i = 0; i < 5; i++)

printf("Address of a[%d] = %x\n", i, p );

printf("Value of a[%d] = %d\n", i, *p );

p++;

getch();

Output:
4

Pointer decrement: Decrement operator returns the previous address pointed by the pointer. The
returned address is the difference of current pointed address and size of pointer data type.

#include <stdio.h>

void main()

int i;

int a[5] = {1, 2, 3, 4, 5};

int *p = &a[4]; // same as int*p = a;

for (i = 5; i > 0; i--)

printf("Address of a[%d] = %x\n", i, p );

printf("Value of a[%d] = %d\n", i, *p );

p--;

getch();

Output:

Pointer Addition:We can add a value to the pointer variable.Adding any number to a pointer
will give an address.
5

Syntax: new_address= current_address + (number * size_of(data type));


Example:
#include<stdio.h>
int main()
{
int number=50;
int *p;//pointer to int
p=&number; //stores the address of number variable
printf("Address of p variable is %u \n",p);
p=p+3;
printf("After adding 3: Address of p variable is %u \n",p);
return 0;
}
Output:
Address of p variable is 3214864300
After adding 3: Address of p variable is 3214864312

As you can see, the address of p is 3214864300. But after adding 3 with p variable, it is
3214864312, i.e., 4*3=12 increment,since integer value occupies 4-byte memory in 64-bit
Operating system.
Pointer Subtraction: Like pointer addition, we can subtract a value from the pointer
variable.Subtracting any number from a pointer will give an address.
Syntax: new_address= current_address - (number * size_of(data type));
Example:
#include<stdio.h>
int main(){
int number=50;
int *p; //pointer to int
p=&number; //stores the address of number variable
printf("Address of p variable is %u \n",p);
p=p-3; //subtracting 3 from pointer variable
printf("After subtracting 3: Address of p variable is %u \n",p);
return 0;
}
Output:
Address of p variable is 3214864300
After subtracting 3: Address of p variable is 3214864288

You can see after subtracting 3 from the pointer variable, it is 12 (4*3) less than the previous
address value.
6

Pointer comparison:

In C, you can compare two pointers using relational operator. You can perform six different type
of pointer comparison <, >, <=, >=, == and !=.Pointer comparison compares two pointer
addresses to which they point to, instead of comparing their values. Pointer comparisons are
useful,If you want to check if two pointer points to same location.

Example:

int main()

int num = 10;

int *ptr1 = &num; // ptr1 points to num

int *ptr2 = &num; // ptr2 also points to num

printf(“address of ptr1 is %u”,ptr1);

printf(“address of ptr2 is %u”,ptr2);

if(ptr1 == ptr2)

ptr2++;

printf(“modified address of ptr2 is %u”,ptr2);

return 0;

Output:
7

MEMORY ALLOCATION FUNCTIONS:

In C it is very convenient to allocate and deallocate blocks of memory as and when needed.The
memory management in C can by using two types of memory spaces.

1. Static Memory

2. Dynamic Memory

1. Static memory: This is where variables, which are defined outside of functions, are located.
it specifies their scope to be local to the current module. Variables that are defined inside of a
function, which are explicitly declared static, are also stored in static memory.

2.Dynamic Memory: The concept of dynamic memory allocation in c language enables the C
programmer to allocate memory at runtime. Dynamic memory allocation in c language is
possible by 4 functions of stdlib.h header file.

1. malloc()

2. calloc()

3. realloc()

4. free()

Function Purpose Syntax

malloc() Allocates the single block of malloc (number * sizeof(int));


requested memory and returns the
pointer to the first byte of allocated
memory.

calloc() Allocates multiple blocks of calloc (number, sizeof(int));


requested memory space.Initializes
the elements to zero and returns a
pointer to the memory.

realloc() It is used to modify the size of realloc (pointer_name, number * sizeof(int));


previously allocated memory space.
8

free() Frees or empties the previously free (pointer_name);


allocated memory space.

malloc():

 malloc () function is used to allocate space in memory during the execution of the program.

 malloc () does not initialize the memory allocated during execution. It carries garbage
value.

 malloc () function returns null pointer if it couldn’t able to allocate requested amount of
memory.

Syntax : ptr=(cast-type*)malloc(byte-size);

calloc():

The calloc() function allocates multiple block of requested memory.

 It initially initialize all bytes to zero.

 It returns NULL if memory is not sufficient.

Syntax : ptr=(cast-type*)calloc(number, byte-size) ;

realloc():

If memory is not sufficient for malloc() or calloc(), you can reallocate the memory by
realloc() function. In short, it changes the memory size.

Syntax: ptr=realloc(ptr, new-size);

free():

The memory occupied by malloc() or calloc() functions must be released by calling free()
function. Otherwise, it will consume memory until program exit.

Syntax: free(ptr);

Example:

C Program to Store Information Using Structures with Dynamic Memory Allocation

#include <stdio.h>
#include<stdlib.h>
9

struct course
{
int marks;
char subject[30];

};
void main()
{
struct course *ptr;
int i, noofRecords;
printf("Enter number of records: ");

scanf("%d", &noofRecords);
// Allocates the memory for noofRecords structures with pointer ptr pointing to the base
address.
ptr = (struct course*) malloc (noOfRecords * sizeof(struct course));

for(i = 0; i < noofRecords; ++i)


{
printf("Enter name of the subject and marks respectively:\n");
scanf("%s %d", &(ptr+i)->subject, &(ptr+i)->marks);
}
printf("Displaying Information:\n");

for(i = 0; i < noofRecords ; ++i)


{
printf("%s\t%d\n", (ptr+i)->subject, (ptr+i)->marks);
}
getch();
}

Output:
10

DIFFERENCE BETWEEN STATIC MEMORY ALLOCATION AND DYNAMIC


MEMORY ALLOCATION IN C:

Static memory allocation Dynamic memory allocation

In static memory allocation, memory is In dynamic memory allocation,


allocated while writing the C program. memory is allocated while
Actually, user requested memory will be executing the program. That
allocated at compile time. means at run time.

Memory size can’t be modified while Memory size can be modified


execution. while execution.
Example: array Example: Linked list
DIFFERENCE BETWEEN malloc() AND calloc() FUNCTIONS IN C:

malloc() calloc()

It allocates only single block of It allocates multiple blocks of requested


requested memory memory

int *ptr; int *ptr;


ptr = malloc(20 * sizeof(int)); ptr = calloc(20, sizeof(int) );
For the above, 20*4 bytes of memory For the above, 20 blocks of memory will
only allocated in one block. be created and each contains 20*4 bytes of
Total = 80 bytes memory.
Total = 1600 bytes

malloc () doesn’t initializes the calloc () initializes the allocated memory


allocated memory. It contains garbage to zero
values
11

type cast must be done since this Same as malloc () function


function returns void pointer int *ptr;
int *ptr; ptr = (int*)calloc(20,sizeof(int));
ptr = (int*)malloc(sizeof(int)*20 );

ARRAY OF POINTERS:

Just like we can declare an array of int, float or char etc, we can also declare an array of
pointers. Array of pointers is an indexed set of variables, where the variables are pointers.
An array of pointers is useful in the same way as all arrays, that is it allows you to index a large
set of variables.
Syntax: datatype *array_name[size];
Eg: int *arr[5];
Here arr is an array of 5 integer pointers. It means that this array can hold the address of 5 integer
variables.

Fig: Array Of Pointers

Example:

#include<stdio.h>
void main()
{
int *arr[3];
int a = 10, b = 20, c = 50, i;
arr[0] = &a;
arr[1] = &b;
arr[2] = &c;
for(i = 0; i < 3; i++)
{
printf("Address = %d\t Value = %d\n", arr[i], *arr[i]);
}

getch();
}
12

Output:

Address = 387130656 Value = 10

Address = 387130660 Value = 20

Address = 387130664 Value = 50

PROGRAMMING APPLICATION:

Dynamic Array:
This program creates a dynamic array where the programmer can choose the number of rows and
number of elements that can be stored per a row (coloumns) dynamically at run time.

#include <stdio.h>

#include <stdlib.h>

void main()

int r, c;

printf("enter number of rows you want to create \n");

scanf("%d",&r);

printf("number of elements you want to insert per row \n");

scanf("%d",&c);

int *arr = (int *)malloc(r * c * sizeof(int));

int i, j, count = 0;

for (i = 0; i < r; i++)

for (j = 0; j < c; j++)

*(arr + i*c + j) = ++count;

}
13

for (i = 0; i < r; i++)

for (j = 0; j < c; j++)

printf("%d ", *(arr + i*c + j));

getch();

Output:
1

UNIT-IV

PART C

PROCESSOR COMMANDS

PROCESSOR COMMANDS (OR) PREPROCESSOR COMMANDS (OR)


PREPROCESSOR DIRECTIVE:

In C programming language, preprocessor directive is a step performed before the


actual source code compilation. It is not part of the compilation. Preprocessor directives are
lines in your program that start with #. The # is followed by an identifier that is the directive
name. For example #include, #define, #ifndef etc.

There are a number of steps involved between writing a program and executing a
program in C

The source code written by programmers is stored in the file program.c. This file is then
processed by preprocessors and an expanded source code file is generated. This expanded file is
compiled by the compiler and an object code file is generated with an extension .obj. Finally, the
linker links this object code file to the library functions to generate the executable file an
extension .exe. This can generate the actual output.
2

Types of preprocessor directives:

There are 4 main types of preprocessor directives

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

1. 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 (or) symbolic constants.
Eg:
#include <stdio.h>
// macro definition
#define LIMIT 5
void main()
{
for (int i = 0; i < LIMIT; i++)
{
printf("%d \n",i);
}

getch();
}

Output:

0
1
2
3
4
In the above program, when the compiler executes the word LIMIT it replaces it with 5.

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

Eg:
3

#include <stdio.h>

// macro with parameter

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

void main()

int l1 = 10, l2 = 5, area;

area = AREA(l1, l2);

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

getch();

Output:

Area of rectangle is: 50

We can see from the above program that whenever the compiler finds AREA(l, b) in the program
it replaces it with the statement (l*b).

2. File Inclusion: This type of preprocessor 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:

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.

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.

user defined files: When a program becomes very 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:

Syntax: #include"filename"

3. 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
4

of the program based on some conditions. This can be done with the help of two preprocessing
commands ‘ifdef‘ and ‘endif‘.

Syntax:

#ifdef macro_name

statement1;

statement2;

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.

4.Other directives: Apart from the above directives there are two more directives which are not
commonly used. These are:

#undef Directive: The #undef directive is used to undefine an existing macro. This directive
works as:

Eg: #undef LIMIT

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

#pragma Directive: This directive is a special purpose directive and is used to turn on or off
some features. This type of directives are compiler-specific i.e., they 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()).

You might also like