0% found this document useful (0 votes)
8 views17 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)
8 views17 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/ 17

Programming for Problem Solving using C UNIT-4

UNIT-4
Introduction:
A pointer is a constant or variable that contains an address that can be used to access
data.
(OR)
A pointer is a variable whose value is the address of another variable, i.e., direct
address of the memory location. Like any variable or constant, you must declare a pointer
before using it to store any variable address.
An address expression, one of the expression types in the unary expression category,
consists of an ampersand(&) and a variable name.
Syntax: &variable_name;
A variable address is the first byte occupied by the variable.
➢ A pointer that points to no variable contains the special null-pointer constant, NULL.

Accessing variables through pointers:


C has provided an operator, the indirection operator(*). When we dereferencing a
pointer, we are using its value to reference (address) another variable. The indirection
operator whose operand must be a pointer value.
To access the variable a through the pointer p, code it as *p.

Pointer declaration:
In C every variable must be declared its type, since pointer variables contain address
of separate data type, they must be declared before use them the declaration of pointer
variable takes the following them:
Syntax : data_type *pointer_name;
Example: int *p;
float *x;

Pointer initialization:
As ordinary variables are initialized with in declaration part of the program. The
pointer variable can initialized be accessing address of the variable that is used in the
program:
Syntax: datatype *ptr_name=expression;
Example: int a;
int *p; /*Declaration*/
P=&a /*initialization*/
Program:
#include<stdio.h>
void main()
{
int m,*ptr;
m=270;
ptr=&m;

Page 1
Programming for Problem Solving using C UNIT-4

printf(“The content of variable m=%d”,*ptr);


*ptr=23;
Printf(“\nThe content of the variable m after
initialization=%d”,*ptr);
}
Output:
The content of the variable m=270
The content of the variable m after initialization=23

Difference between address and De-referencing operators:

Address Operator De-Referencing Operator


Address operator can be denoted by & De-Referencing operator can be denoted by
*
The & operator can be called as “address of” The * operator can be called as “value at
address”
Another name for & operator is address Another name for de-referencing operator
operator is indirection operator
The & operator can be used only with a The * operator can be used by means of
simple variable ar4e an array element symbolic names.
Example: int number; Example: int number; *ptr; number=200;
a= & number; Ptr= &number; n= *ptr;

Pointer to pointer:
Pointers are used to store the address of other variables of similar datatype. But if you
want to store the address of a pointer variable, then you again need a pointer to store it. Thus,
when one pointer variable stores the address of another pointer variable, it is known as
Pointer to Pointer variable or Double Pointer.

Pointer Pointer Variable

Address Address Value

Page 2
Programming for Problem Solving using C UNIT-4

Syntax: int **p1;


Here, we have used two indirection operator(*) which stores and points to the address
of a pointer variable i.e, int *. If we want to store the address of this (double pointer) variable
p1, then the syntax would become:
int ***p2;
Example:
#include <stdio.h>
int main()
{
int a = 10;
int *p1; //this can store the address of variable a
int **p2;
p1 = &a; p2 = &p1;
printf("Address of a = %u\n", &a);
printf("Address of p1 = %u\n", &p1);
printf("Address of p2 = %u\n\n", &p2);
printf("Value at the address stored by p2 = %u\n",
*p2);
printf("Value at the address stored by p1 = %d\n\n",
*p1);
printf("Value of **p2 = %d\n", **p2);
printf("%u", p2);
return 0;
}
Output
Address of a = 2686724
Address of p1 = 2686728
Address of p2 = 2686732
Value at the address stored by p2 = 2686724
Value at the address stored by p1 = 10
Value of **p2 = 10
Compatibility:
Pointer size compatibility:
The size of all pointers is the same. Every pointer variable holds the address of one
memory location in the computer.
Dereference type compatibility:
The dereference type is the type of the variable that the pointer is referencing. With
one expectation it is invalid to assign a pointer of one type to a pointer of another type, even
though the value in both cases are memory addresses and would therefore seem to be fully
compatible.
A void pointer cannot be dereferenced.
L value and R value:
Every expression has a value. But the value in an expression can be used in two
different ways.
1. An lvalue expression must be used whenever the object is receiving a value; that is, it
is being modified.
2. An rvalue expression can be used to supply a value for further use; that is, to examine
or copy its value.

Page 3
Programming for Problem Solving using C UNIT-4

