SlideShare una empresa de Scribd logo
1 de 164
Descargar para leer sin conexión
2.2. POINTER 301
{31, 32, 33},
17 {34, 35, 36},
{37, 38, 39}
19 }
};
21 int (* mat)[3][3];
mat = Arr;
23 printf("Element at mat [0][1][1] = %dn",
*(*(*( mat + 0) + 1) + 1));
25 printf("8th element from position of mat [0][2][0] = %dn",
(*(*( mat + 0) + 2))[8]) ;
27 printf("8th element from position of mat [0][2][0] = %dn",
(*( mat + 0))[2][8]) ;
29 return 0;
}
✌
✆
✞
Element at mat [0][1][1] = 15
8th element from the position of mat [0][2][0] = 26
8th element from the position of mat [0][2][0] = 26
✌
✆
2.2.3 Pointers and Text Strings
Historically, text strings in C have been implemented as array of characters, with the
last byte in the string being a character code zero, or the null character ‘0’. Most
C implementations came with a standard library of functions for manipulating strings.
Many of the more commonly used functions expect the strings to be null terminated string
of characters. To use these functions requires the inclusion of the standard C header file
“string.h”. A statically declared, initialized string would look similar to the following:
✞
1 static const char *myFormat = "Total Amount Due: %d";
✌
✆
The variable ‘myFormat’ can be view as an array of 21 characters. There is an implied
null character (’0’) tacked on to the end of the string after the ’d’ as the 21st item in
the array. You can also initialize the individual characters of the array as follows:
✞
1 static const char myFlower [ ]
= {’P’, ’e’, ’t’, ’u’, ’n’, ’i’, ’a’, ’0’};
✌
✆
An initialized array of strings would typically be done as follows:
✞
static const char *myColors [ ] = {"Red", "Green", "Blue "};
✌
✆
The initialization of an especially long string can be splitted across lines of source code
as follows.
✞
1 static char *longString = "My name is XYZ.";
✌
✆
The library functions those are used with strings are discussed in later. A simple example
of copying string from one variable to other by using pointer is given below.
302 Array & Pointer
✞
1 #include <stdio.h>
/* Defined two arrays to be copied*/
3 char A[80] = "Lucknow is capital city .";
char B[80];
5
int main (void ) {
7 /* First pointer A*/
char *ptrA ;
9 /* Second pointer B*/
char *ptrB ;
11 /* Assign string pointer of*
*array A to pointer ptrA */
13 ptrA = A;
/* Assign string pointer of*
15 *array B to pointer ptrB */
ptrB = B;
17 /*do loop */
while (* ptrA != ’0 ’) {
19 /* Copy text from array A to array*
*B using pointers prtA and ptrB */
21 *ptrB ++ = *ptrA ++;
}
23 /* Add line terminating value*/
*ptrB = ’0’;
25 /* Show array B on screen */
puts (B);
27 return 0;
}
✌
✆
From above example, always remember that a pointer to an array always points to the
elements of the array and make copy-paste an element from one array to another array.
Pointer never stores elements itself. The output of the above example is given below:
✞
Lucknow is capital city .
✌
✆
By default, strings are pointer to itself. For example “I am a king” is a pointer to
itself. This pointer points to the first character “I”. See example
✞
1 #include <stdio.h>
3 int main (int argc , char *argv [ ]) {
int i=0;
5 for(i =0;*("I am king " + i)!=’0’;i++)
printf("%cn" ,*("I am king " + i));
7 return 0;
}
✌
✆
In above example
✞
*("I am king " + i)
✌
✆
2.2. POINTER 303
extracts character by character from the string pointed by string itself. for loop is used to
print all characters. When string pointer encountered by a null character, loop is halted.
Output of above example is
✞
I
a
m
k
i
n
g
✌
✆
Pointers to Function
To declare a pointer-to-function do:
✞
1 int (*pf) ();
✌
✆
The question rises why this declaration is not written as
✞
1 int *pf ();
✌
✆
The reason is that parentheses operator, ( ), has higher precedence than that of derefer-
encing operator (*). Hence for pointer-to-function variable, dereferencing of function is
grouped by parentheses. Example for pointer-to-function is given below.
✞
1 #include <stdio.h>
3 int main () {
int (*r)();
5 r = puts ;
(*r)("My String");
7 return 0;
}
✌
✆
Here, the function line is equivalent to
✞
puts ("My String");
✌
✆
✞
My String
✌
✆
Unlike the normal pointers, a function pointer points to code, not data. A function
pointer points to the memory address where execution codes are stored. Remember that,
we do not allocate or de-allocate memory using function pointers.
✞
1 #include <stdio.h>
304 Array & Pointer
3 void myFunc(int a) {
printf("Value of a is %dn", a);
5 }
7 int main () {
void (* ptrFunc)(int) = &myFunc;
9 (* ptrFunc )(10) ;
return 0;
11 }
✌
✆
✞
Value of a is 10
✌
✆
Function name is also points to the address of execution code. Therefore, use of ‘myFunc’
at the place of ‘&myFunc’ in the following example give same result as given by above
example.
✞
1 #include <stdio.h>
3 void myFunc(int a) {
printf("Value of a is %dn", a);
5 }
7 int main () {
void (* ptrFunc)(int) = myFunc;
9 ptrFunc (10) ;
return 0;
11 }
✌
✆
✞
Value of a is 10
✌
✆
A pointer-to-function that returns output as string pointer is shown in the following
example:
✞
1 #include <stdlib.h>
#define STRLEN 1024
3
char *str_func (char *str) {
5 char *s = NULL ;
/* Allocate the required memory space.*/
7 s = malloc(sizeof (char )*( STRLEN + 1));
/* Copy contents of str into memory */
9 memcpy(s, str , STRLEN);
/* Return the pointer of memory location */
11 return s;
}
13
main (int argc , char *argvc[ ]) {
15 /* Test string.*/
char s[STRLEN] = "The Sarnath.";
17 /* Returned string pointer .*/
2.2. POINTER 305
char *st;
19 /* Pointer to function declaration .*/
int (*fn)();
21 /* Get the function object pointer .*/
fn = str_func ;
23 /* Pass the func object to declared function .*/
st = (*fn)(s);
25 /* Print returned string.*/
printf("%sn", st);
27 return 0;
}
✌
✆
✞
The Sarnath .
✌
✆
C also allows to create pointer-to-function. Pointer-to-function can get rather messy.
Declaring a data type to a function pointer generally clarifies the code. Here’s an example
that uses a function pointer, and a (void *) pointer to implement what’s known as a
callback. A switch case example
✞
1 #include <stdio.h>
int add(int a, int b);
3 int sub(int a, int b);
int mul(int a, int b);
5 int div(int a, int b);
7 int main () {
int i, result;
9 int a = 10;
int b = 5;
11 printf("Enter the value between [0, 3] : ");
scanf("%d", &i);
13 switch (i) {
case 0:
15 result = add(a, b);
break;
17 case 1:
result = sub(a, b);
19 break;
case 2:
21 result = mul(a, b);
break;
23 case 3:
result = div(a, b);
25 break;
}
27 printf(":-> Result is %d",result);
return 0;
29 }
31 int add(int i, int j) {
return (i + j);
306 Array & Pointer
33 }
35 int sub(int i, int j) {
return (i - j);
37 }
39 int mul(int i, int j) {
return (i * j);
41 }
43 int div(int i, int j) {
return (i / j);
45 }
✌
✆
✞
Enter the value between 0 and 3 : 2
:-> Result is 50
✌
✆
Array of function pointers may also be used to access a function by using array pointer
index. See the example given below:
✞
#include <stdio.h>
2 #include <math .h>
typedef int *(* func )(int);
4
int mySum(int i) {
6 return (i + 2);
}
8
int mySub(int i) {
10 return (i - 2);
}
12
int main () {
14 func myFuncArray [10] = {NULL };
myFuncArray [0] = &mySum;
16 myFuncArray [1] = &mySub;
printf("%dn", (* myFuncArray [0]) (5));
18 printf("%dn", (* myFuncArray [1]) (5));
return 0;
20 }
✌
✆
✞
7
3
✌
✆
In above example, a array function pointer is created by using typedef and each array
function pointer is assigned the address of the function object.
✞
typedef int *(* func )(int); // array function pointer
2 myFuncArray [0] = &mySum; /* assigning function pointer *
*to array function pointer . */
✌
✆
2.2. POINTER 307
When array function pointer is called, we get desired result. Above array function pointer
is re-implemented in the following example.
✞
1 #include <stdio.h>
int add(int a, int b);
3 int sub(int a, int b);
int mul(int a, int b);
5 int div(int a, int b);
/* Function pointer used for execution of *
7 *four functions called by their positions .*/
int (* operator [4]) (int a, int b) = {add , sub , mul , div};
9
int main () {
11 int i, result;
int a = 10;
13 int b = 5;
printf("Enter the value between [0, 3] : ");
15 scanf("%d", &i);
result = operator [i](a, b);
17 printf(":-> Result is %d", result);
return 0;
19 }
21 int add(int i, int j) {
return (i + j);
23 }
25 int sub(int i, int j) {
return (i - j);
27 }
29 int mul(int i, int j) {
return (i * j);
31 }
33 int div(int i, int j) {
return (i / j);
35 }
✌
✆
✞
Enter the value between 0 and 3 : 1
:-> Result is 5
✌
✆
A struct member function can also be created by using pointer. Following is the example
for the purpose.
✞
#include <stdio.h>
2 #include <string.h>
/* Global declaration of file pointer . */
4 FILE *fp;
6 data type struct {
308 Array & Pointer
int (* open )(void );
8 int (* del)(void );
} file ;
10
int my_file_open (void ) {
12 fp = fopen("my_file .txt", "w");
if (fp == NULL ) {
14 printf("File can not be opened .n");
} else {
16 printf("File opened .n");
fputs("Hello World!", fp);
18 }
}
20
void my_file_del (void ) {
22 printf("Try to remove .n");
if (remove("my_file .txt") == 0) {
24 printf("File is removed .n");
} else {
26 printf("No file to remove.n");
}
28 }
30 file create(void ) {
file my_file;
32 my_file .open = my_file_open ;
my_file .del = my_file_del ;
34 my_file .open ();
my_file .del();
36 return my_file;
}
38
int main (int argc , char *argv [ ]) {
40 create ();
return 0;
42 }
✌
✆
Casting of Pointer
To assign an integer type pointer ‘iptr’ to a floating type pointer ‘fptr’, we cast ‘iptr’ as
a floating type pointer and then carry out the assignment, as shown :
✞
fptr = (float *) iptr ;
✌
✆
When a pointer is casted from old data type to new data type then it only keeps the
address of a size of new data type. For example, in Linux GCC, data size of integer is 4
byte while data size of character is 1 byte. Hence when integer data type is casted into
character data type and pointed by a pointer then pointer keep the address one byte at
time.
2.2. POINTER 309
✞
1 #include <stdio.h>
3 int main () {
int a = 320;
5 /* Integer 320 = binary 00000001 01000000 */
char *ptr;
7 ptr = (char *) &a;
/* Cast intger into character and point to first *
9 *byte of the integer containing value 01000000 */
11 printf("%d ", *ptr);/* Print 01000000 as decimal 64*/
return 0;
13 }
✌
✆
✞
64
✌
✆
Address Copying Vs Content Copying
A pointer points to location of content stored in the memory. It does not point to value
stored in the memory. For example, take a string “This”, that is stored in memory
location 0
×
001250. Now this value is assigned to a pointer variable (say ‘str’) then pointer
holds address value 0×001250 not to the value “This”. When one pointer is assigned to
the other pointer then only location of contents is assigned. See the example:
✞
1 #include <stdio.h>
3 int main () {
char *str="This "; /* location at 0x0011 (say)*/
5 char *pt = "That ";/* location at 0x0022 (say)*/
printf("str:%s, pt:%sn",str ,pt);
7 str=pt; /* str ’s memory location changed to 0x0022*/
printf("str:%sn",str);
9 return 0;
}
✌
✆
✞
str:This , pt:That
str:That
✌
✆
Here, address of ‘pt’ is copied to address of ‘str’. If we wants to copy contents from the
memory location pointed by ‘pt’ to the memory location pointed by pointer ‘str’, then
strcpy function is used.
✞
#include <stdio.h>
2 #include <string.h>
4 int main () {
char *str="This "; /* location at 0x0011 (say)*/
6 char *pt = "That ";/* location at 0x0022 (say)*/
310 Array & Pointer
printf("str:%s, pt:%sn",str ,pt);
8 str=malloc (5); /* Memory allocation is required as *
*compiler do not kew the memory size *
10 *assigned to str pointer while copy .*/
strcpy(str ,pt); /* contents of memory location of ’pt’ *
12 *is copied at memory location of ’str’*/
printf("str:%sn",str);
14 free (str);
return 0;
16 }
✌
✆
✞
str:This , pt:That
str:That
✌
✆
Here, contents from the memory location pointed by pointer ‘pt’ are copied into the
memory location pointed by pointer ‘str’.
2.2.4 Dangling & Wild Pointers
Dangling pointers and wild pointers are pointers that do not point to a valid object of the
appropriate type. Dangling pointers arise when it points to the location that is deallocated
without modifying the value of the pointer. The pointer still points to the memory
location of the deallocated memory. Dangling pointers causes memory sharing violation
and returns error of segmentation faults in UNIX and Linux, or general protection faults
in Windows.
✞
#include <stdio.h>
2
int main () {
4 {
char *dp = NULL ;
6 {
char c;
8 dp = &c;
printf("%dn", dp);
10 }
/* dp is now a dangling pointer */
12 }
14 return 0;
}
✌
✆
✞
2280807
✌
✆
Another example of dangling pointer, in which function ‘func’ returns the addresses of a
stack-allocated local variable. Once called function returns, the space for these variables
gets deallocated and technically they have “garbage values”.
2.2. POINTER 311
✞
1 #include <stdio.h>
3 int *func (void ) {
int num = 1234;
5 return &num;
}
7
int main () {
9 printf("%dn", func ());
printf("%dn", *func ());
11 return 0;
}
✌
✆
✞
2280756
2280756
✌
✆
Wild pointers arise when a pointer is used prior to initialization to some known state,
which is possible in some programming languages. They show the same erratic behavior
as dangling pointers, though they are less likely to stay undetected because many com-
pilers will raise a warning at compile time if declared variables are accessed before being
initialized.
✞
#include <stdio.h>
2
int main () {
4 int i; // Declared but not initialized
printf("%dn", i); //i acts as wild pointer
6 return 0;
}
✌
✆
Output is strange:
✞
1629773328
✌
✆
2.2.5 Pointer, Variable & Address
A variable is a literal name which addresses to a memory location. An address is a
reference to a variable. Pointer points to the address of a variable. One of the most
common problem arises in C programming is analyses of pointer variable size, position
of its current address and next address after arithmetic operations. The pointers and
their locations are similar to milestones along the road. Suppose, a road along-with the
distance milestone separated by one meter (for concept purpose).
312 Array & Pointer
0
1
2 3
4
5
6 7
8
9
10
Initially, we are at the 3rd
milestone. One meter long unit is used to measure the
distances between two consecutive milestones. In one step measurement, next milestone
will be 4th
one. It means that, if initially pointer location is at 3rd
milestone then after
one increment (by one meter), the pointer location will be at 4th
milestone.
0
1
2 3
bc
4
b
5
6 7
8
9
10
Now, we change measurement count from one meter long unit to two meter long unit.
Assume that initially location pointer is at 3rd
milestone. In one increment to the location
pointer (two meter unit), next milestone will be 5th
one.
0
1
2 3
bc
4
5
b
6 7
8
9
10
In C programming, integer type variable is four byte long. So, if initially pointer
location of the integer variable is at 3rd
milestone then after one increment (by four
bytes) to the integer variable, the pointer location shall be at 7th
milestone.
0
1
2 3
bc
4
5
6 7
b
8
9
10
In the following example a character data-type pointer is declared as variable ‘a’.
Pointer arithmetic is performed. New locations of pointers fetched to see the change in
the length between two consecutive addresses of pointer.
2.2. POINTER 313
✞
1 #include <stdio.h>
3 int main () {
char *a;
5 printf("%pn", a);
a++; /* First increment of pointer */
7 printf("%pn", a);
a++; /* Second increment of pointer */
9 printf("%pn", a);
return 0;
11 }
✌
✆
✞
0xb 7758000 %First address location of character
%pointer is here
0xb 7758001 %New location of character pointer after
%first increment . Distance from the
%first address location is 1 bytes.
0xb 7758002 %New location of character pointer after
%second increments . Distance from the
%first address location is 2 bytes.
✌
✆
Bytes Memory Blocks Memory Address
0×b7758000
Byte No. 0
0×b7758001
Byte No. 1
0×b7758002
Byte No. 2
0×b7758003
Byte No. 3
0×b7758004
Byte No. 4
0×b7758005
Byte No. 5
0×b7758006
Byte No. 6
0×b7758007
Byte No. 7
0×b7758008
Byte No. 8
a
a + 1
a + 2
In the following example an integer data-type pointer is declared as variable ‘a’. Pointer
arithmetic is performed. New locations of pointers fetched to see the change in the length
between two consecutive addresses of pointer.
✞
#include <stdio.h>
2
int main () {
4 int *a;
printf("%pn", a);
6 a++; /* First increment of pointer */
printf("%pn", a);
8 a++; /* Second increment of pointer */
printf("%pn", a);
314 Array & Pointer
10 return 0;
}
✌
✆
✞
0xb 7758000 %First address location of integer pointer is here
0xb 7758004 %New location of integer pointer after first increment .
%Distance from the first address location is 4 bytes.
0xb 7758008 %New location of integer pointer after second increments .
%Distance from the first address location is 8 bytes.
✌
✆
Bytes Memory Blocks Memory Address
0×b7758000
Byte No. 0
0×b7758001
Byte No. 1
0×b7758002
Byte No. 2
0×b7758003
Byte No. 3
0×b7758004
Byte No. 4
0×b7758005
Byte No. 5
0×b7758006
Byte No. 6
0×b7758007
Byte No. 7
0×b7758008
Byte No. 8
a
a + 1
a + 2
In the following example a two dimensional integer data-type array is declared and initial-
ized as variable ‘a’. Pointer arithmetic is performed. New locations of pointers fetched to
see the change in the length between two consecutive addresses of pointer for first column.
✞
1 #include <stdio.h>
3 int main (void ) {
int *mPtr [ ][3] = {
5 {-1, 2, 3}, /*8 bytes , 8 bytes , 8 bytes*/
{4, -3, 5}, /*8 bytes , 8 bytes , 8 bytes*/
7 {5, 6, -5} /*8 bytes , 8 bytes , 8 bytes*/
}; /*3 By 3 matrix*/
9 int i, j;
for (i = 0; i < 3; i++) {
11 printf("%2d -> %pt", *(* mPtr + (3 * i)), (mPtr + (3 * i)));
printf("n");
13 }
return 0;
15 }
✌
✆
✞
-1 -> 0xbfa 09b8c %1X1 element is at this address
4 -> 0xbfa 09bb0 %2X1 element is at this address
%Distance from 1X1 element is 24 Bytes
5 -> 0xbfa 09bd4 %3X1 element is at this address
%Distance from 1X1 element is 48 Bytes
2.2. POINTER 315
%Distance from 2X1 element is 24 Bytes
✌
✆
In pointers, we must be cautious, that pointers holds address values. The pointers are used
to hold addresses of other memory bytes not the numbers, hence only pointer comparison,
addition and subtraction operations are allowed . For example, in following code lines,
the memory byte pointed by the variable x holds value 20 as binary 10100.
✞
int *x = 20; // assign address
✌
✆
0×45 0×46 0×47 0×48
00000000 00000000 00000000 00010100
∗x
When pointer is assigned a value, it is treated as address value. Now, we can retrieve this
address by just calling pointer as
✞
1 printf("%d", x);
✌
✆
We shall get value 20 as its result. But when we dereference the variable x as
✞
1 printf("%d", *x);
✌
✆
It tries to read the value at address 0×14 (equal to decimal 20 and binary 00010100), it
gives access status violation as we try to access restricted memory space set by the OS.
It is because, dereference is the retrieving of value from that address which is stored in
the memory bytes pointed by the dereferencing pointer. If we change the value of x as
✞
1 int *x = 2346192; // assign address
printf("%d", *x);
✌
✆
0×45 0×46 0×47 0×48
00000000 00100011 11001100 11010000
∗x
We get a random value which is stored at address 0
×
23CCD0 (equal to decimal 2346192 or
binary 1000111100110011010000). Note that, the address location 0×23CCD0 is beyond
the restricted memory region set by OS, hence it returns random output.
2.2.6 Constant Pointers
A pointer may be declared as constant by using const keyword.
✞
int i = 5;
2 const int *p = &i;
//Or
4 int const *p = &i;
✌
✆
316 Array & Pointer
There are two cases, (i) where a pointer pointed to constant data (pointee) and pointee
can not be changed, and (b) where constant pointer (address) can not be changed. The
usual pointer-pointee relation are given below:
✞
#include <stdio.h>
2 #include <stdlib.h>
4 int main () {
int i = 2;
6 int j = 3;
int *k = &j; // k points to j and *k is 3
8 printf("%d n", *k);
j = 6; // Now both j and *k are 6
10 printf("%d %dn", j, *k);
*k = 7; // j and *k are 7. Pointee changes
12 printf("%d %dn", j, *k);
k = &i; // k points to i. *k is 2. Pointer changes
14 printf("%d %dn", i, *k);
*k = 8; // i and *k are 8 now. Pointee changes
16 printf("%d %dn", i, *k);
return 0;
18 }
✌
✆
✞
3
6 6
7 7
2 2
8 8
✌
✆
Now the const keyword is used as shown in modified example. There are errors shows by
the compiler.
✞
1 #include <stdio.h>
#include <stdlib.h>
3
int main () {
5 int i = 2;
const int j = 3;
7 const int *k = &j;
j = 6; // Error! assignment of read -only variable ’j’
9 *k = 7; // Error! assignment of read -only location ’* k’
k = &i; // k points to i. *k is 2. Pointer changes
11 *k = 8; // Error! assignment of read -only location ’* k’
return 0;
13 }
✌
✆
Here, code line
✞
1 //+--Pointee type , i.e. constant pointee
//|
3 const int *k = &j;
✌
✆
2.2. POINTER 317
2
0×50
3
0×51
4
0×52
5
0×53
6
0×54
7
0×55
8
0×56
const int *k = &j
j
&j
(const) j
represents that ‘k’ is a non constant type pointer and the value to which it is pointing
is constant type. Therefore, value of ‘j’ can not be changed while address of ‘k’ can be
changed.
✞
1 #include <stdio.h>
#include <stdlib.h>
3
int main () {
5 int i = 2;
const int j = 3;
7 const int *k = &j;
// int const *k = &j; // Or state
9 printf("Address of k is %xn", k);
k = &i; // k points to i. *k is 2. Pointer changes
11 printf("New address of k is %xn", k);
//
13 printf("i : %d, k : %dn", i, *k);
return 0;
15 }
✌
✆
✞
Address of k is 0x22ff44
New address of k is 0x22 ff48
i : 2, k : 2
✌
✆
Similarly, if
✞
1 // +--Pointer type , i.e. constant pointer
// |
3 int * const k = &j;
✌
✆
then, pointer becomes constant while value of pointee can be changed. Notice the position
of asterisk (*) not the const keyword.
2
0×50
3
0×51
4
0×52
5
0×53
6
0×54
7
0×55
8
0×56
int * const k = &j
(const) *k
j
&j
318 Array & Pointer
✞
1 #include <stdio.h>
#include <stdlib.h>
3
int main () {
5 int i = 2;
int j = 3;
7 int * const k = &j;
printf("Address of k is %dn", k);
9 printf("Old values - j : %d, k : %dn", j, *k);
j = 5; // k points to i. *k is 2. Pointer changes
11 printf("New values - j : %d, k : %dn", j, *k);
//k = &i;// Error! assignment of read -only variable ’k’
13 return 0;
}
✌
✆
✞
Address of k is 0x22ff44
Old values - j : 3, k : 3
New values - j : 5, k : 5
✌
✆
The change in the position of the asterisk (*) and keyword const changes the pointer and
pointee type. The general representation is
✞
1 int n = 5;
int * p = &n; // non -const -Pointer to non -const -Pointee
3 const int * p = &n; // non -const -Pointer to const - Pointee
int * const p = &n; // const -Pointer to non -const - Pointee
5 const int * const p = &n; // const -Pointer to const -Pointee
✌
✆
The data type keywords before the asterisk symbol represent the nature of the pointee
(the address location where data is stored). The data type keywords after the asterisk
symobl represent the nature of the pointer itself. This contents add in C just before
Memory Allocation section.
2.2.7 Memory Allocation
There are two types of memory allocation. (i) Static memory allocation and (ii) dynamic
memory allocation. When a static or global variable is declared, it allocates static memory
of one block of space or of a fixed size. The space is allocated once is never freed until
program is not exit. Automatic variables, such as a function argument or a local variable
allocate memory space dynamically. The allocated space is deallcoated (freed) when the
compound statement that contains these variable is exited.
Dynamic Memory Allocation
malloc is used to allocate dynamic memory to a pointer. It returns pointer to newly
allocated memory space block and null pointer if memory allocation failed. This is why,
before using the memory block, the size of the memory block should be checked. The
contents of the block are undefined. It should be initialized manually. The syntax of the
function is given as
2.2. POINTER 319
✞
1 void *malloc(size_t size );
✌
✆
The address of a block returned by malloc or realloc in GNU systems is always a multiple
of eight. Casting of malloc() function is required as shown in the above syntax. The
function, malloc is meant for implementing dynamic memory allocation. It is defined in
stdlib.h or malloc.h, depending on what operating system is used. malloc.h contains only
the definitions for the memory allocation functions and not the rest of the other functions
defined in stdlib.h. It is good programming practices that when allocated memory is no
longer needed, free should be called to release it back to the memory pool. Overwriting
a pointer that points to dynamically allocated memory can result in that data becoming
inaccessible. If this happens frequently, eventually the operating system will no longer
be able to allocate more memory for the process. Once the process exits, the operating
system is able to free all dynamically allocated memory associated with the process. A
simple example is
✞
1 #include <stdio.h>
3 int main (void ) {
int * MemAllo;
5 /* Allocate the memory space*/
MemAllo = (char *) malloc (100);
7 if (MemAllo ) {
printf("Memory allocation successfull !!n");
9 } else {
printf("Memory allocation un -successfull !!");
11 exit (0);
}
13 /* Allocated memory is not freed here .*
*It is not C programming standards . */
15 return 0;
}
✌
✆
✞
Memory allocation successfull !!!!!
✌
✆
In standard C programming, each allocated memory should be freed when it is not in use.
Unfreed memory is locked by the allocating program and can not be accessed by other
programs until the program which allocates memory space is not terminated. free() is
used to free the allocated memory.
✞
1 #include <stdio.h>
3 int main (void ) {
int *p;
5 /* Allocate space for 3490 integers !*/
p = malloc(sizeof (int) * 3490);
7 if (p == NULL ) {
printf("Out of memory ... n");
9 } else {
printf("Memory allocated ... n");
320 Array & Pointer
11 }
/* Out of memory for integer allocation *
13 *while allocating memory space block *
*for 349000000 integers bytes! */
15 p = malloc(sizeof (int) * 349000000) ;
if (p == NULL ) {
17 printf("Out of memory for integer size ... n");
} else {
19 printf("Memory allocated ... n");
}
21 /* Second method of memory allocation .*/
if ((p = malloc (100)) == NULL ) {/* Allocates 100 bytes space.*/
23 printf("Ooooopps ! Out of memory !n");
exit (1);
25 } else {
printf("100 Byte memory allocated ... n");
27 }
/* Free memory*/
29 free (p);
return 0;
31 }
✌
✆
✞
Memory allocated ...
Out of memory for integer size ...
100 Byte memory allocated ...
✌
✆
The operand of sizeof only has to be parenthesized if it’s a type name, as shown in example
below.
✞
1 float *fp;
fp = (float *) malloc(sizeof(float));
✌
✆
If there are the name of a data object instead, then the parentheses can be omitted, but
they rarely are.
✞
int *ip , ar [100];
2 ip = (int *) malloc(sizeof ar);
✌
✆
In the above example, the array ‘ar’ is an array of 100 integers; after the call to malloc
(assuming that it was successful), ‘ip’ will point to a region of store that can also be treated
as an array of 100 integers. The fundamental unit of storage in C is the character, and
by definition sizeof(char) is equal to 1, so there could allocate space for an array of ten
characters with malloc(10) while to allocate room for an array of ten integers, it have to
use as
✞
malloc(sizeof(int [10]))
✌
✆
malloc function should be used cautiously. Loosely use of this function cause memory
leakage. For example,
2.2. POINTER 321
✞
1 void myF(){
int *p=( int *) malloc(sizeof(int));
3 return;
}
✌
✆
function creates a local pointer with dynamic size of array. But pointer is not freed here.
In this case, the memory contents are not accessible by other pointers with same address.
This is why, memory allocated on heap should always be freed when it is not needed.
✞
void myF(){
2 int *p=( int *) malloc(sizeof(int));
free (p);
4 return;
}
✌
✆
If you want to allocate memory and set all memory bits to ‘0s’ then use calloc() function
as given in the following syntax.
✞
1 in *i = (int *) calloc(5, sizeof(int));
✌
✆
It shall allocate memory space equal to the product of 5 and size of integer, i.e. 20 bytes
and each bit is set to ‘0’. Note that, malloc is much faster than calloc.
Reallocate Memory
realloc() function is used to reallocate the size of the memory block created by the malloc
function previously.
✞
1 realloc(<ptr >, <new size >)
✌
✆
If the new size specify is the same as the old size, realloc changes nothing and return the
same address.
✞
1 #include <stdio.h>
#include <stdlib.h>
3
int main (int argc , char ** argv ) {
5 int *p = malloc (1024 * sizeof (int));
if (p == NULL )
7 printf("Memory not allocated .");
int *q = realloc(p, 512 * sizeof (int));
9 if (q == NULL )
printf("Memory not reallocated .");
11 return 0;
}
✌
✆
Memory Management Sometimes, in a string pointer, we erase few memory bytes in a
programming process. These memory bytes remain unused if string array is not refreshed.
For example, we have an array of characters as shown in the following figure.
322 Array & Pointer
ptr G
1
H
2
I
3
J
4
K
5
L
6
Q
7
R
8
S
9
T
10
U
11
V
12
[
13
“
14
]
15
ˆ
16
˙
17
‘
18
The number over the byte are index numbers of the memory byte location. Let the
memory bytes having values Q to V are erased. Now, we rearrange the memory bytes as
shown in the following figure to free some memory space.
ptr G
1
H
2
I
3
J
4
K
5
L
6
[
7
“
8
]
9
ˆ
10
˙
11
‘
12
Actually, memory bytes are not shifted leftward, but the contents of the memory
bytes at indices from 13 to 28 are copied into the memory bytes at indices from 7 to 12.
Rearranging of the memory space is good where contents are linear, i.e. contents are not
structured. For example, it is good in case of string, but it is hard to manipulate the
matrix of 6 × 3 order if few memory bytes are erased.
2.2.8 Pointer Arithmetic
In normal mathematics numbers are used for addition, subtraction, division and multipli-
cation etc. A pointer to an integer has different behavior to the integer. This is why, in
pointer arithmetic, we have to arrange or conform the pointers so that they can behave in
properly. A pointer-to-variable always points to the address where value of the variable
is stored. This is why direct arithmetic of the pointers is of the arithmetic of the address
rather than the values stored at the addresses.
✞
#include <stdio.h>
2
int main (void ) {
4 int a[4] = {50, 99, 3490, 0};
int *p;
6 p = a;
while (*p > 0) {
8 printf("%in", *p);
/* Go to next integer in memory */
2.2. POINTER 323
10 p++;
}
12 return 0;
}
✌
✆
✞
:-> 50
:-> 99
:-> 3490
✌
✆
Another example, using pointer for addition of numbers in an array.
✞
1 #include <stdio.h>
3 int sum_ptr (char *s) {
/* Array is passed to function as pointer. *
5 *sum is variable that store result. */
int sum = 0;
7 /* Until the array not become empty.*/
while (*s != ’0’) {
9 /* Get the pointer value and add it to sum.*/
sum += *s;
11 /* Jump to the next pointer position .*/
s++;
13 }
/* Return the answer as sum.*/
15 return sum;
}
17
int main (int argc , char ** argv ) {
19
/* Array s containing integers .*/
21 char s[ ] = {20, 15, 50, 42};
/* Print the answer.*/
23 printf("Sum : %dn", sum_ptr(s));
25 return 0;
}
✌
✆
✞
Sum : 127
✌
✆
A pointer based integer array is shown in the following example.
✞
1 #include <stdio.h>
#include <stdlib.h>
3
int main () {
5 int *i; /* one row multiple columns , 1Xn array*/
int j = 0;
7 i = (int *) malloc(5 * sizeof (int));
while (j < 5) {
324 Array & Pointer
9 i[j] = j; /* Assign values to i*/
j++;
11 }
j = 0;
13 while (j < 5) {
printf("%d ", *i);
15 i++;
j++;
17 }
return 0;
19 }
✌
✆
✞
0 1 2 3 4
✌
✆
Pointers follow increment or decrements operations. For example, if pointer ‘i’ represents
to first element of the array (either integer or character type arrays) then ‘i++’ (or ‘i+1’)
represents to the next element of the array. See following figure:
bytes x x x x
i
y y y y z z z z n n n n
bytes x x x x y y y y
i + 1
z z z z n n n n
bytes x x x x y y y y z z z z
i + 2
n n n n
Computer Character Codes
In English language, there are 26 alphabets, ten numerals, other punctuation marks
and special characters. These alpha-numeric characters are put in sequence to form
meaning full words. Computer is an electronic device which operates on alternate
current or direct current. There are only two wave forms of alternate current. First is
positive wave form and second is negative wave form. Thus, there is sequences of these
two waveforms when we operate a computer.
2.2. POINTER 325
1
−1
bits
y
0 0
1
0
1
0
1 1
Conventionally, positive waveform is taken as ‘1’ and negative waveform or no
waveform is taken as ‘0’. If computer operates in direct current then there is no negative
wave form to represent ‘0’ bit. In this condition, bit ‘0’ means no current. These
two symbols are binary digits and called as bits. To identify alpha-numeric symbols,
computer uses sequences of these binary digits to form a unique code for each character
or symbol. These unique codes are known as character codes of the computer. Computer
uses eight binary digits for recognition of each character. There are 256 different types
of characters that can be recognized by computer. These 256 characters are assigned
unique decimal character codes ranging from ‘0’ to ‘256’. For example character ‘a’
has character code ‘97’, ‘A’ has character code ‘65’ etc. All the sequential alphabets
and numerals have sequential character codes. For example, upper case alphabets have
character codes ranging from 65 to 90 and lower case alphabets have character codes
ranging from 97 to 122.
Code Symbol Binary
0 00000000
5 00000101
9 00001001
46 . 00101110
47 / 00101111
48 0 00110000
49 1 00110001
50 2 00110010
56 8 00111000
57 9 00111001
65 A 01000001
90 Z 01011010
97 a 01100001
122 z 01111010
Character codes are not same to the user defined binary numbers. This is why,
character code ‘9’ does not represent to numeric decimal ‘9’. Computer accepts ‘9’ as
number digit 9 and computer recognizes it by its equivalent binary sequence 00111001,
i.e. character code 57 rather than binary sequence 00001001. The signal waveform of
326 Array & Pointer
binary 00111001 is given below:
1
bits
y
0 0 1 1 1 0 0 1
Decimal digit 9
2.2.9 Pointer Address
Pointers are used to point the memory address where data is stored. Four memory bytes
are required for a pointer variable to store the address that it is pointing. During the
declaration of a pointer, data type preceded to it tells the nature of data stored at the
address which is being pointed by it. For example, in the pointer variable declaration
✞
1 string *ptr= new string [8];
✌
✆
data type ‘string’ tells that the pointer ‘ptr’ points to memory address 0
×
00 where a string
of one byte long character is stored. Whenever we will perform pointer’s increment or
decrement operation, like ‘ptr++’ pointer’s pointing address will increase by the size of
character, i.e. one byte. Here, ‘ptr++’ will point to the memory address 0×01 as shown
in the following figure.
d
0×00
e
0×01
f
0×02
g
0×03
h
0×04
i
0×05
j
0×06
k
0×07
Bytes
ptr ptr++
*ptr *(ptr++)
Again ‘*ptr’ dereference to the character ‘d’ which is stored at the memory ad-
dress pointed by the pointer ‘ptr’. To get the next character ‘e’, dereference is done
as ‘*(ptr++)’. Similarly, if pointer is integer type as declared below:
✞
1 int *ptr= new int [10];
✌
✆
The size of the pointer variable is always equal to the address bus size. In 32 bit micro-
processor system, it is 4 bytes long. Now, if pointer ‘prt’ points to the memory address
0×00 then ‘ptr++’ points to the memory address 0×04 as shown in the figure given below:
2.2. POINTER 327
xxxx
0×00
xxxx
0×01
xxxx
0×02
xxxx
0×03
yyyy
0×04
yyyy
0×05
yyyy
0×06
yyyy
0×07
Bytes
ptr ptr++
*ptr *(ptr++)
Again ‘*ptr’ dereference to the integer value stored at the memory address pointed by
the pointer ‘ptr’. To get the next integer value, de-reference is done as ‘*(ptr++)’.
✞
1 #include <stdio.h>
#define SIZE 4
3
int main (void ) {
5 short idx;
double d[SIZE ];
7 double *ptd; // data type at pointed address is
//8 bytes long
9 ptd = d;// assign address of array to pointer
printf("%18sn", "double");
11 for (idx = 0; idx < SIZE ; idx ++)
printf("pt + %d: %10pn",
13 idx , ptd + idx);
return 0;
15 }
✌
✆
✞
double
pt + 0: 0x22cd30 //
pt + 1: 0x22cd38 //38 is more than 8 from 30
pt + 2: 0x22cd40 //40 is more than 16 from 30
pt + 3: 0x22cd48 //48 is more than 24 from 30
✌
✆
The value assigned to a pointer is the address of the object to which it points. The
address of a large object, such as type double variable, typically is the address of the first
byte of the object. Applying the ‘*’ operator to a pointer yields the value stored in the
pointed-to object. Adding ‘1’ to the pointer increases its value by the size, in bytes, of
the pointed-to type. There is close connection between arrays and pointers. They mean
that a pointer can be used to identify an individual element of an array and to obtain its
value. In arrays and pointers
✞
1 arr[n] == *( arr + n) /* same value */
arr+2 == &arr [2] /* same address */
✌
✆
✞
#include <stdio.h>
2 #define MONTHS 12
4 int main (void ) {
int days [MONTHS] = {31, 28, 31, 30, 31, 30,
328 Array & Pointer
6 31, 31, 30, 31, 30, 31};
int ind;
8 for (ind = 0; ind < MONTHS; ind ++)
printf("Month %2d has %d days .n", ind + 1,
10 *( days + ind)); // same as days [ind]
return 0;
12 }
✌
✆
✞
Month 1 has 31 days .
Month 2 has 28 days .
Month 3 has 31 days .
Month 4 has 30 days .
Month 5 has 31 days .
Month 6 has 30 days .
Month 7 has 31 days .
Month 8 has 31 days .
Month 9 has 30 days .
Month 10 has 31 days .
Month 11 has 30 days .
Month 12 has 31 days .
✌
✆
Above program can be written as shown below:
✞
#include <stdio.h>
2 #define MONTHS 12
4 int main (void ) {
int days [MONTHS] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30,
31};
6 int ind;
for (ind = 0; ind < MONTHS; ind ++)
8 printf("Month %2d has %d days .n", ind + 1,
days [ind]); // same as *( days + ind)
10 return 0;
}
✌
✆
✞
Month 1 has 31 days .
Month 2 has 28 days .
Month 3 has 31 days .
Month 4 has 30 days .
Month 5 has 31 days .
Month 6 has 30 days .
Month 7 has 31 days .
Month 8 has 31 days .
Month 9 has 30 days .
Month 10 has 31 days .
Month 11 has 30 days .
Month 12 has 31 days .
✌
✆
2.2. POINTER 329
Here, days is the address of the first element of the array, ‘days + ind’ is the address of
element days[ind] and *(days + ind) is the value of that element, just as days[ind] is.
The loop references each element of the array, in turn, and prints the contents of what it
finds. Another example is
✞
#include <stdio.h>
2
int main () {
4 int *ptr;
int arrVal [7] = {44, 55, 66, 77};
6 ptr = &arrVal;
int i;
8 for (i = 0; i <= 4; i++) {
printf("arrVal[%d]: value is %d and address is %pn", i,
*( ptr + i), (ptr + i));
10 }
return 0;
12 }
✌
✆
✞
arrVal [0]: value is 44 and address is 0xbf85ad84
arrVal [1]: value is 55 and address is 0xbf85ad88
arrVal [2]: value is 66 and address is 0xbf85ad8c
arrVal [3]: value is 77 and address is 0xbf85ad90
✌
✆
In C, when an integer is pointed as pointer-to-address-of-integer by a character pointer
variable, then the character variable can addressed to each byte of the integer. An integer
variable is a 4 bytes long. If the address of this integer variable is pointed by character
pointer, i.e. which is one byte long then it can points to each of the byte of the integer
variable. Assume an integer variable is ‘a’. This integer variable is 4 bytes long. The
allocated memory for this integer variable shall be looked like
B[2] B[3] B[4] B[5] B[6] B[7] B[8] B[9] B[10] B[11]
xxxx xxxx xxxx xxxx
a
Here, bytes are labeled as B[2] and so on. The address of integer variable ‘a’ is pointed
by a pointer variable, which is char data type, as shown in syntax given below.
✞
int a;
2 char *x;
x = (char *) &a;
✌
✆
Variable ‘x’ can access to each byte of the integer variable ‘a’.
B[2] B[3] B[4] B[5] B[6] B[7] B[8] B[9] B[10] B[11]
xxxx xxxx xxxx xxxx
x
330 Array & Pointer
See the example below:
✞
1 #include <stdio.h>
3 int main () {
int a; /* Integer variable .*/
5 char *x; /* Character pointer */
x = (char *) &a; /* Pointer to the address of integer .*/
7 a = 512;
x[0] = 0; /* Change value of first byte of integer */
9 printf("%dn", a);
return 0;
11 }
✌
✆
✞
512
✌
✆
Initially, the value assigned to integer variable is stored in memory as shown in the figure
given below.
x[3] x[2] x[1] x[0]
00000000 00000000 00000001 00000000
x a
When we change the data of byte x[0] the new value of integer variable ‘a’ is 512. The
above example is modified as
✞
1 #include <stdio.h>
3 int main () {
int a; /* Declare integer variable .*/
5 char *x; /* Presumes that , data at pointed*
*address is characters type . */
7 x = (char *) &a; /* Pointer to the address of integer .*/
a = 512;
9 x[0] = 1; /* Change value of first byte of integer */
printf("%dn", a);
11 return 0;
}
✌
✆
✞
513
✌
✆
Now, the memory representation is like
x[3] x[2] x[1] x[0]
00000000 00000000 00000001 00000001
x a
It gives the result a = 513.
2.2. POINTER 331
2.2.10 Pointer to Pointer
Expression of N-element array of pointer ‘ptr’ can be converted into a pointer ‘ptr’ and
its value is the address of first element of the array. If “ptr” is “pointer to char”, then an
expression of type “N-element array of pointer to char” will be converted to “pointer to
pointer to char”.
✞
1 #include <stdio.h>
#include <string.h>
3 #include <stdlib.h>
5 /* The function printIt returns as character pointer */
char *printIt (const char **strs , size_t size ) {
7
size_t i, len = 0;
9 for (i = 0; i < size ; i++)
len += strlen(strs [i]);
11 printf("Total characters in array are : %d.n", len);
char *s = malloc(len * sizeof (*s));
13 if (!s) {
perror("Can’t allocate memory !n");
15 exit (EXIT_FAILURE );
}
17
for (i = 0; i < size ; i++) {
19 strcat(s, strs [i]);
}
21 return s;
free (s);
23 }
25 int main (void ) {
const char *test [ ] = {"ABC", "DEF", "G", "H"};
27 /* Character pointer for s*/
char *s;
29 /* Character pointer s is pointed -to *
*character pointer printIt */
31 s = printIt (test , 4);
printf("Concated string is : %sn", s);
33 /* Free allocated memory that was*
*allocated by function printIt.*/
35 free (s);
return EXIT_SUCCESS ;
37 }
✌
✆
✞
Total characters in array are : 8.
Concated string is : ABCDEFGH
✌
✆
Another example of the pointer is given below
✞
#include <stdio.h>
332 Array & Pointer
2
int main (void ) {
4 /* Character to pointer .*/
char ch = ’A’;
6 char * chptr = &ch;
/* Integer to pointer .*/
8 int i = 20;
int * intptr = &i;
10 /* Float to pointer.*/
float f = 1.20000;
12 float *fptr = &f;
/* String to pointer .*/
14 char *ptr = "It is string.";
/* Print all.*/
16 printf("[%c], [%d] ", *chptr , *intptr);
printf("[%f], [%c] ", *fptr , *ptr);
18 printf("[%s]n", ptr);
return 0;
20 }
✌
✆
✞
[A], [20], [1.200000] , [I], [It is string .]
✌
✆
The following is an example for pointer to an array of integer.
✞
1 #include <stdio.h>
3 int main () {
/* Pointer to array having only 5 integer *
5 *elements . Size of integer is four bytes.*/
int (* ptr)[5];
7 /* Array of 5 integers , each integer is 4 bytes long . *
*Elements should equal to the size of pointer to array.*/
9 int arr [5] = {1, 2, 3, 4, 5};
int i;
11 /* Take the contents of what *
*the array pointer points at*/
13 ptr = &arr;
/* Prints the contents . */
15 for (i = 0; i < 5; i++) {
printf("value: %dn", (* ptr)[i]);
17 }
}
✌
✆
✞
value: 1
value: 2
value: 3
value: 4
value: 5
✌
✆
2.2. POINTER 333
In above example, if number of elements in pointer to array (ptr) are not equal to the
number of elements in the array (arr) then relation
✞
1 ptr=& arr
✌
✆
will give the warning “assignment of incompatible type”. Following is another example
in which pointer to an array of character points to the array of integers. And values are
printed in output at fourth byte position.
✞
1 #include <stdio.h>
3 int main () {
/* Pointer to array of 5 characters . *
5 *Size of each character is one byte .*/
char (* ptr)[5];
7 /* Array of 5 integers , each integer is 4 bytes long .*/
int arr [5] = {1, 2, 3, 4, 5};
9 int i;
/* Take the contents of what the arr pointer *
11 *points at by the ptr. Here character type *
*pointer points to integer array. Pointer *
13 *ptr is itself one byte long but points to *
*4 byte long integer . So , value shall be *
15 *printed after each four bytes position */
ptr = &arr;
17 /* Prints the contents . */
for (i = 0; i <5; i++) {
19 printf("value: %dn", (* ptr)[i]);
}
21 }
✌
✆
✞
value: 1
value: 0
value: 0
value: 0
value: 2
✌
✆
In following example, pointer of array points to the array of characters.
✞
1 #include <stdio.h>
3 int main () {
/* Pointer to array of 5 characters . *
5 *Size of each character is one byte .*/
char (* ptr)[5];
7 /* Array of 5 characters . Each character size is one byte .*/
char arr [5] = {’1’, ’2’, ’3’, ’4’, ’5’};
9 int i;
/* Take the contents of what the arr*
11 *pointer points at by the ptr. */
ptr = &arr;
334 Array & Pointer
13 /* Prints the contents . */
for (i = 0; i < 5; i++) {
15 printf("value: %cn", (* ptr)[i]);
}
17 }
✌
✆
✞
value: 1
value: 2
value: 3
value: 4
value: 5
✌
✆
In the following example, a function prototype
✞
1 char *str_func (char *str)
✌
✆
is declared, which returns a pointer to an character string.
✞
1 #include <stdlib.h>
3 char *str_func (char *str) {
/* Flush the pointer value to NULL .*/
5 char *s = NULL ;
/* Pass the pointer of str to s*
7 *from the location of str +0. */
s = str;
9 return s;
}
11
main (int argc , char *argvc[ ]) {
13 /* sample string.*/
char s[100] = "The Sarnath.";
15 char *st;
/* Pass pointer of char string returned *
17 *by the function str_func (s) to st. */
st = str_func (s);
19 /* Print the result*/
printf("%sn", st);
21 return 0;
}
✌
✆
✞
The Sarnath .
✌
✆
Above example is similar to the example given below.
✞
1 #include <stdlib.h>
#define STRLEN 1024
3
char *str_func (char *str) {
5 char *s = NULL ;
2.2. POINTER 335
/* Allocate the required memory space.*/
7 s = malloc(sizeof (char )*( STRLEN + 1));
/* Copy contents of str into memory */
9 memcpy(s, str , STRLEN);
/* Return the pointer of memory location */
11 return s;
free (s);
13 }
15 main (int argc , char *argvc[ ]) {
/* sample string.*/
17 char s[STRLEN] = "The Sarnath.";
char *st;
19 /* Pass pointer of char string returned *
*by the function str_func (s) to st. */
21 st = str_func (s);
/* Print the result*/
23 printf("%sn", st);
return 0;
25 }
✌
✆
✞
The Sarnath .
✌
✆
In the following example, we pass the pointer location of ‘str’ pointer to another pointer
‘s’ after increasing the pointer of ‘str’ by char position (equivalent to 2 bytes) in str func()
body.
✞
1 #include <stdlib.h>
3 char *str_func (char *str) {
char *s = NULL ;
5 /* Pass the pointer of str to s*
*from the location of str +2. */
7 s = str + 2;
return s;
9 }
11 main (int argc , char *argvc[ ]) {
/* sample string.*/
13 char s[100] = "The Sarnath.";
char *st;
15 /* Pass pointer of char string returned *
*by the function str_func (s) to st. */
17 st = str_func (s);
/* Print the result*/
19 printf("%sn", st);
return 0;
21 }
✌
✆
✞
e Sarnath .
✌
✆
336 Array & Pointer
Again modified form of above example.
✞
1 #include <stdlib.h>
3 char *str_func (char *str) {
char *s = NULL ;
5 while (* str != ’0’) {
if (!s && *str == ’ ’) {
7 /* Pass the pointer of str to s*
*from the location of str +1 *
9 *where str has ’ ’ character .*/
s = str +1;
11 }
str ++;
13 }
return s;
15 }
17 main (int argc , char *argvc[ ]) {
/* sample string.*/
19 char s[100] = "The Sarnath.";
char *st;
21 /* Pass pointer of char string returned *
*by the function str_func (s) to st. */
23 st = str_func (s);
/* Print the result*/
25 printf("%sn", st);
return 0;
27 }
✌
✆
✞
Sarnath.
✌
✆
Parentheses are used to define the priority of the pointer. See two declarations
✞
1 char *fp() /* Type 1*/
char (*fp)() /* Type 2*/
✌
✆
In first type declaration, ‘fp’ is a function that returns a pointer to char. In second type
declaration the parentheses around ‘*fp’ have the highest priority, so ‘fp’ is a pointer to
a function returning char, i.e. it holds the address of function object which returns char
data type. A pointer of pointer example is given below.
✞
#include <stdio.h>
2 int main () {
int var; /* Variable var.*/
4 int *ptr; /* Pointer ptr.*/
int ** pptr ; /* Pointer of the pointer , pptr .*/
6 var = 1234;
/* Take the address of var */
8 ptr = &var;
/* Take the address of ptr */
2.2. POINTER 337
10 pptr = &ptr;
/* Read the value using pptr */
12 printf("Value of var = %dn", var);
printf("Value at *ptr = %dn", *ptr);
14 printf("Value at ** pptr = %dn", ** pptr );
return 0;
16 }
✌
✆
✞
Value of var = 1234
Value at *ptr = 1234
Value at ** pptr = 1234
✌
✆
The memory bytes used by the variables declared in above examples are shown in the
following figure.
0×20 0×21 0×22 0×23 0×24 0×25
var
00000000 00000000 00000100 11010010
var=1234
0×40 0×41 0×42 0×43 0×44 0×45
*ptr
00000000 00000000 00000000 00100001
ptr=&var = 0×21
0×60 0×61 0×62 0×63 0×64 0×65
**pptr
00000000 00000000 00000000 010000001
pptr=&ptr=0×41
Example of pointer to pointer of an array is given below.
✞
1 #include <stdio.h>
3 int main () {
char *ptr= "Arun "; /* Pointer ptr.*/
5 char ** pptr ;
pptr = &ptr;
7 while (*(* pptr ) != ’0’) {
printf("Value = %cn", *(* pptr ));
9 (* pptr )++;
}
11 return 0;
}
✌
✆
✞
Value = A
Value = r
Value = u
Value = n
✌
✆
338 Array & Pointer
0×51 0×52 0×53 0×54 0×55 0×56 0×57 0×58 0×59
A r u n
0×81 0×82 0×83 0×84
0×53
ptr
0×91 0×92 0×93 0×94
0×81
pptr
From the above example code, the code line
✞
char *ptr = "Arun "; /* Pointer ptr.*/
✌
✆
tells that, in memory, string “Arun ” is stored. The memory location at which first
character ‘A’ is stored is assigned to the pointer variable ‘ptr’. Thus ‘ptr’ points to
that memory cell which stores address of ‘A’. From the figure, its value is 0×53. Note
that asterisk used during variable declaration, it makes that variable a pointer. Once
the variable is declared as pointer and if asterisk is prefixed to it, it returns the value
stored at address contains by pointer’s memory cell. After pointer’s declaration, they are
identified by their names without using asterisk prefixed.
✞
1 char ** pptr ;
pptr = &ptr;
✌
✆
These lines tell that second pointer variable ‘pptr’ is declared and address of ‘ptr’ pointer
variable is assigned to it. Thus the memory cell of pointer variable ‘pptr’ holds value 0
×
81
(let). The memory address of pointer variable ‘pptr’ itself is 0×91.
✞
printf("Value = %cn", *(* pptr ));
✌
✆
In above code line ‘*(*pptr))’ has special meaning. Parenthesis are used to define priority.
First we dereference to pointer variable ‘pptr’ as ‘*pptr’. It returns the value stored at
address pointed by pointer variable ‘pptr’. From above figure, the address pointed by
‘pptr’ is 0×81. So, the value at memory address 0×81 is value 0×53. Though this
address is pointer itself, hence the value at this memory address is address of another
memory location. When we dereference this address as ‘*(*pptr)’ (say double dereference
of pointer ‘pptr’) we get the value ‘A’ that is stored at the memory address 0×53. The
code line
✞
1 (* pptr )++;
✌
✆
adds one in the dereference value of ‘pptr’, actually it is value stored at the memory
address 0×81. This value is address of other location, hence when (*pptr) in incremented
by one, it increases the value 0×53 by one and it becomes 0×54 that is address of string
character ‘r’. Using while loop, we retrieve all the string characters one by one.
✞
1 #include <stdio.h>
3 int main () {
2.2. POINTER 339
int num = 48;
5 int *ptr;
int ** pptr ;
7 int *** ppptr;
// *** ppptr = ** pptr = *ptr = num; //
9 ptr = &num;
pptr = &ptr;
11 ppptr = &pptr ;
int i = 1;
13 while (i < 5) {
printf("Value = %dn", *** ppptr + i);
15 i++;
}
17 return 0;
}
✌
✆
✞
Value = 49
Value = 50
Value = 51
Value = 52
✌
✆
✞
#include <stdio.h>
2
int main () {
4 int num = 48;
int *ptr;
6 int ** pptr ;
int *** ppptr;
8 int **** pppptr;
ptr = &num;
10 pptr = &ptr;
ppptr = &pptr ;
12 pppptr = &ppptr;
int i = 1;
14 while (i < 5) {
printf("Value = %dn", **** pppptr + i);
16 i++;
}
18 return 0;
}
✌
✆
✞
Value = 49
Value = 50
Value = 51
Value = 52
✌
✆
✞
#include <stdio.h>
2
int *sum(int a, int b) {
340 Array & Pointer
4 static int k[1];
k[0] = a + b;
6 return k;
}
8
int main (void ) {
10 int *s;
s = sum (1, 2);
12 printf("Sum is : %dn", *s);
return 0;
14 }
✌
✆
✞
Sum is : 3
✌
✆
The example for the array of pointers to an integer is given below:
✞
1 #include <stdio.h>
3 int main (void ) {
int i;
5 int Arr1 [ ] = {1, 2};
int Arr2 [ ] = {10, 20};
7 int *ptr [2];
9 ptr [0] = &Arr1 [0];
ptr [1] = &Arr2 [0];
11
for (i = 0; i < 2; i++) {
13 printf("%d t %dn", *( ptr [0] + i), *( ptr [1] + i));
}
15 return 0;
}
✌
✆
✞
1 10
2 20
✌
✆
The memory arrangement figure of this example is given below. Integer data type stores
values in group of four bytes. In each group of four bytes, the decimal values of ‘Arr1’
and ‘Arr2’ are shown in the following figure.
0×51 0×52 0×53 0×54 0×55 0×56 0×57 0×58
1 2
Arr1
0×81 0×82 0×83 0×84 0×85 0×86 0×87 0×88
10 20
Arr2
0×91 0×92 0×93 0×94 0×95 0×96 0×97 0×98
0×51 0×81
ptr
2.2. POINTER 341
The stored integer values are small, hence only one byte of group of four bytes has
values and rest has zeros. From the above example code, the code line
✞
int Arr1 [ ] = {1, 2};
2 int Arr2 [ ] = {10, 20};
✌
✆
declares two arrays, each has two elements. The code line
✞
int *ptr [2];
2
ptr [0] = &Arr1 [0];
4 ptr [1] = &Arr2 [0];
✌
✆
declare an array pointer ‘ptr’ of pointer to integers. The array size of the pointer variable
is two. Its first element stored is address of first element of the array ‘Arr1’ and second
element stored is address of first element of the array ‘Arr2’. The code line
✞
printf("%d t %dn", *( ptr [0] + i), *( ptr [1] + i));
✌
✆
returns the elements of by incrementing pointers for ith
array indices. Be cautious about
the addition of one with value of normal variable and value of pointer variable. For
example, if an integer type variable ‘a’ assigned a value 10 and it is added by one as ‘i+1’
then its result will be 11. This is addition of the two integers. But if there is pointer
variable, say ‘*a’ pointing to address of integers, the datasize of pointer variable is always
four bytes, i.e. size of addresses is always four bytes. Let this pointer variable points to
address 0×10. Then addition of one as ‘a+1’ will be equal to the sum of address and size
of address. In this case result be 0×14. Remember that datasize of pointers is four bytes.
The data type precedented to a pointer variable tells about the type of data stored at
the address pointed by it and how the data is read during dereferencing of the pointer.
In the below example, two different pointers has same datasize.
✞
1 #include <stdio.h>
3 int main (void ) {
char *c;
5 int *i;
printf("%d t %d n", sizeof (c), sizeof (i));
7 return 0;
}
✌
✆
✞
4 4
✌
✆
int *p[ ];
This declaration is array ‘p’ of pointers to an integer. It means, there are multiple arrays
which stores integer type values. The address of first byte of these arrays are stored at
another places in array form which are pointed by ‘p’.
342 Array & Pointer
0×51 0×52 0×53 0×54 0×55 0×56 0×57 0×58
1 2
Arr1
0×81 0×82 0×83 0×84 0×85 0×86 0×87 0×88
10 20
Arr2
0×91 0×92 0×93 0×94 0×95 0×96 0×97 0×98
0×51 0×81
int *p[ ];
p
In the above figure, there are two arrays, ‘Arr1’ and ‘Arr2’. The addresses of first
bytes of these two arrays are 0×51 and 0×81 respectively. These addresses are further
arranged in array form whose first byte address (say 0×91) is pointed by pointer ‘p’. A
pointer is always four bytes long in 32 bit system. So, whatever is the size of address of
first bytes, byte address is stored in four bytes long memory space.
int **p[ ];
This declaration stands for array of pointers ‘p’ that point to pointers to integer values.
Let we have two integer variables ‘i’ and ‘j’. These numbers are arranged in memory as
shown in following figure.
0×10 0×11 0×12 0×13 0×14 0×15 0×16 0×17 0×18 0×19
1 2
int i; int j;
0×30 0×31 0×32 0×33 0×34 0×35 0×36 0×37 0×38 0×39
0×10 0×16
int *A; int *B;
The addresses of the integer variables are pointed by pointers ‘A’ and ‘B’ respectively.
The addresses of these two pointers (not pointee) are arranged as array of another pointer
‘p’ as shown in the following figure.
0×70 0×71 0×72 0×73 0×74 0×75 0×76 0×77
0×30 0×36
int **p[ ];
p
Now, the pointer ‘p’ can be dereferences using this pointer ‘p’. The equivalent C codes
are given below:
✞
1 #include <stdio.h>
2.2. POINTER 343
3 int main () {
int i=1;
5 int j=2;
int *A=&i;
7 int *B=&j;
int **p[2];
9 p[0]=&A;
p[1]=&B;
11 printf("%d n" ,*(*(p[0]) ));
printf("%d n" ,*(*(p[1]) ));
13 return 0;
}
✌
✆
✞
1
2
✌
✆
int (*p)[ ];
This is explained as pointer ‘p’ to an array of integers. Parentheses enclosing ‘*p’ has
higher priority, hence pointer definition goes with ‘p’ while array definition (by []) goes
to values stored at pointee address. Let we have an array ‘Arr’.
0×10 0×11 0×12 0×13 0×14 0×15 0×16 0×17
12345 12346
Arr
0×30 0×31 0×32 0×33 0×34 0×35 0×36 0×37
0×10
int (*p)[ ];
p
The pointer ‘p’ points to the first element of the array ‘Arr’ as shown in above figure.
The C equivalent codes are given below:
✞
#include <stdio.h>
2
int main () {
4 int Arr [2]={12345 ,12346};
int (*p)[2];
6 p=& Arr;
printf("%d n" ,(*p)[0]) ;
8 printf("%d n" ,(*p)[1]) ;
return 0;
10 }
✌
✆
✞
12345
12346
✌
✆
344 Array & Pointer
int (**p)[ ];
It constructs a pointer ‘p’ which points to the address of another pointer to an array of
integers. The memory arrangement and its relation is shown in the following figure.
0×10 0×11 0×12 0×13 0×14 0×15 0×16 0×17
1 2
Arr1
0×20 0×21 0×22 0×23 0×24 0×25 0×26 0×27
0×10
int (*A)[ ];
0×30 0×31 0×32 0×33 0×34 0×35 0×36 0×37
0×20
int (**p)[ ];
p
C codes for above declaration are given below:
✞
#include <stdio.h>
2
int main (void ) {
4 int Arr [2]={1,2};
int *A;
6 A=& Arr [0];
int **p;
8 p=&A;
printf("%dn", **p);
10 return 0;
}
✌
✆
✞
1
✌
✆
int *(*p)[ ];
It constructs a pointer ‘p’ which points to the array of pointers those are pointing to
integers. The memory arrangement and its relation is shown in the following figure.
2.2. POINTER 345
0×51 0×52 0×53 0×54 0×55 0×56 0×57 0×58
1
i
0×61 0×62 0×63 0×64 0×65 0×66 0×67 0×68
10
j
0×71 0×72 0×73 0×74 0×75 0×76 0×77 0×78
0×51 0×61
int *P[ ];
0×81 0×82 0×83 0×84 0×85 0×86 0×87 0×88
0×71
int *(*p)[ ];
p
The C example is
✞
1 #include <stdio.h>
3 int main (void ) {
int i = 105, j = 201;
5 int *A[2] = {&i, &j};
int *(*p)[];
7 p=&A;
printf("%d t %dn", *(*p)[0], *(*p)[1]) ;
9 return 0;
}
✌
✆
✞
105 201
✌
✆
int (*p[ ])[ ];
It constructs array of pointer ‘p’ which points to the array of integers. The memory
arrangement and its relation is shown in the following figure.
0×51 0×52 0×53 0×54 0×55 0×56 0×57 0×58
1 2
Arr1
0×81 0×82 0×83 0×84 0×85 0×86 0×87 0×88
10 20
Arr2
0×91 0×92 0×93 0×94 0×95 0×96 0×97 0×98
0×51 0×81
int (*p[ ])[ ];
p
The C example is given below:
346 Array & Pointer
✞
1 #include <stdio.h>
3 int main (void ) {
int Arr1 [2] = {1, 2};
5 int Arr2 [2] = {4, 5};
int (*p[2]) [2];
7 p[0] = &Arr1 ;
p[1] = &Arr2 ;
9 printf("%d t %dn", (*p[0]) [1], (*p[1]) [0]) ;
return 0;
11 }
✌
✆
✞
2 4
✌
✆
int *p();
It constructs a function which returns a pointer pointing to an integer value. The memory
arrangement of this declaration is shown below:
0×30 0×31 0×32 0×33 0×34 0×35 0×36 0×37
int v;
0x14AEFC
0×91 0×92 0×93 0×94 0×95 0×96 0×97 0×98
0×32
int *p();
p
C code for above declaration are given below. In this example, the returned pointer
pointed to an integer value.
✞
1 #include <stdio.h>
3 int *p(int *j) {
*j = 10 * (*j);
5 return j;
}
7
int main (void ) {
9 int v = 10;
printf("%dn", *p(&v));
11 return 0;
}
✌
✆
✞
100
✌
✆
We can also return a pointer which points to a real value, like double or float type values.
See the example given below:
2.2. POINTER 347
✞
1 #include <stdio.h>
3 double *p(double *j) {
*j = 10 * (*j);
5 return j;
}
7
int main (void ) {
9 double v = 10;
printf("%lfn", *p(&v));
11 return 0;
}
✌
✆
✞
100.000000
✌
✆
int (*p)();
It constructs a pointer ‘p’ which points to a function which returns an integer value. The
C codes are
✞
1 int myf(int r){
return 2*r;
3 }
(*p)() =&myf;
✌
✆
The memory arrangement and its relation is shown in the following figure.
0×30 0×31 0×32 0×33 0×34 0×35 0×36 0×37
myf 3.14
0×91 0×92 0×93 0×94 0×95 0×96 0×97 0×98
0×32
int (*p)();
p
int (**p)();
It constructs a pointer ‘p’ which points to another pointer to a function. The function
being pointed here returns an integer value.
348 Array & Pointer
0×30 0×31 0×32 0×33 0×34 0×35 0×36 0×37
myf 100
0×81 0×82 0×83 0×84 0×85 0×86 0×87 0×88
0×32
int (*f)();
f
0×91 0×92 0×93 0×94 0×95 0×96 0×97 0×98
0×81
int (**p)();
p
In the above figure, the function ‘myf’ returns the pointer address of computed value
‘100’ via a pointer variable ‘j’. Pointer variable ‘j’ points to the address of 0×22 (for
example). The C equivalent codes are given below:
✞
#include <stdio.h>
2
int myf(int j) {
4 j = 10 * j;
return j;
6 }
8 int main (void ) {
int v = 10;
10 int (*f)();
int (**p)();
12 f = &myf;
p = &f;
14 printf("%dn", (**p)(v));
return 0;
16 }
✌
✆
✞
100
✌
✆
int *(*p)();
It constructs a pointer ‘p’ which points to a function. The function being pointed here
returns pointer to an integer value.
2.2. POINTER 349
0×20 0×21 0×22 0×23 0×24 0×25 0×26 0×27
100
j=0×22
0×30 0×31 0×32 0×33 0×34 0×35 0×36 0×37
myf 0×22
0×91 0×92 0×93 0×94 0×95 0×96 0×97 0×98
0×32
int *(*p)();
p
The C equivalent codes are given below:
✞
1 #include <stdio.h>
3 int *myf(int *j) {
*j = 10 * (*j);
5 return j;
}
7
int main (void ) {
9 int v = 10;
int *(*p)();
11 p=& myf;
printf("%dn", *(*p)(&v));
13 return 0;
}
✌
✆
✞
100
✌
✆
int (*p())();
It constructs a function ‘p’, which returns value of a pointer to function (say ‘myf’), where
function ‘myf’ returns an integer value.
0×30 0×31 0×32 0×33 0×34 0×35 0×36 0×37
myf 100
0×40 0×41 0×42 0×43 0×44 0×45 0×46 0×47
p 0×32
The equivalent C codes are given below:
350 Array & Pointer
✞
1 #include <stdio.h>
3 int myf(int j) {
j = 10 * j;
5 return j;
}
7
int *p(int *j) {
9 j = myf (*j);
return j;
11 }
13 int main (void ) {
int v = 11;
15 int *(*p())();
printf("%dn", *p(&v));
17 return 0;
}
✌
✆
✞
110
✌
✆
int (*p[ ])();
It constructs an array of pointers ‘p’ which points to the address of functions. Functions
returns integer type value.
0×30 0×31 0×32 0×33 0×34 0×35 0×36 0×37
myf1 12
0×40 0×41 0×42 0×43 0×44 0×45 0×46 0×47
myf2 13
0×91 0×92 0×93 0×94 0×95 0×96 0×97 0×98
0×32 0×42
int (*p[])();
p
The C codes are
✞
1 #include <stdio.h>
3 int myf1 (int j) {
return 10 * j;
5 }
7 int myf2 (int j) {
return 5 * j;
2.2. POINTER 351
9 }
11 int main (void ) {
int v = 11;
13 int (*p[2]) ();
p[0]=& myf1 ;
15 p[1]=& myf2 ;
printf("%d t %dn", (*p[0]) (v) ,(*p[1]) (v));
17 return 0;
}
✌
✆
✞
110 55
✌
✆
int (*p())[ ];
It constructs a function ‘p’ which returns a pointer value. The return pointer points to
an array of integers.
0×20 0×21 0×22 0×23 0×24 0×25 0×26 0×27
100 200
j[]
0×30 0×31 0×32 0×33 0×34 0×35 0×36 0×37
myf 0×20
The C codes are
✞
1 #include <stdio.h>
int j[2]={100 ,200};
3
int *myf() {
5 return j;
}
7
int main (void ) {
9 int (* myf())[];
printf("%d t %dn", (* myf())[0], (* myf())[1]);
11 return 0;
}
✌
✆
✞
100 200
✌
✆
352 Array & Pointer
2.2.11 Pointer Casting
Suppose a pointer is declared as
✞
1 int *i;
✌
✆
It declares a variable that points to the address of other variable. This declaration also
tells about the data type of pointed address. In above declaration, the address, which
‘i’ will point, shall be integer type. In other words, the data started from the pointed
address shall be grouped in four successive bytes. See the code snippets
✞
1 unsigned int i=1818004170;
int *j=&i; // let address of i is 0x21
3 printf("%d" ,*j);// call value started at address 0x21
✌
✆
0×20 0×21 0×22 0×23 0×24 0×25
00110110 00101110 10001010 11001010
i = 1818004170
Data type int for the pointer ‘j’ tells us that when we retrieve data from the address of
‘i’, data must be read from four successive memory bytes started at the address of
‘i’ and onward. If address data type is different from the data type of the pointer itself,
then pointers are typecast suitably to tell the compiler about the number of bytes being
read or write at once started from the address. Normally, in pointer casting, data size of
the pointer and address pointed by the pointer are made equal. See the following code
snippets.
✞
1 #include <stdio.h>
3 int main () {
/*A double floating type value.*/
5 double d=1000000.22255;
/*A pointer of long int type .*/
7 long int *iptr ;
/* Cast address of the double floating *
9 *type number into the long int type . */
iptr =( long int *)&d;
11 /* Retrieve value from the address pointed *
*by iptr and convert it into double type .*/
13 printf("%lf", *( double *) iptr );
return 0;
15 }
✌
✆
✞
1000000.222550
✌
✆
2.2. POINTER 353
2.2.12 Pointer as Structure
A structure object can be assigned to a pointer to object by assigning it the address of
the structure object.
✞
1 #include <stdio.h>
3 struct Struc {
int i;
5 char ch;
};
7
int main (void ) {
9 /* Structure object obj*/
struct Struc obj;
11 /* Pointer structure object strucObj *
*assigned the address of obj */
13 struct Struc *strucObj = &obj;
15 /* Assign values to elements of structure */
strucObj ->i = 5;
17 strucObj ->ch = ’A’;
19 /* Access value of elements of structure */
printf("[%d] [%c]n", strucObj ->i, strucObj ->ch);
21 return 0;
}
✌
✆
✞
[5] [A]
✌
✆
In the above example, code line
✞
1 struct Struc obj;
✌
✆
creastes a structure object ‘obj’. The code line
✞
1 struct Struc *strucObj = &obj;
✌
✆
creates pointer struct object ‘strucObj’ and the address of ‘obj’ is assigned to it. Now
the structure elements can be accessed by using pointer object and using operator ‘−>’
as shown in above example.
354 File & Data Structure
3.1. INPUT OUTPUT 355
3File & Data Structure
Standard Input-Output and access of files is a main part of computer programming.
In this chapter we shall discuss the importance and methodology of accessing system and
user define files.
3.1 Input Output
A C program under execution opens automatically three standard streams named stdin,
stdout, and stderr. These are attached to every C program. The first standard stream
is used for input buffering and the other two are used for outputs. These streams are
sequences of bytes.
✞
1 int main (){
int var;
3 /* Use stdin for scanning an*
*integer from keyboard . */
5 scanf ("%d", &var);
/* Use stdout for printing a character .*/
7 printf ("%d", var);
return 0;
9 }
✌
✆
By default stdin points to the keyboard and stdout and stderr point to the screen. It is
possible under Unix and may be possible under other operating systems to redirect input
from or output to a file or both.
3.1.1 Handling File Directory
Sometimes user needs to read, create, delete or change a directory. Directories are sep-
arated by symbol ‘/’. To represent current working directory or parent directory of the
current working directory, dots are used as ‘./’ and ‘../’ respectively. ‘/..’ has same
meaning as ‘/’.
3.1.2 Change Directory
Current working directory of a program is the location where all the temporary or per-
manent files are stored and retrieved by default. Location of current working directory of
a program may be changed to other directory by using chdir() function. Syntax of this
function is
✞
1 chdir(<directory path >)
✌
✆
On successful change of location of old working directory to new location of working
directory, it returns ‘0’ otherwise ‘-1’. An example of the function is given below.
356 File & Data Structure
✞
1 #include <stdio.h>
#include <string.h>
3 #include <stdlib.h>
5 int main (void ) {
char dr [10];
7 int ret;
printf("Enter the directory name :");
9 scanf("%s", &dr);
ret = chdir(dr);
11 printf("%dn", ret);
return EXIT_SUCCESS ;
13 }
✌
✆
3.1.3 FILE pointers
The <stdio.h>header contains a definition for a type FILE (usually via a data type)
which is capable of processing all the information needed to exercise control over a stream,
including its file position indicator, a pointer to the associated buffer (if any), an error
indicator that records whether a read/write error has occurred and an end-of-file indicator
that records whether the end of the file has been reached. There may be multiple FILE
descriptors for a single file.
✞
1 #include <stdio.h>
3 int main (void ) {
FILE *f1 , *f2;
5 /* First discriptor for file a.txt */
f1 = fopen("a.txt", "r");
7 if (!f1) {
printf("Unable to open file a.txtn");
9 return 1;
}
11 /* Second discriptor for file a.txt */
f2 = fopen("a.txt", "r");
13 if (!f2) {
printf("Unable to open file a.txtn");
15 return 1;
}
17
/* Change f1 location */
19 fseek(f1 , 7, SEEK_SET );
21 /* Change f2 location */
fseek(f2 , 14, SEEK_SET );
23 /* Print results */
printf("Position of f1 is %dn", ftell(f1));
25 printf("Position of f2 is %dn", ftell(f2));
/* close streams */
3.1. INPUT OUTPUT 357
27 fclose(f1);
fclose(f2);
29 return 0;
}
✌
✆
✞
Position of f1 is 7
Position of f2 is 14
✌
✆
But this way of accessing file is not safe as both file descriptors access file simultaneously.
To avoid any problems arise due to mixing of streams and descriptors, a file locking facility
should be used to avoid simultaneous access.
Locking & Unlocking a File
The flockfile() function acquires the internal locking to the file stream. It ensures that no
other stream may access the file while the file is locked and accessed by current stream. If
there is no further required to access the file, then file is unlocked by funlockfile() function.
funlockfile() function is called if locking function is able to lock the file.
✞
#include <stdio.h>
2 #include <stdlib.h>
4 int main (void ) {
FILE *f1 , *f2;
6 /* first discriptor for file a.txt */
f1 = fopen("a.txt", "r");
8 /* lock the file */
flockfile (f1);
10 if (!f1) {
printf("Unable to open file a.txtn");
12 return 1;
}
14 /* change f1 location */
fseek(f1 , 7, SEEK_SET );
16 printf("Position of f1 is %dn", ftell(f1));
/* unlock the file */
18 funlockfile (f1);
/* close streams */
20 fclose(f1);
22 return 0;
}
✌
✆
✞
Position of f1 is 7
✌
✆
But direct locking of the file by flockfile() function may return error if the file is already
locked. So, it is safe to use ftrylockfile() function to avoid multiple locking of the same
file simultaneously.
358 File & Data Structure
✞
1 #include <stdio.h>
#include <stdlib.h>
3
int main (void ) {
5 FILE *f1 , *f2;
/* first discriptor for file a.txt */
7 f1 = fopen("a.txt", "r");
/* lock the file */
9 ftrylockfile (f1);
if (!f1) {
11 printf("Unable to open file a.txtn");
return 1;
13 }
/* change f1 location */
15 fseek(f1 , 7, SEEK_SET );
printf("Position of f1 is %dn", ftell(f1));
17 /* unlock the file */
funlockfile (f1);
19 /* close streams */
fclose(f1);
21
return 0;
23 }
✌
✆
✞
Position of f1 is 7
✌
✆
In the above example, we are trying to lock a file by using function ftrylockfile() and
seeking file stream location in the file. If the file is already locked by other program,
then ftrylockfile() function will fail to lock the file and stream will try to access the file
without locking it (simultaneous access). This is why, before accessing to the file, its
locking status must be checked.
✞
1 #include <stdio.h>
#include <stdlib.h>
3
int main (void ) {
5 FILE *f1 , *f2;
/* first discriptor for file a.txt */
7 f1 = fopen("a.txt", "r");
/* try to lock the file and check lock status*/
9 if (ftrylockfile (f1) == 0) {
if (!f1) {
11 printf("Unable to open file a.txtn");
return 1;
13 }
/* change f1 location */
15 fseek(f1 , 7, SEEK_SET );
printf("Position of f1 is %dn", ftell(f1));
17 }
/* unlock the file */
3.1. INPUT OUTPUT 359
19 funlockfile (f1);
/* close streams */
21 fclose(f1);
return 0;
23 }
✌
✆
✞
Position of f1 is 7
✌
✆
Reading/Scanning Directory
In C, there is no dedicated function to read or scan a directory but using readdir or
scandir function, a directory can be read or scanned respectively.
✞
1 #include <stdio.h>
#include <dirent.h>
3
int main () {
5 DIR *dir;
struct dirent *dp;
7 char * file_name ;
dir = opendir(".");
9 while ((dp = readdir (dir)) != NULL ) {
printf("debug: %sn", dp ->d_name);
11 if (! strcmp(dp ->d_name , ".") || !strcmp(dp ->d_name , "..")) {
/* your code here .*/
13 } else {
file_name = dp ->d_name; // use it
15 printf("file_name : "%s"n", file_name );
}
17 }
closedir (dir);
19 return 0;
}
✌
✆
✞
debug: .
debug: ..
debug: nbproject
file _name : "nbproject "
debug: main .c
file _name : "main .c"
✌
✆
Similarly
✞
#include <dirent.h>
2
int main (void ) {
4 struct dirent ** namelist ;
int n;
6
360 File & Data Structure
n = scandir (".", &namelist , NULL , alphasort );
8 if (n < 0)
perror("scandir ");
10 else {
while (n--) {
12 printf("%sn", namelist [n]->d_name);
free (namelist [n]);
14 }
free (namelist );
16 }
}
✌
✆
✞
nbproject
main .c
image.bmp
dist
..
.
✌
✆
Open a File
To open or close a file, the <stdio.h>library has three functions: fopen, freopen, and
fclose. We can open a file to read or write as
✞
#include <stdio.h>
2 FILE *fopen(const char *filename , const char *mode );
FILE *freopen (const char *filename , const char *mode , FILE *stream);
✌
✆
fopen and freopen opens the file whose name is in the string pointed-by a file name and
associates a stream with it. Both return a pointer to the object controlling the stream.
If the open operation fails, a null pointer is returned and error is set. On successfully
opening of a file, the error and end-of-file indicators are cleared. freopen differs from
fopen by a bit and the file pointed-by ‘stream’ is firstly closed if it already open and
errors related to close operation are ignored. File operation mode for both file opening
functions points-to a string consisting of one of the following sequences:
3.1. INPUT OUTPUT 361
Mode Explanation
r Open a text file for reading
w Truncate to zero length or create a text file for writing
a Append or open or create text file for writing at end-of-file
rb Open binary file for reading
wb Truncate to zero length or create a binary file for writing
ab Append or open or create binary file for writing at end-of-file
r+ Open text file for update (reading and writing)
w+ Truncate to zero length or create a text file for update
a+ Append or open or create text file for update
r+b or rb+ Open binary file for update (reading and writing)
w+b or wb+ Truncate to zero length or create a binary file for update
a+b or ab+ Append or open or create binary file for update
Table 3.1: File read and write mode.
Opening a file with read mode (‘r’ as the first character in the mode argument) fails
if the file does not exist or can not be read. Opening a file with append mode (‘a’ as
the first character in the mode argument) causes all subsequent writes to the file to be
forced to the then-current end-of-file. Opening a binary file with append mode (‘b’ as
the second or third character in the above list of mode arguments) may initially position
the file position indicator for the stream beyond the last data written, because of null
character padding. When a file is opened with update mode (‘+’), both input and output
may be performed on the associated stream.
✞
1 #include <stdio.h>
#include <stdlib.h>
3
int main (void ) {
5 /* File pointer that is defined in stdlib.h header*
*file and used for file handling by data type FILE */
7 FILE *fo;
char f_name [10]="fname.txt";
9 /* Open file fname.txt in write mode */
fo = fopen(f_name , "w");
11 /* Show warning if file can not be open .*/
if (fo == NULL ) {
13 printf("Could not open fname file .n");
exit (0);
15 }else {
printf("%s file is created .n",f_name);
17 }
int i = 0, n;
362 File & Data Structure
19 /* Get the rows up to which data *
*is to be write in the file */
21 printf("Enter the data rows No. : ");
scanf("%d", &n);
23 /*Do what you want .*/
while (i < n) {
25 fprintf (fo , "%d %d %dn", i, i*i, i * i * i);
i++;
27 }
printf("Details are written in file %s.n",f_name);
29 /* Close the open file .*/
fclose(fo);
31 /*If every thing gone ok , return success.*/
return 0;
33 }
✌
✆
✞
fname.txt file is opened.
Enter the data rows No. : 10
Details are written in file fname.txt
✌
✆
Close a File
We can close a file pointer by using close function as shown in the following syntax.
✞
1 #include <stdio.h>
int fclose(FILE *stream);
✌
✆
The fclose() function causes the stream pointed-by ‘stream’ to be flushed and the as-
sociated file is closed. Any unwritten buffered data for the stream are delivered to the
host environment to be written to the file. Any unread buffered data are discarded. The
function returns zero if the stream was successfully closed or stream is encounters with
EOF.
✞
#include <stdio.h>
2 #include <stdlib.h>
4 int main (void ) {
/* File pointer that is defined in stdlib.h header *
6 *file and used for file handling by data type FILE */
FILE *fo;
8 char f_name [10]="fname.txt";
/* Open file fname.txt in write mode */
10 fo = fopen(f_name , "w");
/* Show warning if file can not be open .*/
12 if (fo == NULL ) {
printf("Could not open fname file .n");
14 exit (0);
}else {
16 printf("%s file is created .n",f_name);
3.1. INPUT OUTPUT 363
}
18 int i = 0, n;
/* Get the rows up to which data *
20 *is to be write in the file */
printf("Enter the data rows No. : ");
22 scanf("%d", &n);
/*Do what you want .*/
24 while (i < n) {
fprintf (fo , "%d %d %dn", i, i*i, i * i * i);
26 i++;
}
28 printf("Details are written in file %s.n",f_name);
/* Close the open file .*/
30 fclose(fo);
printf("%s file is closed.n",f_name);
32 /*If every thing gone ok , return success.*/
return 0;
34 }
✌
✆
✞
fname.txt file is opened.
Enter the data rows No. : 10
Details are written in file fname.txt
fname.txt file is closed.
✌
✆
fflush function The synopsis of this function is
✞
#include <stdio.h>
2 int fflush(FILE *stream);
✌
✆
If stream points to output or update stream in which the most recent operation was not
input, the fflush function causes any unwritten data for that stream to be deferred to the
host environment to be written to the file. A simple example is
✞
#include <stdio.h>
2 /* For prototype for sleep()*/
#include <unistd.h>
4
int main (void ) {
6 int count;
for ( count = 10; count >= 0; count --) {
8 /* Lead with a CR */
printf("rSeconds until launch: ");
10 if (count > 0)
printf("%2d", count);
12 else
printf("blastoff !n");
14 /* Force output now!!*/
fflush(stdout);
16 /* The sleep() delayed system by number of seconds:*/
sleep (1);
364 File & Data Structure
18 }
return 0;
20 }
✌
✆
✞
Seconds until launch: 10
Seconds until launch: blastoff !
✌
✆
The effect of using fflush() on an input stream is undefined. Sometime a program needed
huge RAM and disk memory to perform a programming job. In between the process
of job, if there is requirement of log data (say) to be stored in disk (outstream), then
OS waits till termination of the resource consuming program and then it writes log data
into the disk file. If the program abrupptly terminated or terminated with error, whole
unwritten log data is vanished. To overcome this problem, fflush function is used to force
OS to write log data immediated into the disk file. It is good programming habbit that
each time when data file being written by program (like using function fprintf etc), it
should be followed by fflush function.
setbuf function The syntax of this function is
✞
#include <stdio.h>
2 void setbuf(FILE *stream , char *buf);
✌
✆
It returns no value. The setbuf function is equivalent to the setvbuf function. setvbuf
function uses two more parameters ‘mode’ and ‘size’. A simple example is
✞
#include <stdio.h>
2
int main () {
4 FILE *fp;
char lineBuf [1024];
6 /*b.txt must be in executable ’s dir*/
fp = fopen("b.txt", "rb");
8 setbuf(fp , NULL ); // set to unbuffered
fclose(fp);
10 return 0;
}
✌
✆
setvbuf function The function syntax is
✞
1 #include <stdio.h>
int setvbuf (FILE *stream , char *buf , int mode , size_t size );
✌
✆
The setvbuf function may be used only after the stream pointed-by ‘stream’ has been
associated with an open file and before any other operation is performed on the stream.
The argument size specifies the ‘size’ of the array. The contents of the array at any time
are indeterminate. The setvbuf function returns zero on success, or nonzero if an invalid
value is given for ‘mode’ or if the request cannot be honored. A simple example is
✞
#include <stdio.h>
3.1. INPUT OUTPUT 365
2
int main () {
4 FILE *fp;
char lineBuf [1024];
6 /*b.txt must be in executable ’s dir*/
fp = fopen("b.txt", "r");
8 /* set to line buffering */
setvbuf (fp , lineBuf , _IOLBF , 1024);
10 fclose(fp);
return 0;
12 }
✌
✆
setvbuf is invoked with ‘mode’ has value IOFBF and ‘size’ when ‘buf’ is not a null
pointer. Again, if ‘buf’ is a null pointer then ‘mode’ has value IONBF.
fgetpos & fsetpos functions The function syntax is
✞
#include <stdio.h>
2 int fgetpos (FILE *stream , fpos_t *pos);
int fsetpos (FILE *stream , const fpos_t *pos);
✌
✆
The fgetpos function stores the current value of the file position indicator for the stream
pointed-by ‘stream’ in the object pointed-by ‘pos’. A simple example is
✞
1 #include <stdio.h>
3 int main () {
FILE * fName;
5 int c;
int n;
7 fpos_t pos;
9 fName = fopen("fname.txt", "r");
if (fName == NULL )
11 perror("Can not open a file .");
else {
13 c = fgetc(fName);
printf("First char is %cn", c);
15 fgetpos (fName , &pos);
for (n = 0; n < 3; n++) {
17 fsetpos(fName , &pos);
c = fgetc(fName);
19 printf("Char in position %d is %cn", n, c);
}
21 fclose(fName);
}
23 return 0;
}
✌
✆
✞
First char is 0
Char in position 0 is
366 File & Data Structure
Char in position 1 is
Char in position 2 is
✌
✆
fseek & ftell functions The function syntax is
✞
#include <stdio.h>
2 int fseek(FILE *stream , long int offset , int whence);
long ftell(FILE *stream);
✌
✆
The fseek function sets the file position indicator for the stream pointed-to the ‘stream’.
For a binary stream, the new position, measured in characters from the beginning of the
file, is obtained by adding ‘offset’ to the position specified by ‘whence’. Three macros
in stdio.h called SEEK SET, SEEK CUR, and SEEK END expand to unique values. If
the position specified by ‘whence’ is SEEK SET, the specified position is the beginning
of the file; if ‘whence’ is SEEK END, the specified position is the end of the file; and
if ‘whence’ is SEEK CUR, the specified position is the current file position. A binary
stream need not meaningfully support fseek calls with a ‘whence’ value of SEEK END.
In case of SEEK END, ‘offset’ may be a negative count (i.e. within the current extent of
file) or may be a positive count (i.e. position past the current end of file). In the later
case file is extended up to that position and filled with zeros.
0 1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
(1)
fp
(2)
fseek(fp, 10, SEEK CUR)
(3)
fp
(4)
Figure 3.1: Change in location of file pointer from current file pointer location.
3.1. INPUT OUTPUT 367
0 1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
(1)
fp
(2)
fseek(fp, -8, SEEK END)
(3)
fp
(4)
Figure 3.2: Change in location of file pointer from the end of file location.
0 1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
(1)
fp
(2)
fseek(fp, 10, SEEK SET)
(3)
fp
(4)
Figure 3.3: Change in location of file pointer from the beginning of file location.
A simple example is
✞
1 #include <stdio.h>
3 int main () {
FILE *fp;
5
fp = fopen("file .txt", "w+");
7 fputs("This is my file name .", fp);
9 fseek(fp , 7, SEEK_SET );
fputs("C Programming Langauge ", fp);
11 fclose(fp);
13 return (0);
}
✌
✆
368 File & Data Structure
For output see the file “file.txt”. ftell returns the current position of file pointer from the
start of the file. Its largest return value is signed long type value. When ftell is used for
obtaining of size of huge files, it fails due to its return size, therefore be cautious when
using for this purpose. Example for ftell is given below:
✞
#include <stdio.h>
2
int main () {
4 FILE *fp;
int len;
6
fp = fopen("file .txt", "r");
8 if (fp == NULL ) {
perror("Error opening file ");
10 return (-1);
}
12 fseek(fp , 0, SEEK_END );
14 len = ftell(fp);
fclose(fp);
16
printf("Total size of file .txt = %d bytesn", len);
18
return (0);
20 }
✌
✆
✞
Total size of file .txt = 32 bytes
✌
✆
Using the pointer in a function, we can also get the file size as shown in the example given
below.
✞
1 #include <stdlib.h>
#include <stdio.h>
3
long getFileSize (const char *filename ) {
5 long result;
FILE *fh = fopen(filename , "rb");
7 fseek(fh , 0, SEEK_END );
result = ftell(fh);
9 fclose(fh);
return result;
11 }
13 int main (void ) {
printf("%ldn", getFileSize ("file .txt"));
15 return 0;
}
✌
✆
✞
Total size of file .txt = 32 bytes
✌
✆
3.1. INPUT OUTPUT 369
fseek and fputc can be used to write a file of specific size. See the example given below.
✞
1 #include <stdio.h>
3 int main () {
FILE *fp = fopen("myfile.txt", "w");
5 fseek(fp , 1024 * 1024, SEEK_SET );
fputc(’n’, fp);
7 fclose(fp);
return 0;
9 }
✌
✆
rewind function The synopsis of the function is
✞
1 #include <stdio.h>
void rewind(FILE *stream);
✌
✆
The rewind function sets the file position indicator for the stream pointed-by ‘stream’ to
the beginning of the file. It is equivalent to
✞
(void )fseek(stream , 0L, SEEK_SET )
✌
✆
except that the error indicator for the stream is also cleared. A simple example is
✞
1 #include <stdio.h>
3 int main () {
FILE *fp;
5 int ch;
7 fp = fopen("file .txt", "r");
9 if (fp != NULL ) {
while (! feof (fp)) {
11 ch = fgetc(fp);
printf("%c", ch);
13 }
rewind(fp);
15
while (! feof (fp)) {
17 ch = fgetc(fp);
printf("%c", ch);
19 }
fclose(fp);
21 }
23 return (0);
}
✌
✆
The output from the file “file.txt” is
370 File & Data Structure
✞
This is C Programming Langauge
This is C Programming Langauge
✌
✆
feof function The synopsis of the function is
✞
#include <stdio.h>
2 int feof (FILE *stream);
✌
✆
The feof function tests the end-of-file indicator for the stream pointed-by ‘stream’ and
returns nonzero if and only if the end-of-file indicator is set for stream, otherwise it returns
zero. A simple example is
✞
#include <stdio.h>
2
int main (void ) {
4 int a;
FILE *fp;
6 fp = fopen("file .txt", "rb");
/* Read single ints at a time , stopping on EOF or error:*/
8 while (fread(&a, sizeof (int), 1, fp), !feof (fp) &&
!ferror(fp)){
printf("I read %dn", a);
10 }
if (feof (fp))
12 printf("End of file was reached .n");
if (ferror(fp))
14 printf("An error occurred .n");
fclose(fp);
16 return 0;
}
✌
✆
✞
I read 543649385
I read 1735287116
I read 1701279073
End of file was reached .
✌
✆
Reading File
There are two ways to read the stuff in C. In first method data is accepted from terminal.
In second method data is read from a file. Following functions are used in reading data
from a file.
fgetc function The syntax of the function is
✞
#include <stdio.h>
2 int fgetc(FILE *stream);
✌
✆
3.1. INPUT OUTPUT 371
The fgetc function obtains the next character (if present) as an unsigned1
char converted
into its equivalent character code, from the input stream pointed-by ‘stream’. fgetc mod-
ified to the file pointer after reading each character. If the stream is at end-of-file, the
end-of-file indicator for the stream is set and fgetc returns EOF. If a read error occurs,
the error indicator for the stream is set and fgetc returns EOF.
A B C D E F G H
fgetc(fp)
A
fp→
A B C D E F G H
fgetc(fp)
B
fp→
✞
#include <stdio.h>
2 #include <stdlib.h>
4 int main (void ) {
/* File pointer */
6 FILE *fr;
/* Open file fread.txt in read mode */
8 fr = fopen("fname.txt", "r");
/*If file is not opened , show warning *
10 *and exit without doing nothing . */
if (fr == NULL ) {
12 printf("Couldn’t open fname.txt file for reading .n");
}
14 /* Read whole data of file by using fgetc*/
int c;
16 while ((c = fgetc(fr)) != EOF) {
putchar (c);
18 }
/* Close the file */
20 fclose(fr);
/*If every thing is ok return successfully */
22 return 0;
}
✌
✆
1
Position of char is determined by integer number started from zero to continue...
372 File & Data Structure
✞
This is C Programming Langauge
✌
✆
fgetc() is more faster than the fread() function. fread() takes 0.1143 seconds to read
1.8MB MP3 file while fgetc takes 0.000142 seconds to read the same file.
✞
1 #include <stdio.h>
#include <time .h>
3
int main () {
5 clock_t startTime = clock();
FILE * fp;
7 fp = fopen("a.mp3", "r");
int s;
9 s = fgetc(fp);
while (s > 0) {
11 s = fgetc(fp);
}
13 fclose(fp);
clock_t endTime = clock();
15 double td = (endTime - startTime ) / (double) CLOCKS_PER_SEC ;
printf("Program has run for %5.8 f secondsn", td);
17 return 0;
}
✌
✆
fgets function The synopsis of the function is
✞
char *fgets(char *s, int n, FILE *stream);
✌
✆
The fgets function reads at most one less than the number of characters specified by
‘n’ from the stream pointed-by ‘stream’ into the array pointed-by ‘s’. No additional
characters are read after a new-line character (which is retained) or after end-of-file. A
null character is written immediately after the last character read into the array. The
fgets function returns ‘s’ if successful. If end-of-file is encountered and no characters have
been read into the array, the contents of the array remain unchanged and a null pointer is
returned. If a read error occurs during the operation, the array contents are indeterminate
and a null pointer is returned.
A B C D E F G H
fgets(s,5,fp)
s=ABCDE
fp→
In following example, fgets() function reads specific number of bytes from a file via
file pointer and prints it in output console.
✞
1 #include <stdio.h>
3.1. INPUT OUTPUT 373
#define BUFFER_SIZE 100
3
int main (void ) {
5 /*A read buffer*/
char buffer[BUFFER_SIZE ];
7 while (fgets(buffer , BUFFER_SIZE , stdin) != NULL ) {
printf("%s", buffer);
9 }
return 0;
11 }
✌
✆
✞
This is
This is
my Car
my Car
✌
✆
Note that each line ends with end of line marker, i.e. ‘rn’, therefore, fgets always returns
a string of size two bytes even if a blank line is read from flat text file.
✞
#include <stdio.h>
2 #include <string.h>
4 int main () {
FILE *f;
6 int i = 0;
char *line = malloc (1024);
8 f = fopen("txt.txt", "r");
if (f) {
10 while (fgets(line , 1024, f) != NULL ) {
i = 0;
12 while (line [i] != ’0’) {
printf("%d %d %dt", line [i], ’r’, ’n’);
14 i++;
}
16 printf("n");
}
18 free (line );
}
20 fclose(f);
return 0;
22 }
✌
✆
✞
13 13 10 10 13 10
97 13 10 98 13 10 99 13 10
13 13 10 10 13 10
✌
✆
Another example, with additional functionality is given below. The texts from ‘fname.txt’
file are read and prints it in output console.
✞
1 #include <stdio.h>
374 File & Data Structure
#include <stdlib.h>
3 #define BUFFER_SIZE 1000
5 int main (void ) {
/* File pointer */
7 FILE *fr;
/*A read buffer*/
9 char buffer [1000];
/* Open file fname.txt in read mode */
11 fr = fopen("fname.txt", "r");
/*If file is not opened , show warning *
13 *and exit without doing nothing . */
if (fr == NULL ) {
15 printf("Couldn’t open fname.txt file for reading .n");
return 0;
17 }
/* Read whole data of file by using fgets*/
19 while (fgets(buffer , BUFFER_SIZE , fr) != NULL ) {
printf("%s", buffer);
21 }
/* Close the file .*/
23 fclose(fr);
/*If every thing is ok return successfully */
25 return 0;
}
✌
✆
✞
This is C Programming Langauge
✌
✆
fgets can also used in place of scanf for receiving string from standard input.
✞
1 #include <stdio.h>
#define STRSIZE 100
3
int main () {
5 int res;
char *str1 , *str2 ;
7
str1 = malloc(sizeof (char ) * STRSIZE + 1);
9 printf("First string : ");
fgets(str1 , STRSIZE , stdin);
11 printf("You entered : %s", str1 );
13 str2 = malloc(sizeof (char ) * STRSIZE + 1);
printf("Second string : ");
15 fgets(str2 , STRSIZE , stdin);
printf("You entered : %s", str2 );
17
free (str1 );
19 free (str2 );
21 return 0;
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming
Pointer Guide for C Programming

Más contenido relacionado

La actualidad más candente

C tech questions
C tech questionsC tech questions
C tech questionsvijay00791
 
C interview question answer 2
C interview question answer 2C interview question answer 2
C interview question answer 2Amit Kapoor
 
Recursion to iteration automation.
Recursion to iteration automation.Recursion to iteration automation.
Recursion to iteration automation.Russell Childs
 
C++ L03-Control Structure
C++ L03-Control StructureC++ L03-Control Structure
C++ L03-Control StructureMohammad Shaker
 
C aptitude scribd
C aptitude scribdC aptitude scribd
C aptitude scribdAmit Kapoor
 
Lecture#8 introduction to array with examples c++
Lecture#8 introduction to array with examples c++Lecture#8 introduction to array with examples c++
Lecture#8 introduction to array with examples c++NUST Stuff
 
C++ L02-Conversion+enum+Operators
C++ L02-Conversion+enum+OperatorsC++ L02-Conversion+enum+Operators
C++ L02-Conversion+enum+OperatorsMohammad Shaker
 
Modern C++ Concurrency API
Modern C++ Concurrency APIModern C++ Concurrency API
Modern C++ Concurrency APISeok-joon Yun
 
C++ Programming - 11th Study
C++ Programming - 11th StudyC++ Programming - 11th Study
C++ Programming - 11th StudyChris Ohk
 

La actualidad más candente (20)

C tech questions
C tech questionsC tech questions
C tech questions
 
C interview question answer 2
C interview question answer 2C interview question answer 2
C interview question answer 2
 
Fp201 unit5 1
Fp201 unit5 1Fp201 unit5 1
Fp201 unit5 1
 
C++ L05-Functions
C++ L05-FunctionsC++ L05-Functions
C++ L05-Functions
 
C++ Pointers
C++ PointersC++ Pointers
C++ Pointers
 
C++ L07-Struct
C++ L07-StructC++ L07-Struct
C++ L07-Struct
 
C++ L06-Pointers
C++ L06-PointersC++ L06-Pointers
C++ L06-Pointers
 
Recursion to iteration automation.
Recursion to iteration automation.Recursion to iteration automation.
Recursion to iteration automation.
 
C++ L04-Array+String
C++ L04-Array+StringC++ L04-Array+String
C++ L04-Array+String
 
C++ L03-Control Structure
C++ L03-Control StructureC++ L03-Control Structure
C++ L03-Control Structure
 
C aptitude scribd
C aptitude scribdC aptitude scribd
C aptitude scribd
 
C++ L01-Variables
C++ L01-VariablesC++ L01-Variables
C++ L01-Variables
 
C++ L08-Classes Part1
C++ L08-Classes Part1C++ L08-Classes Part1
C++ L08-Classes Part1
 
Python unit 3 and Unit 4
Python unit 3 and Unit 4Python unit 3 and Unit 4
Python unit 3 and Unit 4
 
Lecture#8 introduction to array with examples c++
Lecture#8 introduction to array with examples c++Lecture#8 introduction to array with examples c++
Lecture#8 introduction to array with examples c++
 
Array notes
Array notesArray notes
Array notes
 
functions of C++
functions of C++functions of C++
functions of C++
 
C++ L02-Conversion+enum+Operators
C++ L02-Conversion+enum+OperatorsC++ L02-Conversion+enum+Operators
C++ L02-Conversion+enum+Operators
 
Modern C++ Concurrency API
Modern C++ Concurrency APIModern C++ Concurrency API
Modern C++ Concurrency API
 
C++ Programming - 11th Study
C++ Programming - 11th StudyC++ Programming - 11th Study
C++ Programming - 11th Study
 

Similar a Pointer Guide for C Programming

booksoncprogramminglanguage-anintroductiontobeginnersbyarunumrao4-21101016591...
booksoncprogramminglanguage-anintroductiontobeginnersbyarunumrao4-21101016591...booksoncprogramminglanguage-anintroductiontobeginnersbyarunumrao4-21101016591...
booksoncprogramminglanguage-anintroductiontobeginnersbyarunumrao4-21101016591...GkhanGirgin3
 
Pointers and Dynamic Memory Allocation
Pointers and Dynamic Memory AllocationPointers and Dynamic Memory Allocation
Pointers and Dynamic Memory AllocationRabin BK
 
VTU DSA Lab Manual
VTU DSA Lab ManualVTU DSA Lab Manual
VTU DSA Lab ManualAkhilaaReddy
 
Dynamic Objects,Pointer to function,Array & Pointer,Character String Processing
Dynamic Objects,Pointer to function,Array & Pointer,Character String ProcessingDynamic Objects,Pointer to function,Array & Pointer,Character String Processing
Dynamic Objects,Pointer to function,Array & Pointer,Character String ProcessingMeghaj Mallick
 
An imperative study of c
An imperative study of cAn imperative study of c
An imperative study of cTushar B Kute
 
Engineering Computers L32-L33-Pointers.pptx
Engineering Computers L32-L33-Pointers.pptxEngineering Computers L32-L33-Pointers.pptx
Engineering Computers L32-L33-Pointers.pptxhappycocoman
 
Assignment c programming
Assignment c programmingAssignment c programming
Assignment c programmingIcaii Infotech
 
Imugi: Compiler made with Python
Imugi: Compiler made with PythonImugi: Compiler made with Python
Imugi: Compiler made with PythonHan Lee
 
Introduction to Computer and Programing - Lecture 04
Introduction to Computer and Programing - Lecture 04Introduction to Computer and Programing - Lecture 04
Introduction to Computer and Programing - Lecture 04hassaanciit
 
Unit-I Pointer Data structure.pptx
Unit-I Pointer Data structure.pptxUnit-I Pointer Data structure.pptx
Unit-I Pointer Data structure.pptxajajkhan16
 
Introduction to cpp (c++)
Introduction to cpp (c++)Introduction to cpp (c++)
Introduction to cpp (c++)Arun Umrao
 

Similar a Pointer Guide for C Programming (20)

booksoncprogramminglanguage-anintroductiontobeginnersbyarunumrao4-21101016591...
booksoncprogramminglanguage-anintroductiontobeginnersbyarunumrao4-21101016591...booksoncprogramminglanguage-anintroductiontobeginnersbyarunumrao4-21101016591...
booksoncprogramminglanguage-anintroductiontobeginnersbyarunumrao4-21101016591...
 
pointers 1
pointers 1pointers 1
pointers 1
 
Pointers and Dynamic Memory Allocation
Pointers and Dynamic Memory AllocationPointers and Dynamic Memory Allocation
Pointers and Dynamic Memory Allocation
 
VTU DSA Lab Manual
VTU DSA Lab ManualVTU DSA Lab Manual
VTU DSA Lab Manual
 
Unit 6 pointers
Unit 6   pointersUnit 6   pointers
Unit 6 pointers
 
CSE240 Pointers
CSE240 PointersCSE240 Pointers
CSE240 Pointers
 
Dynamic Objects,Pointer to function,Array & Pointer,Character String Processing
Dynamic Objects,Pointer to function,Array & Pointer,Character String ProcessingDynamic Objects,Pointer to function,Array & Pointer,Character String Processing
Dynamic Objects,Pointer to function,Array & Pointer,Character String Processing
 
C program
C programC program
C program
 
C programming
C programmingC programming
C programming
 
An imperative study of c
An imperative study of cAn imperative study of c
An imperative study of c
 
Engineering Computers L32-L33-Pointers.pptx
Engineering Computers L32-L33-Pointers.pptxEngineering Computers L32-L33-Pointers.pptx
Engineering Computers L32-L33-Pointers.pptx
 
Assignment c programming
Assignment c programmingAssignment c programming
Assignment c programming
 
ch08.ppt
ch08.pptch08.ppt
ch08.ppt
 
Imugi: Compiler made with Python
Imugi: Compiler made with PythonImugi: Compiler made with Python
Imugi: Compiler made with Python
 
Introduction to Computer and Programing - Lecture 04
Introduction to Computer and Programing - Lecture 04Introduction to Computer and Programing - Lecture 04
Introduction to Computer and Programing - Lecture 04
 
Pointers and arrays
Pointers and arraysPointers and arrays
Pointers and arrays
 
Unit-I Pointer Data structure.pptx
Unit-I Pointer Data structure.pptxUnit-I Pointer Data structure.pptx
Unit-I Pointer Data structure.pptx
 
Vcs16
Vcs16Vcs16
Vcs16
 
Introduction to cpp (c++)
Introduction to cpp (c++)Introduction to cpp (c++)
Introduction to cpp (c++)
 
pointers
pointerspointers
pointers
 

Más de Arun Umrao

maths_practice_sheet_28.12.23 (copy).pdf
maths_practice_sheet_28.12.23 (copy).pdfmaths_practice_sheet_28.12.23 (copy).pdf
maths_practice_sheet_28.12.23 (copy).pdfArun Umrao
 
Function Analysis v.2
Function Analysis v.2Function Analysis v.2
Function Analysis v.2Arun Umrao
 
Average value by integral method
Average value by integral methodAverage value by integral method
Average value by integral methodArun Umrao
 
Xcos simulation
Xcos simulationXcos simulation
Xcos simulationArun Umrao
 
Work and energy
Work and energyWork and energy
Work and energyArun Umrao
 
Units of physical quantities
Units of physical quantitiesUnits of physical quantities
Units of physical quantitiesArun Umrao
 
Scilab help book 2 of 2
Scilab help book 2 of 2Scilab help book 2 of 2
Scilab help book 2 of 2Arun Umrao
 
Scilab help book 1 of 2
Scilab help book 1 of 2Scilab help book 1 of 2
Scilab help book 1 of 2Arun Umrao
 
Modelica programming help book
Modelica programming help bookModelica programming help book
Modelica programming help bookArun Umrao
 
Measurements and errors
Measurements and errorsMeasurements and errors
Measurements and errorsArun Umrao
 
Linear motion for k12 students
Linear motion for k12 studentsLinear motion for k12 students
Linear motion for k12 studentsArun Umrao
 
Gnu octave help book 02 of 02
Gnu octave help book 02 of 02Gnu octave help book 02 of 02
Gnu octave help book 02 of 02Arun Umrao
 
Gnu octave help book 01 of 02
Gnu octave help book 01 of 02Gnu octave help book 01 of 02
Gnu octave help book 01 of 02Arun Umrao
 
Fortran programming help book
Fortran programming help bookFortran programming help book
Fortran programming help bookArun Umrao
 
Force and its application for k12 students
Force and its application for k12 studentsForce and its application for k12 students
Force and its application for k12 studentsArun Umrao
 
Electric field for k12 student
Electric field for k12 studentElectric field for k12 student
Electric field for k12 studentArun Umrao
 
Dictionary of physics
Dictionary of physicsDictionary of physics
Dictionary of physicsArun Umrao
 
Decreasing and increasing function
Decreasing and increasing functionDecreasing and increasing function
Decreasing and increasing functionArun Umrao
 
Circular motion
Circular motionCircular motion
Circular motionArun Umrao
 

Más de Arun Umrao (20)

maths_practice_sheet_28.12.23 (copy).pdf
maths_practice_sheet_28.12.23 (copy).pdfmaths_practice_sheet_28.12.23 (copy).pdf
maths_practice_sheet_28.12.23 (copy).pdf
 
Function Analysis v.2
Function Analysis v.2Function Analysis v.2
Function Analysis v.2
 
Average value by integral method
Average value by integral methodAverage value by integral method
Average value by integral method
 
Xcos simulation
Xcos simulationXcos simulation
Xcos simulation
 
Work and energy
Work and energyWork and energy
Work and energy
 
Units of physical quantities
Units of physical quantitiesUnits of physical quantities
Units of physical quantities
 
Scilab help book 2 of 2
Scilab help book 2 of 2Scilab help book 2 of 2
Scilab help book 2 of 2
 
Scilab help book 1 of 2
Scilab help book 1 of 2Scilab help book 1 of 2
Scilab help book 1 of 2
 
Notes of Java
Notes of JavaNotes of Java
Notes of Java
 
Modelica programming help book
Modelica programming help bookModelica programming help book
Modelica programming help book
 
Measurements and errors
Measurements and errorsMeasurements and errors
Measurements and errors
 
Linear motion for k12 students
Linear motion for k12 studentsLinear motion for k12 students
Linear motion for k12 students
 
Gnu octave help book 02 of 02
Gnu octave help book 02 of 02Gnu octave help book 02 of 02
Gnu octave help book 02 of 02
 
Gnu octave help book 01 of 02
Gnu octave help book 01 of 02Gnu octave help book 01 of 02
Gnu octave help book 01 of 02
 
Fortran programming help book
Fortran programming help bookFortran programming help book
Fortran programming help book
 
Force and its application for k12 students
Force and its application for k12 studentsForce and its application for k12 students
Force and its application for k12 students
 
Electric field for k12 student
Electric field for k12 studentElectric field for k12 student
Electric field for k12 student
 
Dictionary of physics
Dictionary of physicsDictionary of physics
Dictionary of physics
 
Decreasing and increasing function
Decreasing and increasing functionDecreasing and increasing function
Decreasing and increasing function
 
Circular motion
Circular motionCircular motion
Circular motion
 

Último

Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfFerryKemperman
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceBrainSell Technologies
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmSujith Sukumaran
 
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Matt Ray
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsChristian Birchler
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Velvetech LLC
 
cpct NetworkING BASICS AND NETWORK TOOL.ppt
cpct NetworkING BASICS AND NETWORK TOOL.pptcpct NetworkING BASICS AND NETWORK TOOL.ppt
cpct NetworkING BASICS AND NETWORK TOOL.pptrcbcrtm
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...confluent
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesPhilip Schwarz
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsAhmed Mohamed
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作qr0udbr0
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesŁukasz Chruściel
 
Sending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdfSending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdf31events.com
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024StefanoLambiase
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...OnePlan Solutions
 
Precise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalPrecise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalLionel Briand
 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringHironori Washizaki
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureDinusha Kumarasiri
 

Último (20)

Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdf
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. Salesforce
 
Advantages of Odoo ERP 17 for Your Business
Advantages of Odoo ERP 17 for Your BusinessAdvantages of Odoo ERP 17 for Your Business
Advantages of Odoo ERP 17 for Your Business
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalm
 
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
 
Odoo Development Company in India | Devintelle Consulting Service
Odoo Development Company in India | Devintelle Consulting ServiceOdoo Development Company in India | Devintelle Consulting Service
Odoo Development Company in India | Devintelle Consulting Service
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...
 
cpct NetworkING BASICS AND NETWORK TOOL.ppt
cpct NetworkING BASICS AND NETWORK TOOL.pptcpct NetworkING BASICS AND NETWORK TOOL.ppt
cpct NetworkING BASICS AND NETWORK TOOL.ppt
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a series
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML Diagrams
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New Features
 
Sending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdfSending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdf
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
 
Precise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalPrecise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive Goal
 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their Engineering
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with Azure
 

Pointer Guide for C Programming

  • 1. 2.2. POINTER 301 {31, 32, 33}, 17 {34, 35, 36}, {37, 38, 39} 19 } }; 21 int (* mat)[3][3]; mat = Arr; 23 printf("Element at mat [0][1][1] = %dn", *(*(*( mat + 0) + 1) + 1)); 25 printf("8th element from position of mat [0][2][0] = %dn", (*(*( mat + 0) + 2))[8]) ; 27 printf("8th element from position of mat [0][2][0] = %dn", (*( mat + 0))[2][8]) ; 29 return 0; } ✌ ✆ ✞ Element at mat [0][1][1] = 15 8th element from the position of mat [0][2][0] = 26 8th element from the position of mat [0][2][0] = 26 ✌ ✆ 2.2.3 Pointers and Text Strings Historically, text strings in C have been implemented as array of characters, with the last byte in the string being a character code zero, or the null character ‘0’. Most C implementations came with a standard library of functions for manipulating strings. Many of the more commonly used functions expect the strings to be null terminated string of characters. To use these functions requires the inclusion of the standard C header file “string.h”. A statically declared, initialized string would look similar to the following: ✞ 1 static const char *myFormat = "Total Amount Due: %d"; ✌ ✆ The variable ‘myFormat’ can be view as an array of 21 characters. There is an implied null character (’0’) tacked on to the end of the string after the ’d’ as the 21st item in the array. You can also initialize the individual characters of the array as follows: ✞ 1 static const char myFlower [ ] = {’P’, ’e’, ’t’, ’u’, ’n’, ’i’, ’a’, ’0’}; ✌ ✆ An initialized array of strings would typically be done as follows: ✞ static const char *myColors [ ] = {"Red", "Green", "Blue "}; ✌ ✆ The initialization of an especially long string can be splitted across lines of source code as follows. ✞ 1 static char *longString = "My name is XYZ."; ✌ ✆ The library functions those are used with strings are discussed in later. A simple example of copying string from one variable to other by using pointer is given below.
  • 2. 302 Array & Pointer ✞ 1 #include <stdio.h> /* Defined two arrays to be copied*/ 3 char A[80] = "Lucknow is capital city ."; char B[80]; 5 int main (void ) { 7 /* First pointer A*/ char *ptrA ; 9 /* Second pointer B*/ char *ptrB ; 11 /* Assign string pointer of* *array A to pointer ptrA */ 13 ptrA = A; /* Assign string pointer of* 15 *array B to pointer ptrB */ ptrB = B; 17 /*do loop */ while (* ptrA != ’0 ’) { 19 /* Copy text from array A to array* *B using pointers prtA and ptrB */ 21 *ptrB ++ = *ptrA ++; } 23 /* Add line terminating value*/ *ptrB = ’0’; 25 /* Show array B on screen */ puts (B); 27 return 0; } ✌ ✆ From above example, always remember that a pointer to an array always points to the elements of the array and make copy-paste an element from one array to another array. Pointer never stores elements itself. The output of the above example is given below: ✞ Lucknow is capital city . ✌ ✆ By default, strings are pointer to itself. For example “I am a king” is a pointer to itself. This pointer points to the first character “I”. See example ✞ 1 #include <stdio.h> 3 int main (int argc , char *argv [ ]) { int i=0; 5 for(i =0;*("I am king " + i)!=’0’;i++) printf("%cn" ,*("I am king " + i)); 7 return 0; } ✌ ✆ In above example ✞ *("I am king " + i) ✌ ✆
  • 3. 2.2. POINTER 303 extracts character by character from the string pointed by string itself. for loop is used to print all characters. When string pointer encountered by a null character, loop is halted. Output of above example is ✞ I a m k i n g ✌ ✆ Pointers to Function To declare a pointer-to-function do: ✞ 1 int (*pf) (); ✌ ✆ The question rises why this declaration is not written as ✞ 1 int *pf (); ✌ ✆ The reason is that parentheses operator, ( ), has higher precedence than that of derefer- encing operator (*). Hence for pointer-to-function variable, dereferencing of function is grouped by parentheses. Example for pointer-to-function is given below. ✞ 1 #include <stdio.h> 3 int main () { int (*r)(); 5 r = puts ; (*r)("My String"); 7 return 0; } ✌ ✆ Here, the function line is equivalent to ✞ puts ("My String"); ✌ ✆ ✞ My String ✌ ✆ Unlike the normal pointers, a function pointer points to code, not data. A function pointer points to the memory address where execution codes are stored. Remember that, we do not allocate or de-allocate memory using function pointers. ✞ 1 #include <stdio.h>
  • 4. 304 Array & Pointer 3 void myFunc(int a) { printf("Value of a is %dn", a); 5 } 7 int main () { void (* ptrFunc)(int) = &myFunc; 9 (* ptrFunc )(10) ; return 0; 11 } ✌ ✆ ✞ Value of a is 10 ✌ ✆ Function name is also points to the address of execution code. Therefore, use of ‘myFunc’ at the place of ‘&myFunc’ in the following example give same result as given by above example. ✞ 1 #include <stdio.h> 3 void myFunc(int a) { printf("Value of a is %dn", a); 5 } 7 int main () { void (* ptrFunc)(int) = myFunc; 9 ptrFunc (10) ; return 0; 11 } ✌ ✆ ✞ Value of a is 10 ✌ ✆ A pointer-to-function that returns output as string pointer is shown in the following example: ✞ 1 #include <stdlib.h> #define STRLEN 1024 3 char *str_func (char *str) { 5 char *s = NULL ; /* Allocate the required memory space.*/ 7 s = malloc(sizeof (char )*( STRLEN + 1)); /* Copy contents of str into memory */ 9 memcpy(s, str , STRLEN); /* Return the pointer of memory location */ 11 return s; } 13 main (int argc , char *argvc[ ]) { 15 /* Test string.*/ char s[STRLEN] = "The Sarnath."; 17 /* Returned string pointer .*/
  • 5. 2.2. POINTER 305 char *st; 19 /* Pointer to function declaration .*/ int (*fn)(); 21 /* Get the function object pointer .*/ fn = str_func ; 23 /* Pass the func object to declared function .*/ st = (*fn)(s); 25 /* Print returned string.*/ printf("%sn", st); 27 return 0; } ✌ ✆ ✞ The Sarnath . ✌ ✆ C also allows to create pointer-to-function. Pointer-to-function can get rather messy. Declaring a data type to a function pointer generally clarifies the code. Here’s an example that uses a function pointer, and a (void *) pointer to implement what’s known as a callback. A switch case example ✞ 1 #include <stdio.h> int add(int a, int b); 3 int sub(int a, int b); int mul(int a, int b); 5 int div(int a, int b); 7 int main () { int i, result; 9 int a = 10; int b = 5; 11 printf("Enter the value between [0, 3] : "); scanf("%d", &i); 13 switch (i) { case 0: 15 result = add(a, b); break; 17 case 1: result = sub(a, b); 19 break; case 2: 21 result = mul(a, b); break; 23 case 3: result = div(a, b); 25 break; } 27 printf(":-> Result is %d",result); return 0; 29 } 31 int add(int i, int j) { return (i + j);
  • 6. 306 Array & Pointer 33 } 35 int sub(int i, int j) { return (i - j); 37 } 39 int mul(int i, int j) { return (i * j); 41 } 43 int div(int i, int j) { return (i / j); 45 } ✌ ✆ ✞ Enter the value between 0 and 3 : 2 :-> Result is 50 ✌ ✆ Array of function pointers may also be used to access a function by using array pointer index. See the example given below: ✞ #include <stdio.h> 2 #include <math .h> typedef int *(* func )(int); 4 int mySum(int i) { 6 return (i + 2); } 8 int mySub(int i) { 10 return (i - 2); } 12 int main () { 14 func myFuncArray [10] = {NULL }; myFuncArray [0] = &mySum; 16 myFuncArray [1] = &mySub; printf("%dn", (* myFuncArray [0]) (5)); 18 printf("%dn", (* myFuncArray [1]) (5)); return 0; 20 } ✌ ✆ ✞ 7 3 ✌ ✆ In above example, a array function pointer is created by using typedef and each array function pointer is assigned the address of the function object. ✞ typedef int *(* func )(int); // array function pointer 2 myFuncArray [0] = &mySum; /* assigning function pointer * *to array function pointer . */ ✌ ✆
  • 7. 2.2. POINTER 307 When array function pointer is called, we get desired result. Above array function pointer is re-implemented in the following example. ✞ 1 #include <stdio.h> int add(int a, int b); 3 int sub(int a, int b); int mul(int a, int b); 5 int div(int a, int b); /* Function pointer used for execution of * 7 *four functions called by their positions .*/ int (* operator [4]) (int a, int b) = {add , sub , mul , div}; 9 int main () { 11 int i, result; int a = 10; 13 int b = 5; printf("Enter the value between [0, 3] : "); 15 scanf("%d", &i); result = operator [i](a, b); 17 printf(":-> Result is %d", result); return 0; 19 } 21 int add(int i, int j) { return (i + j); 23 } 25 int sub(int i, int j) { return (i - j); 27 } 29 int mul(int i, int j) { return (i * j); 31 } 33 int div(int i, int j) { return (i / j); 35 } ✌ ✆ ✞ Enter the value between 0 and 3 : 1 :-> Result is 5 ✌ ✆ A struct member function can also be created by using pointer. Following is the example for the purpose. ✞ #include <stdio.h> 2 #include <string.h> /* Global declaration of file pointer . */ 4 FILE *fp; 6 data type struct {
  • 8. 308 Array & Pointer int (* open )(void ); 8 int (* del)(void ); } file ; 10 int my_file_open (void ) { 12 fp = fopen("my_file .txt", "w"); if (fp == NULL ) { 14 printf("File can not be opened .n"); } else { 16 printf("File opened .n"); fputs("Hello World!", fp); 18 } } 20 void my_file_del (void ) { 22 printf("Try to remove .n"); if (remove("my_file .txt") == 0) { 24 printf("File is removed .n"); } else { 26 printf("No file to remove.n"); } 28 } 30 file create(void ) { file my_file; 32 my_file .open = my_file_open ; my_file .del = my_file_del ; 34 my_file .open (); my_file .del(); 36 return my_file; } 38 int main (int argc , char *argv [ ]) { 40 create (); return 0; 42 } ✌ ✆ Casting of Pointer To assign an integer type pointer ‘iptr’ to a floating type pointer ‘fptr’, we cast ‘iptr’ as a floating type pointer and then carry out the assignment, as shown : ✞ fptr = (float *) iptr ; ✌ ✆ When a pointer is casted from old data type to new data type then it only keeps the address of a size of new data type. For example, in Linux GCC, data size of integer is 4 byte while data size of character is 1 byte. Hence when integer data type is casted into character data type and pointed by a pointer then pointer keep the address one byte at time.
  • 9. 2.2. POINTER 309 ✞ 1 #include <stdio.h> 3 int main () { int a = 320; 5 /* Integer 320 = binary 00000001 01000000 */ char *ptr; 7 ptr = (char *) &a; /* Cast intger into character and point to first * 9 *byte of the integer containing value 01000000 */ 11 printf("%d ", *ptr);/* Print 01000000 as decimal 64*/ return 0; 13 } ✌ ✆ ✞ 64 ✌ ✆ Address Copying Vs Content Copying A pointer points to location of content stored in the memory. It does not point to value stored in the memory. For example, take a string “This”, that is stored in memory location 0 × 001250. Now this value is assigned to a pointer variable (say ‘str’) then pointer holds address value 0×001250 not to the value “This”. When one pointer is assigned to the other pointer then only location of contents is assigned. See the example: ✞ 1 #include <stdio.h> 3 int main () { char *str="This "; /* location at 0x0011 (say)*/ 5 char *pt = "That ";/* location at 0x0022 (say)*/ printf("str:%s, pt:%sn",str ,pt); 7 str=pt; /* str ’s memory location changed to 0x0022*/ printf("str:%sn",str); 9 return 0; } ✌ ✆ ✞ str:This , pt:That str:That ✌ ✆ Here, address of ‘pt’ is copied to address of ‘str’. If we wants to copy contents from the memory location pointed by ‘pt’ to the memory location pointed by pointer ‘str’, then strcpy function is used. ✞ #include <stdio.h> 2 #include <string.h> 4 int main () { char *str="This "; /* location at 0x0011 (say)*/ 6 char *pt = "That ";/* location at 0x0022 (say)*/
  • 10. 310 Array & Pointer printf("str:%s, pt:%sn",str ,pt); 8 str=malloc (5); /* Memory allocation is required as * *compiler do not kew the memory size * 10 *assigned to str pointer while copy .*/ strcpy(str ,pt); /* contents of memory location of ’pt’ * 12 *is copied at memory location of ’str’*/ printf("str:%sn",str); 14 free (str); return 0; 16 } ✌ ✆ ✞ str:This , pt:That str:That ✌ ✆ Here, contents from the memory location pointed by pointer ‘pt’ are copied into the memory location pointed by pointer ‘str’. 2.2.4 Dangling & Wild Pointers Dangling pointers and wild pointers are pointers that do not point to a valid object of the appropriate type. Dangling pointers arise when it points to the location that is deallocated without modifying the value of the pointer. The pointer still points to the memory location of the deallocated memory. Dangling pointers causes memory sharing violation and returns error of segmentation faults in UNIX and Linux, or general protection faults in Windows. ✞ #include <stdio.h> 2 int main () { 4 { char *dp = NULL ; 6 { char c; 8 dp = &c; printf("%dn", dp); 10 } /* dp is now a dangling pointer */ 12 } 14 return 0; } ✌ ✆ ✞ 2280807 ✌ ✆ Another example of dangling pointer, in which function ‘func’ returns the addresses of a stack-allocated local variable. Once called function returns, the space for these variables gets deallocated and technically they have “garbage values”.
  • 11. 2.2. POINTER 311 ✞ 1 #include <stdio.h> 3 int *func (void ) { int num = 1234; 5 return &num; } 7 int main () { 9 printf("%dn", func ()); printf("%dn", *func ()); 11 return 0; } ✌ ✆ ✞ 2280756 2280756 ✌ ✆ Wild pointers arise when a pointer is used prior to initialization to some known state, which is possible in some programming languages. They show the same erratic behavior as dangling pointers, though they are less likely to stay undetected because many com- pilers will raise a warning at compile time if declared variables are accessed before being initialized. ✞ #include <stdio.h> 2 int main () { 4 int i; // Declared but not initialized printf("%dn", i); //i acts as wild pointer 6 return 0; } ✌ ✆ Output is strange: ✞ 1629773328 ✌ ✆ 2.2.5 Pointer, Variable & Address A variable is a literal name which addresses to a memory location. An address is a reference to a variable. Pointer points to the address of a variable. One of the most common problem arises in C programming is analyses of pointer variable size, position of its current address and next address after arithmetic operations. The pointers and their locations are similar to milestones along the road. Suppose, a road along-with the distance milestone separated by one meter (for concept purpose).
  • 12. 312 Array & Pointer 0 1 2 3 4 5 6 7 8 9 10 Initially, we are at the 3rd milestone. One meter long unit is used to measure the distances between two consecutive milestones. In one step measurement, next milestone will be 4th one. It means that, if initially pointer location is at 3rd milestone then after one increment (by one meter), the pointer location will be at 4th milestone. 0 1 2 3 bc 4 b 5 6 7 8 9 10 Now, we change measurement count from one meter long unit to two meter long unit. Assume that initially location pointer is at 3rd milestone. In one increment to the location pointer (two meter unit), next milestone will be 5th one. 0 1 2 3 bc 4 5 b 6 7 8 9 10 In C programming, integer type variable is four byte long. So, if initially pointer location of the integer variable is at 3rd milestone then after one increment (by four bytes) to the integer variable, the pointer location shall be at 7th milestone. 0 1 2 3 bc 4 5 6 7 b 8 9 10 In the following example a character data-type pointer is declared as variable ‘a’. Pointer arithmetic is performed. New locations of pointers fetched to see the change in the length between two consecutive addresses of pointer.
  • 13. 2.2. POINTER 313 ✞ 1 #include <stdio.h> 3 int main () { char *a; 5 printf("%pn", a); a++; /* First increment of pointer */ 7 printf("%pn", a); a++; /* Second increment of pointer */ 9 printf("%pn", a); return 0; 11 } ✌ ✆ ✞ 0xb 7758000 %First address location of character %pointer is here 0xb 7758001 %New location of character pointer after %first increment . Distance from the %first address location is 1 bytes. 0xb 7758002 %New location of character pointer after %second increments . Distance from the %first address location is 2 bytes. ✌ ✆ Bytes Memory Blocks Memory Address 0×b7758000 Byte No. 0 0×b7758001 Byte No. 1 0×b7758002 Byte No. 2 0×b7758003 Byte No. 3 0×b7758004 Byte No. 4 0×b7758005 Byte No. 5 0×b7758006 Byte No. 6 0×b7758007 Byte No. 7 0×b7758008 Byte No. 8 a a + 1 a + 2 In the following example an integer data-type pointer is declared as variable ‘a’. Pointer arithmetic is performed. New locations of pointers fetched to see the change in the length between two consecutive addresses of pointer. ✞ #include <stdio.h> 2 int main () { 4 int *a; printf("%pn", a); 6 a++; /* First increment of pointer */ printf("%pn", a); 8 a++; /* Second increment of pointer */ printf("%pn", a);
  • 14. 314 Array & Pointer 10 return 0; } ✌ ✆ ✞ 0xb 7758000 %First address location of integer pointer is here 0xb 7758004 %New location of integer pointer after first increment . %Distance from the first address location is 4 bytes. 0xb 7758008 %New location of integer pointer after second increments . %Distance from the first address location is 8 bytes. ✌ ✆ Bytes Memory Blocks Memory Address 0×b7758000 Byte No. 0 0×b7758001 Byte No. 1 0×b7758002 Byte No. 2 0×b7758003 Byte No. 3 0×b7758004 Byte No. 4 0×b7758005 Byte No. 5 0×b7758006 Byte No. 6 0×b7758007 Byte No. 7 0×b7758008 Byte No. 8 a a + 1 a + 2 In the following example a two dimensional integer data-type array is declared and initial- ized as variable ‘a’. Pointer arithmetic is performed. New locations of pointers fetched to see the change in the length between two consecutive addresses of pointer for first column. ✞ 1 #include <stdio.h> 3 int main (void ) { int *mPtr [ ][3] = { 5 {-1, 2, 3}, /*8 bytes , 8 bytes , 8 bytes*/ {4, -3, 5}, /*8 bytes , 8 bytes , 8 bytes*/ 7 {5, 6, -5} /*8 bytes , 8 bytes , 8 bytes*/ }; /*3 By 3 matrix*/ 9 int i, j; for (i = 0; i < 3; i++) { 11 printf("%2d -> %pt", *(* mPtr + (3 * i)), (mPtr + (3 * i))); printf("n"); 13 } return 0; 15 } ✌ ✆ ✞ -1 -> 0xbfa 09b8c %1X1 element is at this address 4 -> 0xbfa 09bb0 %2X1 element is at this address %Distance from 1X1 element is 24 Bytes 5 -> 0xbfa 09bd4 %3X1 element is at this address %Distance from 1X1 element is 48 Bytes
  • 15. 2.2. POINTER 315 %Distance from 2X1 element is 24 Bytes ✌ ✆ In pointers, we must be cautious, that pointers holds address values. The pointers are used to hold addresses of other memory bytes not the numbers, hence only pointer comparison, addition and subtraction operations are allowed . For example, in following code lines, the memory byte pointed by the variable x holds value 20 as binary 10100. ✞ int *x = 20; // assign address ✌ ✆ 0×45 0×46 0×47 0×48 00000000 00000000 00000000 00010100 ∗x When pointer is assigned a value, it is treated as address value. Now, we can retrieve this address by just calling pointer as ✞ 1 printf("%d", x); ✌ ✆ We shall get value 20 as its result. But when we dereference the variable x as ✞ 1 printf("%d", *x); ✌ ✆ It tries to read the value at address 0×14 (equal to decimal 20 and binary 00010100), it gives access status violation as we try to access restricted memory space set by the OS. It is because, dereference is the retrieving of value from that address which is stored in the memory bytes pointed by the dereferencing pointer. If we change the value of x as ✞ 1 int *x = 2346192; // assign address printf("%d", *x); ✌ ✆ 0×45 0×46 0×47 0×48 00000000 00100011 11001100 11010000 ∗x We get a random value which is stored at address 0 × 23CCD0 (equal to decimal 2346192 or binary 1000111100110011010000). Note that, the address location 0×23CCD0 is beyond the restricted memory region set by OS, hence it returns random output. 2.2.6 Constant Pointers A pointer may be declared as constant by using const keyword. ✞ int i = 5; 2 const int *p = &i; //Or 4 int const *p = &i; ✌ ✆
  • 16. 316 Array & Pointer There are two cases, (i) where a pointer pointed to constant data (pointee) and pointee can not be changed, and (b) where constant pointer (address) can not be changed. The usual pointer-pointee relation are given below: ✞ #include <stdio.h> 2 #include <stdlib.h> 4 int main () { int i = 2; 6 int j = 3; int *k = &j; // k points to j and *k is 3 8 printf("%d n", *k); j = 6; // Now both j and *k are 6 10 printf("%d %dn", j, *k); *k = 7; // j and *k are 7. Pointee changes 12 printf("%d %dn", j, *k); k = &i; // k points to i. *k is 2. Pointer changes 14 printf("%d %dn", i, *k); *k = 8; // i and *k are 8 now. Pointee changes 16 printf("%d %dn", i, *k); return 0; 18 } ✌ ✆ ✞ 3 6 6 7 7 2 2 8 8 ✌ ✆ Now the const keyword is used as shown in modified example. There are errors shows by the compiler. ✞ 1 #include <stdio.h> #include <stdlib.h> 3 int main () { 5 int i = 2; const int j = 3; 7 const int *k = &j; j = 6; // Error! assignment of read -only variable ’j’ 9 *k = 7; // Error! assignment of read -only location ’* k’ k = &i; // k points to i. *k is 2. Pointer changes 11 *k = 8; // Error! assignment of read -only location ’* k’ return 0; 13 } ✌ ✆ Here, code line ✞ 1 //+--Pointee type , i.e. constant pointee //| 3 const int *k = &j; ✌ ✆
  • 17. 2.2. POINTER 317 2 0×50 3 0×51 4 0×52 5 0×53 6 0×54 7 0×55 8 0×56 const int *k = &j j &j (const) j represents that ‘k’ is a non constant type pointer and the value to which it is pointing is constant type. Therefore, value of ‘j’ can not be changed while address of ‘k’ can be changed. ✞ 1 #include <stdio.h> #include <stdlib.h> 3 int main () { 5 int i = 2; const int j = 3; 7 const int *k = &j; // int const *k = &j; // Or state 9 printf("Address of k is %xn", k); k = &i; // k points to i. *k is 2. Pointer changes 11 printf("New address of k is %xn", k); // 13 printf("i : %d, k : %dn", i, *k); return 0; 15 } ✌ ✆ ✞ Address of k is 0x22ff44 New address of k is 0x22 ff48 i : 2, k : 2 ✌ ✆ Similarly, if ✞ 1 // +--Pointer type , i.e. constant pointer // | 3 int * const k = &j; ✌ ✆ then, pointer becomes constant while value of pointee can be changed. Notice the position of asterisk (*) not the const keyword. 2 0×50 3 0×51 4 0×52 5 0×53 6 0×54 7 0×55 8 0×56 int * const k = &j (const) *k j &j
  • 18. 318 Array & Pointer ✞ 1 #include <stdio.h> #include <stdlib.h> 3 int main () { 5 int i = 2; int j = 3; 7 int * const k = &j; printf("Address of k is %dn", k); 9 printf("Old values - j : %d, k : %dn", j, *k); j = 5; // k points to i. *k is 2. Pointer changes 11 printf("New values - j : %d, k : %dn", j, *k); //k = &i;// Error! assignment of read -only variable ’k’ 13 return 0; } ✌ ✆ ✞ Address of k is 0x22ff44 Old values - j : 3, k : 3 New values - j : 5, k : 5 ✌ ✆ The change in the position of the asterisk (*) and keyword const changes the pointer and pointee type. The general representation is ✞ 1 int n = 5; int * p = &n; // non -const -Pointer to non -const -Pointee 3 const int * p = &n; // non -const -Pointer to const - Pointee int * const p = &n; // const -Pointer to non -const - Pointee 5 const int * const p = &n; // const -Pointer to const -Pointee ✌ ✆ The data type keywords before the asterisk symbol represent the nature of the pointee (the address location where data is stored). The data type keywords after the asterisk symobl represent the nature of the pointer itself. This contents add in C just before Memory Allocation section. 2.2.7 Memory Allocation There are two types of memory allocation. (i) Static memory allocation and (ii) dynamic memory allocation. When a static or global variable is declared, it allocates static memory of one block of space or of a fixed size. The space is allocated once is never freed until program is not exit. Automatic variables, such as a function argument or a local variable allocate memory space dynamically. The allocated space is deallcoated (freed) when the compound statement that contains these variable is exited. Dynamic Memory Allocation malloc is used to allocate dynamic memory to a pointer. It returns pointer to newly allocated memory space block and null pointer if memory allocation failed. This is why, before using the memory block, the size of the memory block should be checked. The contents of the block are undefined. It should be initialized manually. The syntax of the function is given as
  • 19. 2.2. POINTER 319 ✞ 1 void *malloc(size_t size ); ✌ ✆ The address of a block returned by malloc or realloc in GNU systems is always a multiple of eight. Casting of malloc() function is required as shown in the above syntax. The function, malloc is meant for implementing dynamic memory allocation. It is defined in stdlib.h or malloc.h, depending on what operating system is used. malloc.h contains only the definitions for the memory allocation functions and not the rest of the other functions defined in stdlib.h. It is good programming practices that when allocated memory is no longer needed, free should be called to release it back to the memory pool. Overwriting a pointer that points to dynamically allocated memory can result in that data becoming inaccessible. If this happens frequently, eventually the operating system will no longer be able to allocate more memory for the process. Once the process exits, the operating system is able to free all dynamically allocated memory associated with the process. A simple example is ✞ 1 #include <stdio.h> 3 int main (void ) { int * MemAllo; 5 /* Allocate the memory space*/ MemAllo = (char *) malloc (100); 7 if (MemAllo ) { printf("Memory allocation successfull !!n"); 9 } else { printf("Memory allocation un -successfull !!"); 11 exit (0); } 13 /* Allocated memory is not freed here .* *It is not C programming standards . */ 15 return 0; } ✌ ✆ ✞ Memory allocation successfull !!!!! ✌ ✆ In standard C programming, each allocated memory should be freed when it is not in use. Unfreed memory is locked by the allocating program and can not be accessed by other programs until the program which allocates memory space is not terminated. free() is used to free the allocated memory. ✞ 1 #include <stdio.h> 3 int main (void ) { int *p; 5 /* Allocate space for 3490 integers !*/ p = malloc(sizeof (int) * 3490); 7 if (p == NULL ) { printf("Out of memory ... n"); 9 } else { printf("Memory allocated ... n");
  • 20. 320 Array & Pointer 11 } /* Out of memory for integer allocation * 13 *while allocating memory space block * *for 349000000 integers bytes! */ 15 p = malloc(sizeof (int) * 349000000) ; if (p == NULL ) { 17 printf("Out of memory for integer size ... n"); } else { 19 printf("Memory allocated ... n"); } 21 /* Second method of memory allocation .*/ if ((p = malloc (100)) == NULL ) {/* Allocates 100 bytes space.*/ 23 printf("Ooooopps ! Out of memory !n"); exit (1); 25 } else { printf("100 Byte memory allocated ... n"); 27 } /* Free memory*/ 29 free (p); return 0; 31 } ✌ ✆ ✞ Memory allocated ... Out of memory for integer size ... 100 Byte memory allocated ... ✌ ✆ The operand of sizeof only has to be parenthesized if it’s a type name, as shown in example below. ✞ 1 float *fp; fp = (float *) malloc(sizeof(float)); ✌ ✆ If there are the name of a data object instead, then the parentheses can be omitted, but they rarely are. ✞ int *ip , ar [100]; 2 ip = (int *) malloc(sizeof ar); ✌ ✆ In the above example, the array ‘ar’ is an array of 100 integers; after the call to malloc (assuming that it was successful), ‘ip’ will point to a region of store that can also be treated as an array of 100 integers. The fundamental unit of storage in C is the character, and by definition sizeof(char) is equal to 1, so there could allocate space for an array of ten characters with malloc(10) while to allocate room for an array of ten integers, it have to use as ✞ malloc(sizeof(int [10])) ✌ ✆ malloc function should be used cautiously. Loosely use of this function cause memory leakage. For example,
  • 21. 2.2. POINTER 321 ✞ 1 void myF(){ int *p=( int *) malloc(sizeof(int)); 3 return; } ✌ ✆ function creates a local pointer with dynamic size of array. But pointer is not freed here. In this case, the memory contents are not accessible by other pointers with same address. This is why, memory allocated on heap should always be freed when it is not needed. ✞ void myF(){ 2 int *p=( int *) malloc(sizeof(int)); free (p); 4 return; } ✌ ✆ If you want to allocate memory and set all memory bits to ‘0s’ then use calloc() function as given in the following syntax. ✞ 1 in *i = (int *) calloc(5, sizeof(int)); ✌ ✆ It shall allocate memory space equal to the product of 5 and size of integer, i.e. 20 bytes and each bit is set to ‘0’. Note that, malloc is much faster than calloc. Reallocate Memory realloc() function is used to reallocate the size of the memory block created by the malloc function previously. ✞ 1 realloc(<ptr >, <new size >) ✌ ✆ If the new size specify is the same as the old size, realloc changes nothing and return the same address. ✞ 1 #include <stdio.h> #include <stdlib.h> 3 int main (int argc , char ** argv ) { 5 int *p = malloc (1024 * sizeof (int)); if (p == NULL ) 7 printf("Memory not allocated ."); int *q = realloc(p, 512 * sizeof (int)); 9 if (q == NULL ) printf("Memory not reallocated ."); 11 return 0; } ✌ ✆ Memory Management Sometimes, in a string pointer, we erase few memory bytes in a programming process. These memory bytes remain unused if string array is not refreshed. For example, we have an array of characters as shown in the following figure.
  • 22. 322 Array & Pointer ptr G 1 H 2 I 3 J 4 K 5 L 6 Q 7 R 8 S 9 T 10 U 11 V 12 [ 13 “ 14 ] 15 ˆ 16 ˙ 17 ‘ 18 The number over the byte are index numbers of the memory byte location. Let the memory bytes having values Q to V are erased. Now, we rearrange the memory bytes as shown in the following figure to free some memory space. ptr G 1 H 2 I 3 J 4 K 5 L 6 [ 7 “ 8 ] 9 ˆ 10 ˙ 11 ‘ 12 Actually, memory bytes are not shifted leftward, but the contents of the memory bytes at indices from 13 to 28 are copied into the memory bytes at indices from 7 to 12. Rearranging of the memory space is good where contents are linear, i.e. contents are not structured. For example, it is good in case of string, but it is hard to manipulate the matrix of 6 × 3 order if few memory bytes are erased. 2.2.8 Pointer Arithmetic In normal mathematics numbers are used for addition, subtraction, division and multipli- cation etc. A pointer to an integer has different behavior to the integer. This is why, in pointer arithmetic, we have to arrange or conform the pointers so that they can behave in properly. A pointer-to-variable always points to the address where value of the variable is stored. This is why direct arithmetic of the pointers is of the arithmetic of the address rather than the values stored at the addresses. ✞ #include <stdio.h> 2 int main (void ) { 4 int a[4] = {50, 99, 3490, 0}; int *p; 6 p = a; while (*p > 0) { 8 printf("%in", *p); /* Go to next integer in memory */
  • 23. 2.2. POINTER 323 10 p++; } 12 return 0; } ✌ ✆ ✞ :-> 50 :-> 99 :-> 3490 ✌ ✆ Another example, using pointer for addition of numbers in an array. ✞ 1 #include <stdio.h> 3 int sum_ptr (char *s) { /* Array is passed to function as pointer. * 5 *sum is variable that store result. */ int sum = 0; 7 /* Until the array not become empty.*/ while (*s != ’0’) { 9 /* Get the pointer value and add it to sum.*/ sum += *s; 11 /* Jump to the next pointer position .*/ s++; 13 } /* Return the answer as sum.*/ 15 return sum; } 17 int main (int argc , char ** argv ) { 19 /* Array s containing integers .*/ 21 char s[ ] = {20, 15, 50, 42}; /* Print the answer.*/ 23 printf("Sum : %dn", sum_ptr(s)); 25 return 0; } ✌ ✆ ✞ Sum : 127 ✌ ✆ A pointer based integer array is shown in the following example. ✞ 1 #include <stdio.h> #include <stdlib.h> 3 int main () { 5 int *i; /* one row multiple columns , 1Xn array*/ int j = 0; 7 i = (int *) malloc(5 * sizeof (int)); while (j < 5) {
  • 24. 324 Array & Pointer 9 i[j] = j; /* Assign values to i*/ j++; 11 } j = 0; 13 while (j < 5) { printf("%d ", *i); 15 i++; j++; 17 } return 0; 19 } ✌ ✆ ✞ 0 1 2 3 4 ✌ ✆ Pointers follow increment or decrements operations. For example, if pointer ‘i’ represents to first element of the array (either integer or character type arrays) then ‘i++’ (or ‘i+1’) represents to the next element of the array. See following figure: bytes x x x x i y y y y z z z z n n n n bytes x x x x y y y y i + 1 z z z z n n n n bytes x x x x y y y y z z z z i + 2 n n n n Computer Character Codes In English language, there are 26 alphabets, ten numerals, other punctuation marks and special characters. These alpha-numeric characters are put in sequence to form meaning full words. Computer is an electronic device which operates on alternate current or direct current. There are only two wave forms of alternate current. First is positive wave form and second is negative wave form. Thus, there is sequences of these two waveforms when we operate a computer.
  • 25. 2.2. POINTER 325 1 −1 bits y 0 0 1 0 1 0 1 1 Conventionally, positive waveform is taken as ‘1’ and negative waveform or no waveform is taken as ‘0’. If computer operates in direct current then there is no negative wave form to represent ‘0’ bit. In this condition, bit ‘0’ means no current. These two symbols are binary digits and called as bits. To identify alpha-numeric symbols, computer uses sequences of these binary digits to form a unique code for each character or symbol. These unique codes are known as character codes of the computer. Computer uses eight binary digits for recognition of each character. There are 256 different types of characters that can be recognized by computer. These 256 characters are assigned unique decimal character codes ranging from ‘0’ to ‘256’. For example character ‘a’ has character code ‘97’, ‘A’ has character code ‘65’ etc. All the sequential alphabets and numerals have sequential character codes. For example, upper case alphabets have character codes ranging from 65 to 90 and lower case alphabets have character codes ranging from 97 to 122. Code Symbol Binary 0 00000000 5 00000101 9 00001001 46 . 00101110 47 / 00101111 48 0 00110000 49 1 00110001 50 2 00110010 56 8 00111000 57 9 00111001 65 A 01000001 90 Z 01011010 97 a 01100001 122 z 01111010 Character codes are not same to the user defined binary numbers. This is why, character code ‘9’ does not represent to numeric decimal ‘9’. Computer accepts ‘9’ as number digit 9 and computer recognizes it by its equivalent binary sequence 00111001, i.e. character code 57 rather than binary sequence 00001001. The signal waveform of
  • 26. 326 Array & Pointer binary 00111001 is given below: 1 bits y 0 0 1 1 1 0 0 1 Decimal digit 9 2.2.9 Pointer Address Pointers are used to point the memory address where data is stored. Four memory bytes are required for a pointer variable to store the address that it is pointing. During the declaration of a pointer, data type preceded to it tells the nature of data stored at the address which is being pointed by it. For example, in the pointer variable declaration ✞ 1 string *ptr= new string [8]; ✌ ✆ data type ‘string’ tells that the pointer ‘ptr’ points to memory address 0 × 00 where a string of one byte long character is stored. Whenever we will perform pointer’s increment or decrement operation, like ‘ptr++’ pointer’s pointing address will increase by the size of character, i.e. one byte. Here, ‘ptr++’ will point to the memory address 0×01 as shown in the following figure. d 0×00 e 0×01 f 0×02 g 0×03 h 0×04 i 0×05 j 0×06 k 0×07 Bytes ptr ptr++ *ptr *(ptr++) Again ‘*ptr’ dereference to the character ‘d’ which is stored at the memory ad- dress pointed by the pointer ‘ptr’. To get the next character ‘e’, dereference is done as ‘*(ptr++)’. Similarly, if pointer is integer type as declared below: ✞ 1 int *ptr= new int [10]; ✌ ✆ The size of the pointer variable is always equal to the address bus size. In 32 bit micro- processor system, it is 4 bytes long. Now, if pointer ‘prt’ points to the memory address 0×00 then ‘ptr++’ points to the memory address 0×04 as shown in the figure given below:
  • 27. 2.2. POINTER 327 xxxx 0×00 xxxx 0×01 xxxx 0×02 xxxx 0×03 yyyy 0×04 yyyy 0×05 yyyy 0×06 yyyy 0×07 Bytes ptr ptr++ *ptr *(ptr++) Again ‘*ptr’ dereference to the integer value stored at the memory address pointed by the pointer ‘ptr’. To get the next integer value, de-reference is done as ‘*(ptr++)’. ✞ 1 #include <stdio.h> #define SIZE 4 3 int main (void ) { 5 short idx; double d[SIZE ]; 7 double *ptd; // data type at pointed address is //8 bytes long 9 ptd = d;// assign address of array to pointer printf("%18sn", "double"); 11 for (idx = 0; idx < SIZE ; idx ++) printf("pt + %d: %10pn", 13 idx , ptd + idx); return 0; 15 } ✌ ✆ ✞ double pt + 0: 0x22cd30 // pt + 1: 0x22cd38 //38 is more than 8 from 30 pt + 2: 0x22cd40 //40 is more than 16 from 30 pt + 3: 0x22cd48 //48 is more than 24 from 30 ✌ ✆ The value assigned to a pointer is the address of the object to which it points. The address of a large object, such as type double variable, typically is the address of the first byte of the object. Applying the ‘*’ operator to a pointer yields the value stored in the pointed-to object. Adding ‘1’ to the pointer increases its value by the size, in bytes, of the pointed-to type. There is close connection between arrays and pointers. They mean that a pointer can be used to identify an individual element of an array and to obtain its value. In arrays and pointers ✞ 1 arr[n] == *( arr + n) /* same value */ arr+2 == &arr [2] /* same address */ ✌ ✆ ✞ #include <stdio.h> 2 #define MONTHS 12 4 int main (void ) { int days [MONTHS] = {31, 28, 31, 30, 31, 30,
  • 28. 328 Array & Pointer 6 31, 31, 30, 31, 30, 31}; int ind; 8 for (ind = 0; ind < MONTHS; ind ++) printf("Month %2d has %d days .n", ind + 1, 10 *( days + ind)); // same as days [ind] return 0; 12 } ✌ ✆ ✞ Month 1 has 31 days . Month 2 has 28 days . Month 3 has 31 days . Month 4 has 30 days . Month 5 has 31 days . Month 6 has 30 days . Month 7 has 31 days . Month 8 has 31 days . Month 9 has 30 days . Month 10 has 31 days . Month 11 has 30 days . Month 12 has 31 days . ✌ ✆ Above program can be written as shown below: ✞ #include <stdio.h> 2 #define MONTHS 12 4 int main (void ) { int days [MONTHS] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 6 int ind; for (ind = 0; ind < MONTHS; ind ++) 8 printf("Month %2d has %d days .n", ind + 1, days [ind]); // same as *( days + ind) 10 return 0; } ✌ ✆ ✞ Month 1 has 31 days . Month 2 has 28 days . Month 3 has 31 days . Month 4 has 30 days . Month 5 has 31 days . Month 6 has 30 days . Month 7 has 31 days . Month 8 has 31 days . Month 9 has 30 days . Month 10 has 31 days . Month 11 has 30 days . Month 12 has 31 days . ✌ ✆
  • 29. 2.2. POINTER 329 Here, days is the address of the first element of the array, ‘days + ind’ is the address of element days[ind] and *(days + ind) is the value of that element, just as days[ind] is. The loop references each element of the array, in turn, and prints the contents of what it finds. Another example is ✞ #include <stdio.h> 2 int main () { 4 int *ptr; int arrVal [7] = {44, 55, 66, 77}; 6 ptr = &arrVal; int i; 8 for (i = 0; i <= 4; i++) { printf("arrVal[%d]: value is %d and address is %pn", i, *( ptr + i), (ptr + i)); 10 } return 0; 12 } ✌ ✆ ✞ arrVal [0]: value is 44 and address is 0xbf85ad84 arrVal [1]: value is 55 and address is 0xbf85ad88 arrVal [2]: value is 66 and address is 0xbf85ad8c arrVal [3]: value is 77 and address is 0xbf85ad90 ✌ ✆ In C, when an integer is pointed as pointer-to-address-of-integer by a character pointer variable, then the character variable can addressed to each byte of the integer. An integer variable is a 4 bytes long. If the address of this integer variable is pointed by character pointer, i.e. which is one byte long then it can points to each of the byte of the integer variable. Assume an integer variable is ‘a’. This integer variable is 4 bytes long. The allocated memory for this integer variable shall be looked like B[2] B[3] B[4] B[5] B[6] B[7] B[8] B[9] B[10] B[11] xxxx xxxx xxxx xxxx a Here, bytes are labeled as B[2] and so on. The address of integer variable ‘a’ is pointed by a pointer variable, which is char data type, as shown in syntax given below. ✞ int a; 2 char *x; x = (char *) &a; ✌ ✆ Variable ‘x’ can access to each byte of the integer variable ‘a’. B[2] B[3] B[4] B[5] B[6] B[7] B[8] B[9] B[10] B[11] xxxx xxxx xxxx xxxx x
  • 30. 330 Array & Pointer See the example below: ✞ 1 #include <stdio.h> 3 int main () { int a; /* Integer variable .*/ 5 char *x; /* Character pointer */ x = (char *) &a; /* Pointer to the address of integer .*/ 7 a = 512; x[0] = 0; /* Change value of first byte of integer */ 9 printf("%dn", a); return 0; 11 } ✌ ✆ ✞ 512 ✌ ✆ Initially, the value assigned to integer variable is stored in memory as shown in the figure given below. x[3] x[2] x[1] x[0] 00000000 00000000 00000001 00000000 x a When we change the data of byte x[0] the new value of integer variable ‘a’ is 512. The above example is modified as ✞ 1 #include <stdio.h> 3 int main () { int a; /* Declare integer variable .*/ 5 char *x; /* Presumes that , data at pointed* *address is characters type . */ 7 x = (char *) &a; /* Pointer to the address of integer .*/ a = 512; 9 x[0] = 1; /* Change value of first byte of integer */ printf("%dn", a); 11 return 0; } ✌ ✆ ✞ 513 ✌ ✆ Now, the memory representation is like x[3] x[2] x[1] x[0] 00000000 00000000 00000001 00000001 x a It gives the result a = 513.
  • 31. 2.2. POINTER 331 2.2.10 Pointer to Pointer Expression of N-element array of pointer ‘ptr’ can be converted into a pointer ‘ptr’ and its value is the address of first element of the array. If “ptr” is “pointer to char”, then an expression of type “N-element array of pointer to char” will be converted to “pointer to pointer to char”. ✞ 1 #include <stdio.h> #include <string.h> 3 #include <stdlib.h> 5 /* The function printIt returns as character pointer */ char *printIt (const char **strs , size_t size ) { 7 size_t i, len = 0; 9 for (i = 0; i < size ; i++) len += strlen(strs [i]); 11 printf("Total characters in array are : %d.n", len); char *s = malloc(len * sizeof (*s)); 13 if (!s) { perror("Can’t allocate memory !n"); 15 exit (EXIT_FAILURE ); } 17 for (i = 0; i < size ; i++) { 19 strcat(s, strs [i]); } 21 return s; free (s); 23 } 25 int main (void ) { const char *test [ ] = {"ABC", "DEF", "G", "H"}; 27 /* Character pointer for s*/ char *s; 29 /* Character pointer s is pointed -to * *character pointer printIt */ 31 s = printIt (test , 4); printf("Concated string is : %sn", s); 33 /* Free allocated memory that was* *allocated by function printIt.*/ 35 free (s); return EXIT_SUCCESS ; 37 } ✌ ✆ ✞ Total characters in array are : 8. Concated string is : ABCDEFGH ✌ ✆ Another example of the pointer is given below ✞ #include <stdio.h>
  • 32. 332 Array & Pointer 2 int main (void ) { 4 /* Character to pointer .*/ char ch = ’A’; 6 char * chptr = &ch; /* Integer to pointer .*/ 8 int i = 20; int * intptr = &i; 10 /* Float to pointer.*/ float f = 1.20000; 12 float *fptr = &f; /* String to pointer .*/ 14 char *ptr = "It is string."; /* Print all.*/ 16 printf("[%c], [%d] ", *chptr , *intptr); printf("[%f], [%c] ", *fptr , *ptr); 18 printf("[%s]n", ptr); return 0; 20 } ✌ ✆ ✞ [A], [20], [1.200000] , [I], [It is string .] ✌ ✆ The following is an example for pointer to an array of integer. ✞ 1 #include <stdio.h> 3 int main () { /* Pointer to array having only 5 integer * 5 *elements . Size of integer is four bytes.*/ int (* ptr)[5]; 7 /* Array of 5 integers , each integer is 4 bytes long . * *Elements should equal to the size of pointer to array.*/ 9 int arr [5] = {1, 2, 3, 4, 5}; int i; 11 /* Take the contents of what * *the array pointer points at*/ 13 ptr = &arr; /* Prints the contents . */ 15 for (i = 0; i < 5; i++) { printf("value: %dn", (* ptr)[i]); 17 } } ✌ ✆ ✞ value: 1 value: 2 value: 3 value: 4 value: 5 ✌ ✆
  • 33. 2.2. POINTER 333 In above example, if number of elements in pointer to array (ptr) are not equal to the number of elements in the array (arr) then relation ✞ 1 ptr=& arr ✌ ✆ will give the warning “assignment of incompatible type”. Following is another example in which pointer to an array of character points to the array of integers. And values are printed in output at fourth byte position. ✞ 1 #include <stdio.h> 3 int main () { /* Pointer to array of 5 characters . * 5 *Size of each character is one byte .*/ char (* ptr)[5]; 7 /* Array of 5 integers , each integer is 4 bytes long .*/ int arr [5] = {1, 2, 3, 4, 5}; 9 int i; /* Take the contents of what the arr pointer * 11 *points at by the ptr. Here character type * *pointer points to integer array. Pointer * 13 *ptr is itself one byte long but points to * *4 byte long integer . So , value shall be * 15 *printed after each four bytes position */ ptr = &arr; 17 /* Prints the contents . */ for (i = 0; i <5; i++) { 19 printf("value: %dn", (* ptr)[i]); } 21 } ✌ ✆ ✞ value: 1 value: 0 value: 0 value: 0 value: 2 ✌ ✆ In following example, pointer of array points to the array of characters. ✞ 1 #include <stdio.h> 3 int main () { /* Pointer to array of 5 characters . * 5 *Size of each character is one byte .*/ char (* ptr)[5]; 7 /* Array of 5 characters . Each character size is one byte .*/ char arr [5] = {’1’, ’2’, ’3’, ’4’, ’5’}; 9 int i; /* Take the contents of what the arr* 11 *pointer points at by the ptr. */ ptr = &arr;
  • 34. 334 Array & Pointer 13 /* Prints the contents . */ for (i = 0; i < 5; i++) { 15 printf("value: %cn", (* ptr)[i]); } 17 } ✌ ✆ ✞ value: 1 value: 2 value: 3 value: 4 value: 5 ✌ ✆ In the following example, a function prototype ✞ 1 char *str_func (char *str) ✌ ✆ is declared, which returns a pointer to an character string. ✞ 1 #include <stdlib.h> 3 char *str_func (char *str) { /* Flush the pointer value to NULL .*/ 5 char *s = NULL ; /* Pass the pointer of str to s* 7 *from the location of str +0. */ s = str; 9 return s; } 11 main (int argc , char *argvc[ ]) { 13 /* sample string.*/ char s[100] = "The Sarnath."; 15 char *st; /* Pass pointer of char string returned * 17 *by the function str_func (s) to st. */ st = str_func (s); 19 /* Print the result*/ printf("%sn", st); 21 return 0; } ✌ ✆ ✞ The Sarnath . ✌ ✆ Above example is similar to the example given below. ✞ 1 #include <stdlib.h> #define STRLEN 1024 3 char *str_func (char *str) { 5 char *s = NULL ;
  • 35. 2.2. POINTER 335 /* Allocate the required memory space.*/ 7 s = malloc(sizeof (char )*( STRLEN + 1)); /* Copy contents of str into memory */ 9 memcpy(s, str , STRLEN); /* Return the pointer of memory location */ 11 return s; free (s); 13 } 15 main (int argc , char *argvc[ ]) { /* sample string.*/ 17 char s[STRLEN] = "The Sarnath."; char *st; 19 /* Pass pointer of char string returned * *by the function str_func (s) to st. */ 21 st = str_func (s); /* Print the result*/ 23 printf("%sn", st); return 0; 25 } ✌ ✆ ✞ The Sarnath . ✌ ✆ In the following example, we pass the pointer location of ‘str’ pointer to another pointer ‘s’ after increasing the pointer of ‘str’ by char position (equivalent to 2 bytes) in str func() body. ✞ 1 #include <stdlib.h> 3 char *str_func (char *str) { char *s = NULL ; 5 /* Pass the pointer of str to s* *from the location of str +2. */ 7 s = str + 2; return s; 9 } 11 main (int argc , char *argvc[ ]) { /* sample string.*/ 13 char s[100] = "The Sarnath."; char *st; 15 /* Pass pointer of char string returned * *by the function str_func (s) to st. */ 17 st = str_func (s); /* Print the result*/ 19 printf("%sn", st); return 0; 21 } ✌ ✆ ✞ e Sarnath . ✌ ✆
  • 36. 336 Array & Pointer Again modified form of above example. ✞ 1 #include <stdlib.h> 3 char *str_func (char *str) { char *s = NULL ; 5 while (* str != ’0’) { if (!s && *str == ’ ’) { 7 /* Pass the pointer of str to s* *from the location of str +1 * 9 *where str has ’ ’ character .*/ s = str +1; 11 } str ++; 13 } return s; 15 } 17 main (int argc , char *argvc[ ]) { /* sample string.*/ 19 char s[100] = "The Sarnath."; char *st; 21 /* Pass pointer of char string returned * *by the function str_func (s) to st. */ 23 st = str_func (s); /* Print the result*/ 25 printf("%sn", st); return 0; 27 } ✌ ✆ ✞ Sarnath. ✌ ✆ Parentheses are used to define the priority of the pointer. See two declarations ✞ 1 char *fp() /* Type 1*/ char (*fp)() /* Type 2*/ ✌ ✆ In first type declaration, ‘fp’ is a function that returns a pointer to char. In second type declaration the parentheses around ‘*fp’ have the highest priority, so ‘fp’ is a pointer to a function returning char, i.e. it holds the address of function object which returns char data type. A pointer of pointer example is given below. ✞ #include <stdio.h> 2 int main () { int var; /* Variable var.*/ 4 int *ptr; /* Pointer ptr.*/ int ** pptr ; /* Pointer of the pointer , pptr .*/ 6 var = 1234; /* Take the address of var */ 8 ptr = &var; /* Take the address of ptr */
  • 37. 2.2. POINTER 337 10 pptr = &ptr; /* Read the value using pptr */ 12 printf("Value of var = %dn", var); printf("Value at *ptr = %dn", *ptr); 14 printf("Value at ** pptr = %dn", ** pptr ); return 0; 16 } ✌ ✆ ✞ Value of var = 1234 Value at *ptr = 1234 Value at ** pptr = 1234 ✌ ✆ The memory bytes used by the variables declared in above examples are shown in the following figure. 0×20 0×21 0×22 0×23 0×24 0×25 var 00000000 00000000 00000100 11010010 var=1234 0×40 0×41 0×42 0×43 0×44 0×45 *ptr 00000000 00000000 00000000 00100001 ptr=&var = 0×21 0×60 0×61 0×62 0×63 0×64 0×65 **pptr 00000000 00000000 00000000 010000001 pptr=&ptr=0×41 Example of pointer to pointer of an array is given below. ✞ 1 #include <stdio.h> 3 int main () { char *ptr= "Arun "; /* Pointer ptr.*/ 5 char ** pptr ; pptr = &ptr; 7 while (*(* pptr ) != ’0’) { printf("Value = %cn", *(* pptr )); 9 (* pptr )++; } 11 return 0; } ✌ ✆ ✞ Value = A Value = r Value = u Value = n ✌ ✆
  • 38. 338 Array & Pointer 0×51 0×52 0×53 0×54 0×55 0×56 0×57 0×58 0×59 A r u n 0×81 0×82 0×83 0×84 0×53 ptr 0×91 0×92 0×93 0×94 0×81 pptr From the above example code, the code line ✞ char *ptr = "Arun "; /* Pointer ptr.*/ ✌ ✆ tells that, in memory, string “Arun ” is stored. The memory location at which first character ‘A’ is stored is assigned to the pointer variable ‘ptr’. Thus ‘ptr’ points to that memory cell which stores address of ‘A’. From the figure, its value is 0×53. Note that asterisk used during variable declaration, it makes that variable a pointer. Once the variable is declared as pointer and if asterisk is prefixed to it, it returns the value stored at address contains by pointer’s memory cell. After pointer’s declaration, they are identified by their names without using asterisk prefixed. ✞ 1 char ** pptr ; pptr = &ptr; ✌ ✆ These lines tell that second pointer variable ‘pptr’ is declared and address of ‘ptr’ pointer variable is assigned to it. Thus the memory cell of pointer variable ‘pptr’ holds value 0 × 81 (let). The memory address of pointer variable ‘pptr’ itself is 0×91. ✞ printf("Value = %cn", *(* pptr )); ✌ ✆ In above code line ‘*(*pptr))’ has special meaning. Parenthesis are used to define priority. First we dereference to pointer variable ‘pptr’ as ‘*pptr’. It returns the value stored at address pointed by pointer variable ‘pptr’. From above figure, the address pointed by ‘pptr’ is 0×81. So, the value at memory address 0×81 is value 0×53. Though this address is pointer itself, hence the value at this memory address is address of another memory location. When we dereference this address as ‘*(*pptr)’ (say double dereference of pointer ‘pptr’) we get the value ‘A’ that is stored at the memory address 0×53. The code line ✞ 1 (* pptr )++; ✌ ✆ adds one in the dereference value of ‘pptr’, actually it is value stored at the memory address 0×81. This value is address of other location, hence when (*pptr) in incremented by one, it increases the value 0×53 by one and it becomes 0×54 that is address of string character ‘r’. Using while loop, we retrieve all the string characters one by one. ✞ 1 #include <stdio.h> 3 int main () {
  • 39. 2.2. POINTER 339 int num = 48; 5 int *ptr; int ** pptr ; 7 int *** ppptr; // *** ppptr = ** pptr = *ptr = num; // 9 ptr = &num; pptr = &ptr; 11 ppptr = &pptr ; int i = 1; 13 while (i < 5) { printf("Value = %dn", *** ppptr + i); 15 i++; } 17 return 0; } ✌ ✆ ✞ Value = 49 Value = 50 Value = 51 Value = 52 ✌ ✆ ✞ #include <stdio.h> 2 int main () { 4 int num = 48; int *ptr; 6 int ** pptr ; int *** ppptr; 8 int **** pppptr; ptr = &num; 10 pptr = &ptr; ppptr = &pptr ; 12 pppptr = &ppptr; int i = 1; 14 while (i < 5) { printf("Value = %dn", **** pppptr + i); 16 i++; } 18 return 0; } ✌ ✆ ✞ Value = 49 Value = 50 Value = 51 Value = 52 ✌ ✆ ✞ #include <stdio.h> 2 int *sum(int a, int b) {
  • 40. 340 Array & Pointer 4 static int k[1]; k[0] = a + b; 6 return k; } 8 int main (void ) { 10 int *s; s = sum (1, 2); 12 printf("Sum is : %dn", *s); return 0; 14 } ✌ ✆ ✞ Sum is : 3 ✌ ✆ The example for the array of pointers to an integer is given below: ✞ 1 #include <stdio.h> 3 int main (void ) { int i; 5 int Arr1 [ ] = {1, 2}; int Arr2 [ ] = {10, 20}; 7 int *ptr [2]; 9 ptr [0] = &Arr1 [0]; ptr [1] = &Arr2 [0]; 11 for (i = 0; i < 2; i++) { 13 printf("%d t %dn", *( ptr [0] + i), *( ptr [1] + i)); } 15 return 0; } ✌ ✆ ✞ 1 10 2 20 ✌ ✆ The memory arrangement figure of this example is given below. Integer data type stores values in group of four bytes. In each group of four bytes, the decimal values of ‘Arr1’ and ‘Arr2’ are shown in the following figure. 0×51 0×52 0×53 0×54 0×55 0×56 0×57 0×58 1 2 Arr1 0×81 0×82 0×83 0×84 0×85 0×86 0×87 0×88 10 20 Arr2 0×91 0×92 0×93 0×94 0×95 0×96 0×97 0×98 0×51 0×81 ptr
  • 41. 2.2. POINTER 341 The stored integer values are small, hence only one byte of group of four bytes has values and rest has zeros. From the above example code, the code line ✞ int Arr1 [ ] = {1, 2}; 2 int Arr2 [ ] = {10, 20}; ✌ ✆ declares two arrays, each has two elements. The code line ✞ int *ptr [2]; 2 ptr [0] = &Arr1 [0]; 4 ptr [1] = &Arr2 [0]; ✌ ✆ declare an array pointer ‘ptr’ of pointer to integers. The array size of the pointer variable is two. Its first element stored is address of first element of the array ‘Arr1’ and second element stored is address of first element of the array ‘Arr2’. The code line ✞ printf("%d t %dn", *( ptr [0] + i), *( ptr [1] + i)); ✌ ✆ returns the elements of by incrementing pointers for ith array indices. Be cautious about the addition of one with value of normal variable and value of pointer variable. For example, if an integer type variable ‘a’ assigned a value 10 and it is added by one as ‘i+1’ then its result will be 11. This is addition of the two integers. But if there is pointer variable, say ‘*a’ pointing to address of integers, the datasize of pointer variable is always four bytes, i.e. size of addresses is always four bytes. Let this pointer variable points to address 0×10. Then addition of one as ‘a+1’ will be equal to the sum of address and size of address. In this case result be 0×14. Remember that datasize of pointers is four bytes. The data type precedented to a pointer variable tells about the type of data stored at the address pointed by it and how the data is read during dereferencing of the pointer. In the below example, two different pointers has same datasize. ✞ 1 #include <stdio.h> 3 int main (void ) { char *c; 5 int *i; printf("%d t %d n", sizeof (c), sizeof (i)); 7 return 0; } ✌ ✆ ✞ 4 4 ✌ ✆ int *p[ ]; This declaration is array ‘p’ of pointers to an integer. It means, there are multiple arrays which stores integer type values. The address of first byte of these arrays are stored at another places in array form which are pointed by ‘p’.
  • 42. 342 Array & Pointer 0×51 0×52 0×53 0×54 0×55 0×56 0×57 0×58 1 2 Arr1 0×81 0×82 0×83 0×84 0×85 0×86 0×87 0×88 10 20 Arr2 0×91 0×92 0×93 0×94 0×95 0×96 0×97 0×98 0×51 0×81 int *p[ ]; p In the above figure, there are two arrays, ‘Arr1’ and ‘Arr2’. The addresses of first bytes of these two arrays are 0×51 and 0×81 respectively. These addresses are further arranged in array form whose first byte address (say 0×91) is pointed by pointer ‘p’. A pointer is always four bytes long in 32 bit system. So, whatever is the size of address of first bytes, byte address is stored in four bytes long memory space. int **p[ ]; This declaration stands for array of pointers ‘p’ that point to pointers to integer values. Let we have two integer variables ‘i’ and ‘j’. These numbers are arranged in memory as shown in following figure. 0×10 0×11 0×12 0×13 0×14 0×15 0×16 0×17 0×18 0×19 1 2 int i; int j; 0×30 0×31 0×32 0×33 0×34 0×35 0×36 0×37 0×38 0×39 0×10 0×16 int *A; int *B; The addresses of the integer variables are pointed by pointers ‘A’ and ‘B’ respectively. The addresses of these two pointers (not pointee) are arranged as array of another pointer ‘p’ as shown in the following figure. 0×70 0×71 0×72 0×73 0×74 0×75 0×76 0×77 0×30 0×36 int **p[ ]; p Now, the pointer ‘p’ can be dereferences using this pointer ‘p’. The equivalent C codes are given below: ✞ 1 #include <stdio.h>
  • 43. 2.2. POINTER 343 3 int main () { int i=1; 5 int j=2; int *A=&i; 7 int *B=&j; int **p[2]; 9 p[0]=&A; p[1]=&B; 11 printf("%d n" ,*(*(p[0]) )); printf("%d n" ,*(*(p[1]) )); 13 return 0; } ✌ ✆ ✞ 1 2 ✌ ✆ int (*p)[ ]; This is explained as pointer ‘p’ to an array of integers. Parentheses enclosing ‘*p’ has higher priority, hence pointer definition goes with ‘p’ while array definition (by []) goes to values stored at pointee address. Let we have an array ‘Arr’. 0×10 0×11 0×12 0×13 0×14 0×15 0×16 0×17 12345 12346 Arr 0×30 0×31 0×32 0×33 0×34 0×35 0×36 0×37 0×10 int (*p)[ ]; p The pointer ‘p’ points to the first element of the array ‘Arr’ as shown in above figure. The C equivalent codes are given below: ✞ #include <stdio.h> 2 int main () { 4 int Arr [2]={12345 ,12346}; int (*p)[2]; 6 p=& Arr; printf("%d n" ,(*p)[0]) ; 8 printf("%d n" ,(*p)[1]) ; return 0; 10 } ✌ ✆ ✞ 12345 12346 ✌ ✆
  • 44. 344 Array & Pointer int (**p)[ ]; It constructs a pointer ‘p’ which points to the address of another pointer to an array of integers. The memory arrangement and its relation is shown in the following figure. 0×10 0×11 0×12 0×13 0×14 0×15 0×16 0×17 1 2 Arr1 0×20 0×21 0×22 0×23 0×24 0×25 0×26 0×27 0×10 int (*A)[ ]; 0×30 0×31 0×32 0×33 0×34 0×35 0×36 0×37 0×20 int (**p)[ ]; p C codes for above declaration are given below: ✞ #include <stdio.h> 2 int main (void ) { 4 int Arr [2]={1,2}; int *A; 6 A=& Arr [0]; int **p; 8 p=&A; printf("%dn", **p); 10 return 0; } ✌ ✆ ✞ 1 ✌ ✆ int *(*p)[ ]; It constructs a pointer ‘p’ which points to the array of pointers those are pointing to integers. The memory arrangement and its relation is shown in the following figure.
  • 45. 2.2. POINTER 345 0×51 0×52 0×53 0×54 0×55 0×56 0×57 0×58 1 i 0×61 0×62 0×63 0×64 0×65 0×66 0×67 0×68 10 j 0×71 0×72 0×73 0×74 0×75 0×76 0×77 0×78 0×51 0×61 int *P[ ]; 0×81 0×82 0×83 0×84 0×85 0×86 0×87 0×88 0×71 int *(*p)[ ]; p The C example is ✞ 1 #include <stdio.h> 3 int main (void ) { int i = 105, j = 201; 5 int *A[2] = {&i, &j}; int *(*p)[]; 7 p=&A; printf("%d t %dn", *(*p)[0], *(*p)[1]) ; 9 return 0; } ✌ ✆ ✞ 105 201 ✌ ✆ int (*p[ ])[ ]; It constructs array of pointer ‘p’ which points to the array of integers. The memory arrangement and its relation is shown in the following figure. 0×51 0×52 0×53 0×54 0×55 0×56 0×57 0×58 1 2 Arr1 0×81 0×82 0×83 0×84 0×85 0×86 0×87 0×88 10 20 Arr2 0×91 0×92 0×93 0×94 0×95 0×96 0×97 0×98 0×51 0×81 int (*p[ ])[ ]; p The C example is given below:
  • 46. 346 Array & Pointer ✞ 1 #include <stdio.h> 3 int main (void ) { int Arr1 [2] = {1, 2}; 5 int Arr2 [2] = {4, 5}; int (*p[2]) [2]; 7 p[0] = &Arr1 ; p[1] = &Arr2 ; 9 printf("%d t %dn", (*p[0]) [1], (*p[1]) [0]) ; return 0; 11 } ✌ ✆ ✞ 2 4 ✌ ✆ int *p(); It constructs a function which returns a pointer pointing to an integer value. The memory arrangement of this declaration is shown below: 0×30 0×31 0×32 0×33 0×34 0×35 0×36 0×37 int v; 0x14AEFC 0×91 0×92 0×93 0×94 0×95 0×96 0×97 0×98 0×32 int *p(); p C code for above declaration are given below. In this example, the returned pointer pointed to an integer value. ✞ 1 #include <stdio.h> 3 int *p(int *j) { *j = 10 * (*j); 5 return j; } 7 int main (void ) { 9 int v = 10; printf("%dn", *p(&v)); 11 return 0; } ✌ ✆ ✞ 100 ✌ ✆ We can also return a pointer which points to a real value, like double or float type values. See the example given below:
  • 47. 2.2. POINTER 347 ✞ 1 #include <stdio.h> 3 double *p(double *j) { *j = 10 * (*j); 5 return j; } 7 int main (void ) { 9 double v = 10; printf("%lfn", *p(&v)); 11 return 0; } ✌ ✆ ✞ 100.000000 ✌ ✆ int (*p)(); It constructs a pointer ‘p’ which points to a function which returns an integer value. The C codes are ✞ 1 int myf(int r){ return 2*r; 3 } (*p)() =&myf; ✌ ✆ The memory arrangement and its relation is shown in the following figure. 0×30 0×31 0×32 0×33 0×34 0×35 0×36 0×37 myf 3.14 0×91 0×92 0×93 0×94 0×95 0×96 0×97 0×98 0×32 int (*p)(); p int (**p)(); It constructs a pointer ‘p’ which points to another pointer to a function. The function being pointed here returns an integer value.
  • 48. 348 Array & Pointer 0×30 0×31 0×32 0×33 0×34 0×35 0×36 0×37 myf 100 0×81 0×82 0×83 0×84 0×85 0×86 0×87 0×88 0×32 int (*f)(); f 0×91 0×92 0×93 0×94 0×95 0×96 0×97 0×98 0×81 int (**p)(); p In the above figure, the function ‘myf’ returns the pointer address of computed value ‘100’ via a pointer variable ‘j’. Pointer variable ‘j’ points to the address of 0×22 (for example). The C equivalent codes are given below: ✞ #include <stdio.h> 2 int myf(int j) { 4 j = 10 * j; return j; 6 } 8 int main (void ) { int v = 10; 10 int (*f)(); int (**p)(); 12 f = &myf; p = &f; 14 printf("%dn", (**p)(v)); return 0; 16 } ✌ ✆ ✞ 100 ✌ ✆ int *(*p)(); It constructs a pointer ‘p’ which points to a function. The function being pointed here returns pointer to an integer value.
  • 49. 2.2. POINTER 349 0×20 0×21 0×22 0×23 0×24 0×25 0×26 0×27 100 j=0×22 0×30 0×31 0×32 0×33 0×34 0×35 0×36 0×37 myf 0×22 0×91 0×92 0×93 0×94 0×95 0×96 0×97 0×98 0×32 int *(*p)(); p The C equivalent codes are given below: ✞ 1 #include <stdio.h> 3 int *myf(int *j) { *j = 10 * (*j); 5 return j; } 7 int main (void ) { 9 int v = 10; int *(*p)(); 11 p=& myf; printf("%dn", *(*p)(&v)); 13 return 0; } ✌ ✆ ✞ 100 ✌ ✆ int (*p())(); It constructs a function ‘p’, which returns value of a pointer to function (say ‘myf’), where function ‘myf’ returns an integer value. 0×30 0×31 0×32 0×33 0×34 0×35 0×36 0×37 myf 100 0×40 0×41 0×42 0×43 0×44 0×45 0×46 0×47 p 0×32 The equivalent C codes are given below:
  • 50. 350 Array & Pointer ✞ 1 #include <stdio.h> 3 int myf(int j) { j = 10 * j; 5 return j; } 7 int *p(int *j) { 9 j = myf (*j); return j; 11 } 13 int main (void ) { int v = 11; 15 int *(*p())(); printf("%dn", *p(&v)); 17 return 0; } ✌ ✆ ✞ 110 ✌ ✆ int (*p[ ])(); It constructs an array of pointers ‘p’ which points to the address of functions. Functions returns integer type value. 0×30 0×31 0×32 0×33 0×34 0×35 0×36 0×37 myf1 12 0×40 0×41 0×42 0×43 0×44 0×45 0×46 0×47 myf2 13 0×91 0×92 0×93 0×94 0×95 0×96 0×97 0×98 0×32 0×42 int (*p[])(); p The C codes are ✞ 1 #include <stdio.h> 3 int myf1 (int j) { return 10 * j; 5 } 7 int myf2 (int j) { return 5 * j;
  • 51. 2.2. POINTER 351 9 } 11 int main (void ) { int v = 11; 13 int (*p[2]) (); p[0]=& myf1 ; 15 p[1]=& myf2 ; printf("%d t %dn", (*p[0]) (v) ,(*p[1]) (v)); 17 return 0; } ✌ ✆ ✞ 110 55 ✌ ✆ int (*p())[ ]; It constructs a function ‘p’ which returns a pointer value. The return pointer points to an array of integers. 0×20 0×21 0×22 0×23 0×24 0×25 0×26 0×27 100 200 j[] 0×30 0×31 0×32 0×33 0×34 0×35 0×36 0×37 myf 0×20 The C codes are ✞ 1 #include <stdio.h> int j[2]={100 ,200}; 3 int *myf() { 5 return j; } 7 int main (void ) { 9 int (* myf())[]; printf("%d t %dn", (* myf())[0], (* myf())[1]); 11 return 0; } ✌ ✆ ✞ 100 200 ✌ ✆
  • 52. 352 Array & Pointer 2.2.11 Pointer Casting Suppose a pointer is declared as ✞ 1 int *i; ✌ ✆ It declares a variable that points to the address of other variable. This declaration also tells about the data type of pointed address. In above declaration, the address, which ‘i’ will point, shall be integer type. In other words, the data started from the pointed address shall be grouped in four successive bytes. See the code snippets ✞ 1 unsigned int i=1818004170; int *j=&i; // let address of i is 0x21 3 printf("%d" ,*j);// call value started at address 0x21 ✌ ✆ 0×20 0×21 0×22 0×23 0×24 0×25 00110110 00101110 10001010 11001010 i = 1818004170 Data type int for the pointer ‘j’ tells us that when we retrieve data from the address of ‘i’, data must be read from four successive memory bytes started at the address of ‘i’ and onward. If address data type is different from the data type of the pointer itself, then pointers are typecast suitably to tell the compiler about the number of bytes being read or write at once started from the address. Normally, in pointer casting, data size of the pointer and address pointed by the pointer are made equal. See the following code snippets. ✞ 1 #include <stdio.h> 3 int main () { /*A double floating type value.*/ 5 double d=1000000.22255; /*A pointer of long int type .*/ 7 long int *iptr ; /* Cast address of the double floating * 9 *type number into the long int type . */ iptr =( long int *)&d; 11 /* Retrieve value from the address pointed * *by iptr and convert it into double type .*/ 13 printf("%lf", *( double *) iptr ); return 0; 15 } ✌ ✆ ✞ 1000000.222550 ✌ ✆
  • 53. 2.2. POINTER 353 2.2.12 Pointer as Structure A structure object can be assigned to a pointer to object by assigning it the address of the structure object. ✞ 1 #include <stdio.h> 3 struct Struc { int i; 5 char ch; }; 7 int main (void ) { 9 /* Structure object obj*/ struct Struc obj; 11 /* Pointer structure object strucObj * *assigned the address of obj */ 13 struct Struc *strucObj = &obj; 15 /* Assign values to elements of structure */ strucObj ->i = 5; 17 strucObj ->ch = ’A’; 19 /* Access value of elements of structure */ printf("[%d] [%c]n", strucObj ->i, strucObj ->ch); 21 return 0; } ✌ ✆ ✞ [5] [A] ✌ ✆ In the above example, code line ✞ 1 struct Struc obj; ✌ ✆ creastes a structure object ‘obj’. The code line ✞ 1 struct Struc *strucObj = &obj; ✌ ✆ creates pointer struct object ‘strucObj’ and the address of ‘obj’ is assigned to it. Now the structure elements can be accessed by using pointer object and using operator ‘−>’ as shown in above example.
  • 54. 354 File & Data Structure
  • 55. 3.1. INPUT OUTPUT 355 3File & Data Structure Standard Input-Output and access of files is a main part of computer programming. In this chapter we shall discuss the importance and methodology of accessing system and user define files. 3.1 Input Output A C program under execution opens automatically three standard streams named stdin, stdout, and stderr. These are attached to every C program. The first standard stream is used for input buffering and the other two are used for outputs. These streams are sequences of bytes. ✞ 1 int main (){ int var; 3 /* Use stdin for scanning an* *integer from keyboard . */ 5 scanf ("%d", &var); /* Use stdout for printing a character .*/ 7 printf ("%d", var); return 0; 9 } ✌ ✆ By default stdin points to the keyboard and stdout and stderr point to the screen. It is possible under Unix and may be possible under other operating systems to redirect input from or output to a file or both. 3.1.1 Handling File Directory Sometimes user needs to read, create, delete or change a directory. Directories are sep- arated by symbol ‘/’. To represent current working directory or parent directory of the current working directory, dots are used as ‘./’ and ‘../’ respectively. ‘/..’ has same meaning as ‘/’. 3.1.2 Change Directory Current working directory of a program is the location where all the temporary or per- manent files are stored and retrieved by default. Location of current working directory of a program may be changed to other directory by using chdir() function. Syntax of this function is ✞ 1 chdir(<directory path >) ✌ ✆ On successful change of location of old working directory to new location of working directory, it returns ‘0’ otherwise ‘-1’. An example of the function is given below.
  • 56. 356 File & Data Structure ✞ 1 #include <stdio.h> #include <string.h> 3 #include <stdlib.h> 5 int main (void ) { char dr [10]; 7 int ret; printf("Enter the directory name :"); 9 scanf("%s", &dr); ret = chdir(dr); 11 printf("%dn", ret); return EXIT_SUCCESS ; 13 } ✌ ✆ 3.1.3 FILE pointers The <stdio.h>header contains a definition for a type FILE (usually via a data type) which is capable of processing all the information needed to exercise control over a stream, including its file position indicator, a pointer to the associated buffer (if any), an error indicator that records whether a read/write error has occurred and an end-of-file indicator that records whether the end of the file has been reached. There may be multiple FILE descriptors for a single file. ✞ 1 #include <stdio.h> 3 int main (void ) { FILE *f1 , *f2; 5 /* First discriptor for file a.txt */ f1 = fopen("a.txt", "r"); 7 if (!f1) { printf("Unable to open file a.txtn"); 9 return 1; } 11 /* Second discriptor for file a.txt */ f2 = fopen("a.txt", "r"); 13 if (!f2) { printf("Unable to open file a.txtn"); 15 return 1; } 17 /* Change f1 location */ 19 fseek(f1 , 7, SEEK_SET ); 21 /* Change f2 location */ fseek(f2 , 14, SEEK_SET ); 23 /* Print results */ printf("Position of f1 is %dn", ftell(f1)); 25 printf("Position of f2 is %dn", ftell(f2)); /* close streams */
  • 57. 3.1. INPUT OUTPUT 357 27 fclose(f1); fclose(f2); 29 return 0; } ✌ ✆ ✞ Position of f1 is 7 Position of f2 is 14 ✌ ✆ But this way of accessing file is not safe as both file descriptors access file simultaneously. To avoid any problems arise due to mixing of streams and descriptors, a file locking facility should be used to avoid simultaneous access. Locking & Unlocking a File The flockfile() function acquires the internal locking to the file stream. It ensures that no other stream may access the file while the file is locked and accessed by current stream. If there is no further required to access the file, then file is unlocked by funlockfile() function. funlockfile() function is called if locking function is able to lock the file. ✞ #include <stdio.h> 2 #include <stdlib.h> 4 int main (void ) { FILE *f1 , *f2; 6 /* first discriptor for file a.txt */ f1 = fopen("a.txt", "r"); 8 /* lock the file */ flockfile (f1); 10 if (!f1) { printf("Unable to open file a.txtn"); 12 return 1; } 14 /* change f1 location */ fseek(f1 , 7, SEEK_SET ); 16 printf("Position of f1 is %dn", ftell(f1)); /* unlock the file */ 18 funlockfile (f1); /* close streams */ 20 fclose(f1); 22 return 0; } ✌ ✆ ✞ Position of f1 is 7 ✌ ✆ But direct locking of the file by flockfile() function may return error if the file is already locked. So, it is safe to use ftrylockfile() function to avoid multiple locking of the same file simultaneously.
  • 58. 358 File & Data Structure ✞ 1 #include <stdio.h> #include <stdlib.h> 3 int main (void ) { 5 FILE *f1 , *f2; /* first discriptor for file a.txt */ 7 f1 = fopen("a.txt", "r"); /* lock the file */ 9 ftrylockfile (f1); if (!f1) { 11 printf("Unable to open file a.txtn"); return 1; 13 } /* change f1 location */ 15 fseek(f1 , 7, SEEK_SET ); printf("Position of f1 is %dn", ftell(f1)); 17 /* unlock the file */ funlockfile (f1); 19 /* close streams */ fclose(f1); 21 return 0; 23 } ✌ ✆ ✞ Position of f1 is 7 ✌ ✆ In the above example, we are trying to lock a file by using function ftrylockfile() and seeking file stream location in the file. If the file is already locked by other program, then ftrylockfile() function will fail to lock the file and stream will try to access the file without locking it (simultaneous access). This is why, before accessing to the file, its locking status must be checked. ✞ 1 #include <stdio.h> #include <stdlib.h> 3 int main (void ) { 5 FILE *f1 , *f2; /* first discriptor for file a.txt */ 7 f1 = fopen("a.txt", "r"); /* try to lock the file and check lock status*/ 9 if (ftrylockfile (f1) == 0) { if (!f1) { 11 printf("Unable to open file a.txtn"); return 1; 13 } /* change f1 location */ 15 fseek(f1 , 7, SEEK_SET ); printf("Position of f1 is %dn", ftell(f1)); 17 } /* unlock the file */
  • 59. 3.1. INPUT OUTPUT 359 19 funlockfile (f1); /* close streams */ 21 fclose(f1); return 0; 23 } ✌ ✆ ✞ Position of f1 is 7 ✌ ✆ Reading/Scanning Directory In C, there is no dedicated function to read or scan a directory but using readdir or scandir function, a directory can be read or scanned respectively. ✞ 1 #include <stdio.h> #include <dirent.h> 3 int main () { 5 DIR *dir; struct dirent *dp; 7 char * file_name ; dir = opendir("."); 9 while ((dp = readdir (dir)) != NULL ) { printf("debug: %sn", dp ->d_name); 11 if (! strcmp(dp ->d_name , ".") || !strcmp(dp ->d_name , "..")) { /* your code here .*/ 13 } else { file_name = dp ->d_name; // use it 15 printf("file_name : "%s"n", file_name ); } 17 } closedir (dir); 19 return 0; } ✌ ✆ ✞ debug: . debug: .. debug: nbproject file _name : "nbproject " debug: main .c file _name : "main .c" ✌ ✆ Similarly ✞ #include <dirent.h> 2 int main (void ) { 4 struct dirent ** namelist ; int n; 6
  • 60. 360 File & Data Structure n = scandir (".", &namelist , NULL , alphasort ); 8 if (n < 0) perror("scandir "); 10 else { while (n--) { 12 printf("%sn", namelist [n]->d_name); free (namelist [n]); 14 } free (namelist ); 16 } } ✌ ✆ ✞ nbproject main .c image.bmp dist .. . ✌ ✆ Open a File To open or close a file, the <stdio.h>library has three functions: fopen, freopen, and fclose. We can open a file to read or write as ✞ #include <stdio.h> 2 FILE *fopen(const char *filename , const char *mode ); FILE *freopen (const char *filename , const char *mode , FILE *stream); ✌ ✆ fopen and freopen opens the file whose name is in the string pointed-by a file name and associates a stream with it. Both return a pointer to the object controlling the stream. If the open operation fails, a null pointer is returned and error is set. On successfully opening of a file, the error and end-of-file indicators are cleared. freopen differs from fopen by a bit and the file pointed-by ‘stream’ is firstly closed if it already open and errors related to close operation are ignored. File operation mode for both file opening functions points-to a string consisting of one of the following sequences:
  • 61. 3.1. INPUT OUTPUT 361 Mode Explanation r Open a text file for reading w Truncate to zero length or create a text file for writing a Append or open or create text file for writing at end-of-file rb Open binary file for reading wb Truncate to zero length or create a binary file for writing ab Append or open or create binary file for writing at end-of-file r+ Open text file for update (reading and writing) w+ Truncate to zero length or create a text file for update a+ Append or open or create text file for update r+b or rb+ Open binary file for update (reading and writing) w+b or wb+ Truncate to zero length or create a binary file for update a+b or ab+ Append or open or create binary file for update Table 3.1: File read and write mode. Opening a file with read mode (‘r’ as the first character in the mode argument) fails if the file does not exist or can not be read. Opening a file with append mode (‘a’ as the first character in the mode argument) causes all subsequent writes to the file to be forced to the then-current end-of-file. Opening a binary file with append mode (‘b’ as the second or third character in the above list of mode arguments) may initially position the file position indicator for the stream beyond the last data written, because of null character padding. When a file is opened with update mode (‘+’), both input and output may be performed on the associated stream. ✞ 1 #include <stdio.h> #include <stdlib.h> 3 int main (void ) { 5 /* File pointer that is defined in stdlib.h header* *file and used for file handling by data type FILE */ 7 FILE *fo; char f_name [10]="fname.txt"; 9 /* Open file fname.txt in write mode */ fo = fopen(f_name , "w"); 11 /* Show warning if file can not be open .*/ if (fo == NULL ) { 13 printf("Could not open fname file .n"); exit (0); 15 }else { printf("%s file is created .n",f_name); 17 } int i = 0, n;
  • 62. 362 File & Data Structure 19 /* Get the rows up to which data * *is to be write in the file */ 21 printf("Enter the data rows No. : "); scanf("%d", &n); 23 /*Do what you want .*/ while (i < n) { 25 fprintf (fo , "%d %d %dn", i, i*i, i * i * i); i++; 27 } printf("Details are written in file %s.n",f_name); 29 /* Close the open file .*/ fclose(fo); 31 /*If every thing gone ok , return success.*/ return 0; 33 } ✌ ✆ ✞ fname.txt file is opened. Enter the data rows No. : 10 Details are written in file fname.txt ✌ ✆ Close a File We can close a file pointer by using close function as shown in the following syntax. ✞ 1 #include <stdio.h> int fclose(FILE *stream); ✌ ✆ The fclose() function causes the stream pointed-by ‘stream’ to be flushed and the as- sociated file is closed. Any unwritten buffered data for the stream are delivered to the host environment to be written to the file. Any unread buffered data are discarded. The function returns zero if the stream was successfully closed or stream is encounters with EOF. ✞ #include <stdio.h> 2 #include <stdlib.h> 4 int main (void ) { /* File pointer that is defined in stdlib.h header * 6 *file and used for file handling by data type FILE */ FILE *fo; 8 char f_name [10]="fname.txt"; /* Open file fname.txt in write mode */ 10 fo = fopen(f_name , "w"); /* Show warning if file can not be open .*/ 12 if (fo == NULL ) { printf("Could not open fname file .n"); 14 exit (0); }else { 16 printf("%s file is created .n",f_name);
  • 63. 3.1. INPUT OUTPUT 363 } 18 int i = 0, n; /* Get the rows up to which data * 20 *is to be write in the file */ printf("Enter the data rows No. : "); 22 scanf("%d", &n); /*Do what you want .*/ 24 while (i < n) { fprintf (fo , "%d %d %dn", i, i*i, i * i * i); 26 i++; } 28 printf("Details are written in file %s.n",f_name); /* Close the open file .*/ 30 fclose(fo); printf("%s file is closed.n",f_name); 32 /*If every thing gone ok , return success.*/ return 0; 34 } ✌ ✆ ✞ fname.txt file is opened. Enter the data rows No. : 10 Details are written in file fname.txt fname.txt file is closed. ✌ ✆ fflush function The synopsis of this function is ✞ #include <stdio.h> 2 int fflush(FILE *stream); ✌ ✆ If stream points to output or update stream in which the most recent operation was not input, the fflush function causes any unwritten data for that stream to be deferred to the host environment to be written to the file. A simple example is ✞ #include <stdio.h> 2 /* For prototype for sleep()*/ #include <unistd.h> 4 int main (void ) { 6 int count; for ( count = 10; count >= 0; count --) { 8 /* Lead with a CR */ printf("rSeconds until launch: "); 10 if (count > 0) printf("%2d", count); 12 else printf("blastoff !n"); 14 /* Force output now!!*/ fflush(stdout); 16 /* The sleep() delayed system by number of seconds:*/ sleep (1);
  • 64. 364 File & Data Structure 18 } return 0; 20 } ✌ ✆ ✞ Seconds until launch: 10 Seconds until launch: blastoff ! ✌ ✆ The effect of using fflush() on an input stream is undefined. Sometime a program needed huge RAM and disk memory to perform a programming job. In between the process of job, if there is requirement of log data (say) to be stored in disk (outstream), then OS waits till termination of the resource consuming program and then it writes log data into the disk file. If the program abrupptly terminated or terminated with error, whole unwritten log data is vanished. To overcome this problem, fflush function is used to force OS to write log data immediated into the disk file. It is good programming habbit that each time when data file being written by program (like using function fprintf etc), it should be followed by fflush function. setbuf function The syntax of this function is ✞ #include <stdio.h> 2 void setbuf(FILE *stream , char *buf); ✌ ✆ It returns no value. The setbuf function is equivalent to the setvbuf function. setvbuf function uses two more parameters ‘mode’ and ‘size’. A simple example is ✞ #include <stdio.h> 2 int main () { 4 FILE *fp; char lineBuf [1024]; 6 /*b.txt must be in executable ’s dir*/ fp = fopen("b.txt", "rb"); 8 setbuf(fp , NULL ); // set to unbuffered fclose(fp); 10 return 0; } ✌ ✆ setvbuf function The function syntax is ✞ 1 #include <stdio.h> int setvbuf (FILE *stream , char *buf , int mode , size_t size ); ✌ ✆ The setvbuf function may be used only after the stream pointed-by ‘stream’ has been associated with an open file and before any other operation is performed on the stream. The argument size specifies the ‘size’ of the array. The contents of the array at any time are indeterminate. The setvbuf function returns zero on success, or nonzero if an invalid value is given for ‘mode’ or if the request cannot be honored. A simple example is ✞ #include <stdio.h>
  • 65. 3.1. INPUT OUTPUT 365 2 int main () { 4 FILE *fp; char lineBuf [1024]; 6 /*b.txt must be in executable ’s dir*/ fp = fopen("b.txt", "r"); 8 /* set to line buffering */ setvbuf (fp , lineBuf , _IOLBF , 1024); 10 fclose(fp); return 0; 12 } ✌ ✆ setvbuf is invoked with ‘mode’ has value IOFBF and ‘size’ when ‘buf’ is not a null pointer. Again, if ‘buf’ is a null pointer then ‘mode’ has value IONBF. fgetpos & fsetpos functions The function syntax is ✞ #include <stdio.h> 2 int fgetpos (FILE *stream , fpos_t *pos); int fsetpos (FILE *stream , const fpos_t *pos); ✌ ✆ The fgetpos function stores the current value of the file position indicator for the stream pointed-by ‘stream’ in the object pointed-by ‘pos’. A simple example is ✞ 1 #include <stdio.h> 3 int main () { FILE * fName; 5 int c; int n; 7 fpos_t pos; 9 fName = fopen("fname.txt", "r"); if (fName == NULL ) 11 perror("Can not open a file ."); else { 13 c = fgetc(fName); printf("First char is %cn", c); 15 fgetpos (fName , &pos); for (n = 0; n < 3; n++) { 17 fsetpos(fName , &pos); c = fgetc(fName); 19 printf("Char in position %d is %cn", n, c); } 21 fclose(fName); } 23 return 0; } ✌ ✆ ✞ First char is 0 Char in position 0 is
  • 66. 366 File & Data Structure Char in position 1 is Char in position 2 is ✌ ✆ fseek & ftell functions The function syntax is ✞ #include <stdio.h> 2 int fseek(FILE *stream , long int offset , int whence); long ftell(FILE *stream); ✌ ✆ The fseek function sets the file position indicator for the stream pointed-to the ‘stream’. For a binary stream, the new position, measured in characters from the beginning of the file, is obtained by adding ‘offset’ to the position specified by ‘whence’. Three macros in stdio.h called SEEK SET, SEEK CUR, and SEEK END expand to unique values. If the position specified by ‘whence’ is SEEK SET, the specified position is the beginning of the file; if ‘whence’ is SEEK END, the specified position is the end of the file; and if ‘whence’ is SEEK CUR, the specified position is the current file position. A binary stream need not meaningfully support fseek calls with a ‘whence’ value of SEEK END. In case of SEEK END, ‘offset’ may be a negative count (i.e. within the current extent of file) or may be a positive count (i.e. position past the current end of file). In the later case file is extended up to that position and filled with zeros. 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 (1) fp (2) fseek(fp, 10, SEEK CUR) (3) fp (4) Figure 3.1: Change in location of file pointer from current file pointer location.
  • 67. 3.1. INPUT OUTPUT 367 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 (1) fp (2) fseek(fp, -8, SEEK END) (3) fp (4) Figure 3.2: Change in location of file pointer from the end of file location. 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 (1) fp (2) fseek(fp, 10, SEEK SET) (3) fp (4) Figure 3.3: Change in location of file pointer from the beginning of file location. A simple example is ✞ 1 #include <stdio.h> 3 int main () { FILE *fp; 5 fp = fopen("file .txt", "w+"); 7 fputs("This is my file name .", fp); 9 fseek(fp , 7, SEEK_SET ); fputs("C Programming Langauge ", fp); 11 fclose(fp); 13 return (0); } ✌ ✆
  • 68. 368 File & Data Structure For output see the file “file.txt”. ftell returns the current position of file pointer from the start of the file. Its largest return value is signed long type value. When ftell is used for obtaining of size of huge files, it fails due to its return size, therefore be cautious when using for this purpose. Example for ftell is given below: ✞ #include <stdio.h> 2 int main () { 4 FILE *fp; int len; 6 fp = fopen("file .txt", "r"); 8 if (fp == NULL ) { perror("Error opening file "); 10 return (-1); } 12 fseek(fp , 0, SEEK_END ); 14 len = ftell(fp); fclose(fp); 16 printf("Total size of file .txt = %d bytesn", len); 18 return (0); 20 } ✌ ✆ ✞ Total size of file .txt = 32 bytes ✌ ✆ Using the pointer in a function, we can also get the file size as shown in the example given below. ✞ 1 #include <stdlib.h> #include <stdio.h> 3 long getFileSize (const char *filename ) { 5 long result; FILE *fh = fopen(filename , "rb"); 7 fseek(fh , 0, SEEK_END ); result = ftell(fh); 9 fclose(fh); return result; 11 } 13 int main (void ) { printf("%ldn", getFileSize ("file .txt")); 15 return 0; } ✌ ✆ ✞ Total size of file .txt = 32 bytes ✌ ✆
  • 69. 3.1. INPUT OUTPUT 369 fseek and fputc can be used to write a file of specific size. See the example given below. ✞ 1 #include <stdio.h> 3 int main () { FILE *fp = fopen("myfile.txt", "w"); 5 fseek(fp , 1024 * 1024, SEEK_SET ); fputc(’n’, fp); 7 fclose(fp); return 0; 9 } ✌ ✆ rewind function The synopsis of the function is ✞ 1 #include <stdio.h> void rewind(FILE *stream); ✌ ✆ The rewind function sets the file position indicator for the stream pointed-by ‘stream’ to the beginning of the file. It is equivalent to ✞ (void )fseek(stream , 0L, SEEK_SET ) ✌ ✆ except that the error indicator for the stream is also cleared. A simple example is ✞ 1 #include <stdio.h> 3 int main () { FILE *fp; 5 int ch; 7 fp = fopen("file .txt", "r"); 9 if (fp != NULL ) { while (! feof (fp)) { 11 ch = fgetc(fp); printf("%c", ch); 13 } rewind(fp); 15 while (! feof (fp)) { 17 ch = fgetc(fp); printf("%c", ch); 19 } fclose(fp); 21 } 23 return (0); } ✌ ✆ The output from the file “file.txt” is
  • 70. 370 File & Data Structure ✞ This is C Programming Langauge This is C Programming Langauge ✌ ✆ feof function The synopsis of the function is ✞ #include <stdio.h> 2 int feof (FILE *stream); ✌ ✆ The feof function tests the end-of-file indicator for the stream pointed-by ‘stream’ and returns nonzero if and only if the end-of-file indicator is set for stream, otherwise it returns zero. A simple example is ✞ #include <stdio.h> 2 int main (void ) { 4 int a; FILE *fp; 6 fp = fopen("file .txt", "rb"); /* Read single ints at a time , stopping on EOF or error:*/ 8 while (fread(&a, sizeof (int), 1, fp), !feof (fp) && !ferror(fp)){ printf("I read %dn", a); 10 } if (feof (fp)) 12 printf("End of file was reached .n"); if (ferror(fp)) 14 printf("An error occurred .n"); fclose(fp); 16 return 0; } ✌ ✆ ✞ I read 543649385 I read 1735287116 I read 1701279073 End of file was reached . ✌ ✆ Reading File There are two ways to read the stuff in C. In first method data is accepted from terminal. In second method data is read from a file. Following functions are used in reading data from a file. fgetc function The syntax of the function is ✞ #include <stdio.h> 2 int fgetc(FILE *stream); ✌ ✆
  • 71. 3.1. INPUT OUTPUT 371 The fgetc function obtains the next character (if present) as an unsigned1 char converted into its equivalent character code, from the input stream pointed-by ‘stream’. fgetc mod- ified to the file pointer after reading each character. If the stream is at end-of-file, the end-of-file indicator for the stream is set and fgetc returns EOF. If a read error occurs, the error indicator for the stream is set and fgetc returns EOF. A B C D E F G H fgetc(fp) A fp→ A B C D E F G H fgetc(fp) B fp→ ✞ #include <stdio.h> 2 #include <stdlib.h> 4 int main (void ) { /* File pointer */ 6 FILE *fr; /* Open file fread.txt in read mode */ 8 fr = fopen("fname.txt", "r"); /*If file is not opened , show warning * 10 *and exit without doing nothing . */ if (fr == NULL ) { 12 printf("Couldn’t open fname.txt file for reading .n"); } 14 /* Read whole data of file by using fgetc*/ int c; 16 while ((c = fgetc(fr)) != EOF) { putchar (c); 18 } /* Close the file */ 20 fclose(fr); /*If every thing is ok return successfully */ 22 return 0; } ✌ ✆ 1 Position of char is determined by integer number started from zero to continue...
  • 72. 372 File & Data Structure ✞ This is C Programming Langauge ✌ ✆ fgetc() is more faster than the fread() function. fread() takes 0.1143 seconds to read 1.8MB MP3 file while fgetc takes 0.000142 seconds to read the same file. ✞ 1 #include <stdio.h> #include <time .h> 3 int main () { 5 clock_t startTime = clock(); FILE * fp; 7 fp = fopen("a.mp3", "r"); int s; 9 s = fgetc(fp); while (s > 0) { 11 s = fgetc(fp); } 13 fclose(fp); clock_t endTime = clock(); 15 double td = (endTime - startTime ) / (double) CLOCKS_PER_SEC ; printf("Program has run for %5.8 f secondsn", td); 17 return 0; } ✌ ✆ fgets function The synopsis of the function is ✞ char *fgets(char *s, int n, FILE *stream); ✌ ✆ The fgets function reads at most one less than the number of characters specified by ‘n’ from the stream pointed-by ‘stream’ into the array pointed-by ‘s’. No additional characters are read after a new-line character (which is retained) or after end-of-file. A null character is written immediately after the last character read into the array. The fgets function returns ‘s’ if successful. If end-of-file is encountered and no characters have been read into the array, the contents of the array remain unchanged and a null pointer is returned. If a read error occurs during the operation, the array contents are indeterminate and a null pointer is returned. A B C D E F G H fgets(s,5,fp) s=ABCDE fp→ In following example, fgets() function reads specific number of bytes from a file via file pointer and prints it in output console. ✞ 1 #include <stdio.h>
  • 73. 3.1. INPUT OUTPUT 373 #define BUFFER_SIZE 100 3 int main (void ) { 5 /*A read buffer*/ char buffer[BUFFER_SIZE ]; 7 while (fgets(buffer , BUFFER_SIZE , stdin) != NULL ) { printf("%s", buffer); 9 } return 0; 11 } ✌ ✆ ✞ This is This is my Car my Car ✌ ✆ Note that each line ends with end of line marker, i.e. ‘rn’, therefore, fgets always returns a string of size two bytes even if a blank line is read from flat text file. ✞ #include <stdio.h> 2 #include <string.h> 4 int main () { FILE *f; 6 int i = 0; char *line = malloc (1024); 8 f = fopen("txt.txt", "r"); if (f) { 10 while (fgets(line , 1024, f) != NULL ) { i = 0; 12 while (line [i] != ’0’) { printf("%d %d %dt", line [i], ’r’, ’n’); 14 i++; } 16 printf("n"); } 18 free (line ); } 20 fclose(f); return 0; 22 } ✌ ✆ ✞ 13 13 10 10 13 10 97 13 10 98 13 10 99 13 10 13 13 10 10 13 10 ✌ ✆ Another example, with additional functionality is given below. The texts from ‘fname.txt’ file are read and prints it in output console. ✞ 1 #include <stdio.h>
  • 74. 374 File & Data Structure #include <stdlib.h> 3 #define BUFFER_SIZE 1000 5 int main (void ) { /* File pointer */ 7 FILE *fr; /*A read buffer*/ 9 char buffer [1000]; /* Open file fname.txt in read mode */ 11 fr = fopen("fname.txt", "r"); /*If file is not opened , show warning * 13 *and exit without doing nothing . */ if (fr == NULL ) { 15 printf("Couldn’t open fname.txt file for reading .n"); return 0; 17 } /* Read whole data of file by using fgets*/ 19 while (fgets(buffer , BUFFER_SIZE , fr) != NULL ) { printf("%s", buffer); 21 } /* Close the file .*/ 23 fclose(fr); /*If every thing is ok return successfully */ 25 return 0; } ✌ ✆ ✞ This is C Programming Langauge ✌ ✆ fgets can also used in place of scanf for receiving string from standard input. ✞ 1 #include <stdio.h> #define STRSIZE 100 3 int main () { 5 int res; char *str1 , *str2 ; 7 str1 = malloc(sizeof (char ) * STRSIZE + 1); 9 printf("First string : "); fgets(str1 , STRSIZE , stdin); 11 printf("You entered : %s", str1 ); 13 str2 = malloc(sizeof (char ) * STRSIZE + 1); printf("Second string : "); 15 fgets(str2 , STRSIZE , stdin); printf("You entered : %s", str2 ); 17 free (str1 ); 19 free (str2 ); 21 return 0;