Unit 4
Unit 4
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.
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.
double *p;
p = &a;
Program:
#include <stdio.h>
void main()
{
getch();
Output:
POINTERS TO POINTERS:
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.
Example Program:
#include <stdio.h>
void main ()
{
int var;
int *ptr;
int **pptr;
var = 3000;
ptr = &var;
pptr = &ptr;
getch();
Output:
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
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));
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
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.
• This converts an integer pointer to a char and assigns the value to pc.
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
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.
p = arr; // or,
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;
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.
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;
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;
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
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()
if(ptr1 == ptr2)
ptr2++;
return 0;
Output:
7
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()
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():
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.
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:
#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));
Output:
10
malloc() calloc()
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.
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:
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;
scanf("%d",&r);
scanf("%d",&c);
int i, j, count = 0;
}
13
getch();
Output:
1
UNIT-IV
PART C
PROCESSOR COMMANDS
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
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>
#define AREA(l, b) (l * b)
void main()
getch();
Output:
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.
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"
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:
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.
#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()).