Expression Type Comments


1. Identifier Variable identifier
2. Expression[…] Array Indexing
3. (expression) Expression must already be lvalue
4. *expression Dereferenced expression
5. Expression.name Structure selection
6. Expression→name Structure indirect selection
7. Function call If function uses return by address
Table: Lvalue Expression

Example: a=…… a[5]=…… (a)=……. *p=………


All expressions that are not lvalue expressions are rvalues.
The following are some of the rvalue expressions:
5 a+2 a*6 a[2]+3 a++

Pointer Arithmetic in C with Examples


Pointer Arithmetic is the set of valid arithmetic operations that can be performed on pointers.
Hence, there are only a few operations that are allowed to perform on Pointers in C language. The
C pointer arithmetic operations are slightly different from the ones that we generally use for
mathematical calculations. These operations are:
1. Increment/Decrement of a Pointer
2. Addition of integer to a pointer
3. Subtraction of integer to a pointer
4. Subtracting two pointers of the same type
5. Comparison of pointers

1. Increment/Decrement of a Pointer
Increment: It is a condition that also comes under addition. When a pointer is incremented, it
increments by the number equal to the size of the data type for which it is a pointer.
For Example: If an integer pointer that stores address 1000 is incremented, then it will increment
by 4(size of an int), and the new address will point to 1004. While if a float type pointer is
incremented then it will increment by 4(size of a float) and the new address will be 1004.
#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=p+1 and p++ both are same
printf("After increment: Address of p variable is %u \n",p); // in our case, p will get incremented
by 4 bytes.
return 0;
}
Output

Page 4
Programming for Problem Solving using C UNIT-4

Address of p variable is 1514864300


After increment: Address of p variable is 1514864304

Decrement, it decrements by the number equal to the size of the data type for which it is a
pointer.

For Example: If an integer pointer that stores address 1000 is decremented, then it will
decrement by 4(size of an int), and the new address will point to 996. While if a float type pointer
is decremented then it will decrement by 4(size of a float) and the new address will be 996.
#include <stdio.h>
void 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-1;
printf("After decrement: Address of p variable is %u \n",p); // P will now point to the immidiate
previous location.
}
Output
Address of p variable is 1514864300
After decrement: Address of p variable is 1514864296

2. Addition of Integer to Pointer


When a pointer is added with an integer value, the value is first multiplied by the size of the data
type and then added to the pointer.
For Example: Consider the same example as above where the ptr is an integer pointer that
stores 1000 as an address. If we add integer 5 to it using the expression, ptr = ptr + 5, then, the
final address stored in the ptr will be ptr = 1000 + sizeof(int) * 5 = 1020.

#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; //adding 3 to pointer variable
printf("After adding 3: Address of p variable is %u \n",p);
return 0;
}
Output
Address of p variable is 1514864300
After adding 3: Address of p variable is 1514864312

Page 5
Programming for Problem Solving using C UNIT-4

3. Subtraction of Integer to Pointer


When a pointer is subtracted with an integer value, the value is first multiplied by the size of the
data type and then subtracted from the pointer similar to addition.
For Example: Consider the same example as above where the ptr is an integer pointer that
stores 1000 as an address. If we subtract integer 5 from it using the expression, ptr = ptr –
5, then, the final address stored in the ptr will be ptr = 1000 – sizeof(int) * 5 = 980.
#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 1514864300
After subtracting 3: Address of p variable is 1514864288

4. Subtraction of Two Pointers


The subtraction of two pointers is possible only when they have the same data type. The result is
generated by calculating the difference between the addresses of the two pointers and calculating
how many bits of data it is according to the pointer data type. The subtraction of two pointers
gives the increments between the two pointers.
For Example: Two integer pointers say ptr1(address:1000) and ptr2(address:1004) are
subtracted. The difference between addresses is 4 bytes. Since the size of int is 4 bytes, therefore
the increment between ptr1 and ptr2 is given by (4/4) = 1.

#include <stdio.h>
void main ()
{
int i = 100,j=200,k;
int *p = &i;
int *q=&j;
k= q-p;
printf("Pointer Subtraction: %u - %u = %u",q, p, k);
}
Output
Pointer Subtraction: 3807733108 - 3807733104 = 1

Page 6
Programming for Problem Solving using C UNIT-4

5. Comparison of Pointers
We can compare the two pointers by using the comparison operators in C. We can implement this
by using all operators in C >, >=, <, <=, ==, !=. It returns true for the valid condition and returns
false for the unsatisfied condition.

#include <stdio.h>

int main()
{
// declaring array
int arr[5];
// declaring pointer to array name
int *ptr1 = &arr;
// declaring pointer to first element
int *ptr2 = &arr[0];

if (ptr1 == ptr2) {
printf("Pointer to Array Name and First Element are Equal.");
}
else {
printf("Pointer to Array Name and First Element are not Equal.");
}

return 0;
}

Output
Pointer to Array Name and First Element are Equal.

Arrays and pointers:


The name of an array is a pointer constant to the first element. And it cannot be used
an lvalue. Since the array is a pointer constant to the first element, the address of the first
element and the name of the array both represent the same location in memory.
The name of the array A is a constant pointer to the first element of the array. So A
can be considered a const int*. Since A is a constant pointer, A = NULL would be an illegal
statement. Arrays and pointers are synonymous in terms of how they use to access memory.
But, the important difference between them is that, a pointer variable can take different
addresses as value whereas, in case of array it is fixed.
Consider the array int age[5];

In C , name of the array always points to the first element of an array. Here, address
of first element of an array is &age[0]. Also, age represents the address of the pointer where
it is pointing. Hence, &age[0] is equivalent to age. Note, value inside the address &age[0]
Page 7
Programming for Problem Solving using C UNIT-4

and address age are equal. Value in address &age[0] is age[0] and value in address age is
*age. Hence, age[0] is equivalent to *age.
In C, you can declare an array and can use pointer to alter the data of an array. This
program declares the array of six element and the elements of that array are accessed using
pointer, and returns the sum.

Program to find sum of six numbers with arrays and pointers.


#include <stdio.h>
int main()
{
int i,class[6],sum=0;
printf("Enter 2 numbers:\n");
for(i=0;i<6;++i)
{
scanf("%d",(class+i)); // (class+i) is equivalent to
&class[i]
sum+= *(class+i); // *(class+i) is equivalent to
class[i]
}
printf("Sum=%d",sum); return 0;
}
Output:
Enter 2 numbers:
2
3
Pointer Array
A pointer is a place in memory that keeps An array is a single, pre allocated chunk of
address of another place inside contiguous element, fixed in size and location
Allows us to indirectly access variables. In Expression a[4] refers to the 5th element of
other words the array a
Pointer can‟t be initialized at definition Array can be definition. Example int
num[]={2,4,5}
Pointer is dynamic in nature. The memory They are static in nature. Once memory is
allocation can be resized or freed later allocated, it cannot be resized or freed
dynamically.
Pointer Arithmetic:
Pointer variables can be used in expressions. If ptr1 and ptr2 are declared and initialize
pointers, then the following statements are valid.

Y=*ptr1 **ptr2; same as (*ptr1)*(*ptr2)


Sum=sum+*ptr1;
Z=7*-*ptr2/*ptr1; same as (7*(-(*ptr2)))/*ptr1\
*ptr2=*ptr2+40;
C allows us to add integers to or subtract integers from pointers.
Passing Pointer to a Function:
When we pass a pointer as an argument instead of a variable then the address of the
Page 8
Programming for Problem Solving using C UNIT-4

variable is passed instead of the value. So any change made by the function using the pointer
is permanently made at the address of passed variable.
Example:1
#include <stdio.h>
void salaryhike(int *var, int b)
{
*var = *var+b;
}
int main()
{
int salary=0, bonus=0;
printf("Enter the employee current salary:");
scanf("%d", &salary);
printf("Enter bonus:");
scanf("%d", &bonus);
salaryhike(&salary, bonus);
printf("Final salary: %d", salary);
return 0;
}
OUTPUT:

Page 9
Programming for Problem Solving using C UNIT-4

Enter the employee current salary:10000


Enter bonus:2000
Final salary: 12000

Functions of returning pointers


It is also possible for functions to return a function pointer as a value. This ability
increases the flexibility of programs. In this case you must be careful, because local variables
of function don‟t live outside the function. They have scope only inside the function. Hence if
you return a pointer connected to a local variable, that pointer will be pointing to nothing
when the function ends.
Example of function pointers as returned values
#include <stdio.h>
int* larger(int*, int*);
void main()
{
int a = 15;
int b = 92;
int *p;
p = larger(&a, &b);
printf("%d is larger",*p);
}
int* larger(int *x, int *y)
{
if(*x > *y)
return x;
else
return y;
}
Note:
1. Either use argument with functions. Because argument passed to the functions are
declared inside the calling function, hence they will live outside the function as well.
2. Or, use static local variables inside the function and return them. As static variables
have a lifetime until the main() function exits, therefore they will be available
throughout the program.
Dynamic memory allocation
The exact size of array is unknown until the compile time, i.e., time when a compiler
compiles code written in a programming language into a executable form. The size of array
you have declared initially can be sometimes insufficient and sometimes more than required.
Dynamic memory allocation allows a program to obtain more memory space, while
running or to release space when no space is required.
Although, C language inherently does not has any technique to allocated memory
dynamically, there are 4 library functions under "stdlib.h" for dynamic memory allocation.
Dynamic memory management refers to manual memory management. This allows
you to obtain more memory when required and release it when not necessary.
malloc()
Page 10
Programming for Problem Solving using C UNIT-4

Allocates requested size of bytes and returns a pointer first byte of allocated space

calloc()
Allocates space for an array elements, initializes to zero and then returns a pointer to
memory
free()
dellocate the previously allocated space
realloc()
Change the size of previously allocated space Examples of calloc() and malloc()
Example:
Write a C program to find sum of n elements entered by user. To perform this
program, allocate memory dynamically using malloc() function.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n,i,*ptr,sum=0;
printf("Enter number of elements: ");
scanf("%d",&n);
ptr=(int*)malloc(n*sizeof(int)); //memory allocated using malloc
if(ptr==NULL)
{
printf("Error! memory not allocated.");
exit(0);
}
printf("Enter elements of array: ");
for(i=0;i<n;++i)
{
scanf("%d",ptr+i);
sum+=*(ptr+i);
}
printf("Sum=%d",sum);
free(ptr);
return 0;
}
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 executing
Actually, user requested memory will be the program. That means at run time.
allocated at compile time.
Memory size can‟t be modified while Memory size can be modified
execution while execution.
Example: array Example: Linked list

Page 11
Programming for Problem Solving using C UNIT-4

Difference Between malloc() and calloc() Functions :

malloc() calloc()
It allocates only single block of requested It allocates multiple blocks of requested
memory memory
int *ptr;Ptr = calloc( 20, 20 * sizeof(int));
int *ptr;ptr = malloc( 20 * sizeof(int) );For
For the above, 20 blocks of memory will be
the above, 20*4 bytes of memory only
created and each contains 20*4 bytes of
allocated in one block.
memory.
Total = 80 bytes
Total = 1600 bytes
Malloc doesn‟t initilize the allocated calloc () initializes the allocated
memory. It contains garbage values memory to zero
type cast must be done since this
Same as malloc () function int
function returns void pointer int
*ptr;ptr = (int*)calloc( 20, 20 *
*ptr;ptr
= (int*)malloc(sizeof(int)*20 ); sizeof(int) );

Array of Pointers:
Array of pointers is an array of the pointer variables. It is also known as pointer
arrays.
Syntax: int *var_name[array_size];
Declaration of an array of pointers:
int *ptr[3];
We can make separate pointer variables which can point to the different values or we
can make one integer array of pointers that can point to all the values.
Example:
#include <stdio.h>
const int SIZE = 3;
void main()
{
for (i = 0; i < SIZE; i++)
{
ptr[i] = &arr[i];
}
for (i = 0; i < SIZE; i++)
{
printf("Value of arr[%d] = %d\n", i, *ptr[i]);
}
}

Page 12
Programming for Problem Solving using C UNIT-4

Processor Commands:
The C complier is made of two functional parts:
1. A processor
2. A translator
➢ The processor uses programmer supplied commands to prepare the source program
for compilation. All preprocessor commands start with a pound sign(#)
➢ The translator converts the C statements into machine code that it places in an object
module.
The three major tasks of a preprocessor: file inclusion, macro definition, and conditional
compilation.
File inclusion:
File inclusion copies one or more files into programs. The files are usually header
files that contain function and data declarations for the program, but they can contain any
valid C statement.
The preprocessor command is #include, which is having 2 different formats:
1. #include<filename.h> →It is used to direct the preprocessor to include files from the
system library
2. #include”filepath.h”→The preprocessor look for the header files in the user-defined
directory.
Macro definition:
A macro definition command associates a name with a sequence of tokens. The name
is called the macro name and the tokens are referred to as the macro body. The macro
definition has the following form:
#define name_body
➢ The macros can take function like arguments, the arguments are not checked for data
type.
Example:Macro INCREMENT(x) can be used for x of any data type.
#include <stdio.h>
#define INCREMENT(x) ++x
int main()
{
char *ptr = "AsdfgZxc";
int x = 10;
printf("%s ", INCREMENT(ptr));
printf("%d", INCREMENT(x));
return 0;
}
Output:

Page 13
Programming for Problem Solving using C UNIT-4

sdfgZxc 8

➢ The macro arguments are not evaluated before macro expansion.


Example:
#include <stdio.h>
#define MULTIPLY(a, b) a*b
int main()
{
printf("%d", MULTIPLY(2+3, 3+5));
return 0;
}
Output: 16

➢ The tokens passed to macros can be concatenated using operator ## called Token-
Pasting operator.
#include <stdio.h>
#define merge(a, b) a##b
int main()
{
printf("%d ", merge(12, 34));
}
Output: 1234

➢ A token passed to macro can be converted to a string literal by using # before it.
#include <stdio.h>
#define get(a) #a
int main()
{
printf("%s", get(AsdfZxcv));
}
Output: AsdfZxcv
➢ The macros can be written in multiple lines using „\‟. The last line doesn‟t need to
have „\‟.

#include <stdio.h>
#define PRINT(i, limit) while (i < limit) \
{ \
printf("AsdfgZxcv "); \
i++; \
}
int main()
{

Page 14
Programming for Problem Solving using C UNIT-4

int i = 0;
PRINT(i, 3);
return 0;
}
Output: AsdfgZxcv AsdfgZxcv AsdfgZxcv
➢ Preprocessors also support if-else directives which are typically used for conditional
compilation.
#include<stdio.h>
int main()
{
#if VERBOSE >= 2
printf("Trace Message");
#endif
}
Output: No Output
➢ A header file may be included more than one time directly or indirectly, this leads to
problems of redeclaration of same variables/functions. To avoid this problem,
directives like defined, ifdef and ifndef are used.
➢ There are some standard macros which can be used to print program file ( FILE ),
Date of compilation ( DATE ), Time of compilation ( TIME ) and Line
Number in C code ( LINE )
#include <stdio.h>
int main()
{
printf("Current File :%s\n", FILE );
printf("Current Date :%s\n", DATE );
printf("Current Time :%s\n", TIME );
printf("Line Number :%d\n", LINE ); return 0;
}
Output:
Current File : C:\TurboC4\TC\BIN
Current Date :June 4 2020
Current Time :10:17:43
Line Number :8
➢ We can remove already defined macros using :
#undef MACRO_NAME
#include <stdio.h>
#define LIMIT 100
int main()
{
printf("%d",LIMIT);
#undef LIMIT
printf("%d",LIMIT);
return 0;
Page 15
Programming for Problem Solving using C UNIT-4

}
Following program is executed correctly as we have declared LIMIT as an integer variable
after removing previously defined macro LIMIT
#include <stdio.h>
#define LIMIT 1000
int main()
{
printf("%d",LIMIT);
#undef LIMIT
int LIMIT=1001;
printf("\n%d",LIMIT);
return 0;
}
Output: 1000
1001
➢ Another interesting fact about macro using (#undef)
#include <stdio.h>
//div function prototype
float div(float, float);
#define div(x, y) x/y
int main()
{
printf("%0.2f",div(10.0,5.0));
#undef div
printf("\n%0.2f",div(10.0,5.0));
return 0;
}
float div(float x, float y){
return y/x;
}
Output: 2.00
0.50

Page 16
Programming for Problem Solving using C UNIT-4

Conditional compilation:
Conditional compilation in C programming language: Conditional compilation as the
name implies that the code is compiled if certain condition(s) hold true. Normally we use if
keyword for checking some condition so we have to use something different so that compiler
can determine whether to compile the code or not. The different thing is #if.
#include <stdio.h>
int main()
{
#define COMPUTER "An amazing device"
#ifdef COMPUTER
printf(COMPUTER);
#endif
return 0;
}

Page 17

You might also like