SlideShare a Scribd company logo
1.4. C OPERATORS 101
Operator Description
<< Left shift
>> Right shift
In the following figure, a character byte is shifted by one bit in right ward. After
shifting of bits of the byte, new value is different from the old value.
1 0 0 1 1 0 1 1
ch
0 1 0 0 1 1 0 1 1
ch >> 1
One byte
Above, a byte is shifted rightward by one place. Note that, in computer memory, data
is arranged in continuous memory bytes. Here, the LSB bit, that is shifted rightward
appears that it takes place of its neighbouring bit which is beyond the range of original
memory byte. But actually, in bit shift, shifted bit does not over write to the data stored
in its neighbouring memory byte but it is eliminated from its original place to create
space for storing of its leftward bit.
1 0 0 1 1 0 1 1
ch
1 0 0 1 1 0 1 1 0 0
ch << 1
One byte
Figure 1.3: Left shift of bits by one place.
Above, a byte is shifted leftward by one place. In the similar principle to the rightward
bitshift, shifted bit does not over write to the data stored in its neighbouring memory
byte but it is eliminated from its original place to create space for storing of its rightward
bit. Example is given below:
✞
1 #include <stdio.h>
3 int main () {
/* Bit pattern of decimal 4 is *
102 Basic C
5 *equivalent to binary 100 */
int i = 4;
7 /* Number of places take place by binary shift.*/
int j = 2;
9 /* << makes 100 to 10000 & print "16" */
printf("<< of %d, %d is %d.n", i, j, i << j);
11 /* >> makes 100 to 1 & print "1"*/
printf(">> of %d, %d is %d.n", i, j, i >> j);
13 return 0;
}
✌
✆
✞
<< of 4, 2 is 16.
>> of 4, 2 is 1.
✌
✆
If a data type is unsigned type and it is assigned a negative number then its bit shift
takes placed for whole bits as shown in the following example. Note that, the vacated
bits are filled with zero bits.
✞
#include <stdio.h>
2
int main () {
4 unsigned char f = 0, c = -16;
printf("Original Number %dn", c);
6 f = c >> 2;
printf(">> shifts number and number becomes %dn", f);
8 f = c << 2;
printf("<< shifts number and number becomes %dn", f);
10 return 0;
}
✌
✆
✞
Original Number 240
>> shifts number and number becomes 60
<< shifts number and number becomes 192
✌
✆
If a data type is signed type and it is assigned a negative number then its bit shift takes
placed for whole bits except the sign bit (MSB) as shown in the following example. Note
that, the vacated bits are filled with zero bits.
✞
1 #include <stdio.h>
3 int main () {
signed char f = 0, c = -16;
5 printf("Original Number %dn", c);
f = c >> 2;
7 printf(">> shifts number and number becomes %dn", f);
f = c << 2;
9 printf("<< shifts number and number becomes %dn", f);
return 0;
11 }
✌
✆
1.4. C OPERATORS 103
✞
Original Number -16
>> shifts number and number becomes -4
<< shifts number and number becomes -64
✌
✆
Bitwise AND & XOR relations may also be used to add two number. AND operation
tells the positions of bits where carry generated and this carry is to be shifted/added to
leftside bit. XOR operation is used to get the binary addition ignoring carry generated if
anywhere.
✞
1 #include <stdio.h>
3 int main () {
unsigned int x = 30, y = 1, sum , carry;
5 /* ---------------------------**
* Decimal 30 is binary 11110
7 * Decimal 01 is binary 00001
* XOR Operation is
9 * 11110
* 00001
11 * ---------
* S= 11111
13 **--------------------------- */
sum = x ^ y;
15 /* ---------------------------**
* Decimal 30 is binary 11110
17 * Decimal 01 is binary 00001
* AND Operation is
19 * 11110
* 00001
21 * ----------
* C = 00000
23 **--------------------------- */
carry = x & y;
25 /* Performed loop until last carry is not zero .*/
while (carry != 0) {
27 /* ----------------------------------------**
* Left shift of carry is
29 * C_s = 000000
* This operation is performed to shift
31 * the carry left hand side by one place
* to add it with next higher place value.
33 **---------------------------------------- */
carry = carry << 1;
35 /* Take x as sum value from XOR Operation .*/
x = sum;
37 /* Take y as carry value form *
* left shift of AND Operation .*/
39 y = carry;
/* Take XOR Operation of x and y*/
41 sum = x ^ y;
/* Get the next carry.*/
104 Basic C
43 carry = x & y;
}
45 /* Print the sum 31. */
printf("Sum of %d and %d is : %dn", x, y, sum);
47 return 0;
}
✌
✆
✞
Sum of 30 and 1 is 31
✌
✆
Binary shift operation can be performed in characters and strings. It is explained in the
example given below.
✞
1 #include <stdio.h>
3 int main () {
char a[ ]="a";/* Binary equivalent -1100001 */
5 char b[ ]="b";/* Binary equivalent -1100010 */
char c[ ]="c";/* Binary equivalent -1100011 */
7 /* ----------------------------------------------*
<< of a by 16 places 11000010000000000000000
9 << of b by 8 places 110001000000000
<< of a by 0 places 1100011
11 ----------------------------------------------
OR Operation 11000010110001001100011
13 Hexadecimal 616263
*---------------------------------------------- */
15 printf("Left binary bit shift %xhn")
printf (*a << 16 | *b <<8 | *c);
17 return 0;
}
✌
✆
✞
Left binary bit shift is 616263h
✌
✆
The unary operator ‘∼’ returns the one’s complements of an integer by changing bit ‘0’
into ‘1’ and viceversa.
✞
1 #include <stdio.h>
#include <stdlib.h>
3
int main (void ) {
5 int j = 0;
printf("Bitwise ~ operation on an integer .n");
7 while (j < 3) {
printf("%d => %dn", j,~j);
9 j++;
}
11 return EXIT_SUCCESS ;
}
✌
✆
1.4. C OPERATORS 105
✞
Bitwise ~ operation on an integer.
0 => -1
1 => -2
2 => -3
✌
✆
Note that, shift operator is applied only to those byte(s) which are pointed by the variable.
On shift operation, values of neighbouring bytes remain unaffected and un-altered. It
means, in shift operation, bits are neither borrows nor carryover from or to neighbouring
memory bytes. See the example below:
✞
#include <stdio.h>
2
int main () {
4 int a = 320;
/* Integer 320 = binary 00000001 01000000 */
6 char *ptr;
ptr = (char *) &a;
8
char ca = *ptr; /* Get 01000000 as decimal 64*/
10 char cb = *(++ ptr); /* Get 00000001 as decimal 1*/
12 printf("%d ", ca);
printf("%d ", cb);
14
cb = (cb << 5); /* Shift the value of cb.*/
16
printf("%d ", ca);/* Print 01000000 as decimal 64*/
18 printf("%d ", cb);/* Print 00100000 as decimal 32*/
20 return 0;
}
✌
✆
✞
64 1 64 32
✌
✆
In above example, bit shift of ‘cb’ does not affects the value of ‘ca’ any way.
1.4.9 Condition & Relation Operators
If a condition is true then successive value is taken otherwise next value. The simplest
form of this operator is
✞
1 x ? y : z
✌
✆
See the example below:
✞
1 #include <stdio.h>
#include <io.h>
3
/* Return true if file exist other wise return false. */
106 Basic C
5 int file_exists (char *filename ) {
return (access(filename , 0) == 0);
7 }
9 main () {
printf("Does myfile.au exist: %sn",
11 file_exists ("myfile.au") ? "YES" : "NO");
}
✌
✆
✞
Does myfile.au exist: NO
✌
✆
1.4.10 Lexical Comparison
Lexical comparison is performed between two strings having alpha-numeric and special
characters. Both strings are compared character-by-character and comparison is done
between the charcter codes. For example, ‘a’ and ‘A’ are same characters but their
character codes are 97 and 65 respectively. Therefore, in lexical comparison, character ‘a’
is larger than ‘A’.
s i m p l e
str1
s i M p l e
str2
Lexical comparision between strings “simple” and “siMple” is taken character by
character. In ASCII character codes, character “M” came before to “m”, this is why in
character by character comparison, ‘str1’ is greater than the ‘str2’.
1.4.11 Arithmetic Operators
Arithmetic operators are given in the following table.
1.4. C OPERATORS 107
Operator Description
+ Addition operator. It adds the right
value with left value.
− Subtraction operator. It subtracts the
right value from left value.
/ Division operator. It divides the left
value with right value. Returns the
quotient. If, both left and right values
are integer then decimal part of the re-
sult is truncated.
∗ Multiplication operator. It multiply the
left value with right value. Returns
product of two numbers.
% It is modulus operator. It returns the
remainder of division between two num-
bers. It accepts only integer type val-
ues as its operands.
= Assignment operator. A variable, at
left side to it, is assigned the value at
the right side of it.
Table 1.15: Arithmetic operators.
See the example below, in which addition and subtraction operators are used in a
single expression.
✞
1 #include <stdio.h>
3 int main () {
int y;
5 /* In first step 5+3=8. In *
* second step 8-4 = 4. As *
7 * + has higher precedence */
y = 5 + 3 - 4;
9 printf("Result is : %dn", y);
return 0;
11 }
✌
✆
✞
Result is : 4
✌
✆
The grouping of terms in a mathematical expression, using parentheses is required to get
correct result when an arithmetic operator is used multiple times. If grouping is not done
then result is different.
✞
1 #include <stdio.h>
108 Basic C
3 int main () {
float a;
5
/* / operator is used thrice.*
7 *will be solved from L to R.*/
a = 20.0 / 10.0 / 2.0;
9 printf("Result is %fn", a);
11 /* First 10.0 is divided by 20.0 and*
*then result will divide to 20.0 */
13 a = 20.0 / (10.0 / 2.0) ;
15 printf("Result is %fn", a);
return 0;
17 }
✌
✆
✞
Result is 1.000000
Result is 4.000000
✌
✆
If grouping is not done, i.e. there is no parentheses, then in C, expression is solved from
left to right maintaining the precedence for mathematical operators.
✞
#include <stdio.h>
2
int main () {
4 float a;
6 /* / operator is used thrice.*
*will be solved from L to R.*/
8 a = 20.0 / 10.0 / 2.0;
printf("Result is %fn", a);
10
a = 2.0 / 10.0 / 20.0;
12 printf("Result is %fn", a);
return 0;
14 }
✌
✆
✞
Result is 1.000000
Result is 0.010000
✌
✆
Note that if operators in an expression or in a term of the expression are in same prece-
dence level/order then they all are solved from left to right in the given expression.
✞
#include <stdio.h>
2
int main () {
4 int a;
6 /*Here , /, * and % operators are *
1.4. C OPERATORS 109
*in same precedence order. */
8 a = 2 * 10 / 20 % 5;
printf("Result is %dn", a);
10
a = 2 % 10 * 20 / 5;
12 printf("Result is %dn", a);
return 0;
14 }
✌
✆
✞
Result is 1
Result is 8
✌
✆
Take another example as given below:
✞
#include <stdio.h>
2
int main () {
4 int a = 1, b = 2, c = 3;
printf("%d", c > b > a);
6 return 0;
}
✌
✆
✞
0
✌
✆
In above case, first value of ‘c’ is compared with value of ‘b’ which is false as per expression,
hence the result is ‘0’. Now this value is compared with value of ‘a’ which is again false
as per expression, hence the final result is ‘0’. Now, modify the above example as given
below:
✞
1 #include <stdio.h>
3 int main () {
int a = -1, b = 2, c = 3;
5 printf("%d", c > b > a);
return 0;
7 }
✌
✆
✞
1
✌
✆
Here first value of ‘c’ is compared with value of ‘b’ which is false as per expression,
hence the result is ‘0’. Now this value is compared with value of ‘a’ which is true as per
expression, hence the final result is ‘1’.
1.4.12 Relational Operators
The relation and assignment operators are given in the table 1.16. The level of precedence
of the operators given in table 1.16 are equal, hence, they are solved from left to right in
an expression where they are present. See the following example, in which application of
‘+=’ operator is explained.
110 Basic C
Operator Description
== It accepts two operands and it meant that the operands are
exactly equal.
∗ = Product and equal. Current value of left side is multiply
by right side value and result is assigned to the left side
variable.
/ = Divide and equal. Current value of left side is divided by
right side value and result is assigned to the left side vari-
able.
+ = Add and equal. Current value of left side is added by right
side value and result is assigned to the left side variable.
− = Subtract and equal. Current value of left side is subtracted
by right side value and result is assigned to the left side
variable.
<<= Left shift and equal. It makes left shift to the current value
of the left side variable by the exactly equal places to the
number given in right side. Its operands are either integer
or character only and shall not be precision values.
>>= Right shift and equal. It makes right shift to the current
value of the left side variable by the exactly equal places
to the number given in right side. Its operands are either
integer or character only and shall not be precision values.
& = AND and equal. Perform AND operation between current
value of left hand side variable and right hand side value
and assign the result to left hand side variable.
ˆ= Exclusive OR and equal. Perform Exclusive OR operation
between current value of left hand side variable and right
hand side value and assign the result to left hand side vari-
able.
| = Inclusive OR and equal. Perform Inclusive OR operation
between current value of left hand side variable and right
hand side value and assign the result to left hand side vari-
able.
Table 1.16: Relation & assignment operators.
1.4. C OPERATORS 111
✞
1 #include <stdio.h>
3 int main () {
int y = 1;
5 y += 2;/*It is equal to y = y + 2;*/
printf("y is %dn", y);
7 int z = 1;
z -= 2; /*It is equal to z = z - 2;*/
9 printf("z is %dn", z);
return 0;
11 }
✌
✆
✞
y is 3
z is -1
✌
✆
Following example is for ‘/=’ operator.
✞
#include <stdio.h>
2
int main () {
4 double y = 2.0;
y /= 3.0; /* It is equal to y = y / 3.0; */
6 printf("y is %fn", y);
return 0;
8 }
✌
✆
✞
y is 0.66666
✌
✆
Example of left shift & equal and right shift & equal operators is given below.
✞
1 #include <stdio.h>
3 int main () {
int y = 9;
5 y <<= 2; /*It is equal to y = y << 2;*/
printf("y is %dn", y);
7 int z = 10;
z >>= 2; /*It is equal to z = y >> 2;*/
9 printf("z is %dn", z);
return 0;
11 }
✌
✆
✞
y is 36
z is 2
✌
✆
112 Basic C
1.4.13 Bit Field
A bit field is just a set of neighboring bits within a signed integer or an unsigned integer.
The syntax of the bit field structure is
✞
struct {
2 unsigned int <field name > : <bit size >;
unsigned int <field name > : <bit size >;
4 };
✌
✆
Or
✞
struct {
2 unsigned <field name > : <bit size >;
unsigned <field name > : <bit size >;
4 };
✌
✆
Always remember that, bit size of field declared inside the bit field structure, can not be
larger than the size of field. And unsigned integer is 4 byte long, hence bit size of it can
not be larger than 8 × 4 = 32 bits. A bit field is set up with a structure declaration that
labels each field and determines its width.
✞
struct {
2 unsigned int boldface : 1;
unsigned int slant : 1;
4 } font ;
✌
✆
This structure definition causes ‘font’ to contain two 1-bit fields. We can assigned the
value to these structure field by
✞
font .slant =0;
2 font .boldface =1;
✌
✆
It can be “pad” a field structure with unnamed holes by using unnamed field widths.
Using an unnamed field width of 0 forces the next field to align with the next integer.
✞
struct {
2 unsigned int f1 : 1;
unsigned int : 2;
4 unsigned int f2 : 3;
} field;
✌
✆
Often bit fields are used as a more compact way of storing data.
✞
1 #include <stdio.h>
3 struct employee {
unsigned id : 8;/* Or use unsigned int id :8;*/
5 unsigned sex : 1;/* Or use unsigned int sex :1;*/
unsigned age : 7;/* Or use unsigned int age :7;*/
7 };
1.4. C OPERATORS 113
9 int main () {
struct employee EmpNo;
11 EmpNo.id = 102;
EmpNo.sex = 1;
13 EmpNo.age = 15;
printf("%dt%dt%dn", EmpNo.id , EmpNo.sex , EmpNo.age);
15 return 0;
}
✌
✆
✞
102 1 15
✌
✆
In above example, bits are filed from right to left direction. Here 8 bits are used for id, 1
bit for sex and 7 bit for age. In following example, natural color is made of three prime
colors red, green and blue. To store these colors in program a three bit data storage is
used.
Bit Pattern Decimal Color
000 0 Black
001 1 Red
010 2 Green
011 3 Yellow
100 4 Blue
101 5 Magenta
110 6 Cyan
111 7 White
Table 1.17: Bit color storing.
These colors are used in structure ‘colstr’ and #define is used to create symbolic
constants for the possible member values.
✞
1 #include <stdio.h>
#define BLUE 4
3 #define GREEN 2
#define RED 1
5 /* mixed colors */
#define BLACK 0
7 #define YELLOW (RED | GREEN)
#define MAGENTA (RED | BLUE )
9 #define CYAN (GREEN | BLUE )
#define WHITE (RED | GREEN | BLUE )
11 const char * colors [8] = {"black", "red", "green", "yellow",
"blue ", "magenta", "cyan ", "white"};
13
114 Basic C
struct colstr {
15 unsigned int fill_color : 2;
unsigned int border_color : 4;
17 };
19 void show_colrs (const struct colstr * pb);
21 int main (void ) {
/* create and initialize box_props structure */
23 struct colstr box = {YELLOW , GREEN};
printf("Original box settings :n");
25 show_colrs (& box);
box.fill_color = WHITE;
27 box.border_color = MAGENTA;
printf("nModified box settings :n");
29 show_colrs (& box);
return 0;
31 }
33 void show_colrs (const struct colstr * pb) {
printf("The fill color is %s.n", colors[pb ->fill_color ]);
35 printf("The border color is ");
switch (pb ->border_color ) {
37 case MAGENTA: printf("magenta .n");
break;
39 case RED: printf("red.n");
break;
41 default : printf("unknown color.n");
break;
43 }
}
✌
✆
✞
Original box settings :
The fill color is yellow.
The border color is unknown color.
Modified box settings :
The fill color is yellow.
The border color is magenta .
✌
✆
Size of bit field structure is determined by the number of fields and bit size of the fields.
An unsigned integer is of word size of 4 byte. Hence minimum size of bit field structure is
4 byte. If there are four fields in a bit field structure then first four byte space is allotted
to accommodate total bits of the fields of the bit field structure. If size of bits of all fields
in a bitfield structure is larger than the 4 bytes then next four byte space is added to
accommodate the all bits of fields of the bit field structure. Following examples clarify it
correctly.
✞
1 #include <stdio.h>
1.4. C OPERATORS 115
3 struct bitfield {
/* First four byte (size of int) is allocated . */
5 unsigned int a : 2; //2 bits +
unsigned int b : 2; //2 bits +-> Total 5 bits < 32 bits
7 unsigned int c : 1; //1 bits +
/* Though there are int fields but all*
9 * bits are accomodated in four bytes ,*
* only four byte space is allocated . */
11 };
13 int main () {
struct bitfield bF;
15 printf("Size of bitfield struct is : %d", sizeof (bF));
return 0;
17 }
✌
✆
✞
Size of bitfield struct is : 4
✌
✆
In following example the bit size of variables ‘a’, ‘b’ and ‘c’ are changed to 12, 12 and 1
respectively. Total sum of bits is 25 which is much lesser than 32. Hence size of structure
is 4 byte.
✞
1 #include <stdio.h>
3 struct bitfield {
/* First four byte (size of int) is allocated .*/
5 unsigned int a : 12; //12 bits +
unsigned int b : 12; //12 bits +-> Total 25 bits < 32 bits
7 unsigned int c : 1; // 1 bits +
/* Though there are int fields but all*
9 * bits are accomodated in four bytes ,*
* only four byte space is allocated . */
11 };
13 int main () {
struct bitfield bF;
15 printf("Size of bitfield struct is : %d", sizeof (bF));
return 0;
17 }
✌
✆
✞
Size of bitfield struct is : 4
✌
✆
In following example the bit size of variables ‘a’, ‘b’ and ‘c’ are changed to 12, 12 and 10
respectively. Total sum of bits is 34 which is larger than 32. Hence size of structure is 8
byte.
✞
1 #include <stdio.h>
3 struct bitfield {
/* First four byte (size of int) is allocated . */
116 Basic C
5 unsigned int a : 12; //12 bits +
unsigned int b : 12; //12 bits +-> Total 34 bits > 32 bits
7 unsigned int c : 10; //10 bits +
/* Though there are int fields but all *
9 * bits can not be accommodated in four *
* bytes. Hence extra four bytes space *
11 * is allocated . Here total allocated *
* space is 8 bytes long . Net bitfield *
13 * struct size is 8 bytes long . */
};
15
int main () {
17 struct bitfield bF;
printf("Size of bitfield struct is : %d", sizeof (bF));
19 return 0;
}
✌
✆
✞
Size of bitfield struct is : 8
✌
✆
A field of a bit field struct is assigned a numeric value, it is accepted as binary number.
As the bit field is restricted to specific size, hence number of bits of a number equal to
the size of bit field are taken. Counting of bits of given number is started from right to
left upto the bit size of the bit field. Rest of the bits are truncated. These bits are stored
in the structure memory space allocated previously. The order of storing data in memory
space is from right to left and first field data is stored at right most and subsequent field
data is stored leftword respectively. See following examples for clarification of this para.
✞
1 #include <stdio.h>
3 struct bitfield {
/* Last three bits 001 of binary *
5 * 00000001 are omitted and stored */
unsigned int a : 3;
7 /* Last three bits 100 of binary *
* 00000100 are omitted and stored */
9 unsigned int b : 3;
/* Last three bits 111 of binary *
11 * 00110111 are omitted and stored */
unsigned int c : 3;
13 };
15 int main () {
/* Four byte space is created. */
17 struct bitfield bF;
bF.a = 1; /* Binary equivalent to 00000001 */
19 bF.b = 4; /* Binary equivalent to 00000100 */
bF.c = 55;/* Binary equivalent to 00110111 */
21 printf("Size of bitfield struct is : %dn", sizeof (bF));
printf("Bit field c has value : %dn", bF.c);
23 return 0;
1.4. C OPERATORS 117
}
✌
✆
✞
Size of bitfield struct is : 4
Bit field c has value : 7
✌
✆
In following example, bit size of bit field ‘c’ is changed to 5. Now the stored value in bit
field ‘c’ is different to the data stored in previous example.
✞
#include <stdio.h>
2
struct bitfield {
4 /* Last three bits 001 of binary *
* 00000001 are omitted and stored */
6 unsigned int a : 3;
/* Last three bits 100 of binary *
8 * 00000100 are omitted and stored */
unsigned int b : 3;
10 /* Last five bits 10111 of binary *
* 00110111 are omitted and stored */
12 unsigned int c : 5;
};
14
int main () {
16 struct bitfield bF;
bF.a = 1; /* Binary equivalent to 00000001 */
18 bF.b = 4; /* Binary equivalent to 00000100 */
bF.c = 55;/* Binary equivalent to 00110111 */
20 printf("Size of bitfield struct is : %dn", sizeof (bF));
printf("Bit field c has value : %dn", bF.c);
22 return 0;
}
✌
✆
✞
Size of bitfield struct is : 4
Bit field c has value : 23
✌
✆
In following example, it is try to explain that how bit field data is stored in the memory
with help of pointer. The bitfield data is stored in memory created by struct from left to
right.
✞
#include <stdio.h>
2
struct bitfield {
4 /* Last three bits 001 of binary *
* 00000001 are omitted and stored */
6 unsigned int a : 3;
/* Last three bits 100 of binary *
8 * 00000100 are omitted and stored */
unsigned int b : 3;
10 /* Last five bits 10111 of binary *
* 00110111 are omitted and stored */
118 Basic C
12 unsigned int c : 5;
};
14
int main () {
16 struct bitfield bF;
bF.a = 1; /* Binary equivalent to 00000001 */
18 bF.b = 4; /* Binary equivalent to 00000100 */
bF.c = 55;/* Binary equivalent to 00110111 */
20 /* In memory the structure data *
* is stored as 10111 100 001 *
22 * read data without white spaces */
char *p;
24 p = &bF;
/* In memory the structure data is stored *
26 * as 10111 100 001*[<- pointer is here ] *
* Above read data without white spaces */
28 p++;
/* 101*[<- pointer jumps here ] 11 100 001 */
30 printf("Size of bitfield struct is : %dn", sizeof (bF));
/* Next 8 bit data is read from pointer location . *
32 * Here it is 00000 101 (Binary equivalent to 5 */
printf("Pointer value is : %dn", *p);
34 return 0;
}
✌
✆
✞
Size of bitfield struct is : 4
Pointer value is : 5
✌
✆
Following example is extended form of above example.
✞
#include <stdio.h>
2
struct bitfield {
4 /* Last five bits 00001 of binary *
* 00000001 are omitted and stored */
6 unsigned int a : 5;
/* Last five bits 00100 of binary *
8 * 00000100 are omitted and stored */
unsigned int b : 5;
10 /* Last five bits 10111 of binary *
* 00110111 are omitted and stored */
12 unsigned int c : 5;
};
14
int main () {
16 struct bitfield bF;
bF.a = 1; /* Binary equivalent to 00000001 */
18 bF.b = 4; /* Binary equivalent to 00000100 */
bF.c = 55;/* Binary equivalent to 00110111 */
20 /* In memory the structure data *
* is stored as 10111 00100 00001*/
1.5. PRECEDENCE OF OPERATORS 119
22 char *p;
p = &bF;
24 /* In memory the structure data is stored as *
* 10111 00100 00001*[ < - pointer is here ] *
26 * Above read data without white spaces */
p++;
28 /* 10111 00*[<- pointer jumps here ] 100 00001*
* Above read data without white spaces */
30 printf("Size of bitfield struct is : %dn", sizeof (bF));
/* Next 8 bit data is read from pointer location . *
32 * Here it is 010111 00 (Binary equivalent to 92)*/
printf("Pointer value is : %dn", *p);
34 return 0;
}
✌
✆
✞
Size of bitfield struct is : 4
Pointer value is : 92
✌
✆
Bitwise operators enable us to control the access and manipulation of individual bits of
a flag byte. these operators are very useful in controlling of bits of a flag register. For
example, in 8085 microprocessor, there are Sign, Zero, Reserve, Auxiliary Carry, Reserve,
Parity, Reserve and Carry bits. When all flag are high, then they form binary 11010101,
that is equal to decimal 213. If we want to change Zero bit to low from high, then we do
AND operation with the decimal 149, i.e. binary 10010101. It will change the Zero bit
low keeping other bits high.
✞
11010101 ; decimal 213
2 10010101 ; decimal 149
-------------; AND operator
4 10010101 ; Zero bit is low
✌
✆
1.5 Precedence of Operators
Precedence of operators is order of execution of C operators presence in an expression.
For example, in an expression
y = 5 + 3 − 4%2
We expect the result by addition of 5 + 3 = 8 which gives 8 − 4 = 4. The modulus of 4 by
2 as 4%2 = 0. Hence the final result is zero. But it is not true. Because addition can not
be performed before operation of modulus operator. Subtraction comes at last. It means
the expression can be written as
y = ((5 + 3) − (4%2))
On solving it, the final result is 8.
✞
#include <stdio.h>
2
int main () {
120 Basic C
4 int y;
y = 5 + 3 - 4 % 2;
6 printf("Result is : %dn", y);
return 0;
8 }
✌
✆
✞
Result is : 8
✌
✆
To use the lower order operator before the upper order operator, parentheses are used.
Rewriting above example:
✞
1 #include <stdio.h>
3 int main () {
int y;
5 /*+ operator is put above the %*
*operator by using parentheses .*/
7 y = (5 + 3 - 4) % 2;
printf("Result is : %dn", y);
9 return 0;
}
✌
✆
In this example at first (5 + 3 − 4) is calculated which is 4 and its modulus with 2 is
4%2 = 0. Therefore the output of this example is
✞
Result is : 0
✌
✆
1.5.1 Precedence of Arithmetic Operators
Arithmetic problems are not solved from left to right in the sequence the expression
is written. But some rules are used. For example, parentheses are solved first, then
division, multiplication, addition and subtraction. Thus, arithmetic operators have some
precedence. Operators in order of decreasing precedence are given in table below.
Operators Associativity
() Left to right
+, – (unary) Right to left
*, /, % (modulo) Left to right
+, – (binary) Left to right
= Right to left
Table 1.18: Precedence of arithmetic operators from top to bottom in high to low order.
The precedence of the binary relational operators is less than that of the arithmetic
operators. This means, for example, x > y + 2 is same as x > (y + 2) and x = y > 2
1.5. PRECEDENCE OF OPERATORS 121
is same as x = (y > 2). It means, in an expression, order of evaluation of operators is
arithmetic operators, relational operators and assignment operators respectively.
✞
1 #include <stdio.h>
3 int main () {
int x = 4, y = 1;
5 /*x > y + 2*/
/*x > 1 + 2*/
7 /*x > 3 */
/*4 > 3 (true )*/
9 if (x > y + 2) {
printf("Expression Passed.");
11 } else {
printf("Expression Failed.");
13 }
return 0;
15 }
✌
✆
✞
Expression Passed.
✌
✆
Here is another example.
✞
1 #include <stdio.h>
#include <stdlib.h>
3
int main (int argc , char *argv [ ]) {
5 int y;
/* Order of arithmetic operators *
7 * are /, *, +, -, =. So first 12*
* is divided by 5 and answer is *
9 * 2.4. 6 is multiply by 2.4 and *
* result is 14.4. It is added to*
11 * 20 and 10 is subtracted *
* The answer is 14.4+20 -10=24.4 */
13 y = 6 * 12 / 5 + 20 - 10;
/* In result only 24 is printed. *
15 * Decimal is truncated . */
printf("Expression result is %dn", y);
17 return 0;
}
✌
✆
✞
Expression result is 24
✌
✆
In an expression, if there is a relational operator, then in the decreasing precedence of
operators, the relational operator comes above the assignment operator but below the
arithmetic operators.
✞
1 #include <stdio.h>
#include <stdlib.h>
122 Basic C
3
int main (int argc , char *argv [ ]) {
5 int y;
/* First 6*12 and 5*20 are evaluated .*
7 *6*12 is 72 while 5*20 is 100. Now *
*relation operator < returns true *
9 *as 72 is less than 100. This true *
*value is assigned to variable y. */
11 y = 6 * 12 < 5 * 20;
printf("%dn", y);
13 return 0;
}
✌
✆
✞
1
✌
✆
1.5.2 Precedence of Relational Operators
The operator precedence of relation & unary operators from top to bottom as high to low
order is given below.
Operators Associativity
( ) LR
–, +, ++, – –, sizeof (type), (all unary) RL
*, /, % (modulo) LR
+, – (binary) LR
<, >, <=, >= LR
==, != LR
= RL
From above table, it is seen that parentheses has highest priority among all the re-
lational and unary operators, after that, increment and unary operators. Arithmetic
operators and comparative operators has next. Assignment operator (=) has lowest pri-
ority. See the example below.
✞
1 #include <stdio.h>
3 int main () {
int y=8;
5 /* First % operator is evaluated . As it has *
*highest priority . Next comes + and - and*
7 *in last , += operators . Using this order *
*the result of expression is y = 16. */
9 y += 5 + 3 - 4 % 2;
printf("Result is : %dn", y);
1.5. PRECEDENCE OF OPERATORS 123
11 return 0;
}
✌
✆
✞
Result is : 16
✌
✆
1.5.3 Precedence of All Operators
In the following table, the precedence of all C operators are given. One should memorize
precedence of all operators if possible for quick troubleshooting and optimization of C
codes.
Operators Associativity
++ (postfix), – – (postfix), ( ), [ ], {}, . (dot), -> L-R
++ (prefix), – – (prefix), –, +, ˜, ! R-L
*, /, % (modulo) LR
+, – (both binary) L-R
<<, >> L-R
<, >, <=, >= L-R
==, != L-R
& L-R
ˆ L-R
| L-R
&& L-R
|| L-R
?: (conditional expression) R-L
=, *=, /=, %=, +=, –=, <<=, >>=, &=, |=, ˆ= R-L
, (comma operator) L-R
Table 1.19: Operator precedence of all C operators from top to bottom from high to low
order.
From above table, asterisk (*) has lower preference than square brackets ([ ], also
called array notation). This is why, to define the precedence order, parentheses are used.
Remember that, if comma used in an expression then C evaluates expression from left-
to-right direction, but the commas separating the arguments in a function call are not
comma operators.
124 Basic C
1.5.4 Precedence in Assignment
Precedence order is also obeyed in assigning a value to a variable. In example
✞
1 #include <stdio.h>
3 int main () {
int a;
5 a = 10, 20, 30;
printf("a=%dn", a);
7 a = (10, 20, 30);
printf("a=%dn", a);
9 return 0;
}
✌
✆
in code line
✞
a = 10, 20, 30;
✌
✆
assigned value 10 to variable ‘a’ as ‘=’ has higher precedence over the ,(comma). Similarly
in code line
✞
1 a = (10, 20, 30);
✌
✆
assigned value 30 to variable ‘a’ as parentheses has highest precedence over the ,(comma)
and ‘=’. This is why, the output of above example is
✞
a=10
a=30
✌
✆
1.5.5 Unary & Binary Operators
In C, there are some unary operators and some binary operators. Unary operators require
only one operand, while binary operators need two operands. Now, if there are both,
unary and binary operators in same expression, then evaluation of operators is take place
according their precedence order. To understand it, we take following example
✞
#include <stdio.h>
2 #include <stdlib.h>
4 int main (int argc , char ** argv ) {
int i = 5;
6 int y;
y = ++i * ++i* ++i;
8 printf("Result is %d.", y);
return 0;
10 }
✌
✆
✞
Result is 392.
✌
✆
1.5. PRECEDENCE OF OPERATORS 125
Here, expression y has two operators, one ++ and other product (∗). In precedence order
of operators, increment operator (++) has higher precedence than product operator (∗).
An arithmetic expression is evaluated from left-to-right sequence according the precedence
order of operators. Sequence of evaluation of given expression is shown below:
✞
1 y = ++i * ++i * ++i;
-------------------------------
3 1. y = ++i //i=6
2. y = ++i * //i=6
5 3. y = ++i * ++i //i=7
4. y = 7 * 7 * ++i //i=7
7 5. y = 49 * ++i //i=8
6. y = 49 * 8 = 392
✌
✆
The evaluation is
First Step: + + i is evaluated and it makes i = 6.
Second Step: + + i∗ is not evaluated as product operator (∗) needs two operands
and it has only left side operand. It wait for its right side operands. Value of i has no
change, and it is i = 6.
Third Step: ++i∗++i is evaluated. Right side ++i to product operator makes i = 7.
There are two operands for product operator, hence arithmetic evaluation is performed.
Now, it is 7 ∗ 7 = 49. Remember, left and right side to product operator are variable i
hence both side the updated values are taken for product operation.
Rest of Steps: Now, + + i ∗ + + i ∗ + + i is evaluated. In this step, the expression is
like 49 ∗ + + i. There is of third + + i no effect on + + i ∗ + + i as it is already evaluated.
Therefore, final evaluation is 49 ∗ 8 = 392. This is final answer.
✞
#include <stdio.h>
2 #include <stdlib.h>
4 int main (int argc , char ** argv ) {
int i = 3;
6 int y;
y = ++i * ++i + ++i;
8 printf("Result is %d.", y);
return 0;
10 }
✌
✆
The initial program is now modified as given above. We have replace last product operator
with sum operator in the expression. The output of above program is
✞
Result is 31.
✌
✆
Here ++ has higher precedence than product operator (∗). Product operator has
higher precedence than sum operator (+). Product and sum operators are evaluated, after
their left and right operand’s evaluation. Steps of evaluation of arithmetic expression of
above program is given below:
126 Basic C
✞
1 /* * has higher precedence than + */
y = ++i * ++i + ++i;
3 ---------------------------------------
1. y = ++i //i=4
5 2. y = ++i * //i=4
3. y = ++i * ++i //i=5
7 4. y = 5 * 5 + ++i //i=6;
//On evaluation , product operator has
9 // higher precedence than sum operator
5. y = 25 + ++i //i=6
11 6. y = 25 + 6 = 31
✌
✆
Again, take the same program with modifications as given below. We have replace first
product operator with sum operator in the expression.
✞
1 #include <stdio.h>
#include <stdlib.h>
3
int main (int argc , char ** argv ) {
5 int i = 3;
int y;
7 y = ++i + ++i * ++i;
printf("Result is %d.", y);
9 return 0;
}
✌
✆
The output of above program is
✞
Result is 42.
✌
✆
It has different result than previous program. The evaluation of program is started
from left to right. Sum operator does not evaluated until product operator is not evaluated
due to precedence order. Steps of evaluation of expression of above program is given below:
✞
1 /* * has higher precedence than + */
y = ++i + ++i * ++i;
3 --------------------------------------
1. y = ++i //i=4
5 2. y = ++i + //i=4
3. y = ++i + ++i //i=5;
7 /* Wait for Evaluation , product operator *
* has higher precedence than sum operator */
9 4. y = ++i + ++i * ++i //i=6
5. y = ++i + 6 * 6 //i=6, use and increment
11 6. y = 6 + 36 = 42
✌
✆
1.5.6 Associativity
The associativity of an operator is a property that determines how operators of the same
precedence are grouped in the absence of parentheses. Operators may be associative, left-
1.6. CONDITIONS 127
associative, right-associative or non-associative. The associativity and precedence of an
operator is a part of the definition of the programming language; different programming
languages may have different associativity and precedence for the same type of operator.
For example, aˆbˆc has left associativity as the expression is solved from left to right and
a=b=c to be interpreted as a=(b=c) and it has right associativity where both ‘a’ and ‘b’
to the value of ‘c’. A chained comparison like a<b<c is interpreted as (a<b) and (b<c),
it is not equivalent to either (a<b)<c or a<(b<c). It is called non-associativity.
1.6 Conditions
Conditions are the comparison statements those controls the execution of codes inside
the conditional blocks.
1.6.1 If Condition
if () provides a way to instruct the program to execute a block of code only if certain
conditions have been met, i.e. conditions given true result. In if condition of C language,
true is represented by ‘1’. The syntax of if () construct is
✞
1 if(/* conditions */) // if condition is true then
statement // execute the condition .
✌
✆
✞
#include <stdio.h>
2
int main () {
4 int b = 2, c = 3;
if (c > b) {
6 printf("True -%dn", c > b); // true case
} else {
8 printf("False -%dn", c > b); // false case
}
10 return 0;
}
✌
✆
✞
True -1
✌
✆
Note that, the equal comparison in C is ‘==’ and not ‘=’. The later symbol is assignment
operator that assigns the its right side value to left side variable and if assignment is
successful, it returns true. See the following simple example:
✞
1 #include <stdio.h>
3 int main () {
int i = 10;
5 int j = 20;
7 /* In if statement , there is assignment not *
* comparison . This is why , if has true state.*/
128 Basic C
9 if (i = j)
printf("Is i equal to j?n"); // Printed.
11
/* Exact comparison . */
13 if (i == j)
printf("i is perfectly equal to j.n"); // Printed.
15 }
✌
✆
✞
Is i equal to j?
i is perfectly equal to j.
✌
✆
1.6.2 If-else Condition
if-else provides a way to instruct the program to execute a block of code only if certain
conditions have been met otherwise execute other block. All the conditions, except than
certain one defined for if, are true for else statement. This is why else has infinite numbers
of true conditions. The syntax of if-else construct is
✞
if(/* conditions */) // if condition is true then
2 statement one // execute the statement one.
else // otherwise if condition is false
4 statement two // execute the statement two.
✌
✆
A simple example is
✞
#include <stdio.h>
2
int main () {
4 int i = 10;
int j = 20;
6 if (i == j)
printf("i is perfectly equal to j.n");
8 else
printf("i is not perfectly equal to j.n");
10 }
✌
✆
If number of lines in a statement is more than one then these lines should be grouped
together by using curly braces i.e. { ..multi line statements.. }.
✞
#include <stdio.h>
2
int main () {
4 int i = 10;
int j = 20;
6 if (i == j){// Grouping by bracing for if condition
printf("i is perfectly equal to j.n");// Line No. 1
8 printf("Conditions are met.n");// Line No. 2
}else // Single line else condition is not braced here
10 printf("i is not perfectly equal to j.n");
1.6. CONDITIONS 129
}
✌
✆
A short hand for of if-else condition is
✞
1 int a=(b > c) ? d : e;
✌
✆
Above statement is similar to the statement of “return d if b is greater than c else return
e”. if - else - if - else - if - else statement can be used successively. See the simple
example as given below:
✞
1 #include <stdio.h>
3 int main () {
int i = 10;
5 int j = 20;
if (i == j)
7 printf("i is perfectly equal to j.n");
else if (i > j)
9 printf("i is greater than j.n");
else if (i < j)
11 printf("i is lesser than j.n"); // Printed .
else
13 printf("i is not equal to j.n");
return 0;
15 }
✌
✆
✞
i is lesser than j.
✌
✆
1.6.3 If-else-if Case
Two if () conditions can be linked by else keyword. If-Else-If provides a way to instruct
the program to execute a block of code only if certain conditions have been met otherwise
execute other block conditionally. All the conditions, except than certain ones defined
for the first if, are true for else if statement. This is why, else if has infinite numbers of
true conditions. These infinite numbers of conditions are again checked for if statement
and the corresponding block is executed if certain conditions are met, otherwise these
conditions are skipped to next else if statement. The syntax of the linked if conditions
is
✞
1 if(/* condition 1*/)
<expressions 1>
3 else if(/* condition 2*/)
<expressions 2>
5 else if(/* condition 2*/)
<expressions 3>
✌
✆
There may be end of this condition by else keyword or not. The example is
130 Basic C
✞
#include <stdio.h>
2
void main () {
4 int i, j;
i = 10;
6 j = 20;
if (i == 10) {// print it
8 printf("i is %dn", i);
} else if (j == 20) {
10 printf("j is %dn", j);
}
12 }
✌
✆
✞
i is 10
✌
✆
Above example is modified so that the conditions are true for else if statement.
✞
1 #include <stdio.h>
3 void main () {
int i, j;
5 i = 11; // value is changed from 10 to 11
j = 20;
7 if (i == 10) {// skip to next else -if
printf("i is %dn", i);
9 } else if (j == 20) { // print it
printf("j is %dn", j);
11 }
}
✌
✆
✞
j is 20
✌
✆
Above example is modified as shown below so that comparative conditions are neither
true for if () conditions or for else if condition. The program skips to both if () and else
if () and prints nothing in output console.
✞
1 #include <stdio.h>
3 void main () {
int i, j;
5 i = 11; // value is changed from 10 to 11
j = 21; // value is changed from 20 to 21
7 if (i == 10) {// skip to next else -if
printf("i is %dn", i);
9 } else if (j == 20) { // skip to next else -if
printf("j is %dn", j);
11 }
}
✌
✆
1.6. CONDITIONS 131
✞
✌
✆
See the example below:
✞
1 #include <stdio.h>
3 int main (int argc , char *argv []) {
int i = 10;
5 if (i == 10) { // First if case
printf("1 : %dn", i);
7 }
if (i == 11) { // Second if case
9 printf("2 : %dn", i);
} else { // Corresponding else to second if
11 printf("3 : %dn", i);
}
13 return 0;
}
✌
✆
It result is
✞
1 : 10
3 : 10
✌
✆
There is only one true condition in the above program for variable ‘i’ but result
obtained twice. The reason is that the compiler checks the condition for first if case,
which is true and the result is obtained. Now the compiler checks the condition for
second if statement, which is false and the control is transferred to corresponding else
statement and program gives result again. If above program is rewritten as
✞
#include <stdio.h>
2
int main (int argc , char *argv []) {
4 int i = 10;
if (i == 10) { // First if case , here true
6 printf("1 : %dn", i);
} else if (i == 11) { //on false , second if case
8 printf("2 : %dn", i);
} else { // Corresponding else to second if
10 printf("3 : %dn", i);
}
12 return 0;
}
✌
✆
The result is
✞
1 : 10
✌
✆
Here from first if statement is true hence corresponding else-if statement is skipped
by the compiler and there is only one result.
132 Basic C
1.6.4 Switch & Case
Use of a long chain as if-else-if-else-if-else-if-else is very complex and less readable.
There’s a solution to it and we may use switch & case construct. A switch statement
is similar to if statement except that switch accepts single argument and compare it
with a range of defined values. It executes the block of statements for which case is
matched. if case is fixed executes only single block of statements. The basic syntax of
this construction is given below.
✞
1 switch (<case variable >) {
case 1:
3 <first statements >
break;
5 case 2:
<second statements >
7 break;
case 3:
9 <third statements >
break;
11 default :
<default statements >
13 break;
}
✌
✆
Here default case is executed if none of the cases is matched with case variable value. If
switch statement has one case or default case then it behaves like if statement.
✞
switch (<case variable >) {
2 case 1:
<first statements >
4 break;
} /*if like */
✌
✆
Or
✞
1 switch (<case variable >) {
default :
3 <default statements >
break;
5 } /*if like */
✌
✆
Note that, the switch parameter takes only integer or character type values. It can not
be used with float type switch parameter. Following is working example
✞
1 #include <stdio.h> /* fprintf */
#include <stdlib.h> /* malloc , free , exit */
3
int grade;
5
int main (void ) {
7 printf("Enter the grade : "); // get the switch case value
1.6. CONDITIONS 133
scanf("%d", &grade); // recognise the supplied variable .
9
switch (grade) {
11 case 1:
printf("An");
13 break;
case 2:
15 printf("Bn");
break;
17 case 3:
printf("Cn");
19 break;
case 4:
21 printf("Dn");
break;
23 default : // if none of the above cases are matched.
printf("Fn");
25 break;
}
27 /* Exiting program */
exit ( EXIT_SUCCESS );
29 }
✌
✆
When program is run and input 1 is supplied, the output is
✞
A
✌
✆
Here operator ‘break’ plays an important role. If break operator is not used in block
of ‘case’ then all the successive blocks are executed successively. The reason behind is
that, ‘break’ inside the ‘case’ exits from the switch block from the current loop.
✞
1 #include <stdio.h>
3 int main () {
int i = 0;
5 switch (i) {
/* for first loop , i=0.*
7 * Case 0 is executed . */
case 0:i += 2;
9 /* No following break operator . Switch*
* passes to the next case . Here i = 2*/
11 case 1:i += 2;
/* No following break operator . Switch*
13 * passes to the next case . Here i=4. */
case 5:i += 2;
15 /* No following break operator . Switch*
* passes to the next case . Here i=6.*/
17 default :
i += 2; /* Here i=8.*/
19 break; /* Exit the switch */
}
134 Basic C
21 /* Print the 8*/
printf("%dt", i);
23 return 0;
}
✌
✆
✞
8
✌
✆
Now, the break operator is inserted after case 1 in above example. The result is different
from the above example. It is so, because break operator let the exit of switch when case
is matched.
✞
1 #include <stdio.h>
3 int main () {
int i = 0;
5 switch (i) {
/* for first loop , i=0.*
7 * Case 0 is executed . */
case 0:i += 2;
9 /* No following break operator . Switch*
* passes to the next case . Here i = 2*/
11 case 1:i += 2;
/* break operator exit switch *
13 * from current loop . Here i=4*/
break;
15 case 5:i += 2; /* Never executed .*/
default :/* Never executed .*/
17 i += 2;
break;
19 }
/* Print the 4*/
21 printf("%dt", i);
return 0;
23 }
✌
✆
✞
4
✌
✆
For a given switch more than one similar case conditions can not be allowed. For example:
✞
1 switch (v){
case 0 : break;
3 case 1 : break;
case 0 : break; // Error!! case 0 is redefine
5 }
✌
✆
returns the compile time error as case ‘0’ is defined twice.
1.6. CONDITIONS 135
1.6.5 Goto Keyword
It is a jump operator. It transfers control unconditionally to another part of a program.
The statement used for goto operator is given below:
✞
1 goto <identifier >;
✌
✆
The identifier must be a label followed by a colon and statement. C language has a unary
&& operator that returns the address of a label. This address can be stored in a void*
variable type and may be used later in a goto instruction.
✞
1 void *ptr = && JUMP1;
3 JUMP1: printf("hi ");
goto *ptr;
✌
✆
✞
#include <stdio.h>
2 #include <stdlib.h>
4 int main (void ) {
int i = 0;
6 LOOP :
if (i == 100) {
8 exit (0);
}
10 while (i < 100) {
i++;
12 if (i % 2 == 0)
goto JUMP1;
14 else
goto JUMP2;
16 }
18 JUMP1:
printf("%d is Even Numbern", i);
20 goto LOOP ;
22 JUMP2:
printf("%d is Odd Numbern", i);
24 goto LOOP ;
return EXIT_SUCCESS ;
26 }
✌
✆
1.6.6 Break Keyword
break keyword is used to break a loop or continuous operation. It is always used within
loop and its use outside the loop cause compile time error.
✞
#include <stdio.h>
2
136 Basic C
int ix;
4 int main (void ) {
for (ix = 1; ix <= 10; ix ++) {
6 /* First hello , world!*/
printf("%d Hello , world!", ix);
8 break;
}
10 return 0;
}
✌
✆
The output of above program is
✞
1 Hello , world!
✌
✆
In above example, loop is iterated only once. During the first loop of for block, break
stops the further execution of for loop. In a simple program we can use blank line for
offset to make the programming code readable.
1.7 Iteration
Iteration is a process in which code statements are executed more than once. For example,
to print a line ten times, either the line is written ten times one after another or a loop
is used to print the line ten times. Most common iteration/loop functions are for and
while.
1.7.1 For Loop
The syntax of for loop is
✞
1 for(initialization ; test ; increment ) {
/* code */
3 }
✌
✆
The function for, first initializes the variable and then conditions are checked according
the ‘test’. If initialized value of the variable passed the ‘test’, expressions or codes in-
side the function body are executed. After each successful execution of loop, variable is
incremented according the relation of ‘increment’. See example given below:
✞
1 #include <stdio.h>
3 main (void ) {
int a, b;
5 b = 15;
for (a = 10; a < b; a++) {
7 printf("The number a is %d.n", a);
}
9 }
✌
✆
The output is
1.7. ITERATION 137
✞
The number a is 10.
The number a is 11.
The number a is 12.
The number a is 13.
The number a is 14.
✌
✆
The declaration cum initialization of variable inside the for parentheses is allowed
only in C99 or C11 standards. All C standards older than C99 need pre-declaration of
variable before they are initialized inside for parentheses.
✞
1 for(int initialization ; test ; increment ) {
/* code */
3 }
✌
✆
Example of above for syntax is given below:
✞
1 #include <stdio.h>
3 main (void ) {
int b = 15;
5 for (int a = 10; a < b; a++) {/* C99 & C11 Standards .*/
printf("The number a is %d.n", a);
7 }
}
✌
✆
The value of variable may also be changed from the function body. See example below:
✞
#include <stdio.h>
2
int main () {
4 int i;
for (i = 1; i < 10; i += 2) {
6 if (i == 3)
i--;
8 printf("%d, ", i);
}
10 return 0;
}
✌
✆
✞
1, 2, 4, 6, 8,
✌
✆
The initialization statement is executed exactly once. It is used to assign an initial value
to some variable. The test expression is evaluated each time before the code in the for
loop executes. If this expression evaluates as 0 (false), the loop is not (re)enter into the
for loop. And execution of program carry on to the code immediately following the for
loop. If the expression is non-zero (ie true), the loop is (re)enter inside the for loop.
After each iteration of the loop, the increment statement is executed. In last iteration,
required conditions are not satisfied and loop exits after execution of increment. This is
often used to increment the loop index.
138 Basic C
✞
1 #include <stdio.h>
3 int main (int argc , char ** argv ) {
int i;
5 for (i=0;i<5;i++); // only increment index , i=5
printf("i is %d.", i);
7 return 0;
}
✌
✆
✞
i is 5.
✌
✆
An infinite loop is executed if for is defined as shown below.
✞
1 for (;;) {
/* statements / codes */
3 }
✌
✆
Multiple initialization can be used by separating them by comma.
✞
1 for(initialization one , /* First var initialized */
initialization two; /* Second var initialized */
3 test of initializers ;/* Test the condition of variables */
increment one , /* Increment of first variable */
5 increment two) { /* Increment of second variable */
7 /* expressions / statements / codes */
9 }
✌
✆
✞
1 #include <stdio.h>
#include <stdlib.h>
3
int main (void ) {
5 int i, j;
for (i = 1, /* First var initialized */
7 j = 2; /* Second var initialized */
i < 5, /* Test first variable */
9 /* Here comma mean OR */
j < 11;/* Test second variable */
11 i++, /* Increment of first variable */
j = j + 2) /* Increment of second variable */{
13 printf("Product of i=%d & j=%d is %dn", i, j, i * j);
}
15 return 0;
}
✌
✆
✞
Product of i=1 & j=2 is 2
Product of i=2 & j=4 is 8
Product of i=3 & j=6 is 18
1.7. ITERATION 139
Product of i=4 & j=8 is 32
Product of i=5 & j=10 is 50
✌
✆
✞
1 #include <stdio.h>
#include <stdlib.h>
3
int main (void ) {
5 int i, j;
for (i = 1, /* First var initialized */
7 j = 2; /* Second var initialized */
i < 5 /* Test first variable */
9 && /* AND test for i and j*/
j < 11; /* Test second variable */
11 i++, /* Increment of first variable */
j = j + 2)/* Increment of second variable */{
13 printf("Product of i=%d & j=%d is %dn", i, j, i * j);
}
15 return 0;
}
✌
✆
✞
Product of i=1 & j=2 is 2
Product of i=2 & j=4 is 8
Product of i=3 & j=6 is 18
Product of i=4 & j=8 is 32
✌
✆
An example containing the conditional for is
✞
#include <stdio.h>
2
main (void ) {
4 int a, b;
a = 10, b = 15;
6 for (a = 10; a < 30 && b != a; a++) {
printf("The number a is %d.n", a);
8 }
}
✌
✆
The output is
✞
The number a is 10.
The number a is 11.
The number a is 12.
The number a is 13.
The number a is 14.
✌
✆
There is an example of finding prime numbers by using for loops.
✞
1 /* For the square root function sqrt () */
#include <math .h>
3 #include <stdio.h>
140 Basic C
5 int is_prime (int n);
7 int main () {
/* Enter a number. Only integer.*/
9 printf("Write an integer : ");
/* Scan the integer.*/
11 int var;
scanf("%d", &var);
13 /* Defining output */
if (is_prime (var) == 1) {
15 printf("A primen");
} else {
17 printf("Not a primen");
}
19 return 1;
}
21
int is_prime (int n) {
23 int x;
int sq = sqrt (n) + 1;
25 /* Checking the trivial cases first*/
if (n < 2)
27 return 0;
if (n == 2 || n == 3)
29 return 1;
/* Check whether n is divisible by 2 or is an*
31 *odd number between 3 and square root of n.*/
if (n % 2 == 0)
33 return 0;
for (x = 3; x <= sq; x += 2) {
35 if (n % x == 0)
return 0;
37 }
39 return 1;
}
✌
✆
✞
Write an integer: 12
Not a prime
✌
✆
Variables used in for control function, can also be assigned a character code if a character
is enclosed inside single quote. In following example, 26 English characters in lower case
form are printed by using for loop.
✞
#include <stdio.h>
2
int main (void ) {
4 int i;
printf("26 english letters : n");
6 for (i = ’a’; i < (’a’ + 26); i++) {
1.7. ITERATION 141
printf("%3d = %c,t", i, i);
8 if ((i - ’a’ + 1) % 5 == 0)
printf("n");
10 }
return 0;
12 }
✌
✆
✞
97 = a, 98 = b, 99 = c, 100 = d, 101 = e,
102 = f, 103 = g, 104 = h, 105 = i, 106 = j,
107 = k, 108 = l, 109 = m, 110 = n, 111 = o,
112 = p, 113 = q, 114 = r, 115 = s, 116 = t,
117 = u, 118 = v, 119 = w, 120 = x, 121 = y,
122 = z,
✌
✆
1.7.2 While Loop
A while() loop is the most basic type of loop. It will run as long as the condition returns
non-zero (ie true) value. At false state, while loop exits.
✞
#include <stdio.h>
2 #include <string.h>
#include <stdlib.h>
4 int a = 1;
6 int main (void ) {
/* Loops until the break statement in the loop is executed */
8 while (42) {
printf(":-> a is %d n", a);
10 a = a * 2;
if (a > 100) {
12 break;
} else if (a == 64) {
14 /* Immediately restarts at while , skips next step */
continue ;
16 }
printf(":-> a is NOT 64n");
18 }
exit ( EXIT_SUCCESS );
20 }
✌
✆
✞
:-> a is 1
:-> a is NOT 16
:-> a is 2
:-> a is NOT 16
:-> a is 4
:-> a is NOT 16
:-> a is 8
:-> a is 16
✌
✆
142 Basic C
1.7.3 For As While
The syntax of for loop as
✞
for(; <test > ; )
✌
✆
is similar to the while loop
✞
1 while (<test >)
✌
✆
Following is an example which shows that for loop is similar to the while loop.
✞
1 #include <stdio.h>
3 int main () {
int i = 0;
5 for (; i < 5;) {
printf("%dt", i);
7 i++;
}
9 printf("n");
int j = 0;
11 while (j < 5) {
printf("%dt", j);
13 j++;
}
15 printf("n");
return 0;
17 }
✌
✆
✞
0 1 2 3 4
0 1 2 3 4
✌
✆
1.7.4 Do While
do-while loop is similar to the while loop except at least one loop is executed before the
conditional test is checked. So while loop is used where execution of loops is required
after test and do-while loop is used where at least one loop is must before conditional
check. This loop has syntax like
✞
do{
2 <loop body >
}while(<conditional check >)
✌
✆
The comparative example of while and do-while loops is given below:
✞
1 #include <stdio.h>
3 int main (void ) {
/*do - while loop */
1.8. STRINGS 143
5 int i = 0;
printf("Do -while Loop : n");
7 do {/* One output loop */
printf("i = %dn", i);
9 i++;
} while (i < 0);
11 /* while loop */
i = 0;
13 printf("nWhile Loop : n");
while (i < 0) {/*No outputs */
15 printf("i = %dn", i);
i++;
17 }
return 0;
19 }
✌
✆
✞
Do -while Loop :
i = 0
While Loop :
✌
✆
1.8 Strings
The string constant “x” is not the same as the character constant i.e. ‘x’. One difference
is that ‘x’ is a basic type (char), but “x” is a derived type, an array of char. A second
difference is that “x” really consists of two characters, ‘x’ and ‘0’, the null character.
✞
1 char ch=’x’; // valid assignment
char str [2]= "x"; // valid assignment
✌
✆
x
ch x 0
str
Again, a chacter inside the single quote is integer type while same character inside double
quote is of char * type. It is implementation method that whether string variable may
or may not be assigned single quote strings.
✞
char str [2]= ’x’; // Valid assignment with warning as ’x’ is int type
2 char *str =’x’ // Valid assignment with warning as ’x’ is int type
✌
✆
String with single quote has special meaning. See the example given below:
✞
#include <stdio.h>
2
int main () {
4 char *ch=’1234 ’;
printf("%d",ch);
144 Basic C
6 return 0;
}
✌
✆
✞
825373492
✌
✆
Here, each character is converted into its equivalent char code and then char codes are
placed in sequential memory bytes. Note that there is no null terminator, hence there is
no end of this string. Compiler will reach beyond the limit of string when read it. So,
when we dereference this string variable as string, error of segmentation fault is returned
by the compiler. Again, when we dereference the string variable as integer, it returns
the decimal number created from first four memory bytes started from the address of
string variable. A string in C is merely an array of characters. The length of a string
is determined by a terminating null character: ‘0’. So, a string with the contents, say,
“abc” has four characters: ‘a’, ‘b’, ‘c’, and the terminating null character ‘0’.
✞
1 char str [4]= "abc";
✌
✆
a b c 0
str
In C, string constants (literals) are surrounded by double quotes (“...”), e.g. “Hello
world!” and are compiled to an array of the specified char values with an additional null
terminating character (0-valued) code to mark the end of the string. Note that, if the
size of character array is larger than the size of string stored, the remaining bytes after
null terminator are part of the array but not the part of string.
✞
1 char str [7]= "abc";
✌
✆
a b c 0 ? ? ?
str
The type of a string constant is char *. String literals may not directly in the source
code contain embedded newlines or other control characters, or some other characters of
special meaning in string. To include such characters in a string, the backslash escapes
may be used, like this:
1.8. STRINGS 145
Escape Meaning
 Literal backslash
" Double quote
’ Single quote
n Newline (line feed)
r Carriage return
b Backspace
t Horizontal tab
f Form feed
a Alert (bell)
v Vertical tab
? Question mark (used to escape trigraphs)
nnn Character with octal value nnn
xhh Character with hexadecimal value hh
Table 1.20: Escape characters in C.
A simple example is
✞
1 #include <stdio.h>
3 int main () {
int i;
5 while (i < 10) {
printf("%i.nav",i);
7 i++;
}
9 return (0);
}
✌
✆
An equivalent hexadecimal value of a charcode as hexadecimal escape character format
(xhh) can be put in the output console of C by using printf function.
✞
#include <stdio.h>
2
int main (void ) {
4 char *s = "x41x42x54";
printf("s = %sn", s);
6 return 0;
}
✌
✆
✞
s = ABT
✌
✆
146 Basic C
Multi-bytes hexadecimal character string can be assigned to a char type variable by using
‘wchar t’ keyword. The value assigned to the variable must be preceded with character
‘L’ as shown in the following example.
✞
1 #include <stdio.h>
#include <wchar.h>
3
int main (void ) {
5 wchar_t *s = L"x4142x4344";
printf("s = %sn", s);
7 return 0;
}
✌
✆
✞
s = BADC
✌
✆
1.8.1 Character Encoding
char and wchar t are not specified in the C standards. Except that the value ‘0×00’ and
‘0×0000’ specify the end of the string and not a character. Input and output codes are
directly affected by the character encoding. Other code should not be too affected. The
editor should also be able to handle the encoding if strings shall be able to written in the
source code. There are three major types of encoding:
1. One byte per character. Normally based on ASCII. There is a limit of 255 different
characters plus the zero termination character.
2. Variable length character strings, which allows many more than 255 different char-
acters. Such strings are written as normal char-based arrays. These encoding are
normally ASCII-based and examples are UTF-8 or Shift JIS.
1.8.2 String Literal In Expression
When a string appears in an expression it is considered as a pointer and indices or
indirection rules can be applied on it. See the example given below:
✞
1 #include <stdio.h>
3 int main (int argc , char ** argv ) {
printf("%dn", "xyz"); // pointer
5 printf("%dn", *"xyz"); // pointer to characters
printf("%dn", ("xyz"[1] + 1)); // sum of ’y’ and 1
7 return 0;
}
✌
✆
✞
4202528
120
122
✌
✆
1.8. STRINGS 147
In first case, string literal represents to a pointer and return the address to which this
string literal is pointing. In second and third case, string literals are converted into
“pointer to character”, therefore it returns the value of first character of what it points,
i.e. ‘x’. In third case, sum of char value of character at indices 1 (i.e. ‘y’), and one is
returned.
1.8.3 String Functions
The nine most commonly used functions in the string library are
strcat
This function concatenate the string source object with destination object. The size of
destination object shall be sufficiently large to hold all the supplied strings from source
object. If size of string variable is deficient to space, an overflow error occurs. The
synopsis of the strcat function is
✞
1 char *strcat(char * restrict s1 , const char * restrict s2);
✌
✆
strcat(str1, str2)
a b c 0
str1
A B C 0
str2
After catenation of the strings, ‘str1’ variable points to the strings as shown below:
a b c A B C 0
str1
It is recommended that strncat() or strlcat() should be used instead of strcat(), in
order to avoid buffer overflow. A simple example is
✞
1 #include <stdio.h>
#include <string.h>
3
int main () {
5 /* initialize a char variable */
char str [80];
7 /* copy string The to variable .*/
strcpy(str , "The ");
9 /* concate the string India with The */
strcat(str , "India ");
11 strcat(str , "is ");
strcat(str , "developing .");
148 Basic C
13 /* put output at the console */
puts (str);
15 return 0;
}
✌
✆
✞
The India is developing .
✌
✆
strchr
The synopsis of the strchr function is
✞
1 char *strchr(const char *s, int c);
✌
✆
The strchr() function shall locate the first occurrence of ‘c’ (converted to a char) in the
string pointed-by ‘s’. A simple example is
✞
1 #include <stdio.h>
#include <string.h>
3
int main () {
5 char str[ ] = "This is my country ";
char * pch;
7 printf("Geting char s in "%s". n", str);
pch = strchr(str , ’s’);
9 while (pch != NULL ) {
printf("’s’ char is at position %dn", pch - str + 1);
11 pch = strchr(pch + 1, ’s’);
}
13 return 0;
}
✌
✆
✞
Geting char s in "This is my country ".
’s’ char is at position 4
’s’ char is at position 7
✌
✆
strcmp
The strcmp synopsis is
✞
1 int strcmp(const char *s1 , const char *s2);
✌
✆
A rudimentary form of string comparison is done with the strcmp() function. It takes
two strings as arguments and returns a negative value if the first is lexographically less
than the second, a value greater than zero if the first is lexographically greater than the
second, or zero if the two strings are equal. The comparison is done by comparing the
coded (ascii) value of the characters in character-by-character manner. A simple example
is
1.8. STRINGS 149
✞
1 #include <stdio.h>
#include <string.h>
3
int main () {
5 char Key[ ] = "apple";
char Input [80];
7 do {
printf("Guess my favourite fruit? ");
9 gets (Input);
} while (strcmp(Key , Input) != 0);
11 puts ("Correct answer!");
return 0;
13 }
✌
✆
✞
Guess my favourite fruit? apple
Correct answer!
✌
✆
This is another example in which two strings are compared without using strcmp() func-
tion.
✞
#include <stdio.h>
2
int Compare_Main_Sub (char *, char *);
4
int main () {
6 char MainStr [100] , SubStr [100] , CnF;
8 printf("Enter Main string : n");
gets ( MainStr);
10
printf("Enter Sub string : n");
12 gets ( SubStr);
14 CnF = Compare_Main_Sub (MainStr , SubStr);
16 if (CnF == 0)
printf("Both strings are same .n");
18 else
printf("Entered strings are not equal.n");
20
return 0;
22 }
24 int Compare_Main_Sub (char *MainStr , char *SubStr) {
while (* MainStr == * SubStr) {
26 if (* MainStr == ’0’ || *SubStr == ’0’)
break;
28
MainStr ++;
30 SubStr ++;
150 Basic C
}
32 if (* MainStr == ’0 ’ && *SubStr == ’0’)
return 0;
34 else
return -1;
36 }
✌
✆
✞
Enter Main string : a
Enter Sub string : a
Both strings are same .
✌
✆
C has no dedicated boolean procedure. Hence in string comparison, return value is 0 on
true and other value on false. In case of != comparison C fails to check condition. See
example
✞
1 #include <stdio.h>
3 int main () {
char c[2];
5 printf("Type ’e’ for encrypt & ’d’ for decrypt : ");
scanf("%s", c);
7 if (strcmp(c, "e") != 0 || strcmp(c, "d") != 0) {
printf("Unknown procedure .n");
9 }
return 0;
11 }
✌
✆
✞
Type ’e’ for encrypt & ’d’ for decrypt : f
Unknown procedure .
✌
✆
✞
Type ’e’ for encrypt & ’d’ for decrypt : e
Unknown procedure .
✌
✆
In these type of problems, try to use the false statement.
✞
#include <stdio.h>
2
int main () {
4 char c[2];
printf("Type ’e’ for encrypt & ’d’ for decrypt : ");
6 scanf("%s", c);
if (strcmp(c, "e") == 0 || strcmp(c, "d") == 0) {
8 } else {
printf("Unknown procedure .n");
10 }
return 0;
12 }
✌
✆
1.8. STRINGS 151
✞
Type ’e’ for encrypt & ’d’ for decrypt : e
✌
✆
✞
Type ’e’ for encrypt & ’d’ for decrypt : f
Unknown procedure .
✌
✆
strcpy
This function copies the string from source into destination. The size of the destination
object shall be sufficiently large to hold the source string. If size of destination object is
deficient of space, an overflow error occurs. The syntax of strcpy() is
✞
char *strcpy(char *restrict dest , 
2 const char *restrict src);
✌
✆
Note, source of strcpy should be string. It is recommended that strncpy() should be used
instead of strcpy(), to avoid buffer overflow. A simple example is
✞
#include <stdio.h>
2 #include <string.h>
4 int main () {
/* initialize a char variable */
6 char str [80];
/* copy string The to variable .*/
8 strcpy(str , "The ");
/* concate the string India with The */
10 strcat(str , "India ");
strcat(str , "is ");
12 strcat(str , "developing .");
/* put output at the console */
14 puts (str);
return 0;
16 }
✌
✆
✞
The India is developing .
✌
✆
An example which copies the contents of one array into other array without using strcpy()
function is given below. In this example, one by one character of array ‘strA’ are copied
into array ‘strB’. When array ‘strA’ encounters the null character, copying is halted.
✞
1 #include <stdio.h>
3 int main () {
char strA [50], strB [50];
5 int i;
printf("nEnter string s1: ");
7 scanf("%s", strA );
/* Copy one by one character into strB .*/
152 Basic C
9 for (i = 0; strA [i] != ’0’; i++) {
strB [i] = strA [i];
11 }
/* Add null character to strB at the end.*/
13 strB [i] = ’0’;
printf("nString s2: %s", strB );
15 return 0;
}
✌
✆
Following is a strcpy() example that is used to trim the white spaces from the left and
right hand side of a string.
✞
#include <stdio.h>
2 #include <string.h>
#include <ctype.h>
4
/* Trimming leading and trailing white spaces. */
6 char *trim (char * s) {
/* Initialize start , end pointers */
8 char *s1 = s, *s2 = &s[strlen(s) - 1];
10 /* If last char is a white space and there*
* is a previous char that is also a white*
12 * space then reduce the pointer by one *
* for each white space. */
14 while (( isspace (*s2)) && (s2 >= s1))
s2 --;
16 /* Finally we find the pointer value for *
* last character other than a white space.*/
18
/* Add end of line . */
20 *(s2 + 1) = ’0’;
22 /* If first char is a white space and there*
* is next char that is also a white space *
24 * then increase the pointer position by *
* one for each white space. */
26 while (( isspace (*s1)) && (s1 < s2))
s1 ++;
28
/* Copy rest of string to s */
30 strcpy(s, s1);
return s;
32 }
34 int main (int argc , char *argv [ ]) {
char *s;
36 char string [100] = " 1arun2 ";
printf("The original string is :%s:n", string);
38 s = trim (string);
printf("The trimmed string is :%s:n", s);
1.8. STRINGS 153
40 return 0;
}
✌
✆
✞
The original string is : 1arun 2 :
The trimmed string is :1 arun 2:
✌
✆
strlen
Synopsis of strlen() function is
✞
size _t strlen(const char *s);
✌
✆
The strlen() function shall compute the number of bytes in the string to which ‘s’ points,
not including the terminating null byte. It returns the number of bytes in the string. No
value is used to indicate an error. A simple example is
✞
1 #include <stdio.h>
#include <string.h>
3
int main () {
5 char Input [256];
printf("Enter a string : ");
7 gets ( Input);
printf("The string length is %u characters long .n",
9 (unsigned ) strlen(Input));
return 0;
11 }
✌
✆
✞
Enter a string : a
The string length is 1 characters long .
✌
✆
strlen() counts only those cells in which string or character is stored. The counting of
strlen() is stopped when, it encountered the cell of null character. We can used several
methods to find the string length without using strlen function.
✞
#include <stdio.h>
2 #include <stdlib.h>
4 int main (void ) {
int n = 0, c;
6 /* get string to be counted */
printf("Enter the string : ");
8 while ((c = getchar ()) != ’n’) {
n++;
10 }
printf("The string length is %d.n", n);
12 return 0;
}
✌
✆
154 Basic C
✞
Enter the string : arun kumar
The string length is 10.
✌
✆
A new example that uses array and strlen() function to get reverse of the supplied string.
Actually in this example, strlen() function is used to get the length of the string. After
that the characters of the string are printed in reverse order.
✞
#include <stdio.h>
2 #include <stdlib.h>
4 int main (void ) {
char rs [1000]; // string to reversed .
6 /* get string to be reversed */
printf("Enter the string to be reversed : ");
8 scanf("%s", rs);
printf("The reversed string is : ");
10 /* While array is not triggered with space*/
int n = strlen(rs);
12 while (n > 0) {
printf("%c", rs[n - 1]);
14 n--;
}
16 return 0;
}
✌
✆
✞
Enter the string to be reversed : arun
The reversed string is : nura
✌
✆
In following example, classical method is used to find the length of a string. In this
example, we count the characters in a string until a null terminating character is not
obtained. After each counting, counter is increased by one. At last the counting value is
the actual length of the string.
✞
#include <stdio.h>
2
int main (void ) {
4 char name [ ] = "NAME arun kr";
int i = 0;
6 while (name [i] != NULL )
i++;
8 printf("The length of string "%s" is %d.", name , i);
return 0;
10 }
✌
✆
✞
The length of string "NAME arun kr" is 12.
✌
✆
The following example is rewritten in which string pointer is passed to a function where
string length is computed. The string length is returned to the main function and printed
in output console.
1.8. STRINGS 155
✞
1 #include <stdio.h>
3 int StrLen(char * str) {
int i = 0;
5 while (str[i] != ’0 ’) {
i++;
7 }
return i;
9 }
11 int main () {
char str[ ] = "This is my string.";
13 int i;
i = StrLen(str);
15 printf("The length of string is %d.n", i);
return 0;
17 }
✌
✆
✞
The length of string is 18.
✌
✆
The memory used by given string may also be retrieve by using keyword ‘sizeof’ as shown
in example below.
✞
1 #include <stdio.h>
#include <string.h> /* provides strlen () prototype */
3 #define PRAISE "Hi!"
5 int main (void ) {
char name [40];
7 printf("What ’s your name ?n");
scanf("%s", name );
9 printf("Hello , %s. %sn", name , PRAISE);
printf("Name has %d letters & occupies %d memory cells.n",
11 strlen(name ), sizeof name );
printf("The praise has %d letters ",strlen(PRAISE));
13 printf("and occupies %d memory cells.n", sizeof PRAISE);
return 0;
15 }
✌
✆
✞
What ’s your name ?
Arun
Hello , Arun . Hi!
Name has 4 letters & occupies 40 memory cells.
The praise has 3 letters and occupies 4 memory cells.
✌
✆
strncat
strncat() function concatenate specific number of characters into destination from the
source. Synopsis of this function is
156 Basic C
✞
1 char *strncat (char *s1 , const char *s2 , size_t n);
✌
✆
The strncat() function shall not append more than ‘n’ bytes. A simple example is
✞
1 #include <stdio.h>
3 int main () {
char str1 [20];
5 char str2 [20];
7 strcpy(str1 , "Hello");
strcpy(str2 , "Worlddddddddd ");
9
printf("Concatenated string is : %sn", strncat (str1 , str2 , 4));
11 printf("Final string is : %sn", str1 );
13 return 0;
}
✌
✆
✞
Concatenated string is : HelloWorl
Final string is : HelloWorl
✌
✆
strncmp
The strncmp function syntax is
✞
int strncmp (const char *s1 , const char *s2 , size_t n);
✌
✆
The strncmp() function shall compare not more than n bytes (bytes that follow a null
byte are not compared) from the array pointed-by ‘s1’ into the array pointed-by ‘s2’. The
sign of a non-zero return value is determined by the sign of the difference between the
values of the first pair of bytes (both interpreted as type unsigned char) that differ in
the strings being compared. See strcmp() for an explanation of the return value. This
function is as useful in comparisons, as the strcmp function is. A simple example is
✞
1 #include <stdio.h>
#include <string.h>
3
int main () {
5 if (strncmp ("arun ", "Arun ", 2) ==0) {
printf("Two strings are equal.");
7 } else {
printf("Two strings are not equal.");
9 }
return (0);
11 }
✌
✆
✞
Two strings are not equal.
✌
✆
1.8. STRINGS 157
strncpy
The syntax of strncpy() function is
✞
1 char *strncpy (char *s1 , const char *s2 , size_t n);
✌
✆
The strncpy() function shall copy not more than ‘n’ bytes (bytes that follow a null byte
are not copied) from the array pointed-by ‘s2’ into the array pointed-by ‘s1’. A simple
example is
✞
1 #include <stdio.h>
#include <string.h>
3
int main () {
5 /* initialize an experimental string */
char str[ ] = "This is a simple string";
7 char * pch;
/* get first occurace of simple*/
9 pch = strstr(str , " simple");
/* copy NAGPUR from the point of simple upto two places.*/
11 strncpy (pch , "NAGPUR", 2);
/* copy NAGPUR from the point of simple upto four places.*/
13 strncpy (pch , "NAGPUR", 4);
puts (str);
15 /* copy NAGPUR from the point of simple upto six places.*/
strncpy (pch , "NAGPUR", 6);
17 puts (str);
return 0;
19 }
✌
✆
✞
This is a NAmple string
This is a NAGPle string
This is a NAGPUR string
✌
✆
In the above program, line
✞
1 strncpy(pch , "NAGPUR", 2);
✌
✆
copied first two characters from the “NAGPUR” at 11th
and 12th
place of the string ‘str’
as shown below:
strncpy(pch, “NAGPUR”, 2)
s i m p l e s
N A G P U R 0
Similarly, in the above program, line
✞
1 strncpy(pch , "NAGPUR", 6);
✌
✆
158 Basic C
copied first six characters from the “NAGPUR” into ‘str’ from 11th
to 16th
place of the
string ‘str’ as shown below:
strncpy(pch, “NAGPUR”, 6)
s i m p l e s
N A G P U R 0
During the copying of strings, size of strings should be clearly defined, otherwise the
actual string may terminate shortly as null terminator is added within the actual string
as shown in the following example.
✞
1 #include <stdio.h>
#include <string.h>
3
int main () {
5 /* initialize an experimental string */
char str[ ] = "This is a simple string";
7 char * pch;
/* get first occurace of simple*/
9 pch = strstr(str , " simple");
/* copy NAGPUR from the point of simple upto seven places.*/
11 strncpy (pch , "NAGPUR", 7);
puts (str);
13 return 0;
}
✌
✆
✞
This is a NAGPUR
✌
✆
strncpy(pch, “NAGPUR”, 7)
s i m p l e s
N A G P U R 0
strrchr
The strrchr() function searches string for the last occurrence of a character. The null
character that represents to the termination of string, is also included in the search. The
prototype of strrchr() function is
✞
1 char *strrchr (const char *s, int c);
✌
✆
strrchr is similar to strchr(), except the string is searched right to left. A simple example
is
1.8. STRINGS 159
✞
1 #include <stdio.h>
3 int main () {
char *s;
5 char buf [ ] = "This is a testing ";
7 s = strrchr (buf , ’t’);
9 if (s != NULL )
printf("found a ’t’ at %sn", s);
11
return 0;
13 }
✌
✆
✞
found a ’t’ at ting
✌
✆
Here is another example that returns the position in a string where a delimiter is found.
✞
1 #include <stdio.h>
#include <string.h>
3
int main () {
5 char str[ ] = "This is my string";
char match[ ] = "i";
7 int i;
int c = 0;
9 for (i = 0; i < strlen(str); i++) {
if (str[i] == match[c] && c < strlen(match)) {
11 c++;
} else {
13 c = 0;
}
15 if (c == strlen(match)) {
printf("Pattern matched after %d charsn",
17 i - strlen(match) + 1);
}
19 }
return 0;
21 }
✌
✆
✞
Pattern matched after 2 chars
Pattern matched after 5 chars
Pattern matched after 14 chars
✌
✆
strstr
The syntax of strstr() function is
160 Basic C
✞
1 char *strstr(const char *string , const char *sub -str);
✌
✆
The strstr() function shall locate the first occurrence in the string pointed-by ‘string’
of the sequence of bytes (excluding the terminating null byte) in the string pointed-by
‘sub-str’. It returns the pointer (or may say the address) of the first occurrence of the
sub-string. A simple example is
✞
1 #include <stdio.h>
#include <string.h>
3
int main () {
5 /* initialize an experimental string */
char str[ ] = "This is a simple string";
7 char * pch;
/* get first occurance of simple */
9 pch = strstr(str , " simple");
puts (pch);
11 return 0;
}
✌
✆
✞
simple string
✌
✆
pch = strstr(str, ”simple”);
T h i s i s a s i m p l e s t r i n g 0
pch s i m p l e s t r i n g 0
strtok
The syntax of strtok function is
✞
1 char *strtok(char *restrict s1 , const char *restrict delimiters );
✌
✆
A sequence of calls to strtok() breaks the string pointed-by ‘s1’ into a sequence of tokens,
each of which is delimited by a byte from the string pointed-by delimiters. This function
returns the address of memory location where tokenised string is stored. first cA simple
example is
✞
1 #include <stdio.h>
#include <string.h>
3
int main () {
5 /* experimental string */
char str[ ] = "- This is my country .";
1.8. STRINGS 161
7 /* pointer for string tokenization */
char * pch;/*Do not need memory allocation , as it*
9 *has to point the memory address *
*being returned by strtok function . */
11 printf("String "%s" is splitted into tokens:n", str);
/* break experimental string with *
13 * spacecomma dot and doublequote */
pch = strtok(str , " ,.-");
15 while (pch != NULL ) {
printf("%sn", pch);
17 pch = strtok(NULL , " ,.-");
}
19 return 0;
}
✌
✆
✞
String "- This is my country ." is splitted into into tokens:
This
is
my
country
✌
✆
Here is an example which splits the string by a delimiter without using strtok() function.
In this example, a string is read character by character and when a read character is equal
to the delimiter, a new line is started.
✞
1 #include <stdio.h>
3 int main (int argc , char *argv [ ]) {
if (argv [1] == NULL ) {
5 printf("Use <utility .exe > <string in double quote >
<delimiter >.n");
exit (0);
7 }
/* get the commandline string*/
9 char *Str = argv [1];
char *Del = argv [2];
11 printf("The delimiter is ’%s ’.n", Del);
printf("The broken strings are : nn", Del);
13 int i = 0;
while (Str[i] != NULL ) {
15 if (Str[i] == Del [0]) {
printf("n");
17 i++;
}
19 printf("%c", Str[i]);
i++;
21 }
printf("nnThe length of string supplied is %d.n", i);
23 return 0;
}
✌
✆
162 Basic C
✞
executable .exe "This is my name " " "
This
is
my
name
The length of string supplied is 15.
✌
✆
strtod
The strtod(), strtof (), and strtold() functions convert the initial portion of the string
pointed-by pointer to double, float, and long double representation, respectively. The
return value is numerical value and pointer stores the rest of string.
✞
1 #include <stdio.h>
#include <stdlib.h>
3
int main () {
5 char str [30] = "20.30300 Rs are spent.";
char *ptr;
7 double ret;
9 ret = strtod(str , &ptr);
printf("The Rs in ( double) is %lfn", ret);
11 printf("|%s|n", ptr);
13 return (0);
}
✌
✆
✞
The Rs in (double) is 20.303000
| Rs are spent.|
✌
✆
1.9 Function
Function in C a group of statements and expressions which accepts inputs, analyse them
according to the statements and expressions, and return the result.
✞
int sum(int a, int b){
2 <function body expressions >
}
✌
✆
A function is like a black box. It takes inputs and do something and throws an output.
A function may be declared with or without definition as shown below:
✞
1 int myFunc (); // Function declared without definition
int myFunc (){} // Function declared with definition
✌
✆
1.9. FUNCTION 163
1.9.1 Function Arguments
A functions accepts inputs through its arguments. A function with two arguments (or
parameters) is defined as
✞
int sum(int a, int b);
✌
✆
These parameters in a function definition are called formal arguments. Here, int a, int b
are known as formal arguments. During the defining of a function, each argument must
be identified by its type. For example, to supply two integer arguments to a function, it
shall be defined like
✞
1 int sum(int a, int b);
✌
✆
while, the definition of function as given below is illegal.
✞
1 int sum(int a, b);// Illegal definition
✌
✆
Here, second argument ‘b’ is type unidentified. A function can be called from anywhere
by supplying actual arguments. The supplied argument to a function are type casted
according to the type of the function argument. For example, when a function type
✞
1 int sum(int a, int b);
✌
✆
is called as
✞
1 sum (2.5, 2);
✌
✆
then the function accepts argument value (or actual arguments) 2.5 as a = 2 because, ar-
gument a is an integer type and supplied argument is float type. While, b = 2. Therefore,
decimal part of the float value is truncated. See example below.
✞
1 #include <stdio.h>
3 /* Sum function with formal arguments */
int sum(int a, int b) {
5 int f;
f = a + b;
7 return f;
}
9
int main (int argc , char *argv [ ]) {
11 int g;
/* Sum function with actual arguments */
13 g = sum (2.5, 2);
printf("Sum of %f and %d is %dn", 2.5, 2, g);
15 return 0;
}
✌
✆
✞
Sum of 2.5 and 2 is 4
✌
✆
164 Basic C
Two dimensional arrays of integer type may also be passed as function argument. Two
dimensional, integer type and static size array is passed to function as shown below:
✞
1 #include <stdio.h>
3 void myFunc(int myArray [3][3]) {
int i, j;
5 for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
7 printf("%d t", myArray[i][j]);
}
9 printf("n");
}
11 }
13 int main () {
int myArray [][3] = {
15 {1, 2, 3},
{4, 5, 6},
17 {7, 8, 9}
};
19 myFunc(myArray);
return 0;
21 }
✌
✆
✞
1 2 3
4 5 6
7 8 9
✌
✆
If height of the two dimensional array is dynamic and only width is fixed then two
dimensional integer type array is passed to a function. The unknown dimension of the
array should be passed to the function as its another parameter.
✞
1 #include <stdio.h>
3 void myFunc(int myArray [][3] , int m) {
int i, j;
5 for (i = 0; i < m; i++) {
for (j = 0; j < 3; j++) {
7 printf("%d t", myArray[i][j]);
}
9 printf("n");
}
11 }
13 int main () {
int myArray [3][3] = {
15 {1, 2, 3},
{4, 5, 6},
17 {7, 8, 9}
};
1.9. FUNCTION 165
19 myFunc(myArray , 3);
return 0;
21 }
✌
✆
✞
1 2 3
4 5 6
7 8 9
✌
✆
A dynamic two dimensional integer type array may passed to a function as its argument
in pointer form. Remember that as two dimensional array passed to function a pointer
only and the called function does not know the actual size of the passed array. Therefore,
dimensions of the array must be passed as another parameters of the function.
✞
1 #include <stdio.h>
3 /* Catch myArray pointer as parameter of *
* function . myr parameter points to passed*
5 * array as 1D array not as 2D array. */
void myF(int *mAr , int m, int n) {
7 int i, j;
for (i = 0; i < m; i++) {
9 for (j = 0; j < n; j++) {
/* Print the array elements row by row.*/
11 printf("%d ", *(( mAr + i * n) + j));
}
13 printf("n");
}
15 }
17 int main () {
int myArray [][3] = {
19 {4, 5, 6},
{1, 2, 3},
21 {9, 8, 7}
};
23 /* Pass myArray as a pointer. */
myF(( int *) myArray , 3, 3);
25 return 0;
}
✌
✆
✞
4 5 6
1 2 3
9 8 7
✌
✆
166 Basic C
myArray[m][n]= 11 12 13 14 15
21 22 23 24 25
31 32 33 34 35
41 42 43 44 45
51 52 53 54 55
i
j
myF((int *) myArray, ...)
Pass Array to Function
In above example, array is passed as pointer and the address of the array pointer is catches
by the function as its parameter. Notice that, inside the function, array pointer does not
represents to two dimensional array but represents to one dimensional array as a group
of bytes in row by row order. This is why, in this function the dimensions of the array are
passed via two additional parameters. These parameters are used to control the printing
of each element of the passed array.
void myF(int *mAr, ...){...} 11 12 13 14 15 21 22 23 24 25 ...
*((mAr+i*n)+j) *((mAr+i*n)+j)
Array as Argument
Now, again, in C, a function without any argument can be compiled ans run by calling
with any number of arguments. See the example below:
✞
1 #include <stdio.h>
3 void testFun () { } // Function declared without arguments
5 int main (void ){
// Function called with three argument .
7 testFun (10, "x", "Y");
return 0;
9 }
✌
✆
But if the argument of prototype function is void type then the program fails to compile
and run. See below:
✞
1 #include <stdio.h>
3 void testFun (void ) { } // Function declared with void arguments
5 int main (void ){
// Function called with three argument .
7 testFun (10, "x", "Y");
return 0;
9 }
✌
✆
1.9. FUNCTION 167
1.9.2 Function Prototype
The declaration of a function prototype tell the compiler three important things about
it:
1. to expect to encounter them further down the program;
2. the return types of the function, e.g. void, int or double;
3. the number and kind of arguments the function is to handle;
The parameter names listed in a function’s prototype may be same as in the function’s
declaration or not. Function prototype allows to omit the variable name in its arguments.
The legal function prototyping are
✞
1 int sum(int , int); /* Legal prototype .*/
int sum(int a, int b); /* Legal prototype .*/
3 int sum(a, int b); /* Illegal prototype .*/
int sum(int *, int *a); /* Legal prototype with pointer array.*/
5 int sum(int *, int &a); /* Illegal prototype with address of a*/
int sum(int [ ], int a[ ]); /* Legal prototype with array.*/
✌
✆
Function prototyping is required when a function is called from the body of another
function which is defined above the called function. It also needed to be declared if
function is envoked before its definition as shown in the below example.
✞
#include <stdio.h>
2 /* Prototype is required .*/
void swap (int * u, int * v);
4
int main (void ) {
6 int x = 5, y = 10;
printf("Originally x = %d and y = %d.n", x, y);
8 swap (&x, &y); /* Send addresses to function */
printf("Now x = %d and y = %d.n", x, y);
10 return 0;
}
12
void swap (int * u, int * v) {
14 int temp ;
temp = *u; /* temp gets value that u points to */
16 *u = *v; /* Store the value of v at address of x*/
*v = temp ; /* Store the value of u at address of y*/
18 }
✌
✆
✞
Originally x = 5 and y = 10.
Now x = 10 and y = 5.
✌
✆
If prototype is not declared, then the compiler shows errors as in the following example,
function is envoked before the definition of the function.
168 Basic C
✞
#include <stdio.h>
2 /* Prototype is disabled .*/
// void swap (int * u, int * v);
4
int main (void ) {
6 int x = 5, y = 10;
printf("Originally x = %d and y = %d.n", x, y);
8 swap (&x, &y); /* send addresses to function */
printf("Now x = %d and y = %d.n", x, y);
10 return 0;
}
12
void swap (int * u, int * v) {
14 int temp ;
temp = *u; /* temp gets value that u points to */
16 *u = *v; /* Store the value of v at address of x*/
*v = temp ; /* Store the value of u at address of y*/
18 }
✌
✆
Again, if a function is called from the body of another function which is defined below to
the called function, then declaration of prototype is not required.
✞
#include <stdio.h>
2
void swap (int * u, int * v) {
4 int temp ;
temp = *u; /* temp gets value that u points to */
6 *u = *v; /* Store the value of v at address of x*/
*v = temp ; /* Store the value of u at address of y*/
8 }
10 int main (void ) {
int x = 5, y = 10;
12 printf("Originally x = %d and y = %d.n", x, y);
swap (&x, &y); /* send addresses to function */
14 printf("Now x = %d and y = %d.n", x, y);
return 0;
16 }
✌
✆
✞
Originally x = 5 and y = 10.
Now x = 10 and y = 5.
✌
✆
Another point is to be remembered that C compiler assumes a function as integer return
type by default. If user defined function is declared as integer type, then C compiler does
not failed to compile a function without prototype declaration. If user defined function
returns other values then compiler fails to compile the program. The following example
compiled successfully.
✞
#include <stdio.h>
2 /* Declaring prototype */
1.9. FUNCTION 169
char myFunc ();
4
int main (void ) {
6 /* Calling function of integer type return.*/
printf("Calling function myFunc()n");
8 printf("Returned value is %c", myFunc ());
return 0;
10 }
12 /* Declaring function of char type return.*/
char myFunc () {
14 return ’A’;
}
✌
✆
✞
Calling function myFunc ()
Returned value is A
✌
✆
Above function is re-written without declaring prototype. This program is failed to
compile.
✞
#include <stdio.h>
2
int main (void ) {
4 /* Calling function of integer type return.*/
printf("Calling function myFunc()n");
6 printf("Returned value is %c", myFunc ());
return 0;
8 }
10 /* Declaring function of char type return.*/
char myFunc () {
12 return ’A’;
}
✌
✆
There is no problem if the function is declared with integer return type. See the example
below which is modified form of above function.
✞
1 #include <stdio.h>
3 int main (void ) {
/* Calling function of integer type return.*/
5 printf("Calling function myFunc()n");
printf("Returned value is %c", myFunc ());
7 return 0;
}
9
/* Declaring function of integer type return.*/
11 int myFunc () {
return ’A’;
13 }
✌
✆
170 Basic C
✞
Calling function myFunc ()
Returned value is A
✌
✆
Compiler does not care about parameters of the declared function prototype. The com-
piler will not be able to perform compile-time checking of argument types. The validity
of arguments is checked during the program run time and sometime program returns
garbage value.
✞
#include <stdio.h>
2
int main (void ) {
4 /* Calling function of integer type return.*/
printf("Calling function myFunc()n");
6 printf("Returned value is %c", myFunc (65) );
return 0;
8 }
10 /* Declaring function of integer type return.*/
int myFunc(int i, int j) {
12 return i + j;
}
✌
✆
1.9.3 Function Types
In old C standards, each function was considered as integer type, while in new implemen-
tation of C standards, the type of the function may be integer, float, double, character
or void. Declaration of a function type is based on the return value of the function not
on the argument type. See example below:
✞
1 #include <stdio.h>
/* Integer type function .*/
3 int max(int a, int b) {
if (a > b)
5 return a;
else
7 return b;
}
9
int main (int argc , char *argv [ ]) {
11 /* integer specifier required to *
*print return value from function .*/
13 printf("Max of %d and %d is %dn", 2, 3, max(2, 3));
return 0;
15 }
✌
✆
✞
Max of 2 and 3 is 3
✌
✆
1.9. FUNCTION 171
In function ‘max’, two arguments are taken as inputs as integer and between them, greater
is returned as integer. Hence, here the function is declare as integer type. If the same
function is declared as float type then return value is a float value not integer value.
✞
1 #include <stdio.h>
/* Float type function .*/
3 float max(int a, int b) {
if (a > b)
5 return a;
else
7 return b;
}
9
int main (int argc , char *argv [ ]) {
11 /* Float specifier required to print*
*return value from function . */
13 printf("Max of %d and %d is %fn", 2, 3, max(2, 3));
return 0;
15 }
✌
✆
✞
Max of 2 and 3 is 3.0000
✌
✆
In case of void functions, the function should return with NULL value even if return
keyword is used inside the function. This type of function do something according to its
expression and stores the result in global variable.
✞
1 #include <stdio.h>
int f;
3
void sum(int a, int b) {
5 f = a+b;
/* Use of return keyword without any value.*/
7 return;
}
9
int main (int argc , char *argv [ ]) {
11 sum(2, 3);
printf("Sum of %d and %d is %dn", 2, 3, f);
13 return 0;
}
✌
✆
✞
Sum of 2 and 3 is 5
✌
✆
Use of return keyword in following manner are valid in void type functions.
✞
1 return; /* Legal return*/
return ""; /* Legal return */
3 return NULL ; /* Legal return */
return "; /* Illegal , " is null character code */
✌
✆
172 Basic C
return keyword is somewhat like exit keyword. After return keyword, anything inside
an expression block is skipped during program execution. Function returns the assigned
value and exits.
✞
#include <stdio.h>
2
int ret();
4
int main (void ) {
6 ret();
return 0;
8 }
10 int ret() {
int i = 0;
12 int loops = 15;
printf("Loop count is %dn", loops);
14 while (i < loops) {
printf("i is %dn", i);
16 if (i == 7) {
printf("Returning from the function at i=%dn", i);
18 printf("reaching before the loop value %dn", loops);
return 0;
20 }
i++;
22 }
return 0;
24 }
✌
✆
✞
Loop count is 15
i is 0
i is 1
i is 2
i is 3
i is 4
i is 5
i is 6
i is 7
Returning from the function at i=7
reaching before the loop value 15
✌
✆
A function with void return type can not be called through printf. For example
✞
1 #include <stdio.h>
#include <stdlib.h>
3
/* function return type is void */
5 void myF() {
printf("myF");
7 }
1.9. FUNCTION 173
9 int main () {
int i = 5, j = 3;
11 /* invalid use of void type function */
printf("%s", myF());
13
return 0;
15 }
✌
✆
program failed to compile and returns compile time error “invalid use of void”.
Never Reach Condition A function with return keyword, returns either NULL or some
alpha-numeric value after successful execution. Execution of function-script is terminated
after first successful return. If a function is designed in such manner that it has to reached
to only fixed return keywords then other return keywords if used are never reached by
the compiler. See the example given below:
✞
1 #include <stdio.h>
3 int executeMe (int i) {
if (i <= 10) { /* If i is less than or equal to 10 */
5 return 0;
} else { /* Otherwise */
7 return 1;
}
9 return -1; /* Mever reached */
}
11
int main () {
13 printf("%dn", executeMe (10) );
printf("%dn", executeMe (15) );
15 printf("%dn", executeMe (1));
return 0;
17 }
✌
✆
✞
0
1
0
✌
✆
1.9.4 Function Recursion
In C, a function can be called recursively, i.e. in nested form from within its body, without
using loop functions, i.e. for, while or do-while etc. See the example given below:
✞
1 #include <stdio.h>
int recFunc (int i, int j);
3
int recFunc (int i, int j) {
5 if (i == 0) {
return (2 + j);
174 Basic C
7 } else {
return recFunc(i - 1, j + 1);
9 }
}
11
int main (int argc , char ** argv ) {
13 int k = recFunc (4, 6);
printf("%d", k);
15 return 0;
}
✌
✆
✞
12
✌
✆
In above example, function ‘recFunc’ takes two arguments and checks the conditions for
its first argument. If it is true then it returns the sum of ‘2’ and second argument and
exits. Otherwise it returns the function ‘recFunc’ with new values of its two arguments.
As function calls itself, hence a loop like recursion is observed. There should be a condition
to be met and break the function recursion otherwise there shall be no return value. See
the following examples,
✞
1 #include <stdio.h>
int recFunc (int i, int j);
3
/* This type of recursion is not acceptable .*/
5 int recFunc (int i, int j) {
/*No Condition , No return value.*/
7 return recFunc(i - 1, j + 1);
}
9
int main (int argc , char ** argv ) {
11 int k = recFunc (4, 6);
printf("%d", k);
13 return 0;
}
✌
✆
If condition in the recursive function is not met then there is no return value from the
function. In the following example, if condition is never met therefore, there shall be no
return value from the recursive function.
✞
#include <stdio.h>
2 int recFunc (int i, int j);
4 int recFunc (int i, int j) {
/* Condition never met. No returned value.*/
6 if (i == 0) {
return (2 + j);
8 } else {
return recFunc(i, j + 1);
10 }
}
1.9. FUNCTION 175
12
int main (int argc , char ** argv ) {
14 int k = recFunc (1, 6);
printf("%d", k);
16 return 0;
}
✌
✆
There shall be no output on running of above two program.
1.9.5 Function As Argument
A function can pass to another function as its argument. The synopsis of the passing of
a function as argument to the other function tFunc() is given below:
✞
1 void tFunc(<data type > (*< func pointer >)());
✌
✆
See the example :
✞
1 #include <stdio.h>
#include <math .h>
3
/* Here *fp is pointer of the function sqrt */
5 void tFunc(char *name , double (*fp)()) {
int n;
7 printf("Testing function %s:n", name );
printf("%s: %10sn", "n", "Square Root ");
9 printf(" --------------n");
for (n = 0; n < 10; n++) {
11 printf("%d: %11.6fn", n, (*fp)(( double) n));
}
13 }
15 int main () {
tFunc("square root ", sqrt );
17 return 0;
}
✌
✆
✞
Testing function square root :
n: Square Root
--------------
0: 0.000000
1: 1.000000
2: 1.414214
3: 1.732051
4: 2.000000
5: 2.236068
6: 2.449490
7: 2.645751
8: 2.828427
9: 3.000000
✌
✆
176 Basic C
1.9.6 Function Callback
A callback is a piece of executable code that is passed as an argument to other code,
which is expected to call back (execute) the argument at some convenient time. In C,
there is no “callback” yet they are implemented by using function pointers. Following
example shows the possible call back.
✞
1 #include <stdio.h>
3 /* This function is calledback from other function .*/
int DoubleIt (int a) {
5 return 2 * a;
}
7
/* Pass DoubleIt function as argument named fPar .*
9 *The argument should be as function prototype . */
int myFunc(int (* fPar )(int)) {
11 int i = 10;
fPar (i);
13 }
15 int main () {
/* Pass function DoubleIt to myFunc */
17 printf("Result is : %dn", myFunc(DoubleIt ));
return 0;
19 }
✌
✆
✞
Result is : 20
✌
✆
The same above example is given in pointer format.
✞
1 #include <stdio.h>
3 /* This function is calledback from other function .*/
int *DoubleIt (int a) {
5 int *i;
i = (2 * a);
7 }
9 /* Pass DoubleIt function as argument named fPar .*
*The argument should be as function prototype . */
11 int *myFunc(int (* fPar )(int )) {
int i = 10;
13 (* fPar )(i);
}
15
int main () {
17 /* Pass function DoubleIt to myFunc */
printf("Result is : %dn", myFunc(DoubleIt ));
19 return 0;
}
✌
✆
1.9. FUNCTION 177
✞
Result is : 20
✌
✆
A function may be called from its pointer index if function pointer is saved in function
symbol table. See the example given below:
✞
1 #include <stdio.h>
#include <stdlib.h>
3 #include <dlfcn.h>
5 /* Memory allocation for 5 Function Pointers */
int (*FP [5]) ();
7
main (int argc , char **argv ) {
9 int i = 0;
void * myLib;
11
/* Function pointer */
13 void *fptr ;
15 /* Load function library */
myLib = dlopen("libtestdll .dll", RTLD_LAZY );
17
/* Find the function object of function "bar"*/
19 fptr = dlsym(myLib , "bar");
21 /* Assign address of library function "bar"*
*to all indexed function pointers (FP) */
23 for (i = 0; i < 5; i++) {
FP[i] = fptr ;
25 }
27 /* Call function from second FP address */
FP [1]();
29
/* Close Library */
31 dlclose (myLib);
33 return 0;
}
✌
✆
✞
called bar function from dll.
✌
✆
1.9.7 Memory Function
Memory functions in C, deals with memory. These functions are used to store, copy and
move data from one memory location to other memory location.
178 Basic C
mmap
To read or write to same file by two or more processes, mmap() function is used. Before
mapping a file to memory, file descriptor is obtained by using open() function as given
below:
✞
1 int fd;
fd=open ("<file name >", "<mode >");
✌
✆
The open function returns the file descriptor as integer value. ‘-1’ if it failed to open the
file otherwise a positive integer as file handle. Now, mmap() is called to map the file as
✞
data = mmap (<address >, <size >, <prot >, <flags >, <file id >,
<offset >);
✌
✆
‘address’ is the memory address where we want to mapped a file. By default its value is
‘0’ for automatic selection of address by the OS. ‘size’ is length of data of the file to be
mapped. ‘prot’ is a kind of access/permission to the file. Its values are PROT READ
for read only permission, PROT WRITE for write only permission and PROT EXEC for
execute permissions. ‘flags’ controls the sharing of changes or just keep them private.
The flag values are MAP SHARED or MAP PRIVATE for sharing and private mode
respectively. ‘offset’ is initial position of the file from where mapping of file data to
memory started. This value must be a multiple of the virtual memory page size. To get
the page size, getpagesize() function is used. See the example below:
✞
1 #include <stdio.h>
#include <stdlib.h>
3 #include <sys/mman .h>
#include <fcntl.h>
5
int main (int argc , char *argv []) {
7 int fd;
char *data ;
9 /* Read only mode of file .*/
if ((fd = open ("a.txt", O_RDONLY )) == -1) {
11 printf("Unable to open file ");
return 1;
13 }
/* Map file in memory with read only permissions */
15 data = mmap (0, 1024, PROT_READ , MAP_SHARED , fd , 0);
if (* data == -1) {
17 printf("Unable to map file ");
return 1;
19 }
printf("Byte at offset %d is ’%c ’n", 0, data [0]) ;
21 return 0;
}
✌
✆
✞
Byte at offset 0 is ’s’
✌
✆
1.9. FUNCTION 179
Each file which is mapped must be freed by using munmap function as
✞
1 int munmap(<address >, <size >);
✌
✆
Once the file is unmapped, data access with old file descriptor is not possible and will
return segmentation fault error. If multiple protected access permissions are granted by
using OR (|) operator in mmap() function, then the file access mode should be according
the access granted. See the example below in which protected access mode is grated for
read and write. Therefore, the file access mode in open() function is “rw” type (i.e. read
and write type via O RDWR).
✞
1 #include <stdio.h>
#include <stdlib.h>
3 #include <sys/mman .h>
#include <fcntl.h>
5
int main (int argc , char *argv []) {
7 int fd;
char *data ;
9 /* Read and write mode of file .*/
if ((fd = open ("a.txt", O_RDWR)) == -1) {
11 printf("Unable to open file ");
return 1;
13 }
/* Map file in memory with read & write permissions */
15 data = mmap (0, 1024, PROT_READ |PROT_WRITE , MAP_SHARED , fd , 0);
if (* data == -1) {
17 printf("Unable to map file ");
return 1;
19 }
printf("Byte at offset %d is ’%c ’n", 0, data [0]) ;
21 data [10] = ’1’;
printf("Byte at offset %d is ’%c ’n", 10, data [10]);
23 return 0;
}
✌
✆
✞
Byte at offset 0 is ’a’
Byte at offset 10 is ’1’
✌
✆
File Mode Key Numeric Description
O RDONLY 0 Read only access to file.
O WRONLY 1 Write only access to file.
O RDWR 2 Read and write access to file.
Table 1.21: File access mode.
180 Basic C
A segment of file may be mapped by using mmap function with setting file pointer by
lseek function as given below:
✞
....
2 for (j = 0; j <= bk; j++) {
/* Map file for block size ‘bks’ from ‘offset’*/
4 data = mmap (0, bks , PROT_READ | PROT_WRITE , 
MAP_SHARED , fd , offset);
6 /* Chagne file pionter ‘fd’ to next block */
int offset=lseek(fd , bks , SEEK_CUR );
8 }
....
✌
✆
File Access Modes
The protection and permission codes of a file in Linux OS system are given in the following
table.
Mode Permission Value Protection Value
NONE 0 0
READ 4 1
WRITE 2 2
EXEC 1 4
Permission to a file in Linux OS system for a user, group or system is managed by
chmod command. This command accepts the file protection mode in numeric form as
given below:
✞
1 chmod 777 <file or dir >
✌
✆
In Linux OS system, a file has three levels of discretionary protection and permission.
permission to a file in Linux OS system is represented by a string that looks like “Zrwxr-
wxrwx”, in which first character, ‘Z’ defined type of directory or file, i.e. ‘d’ for directory,
‘l’ for linked file, ‘s’ for setuid bit, ‘t’ for the sticky bit etc. Next three characters (triads)
are protection/permission mode for owner, second is for group and third is for all other
users. Character ‘r’, ‘w’ and ‘x’ represents to read, write and execute modes respectively.
If user has readonly permission to a file then three characters shall be looked like ‘r –
–’ where dashes represent no write and no execute permissions to the user for the given
file or directory. The permission code in chmod command, as given above is splited in
all possible combinations before defining user’s permission and execution of chmod com-
mand. Note that, in permission code ‘777’, first ‘7’ is for owner second ‘7’ is for group
and third ‘7’ is for all other users. For example, ‘7’ is splitted in 4+2+1 form to mark
a file as read-write-exec. ‘3’ as 0+2+1, i.e. read-write- –. ‘5’ as 4+0+1, i.e. read- – -
exec. Permission with ‘–’ means files can not be either read, write or permissioned and
directories can not be permissioned with cd command. If there is no valid combinations
1.9. FUNCTION 181
are made from permission code, then invalid mode error is thrown by the system. The
permission string can be equivalently computed with binary values as shown below:
✞
1 -rwxrwxrwx ; permission string
111111111 ; Binary values
✌
✆
The triad values for owner (let) are computed for read permission as 1002 = 410, for write
permission as 0102 = 210, for read-write 1102 = 610 and so on.
memset
Syntax of memset() function is
✞
void *memset(void *s, int c, size_t n);
✌
✆
The memset() function converts ‘c’ into unsigned char, then stores the character into the
first ‘n’ bytes of memory pointed-by ‘s’. A simple example is
✞
1 #include <stdio.h>
#include <string.h>
3
int main () {
5 /* iniitalized a string */
char str1 [ ] = "These is memset !!!! ";
7 /* memset first six characters of the string*/
memset(str1 , ’-’, 6);
9 puts (str1 );
/* iniitalized a string */
11 char str2 [ ] = "These is memset !!!! ";
/* memset first three characters of the string*/
13 memset(str2 , ’-’, 3);
puts (str2 );
15 /* iniitalized a string */
char str3 [ ] = "These is memset !!!! ";
17 /* memset first four characters of the string*/
memset(str3 , ’-’, 4);
19 puts (str3 );
return 0;
21 }
✌
✆
✞
------is memset !!!!
---se is memset !!!!
----e is memset !!!!
✌
✆
memcpy
The memcpy() function shall copy n bytes from the object pointed to by ‘source’ into the
object pointed to by ‘destination’. If copying takes place between objects that overlap,
the behavior is undefined. The function returns ‘destination’. Syntax of the function is
182 Basic C
✞
1 void *memcpy(void * restrict <destination >, 
const void * restrict <source >, size_t <n>);
✌
✆
Because the function does not have to worry about overlap, it can do the simplest copy
it can.
✞
#include <stdio.h>
2 #include <string.h>
4 int main () {
const char src [50] = "Experimental string.";
6 char dest [50];
8 printf("Before memcpy destination is : %sn", dest );
memcpy(dest , src , strlen(src) + 1);
10 printf("After memcpy destination is : %sn", dest );
12 return (0);
}
✌
✆
✞
Before memcpy destination is :
After memcpy destination is : Experimental string.
✌
✆
memcpy() function is very useful when a user defined function pointer is required to
return the local pointer defined inside the function.
✞
#include <stdio.h>
2
char *toLower (char str[ ]) {
4 /* Initiate local string pointer */
char *s = NULL ;
6 /* Allocate memory for local pointer */
s = malloc(sizeof (char )*(1024));
8 int i = 0;
/* Create a local array for storing *
10 * modified string received from *
* from function argument . */
12 char st [1024];
while (str[i] != ’0 ’) {
14 /* Capital letters starts from *
* char code 65 to 90. While *
16 * small letters starts from 97*
* to 122. A difference of +32 */
18 if (str[i] >= 65 && str[i] <= 90) {
st[i] = str[i] + 32;
20 } else {
st[i] = str[i];
22 }
i++;
24 }
1.9. FUNCTION 183
st[i] = ’0’;
26 /* Copy array into memory as a pointer . */
memcpy(s, st , 1024);
28 /* Return function pointer.*/
return s;
30 /* Free allocated memory.*/
free (s);
32 }
34 int main (void ) {
char str[ ] = "This iS MY striNg.";
36 printf("Actual string is :");
printf(""%s"n",str);
38 printf("Lower case string is :");
printf(""%s"", toLower (str));
40 return 0;
}
✌
✆
✞
Actual string is : "This iS MY striNg ."
Lower case string is : "this is my string ."
✌
✆
memmov
The memmove() function shall copy n bytes from the object pointed to by ‘source’ into
the object pointed to by ‘dest’. Copying takes place as if the n bytes from the object
pointed to by ‘source’ are first copied into a temporary array of n bytes that does not
overlap the objects pointed to by ‘dest’ and ‘source’, and then the n bytes from the
temporary array are copied into the object pointed to by ‘dest’. The function returns the
value of ‘dest’. The easy way to implement this without using a temporary array is to
check for a condition that would prevent an ascending copy, and if found, do a descending
copy. Unlike the memcpy(), this function guaranteed to move contents from source to
destination even if the memory regions pointed by ‘source’ and ‘dest’ overlaps. Its syntax
is
✞
void *memmove (void * <dest >, const void *<source >, size_t <n>);
✌
✆
✞
1 #include <stdio.h>
#include <string.h>
3
int main () {
5 char str[ ] = "Experimental string";
memmove (str + 10, str + 5, 5);
7 puts (str);
return 0;
9 }
✌
✆
✞
Experimentimentring
✌
✆
184 Basic C
memchr
The memchr() function shall locate the first occurrence of ‘c’ (converted to an unsigned
char) in the initial n bytes (each interpreted as unsigned char) of the object pointed to
by ‘string’. If ‘c’ is not found, memchr() returns a null pointer. Its syntax is
✞
1 void *memchr(const void *<string >, int <c>, size_t <n>);
✌
✆
✞
1 #include <stdio.h>
#include <string.h>
3
int main () {
5 char * pch;
char str[ ] = "Example string";
7 pch = (char *) memchr(str , ’e’, strlen(str));
if (pch != NULL )
9 printf("’e’ found at position %d.n", pch - str + 1);
else
11 printf("’e’ not found.n");
return 0;
13 }
✌
✆
✞
’e’ found at position 7.
✌
✆
memcmp
The memcmp() function shall compare the first n bytes (each interpreted as unsigned
char) of the object pointed to by ‘mem1’ to the first n bytes of the object pointed to
by ‘mem2’. The sign of a non-zero return value shall be determined by the sign of the
difference between the values of the first pair of bytes (both interpreted as type unsigned
char) that differ in the objects being compared.
✞
1 int memcmp(const void *<mem1 >, const void *<mem2 >, size_t <n>);
✌
✆
✞
1 #include <stdio.h>
#include <string.h>
3
int main () {
5 char buff [ ] = "Artificial ";
char buff2[ ] = "ARtificial ";
7
int n;
9
n = memcmp(buff , buff2 , sizeof (buff ));
11
if (n > 0)
13 printf(" ’%s’ is greater than ’%s ’.n", buff , buff2);
else if (n < 0)
15 printf(" ’%s’ is less than ’%s ’.n", buff , buff2);
1.9. FUNCTION 185
else
17 printf(" ’%s’ is the same as ’%s ’.n", buff , buff2);
19 return 0;
}
✌
✆
✞
’Artificial ’ is greater than ’ARtificial ’.
✌
✆
1.9.8 Unicode Support
C provides unicode support for the native operating systems which have their own unicode
support. To set the native local language
✞
1 char *locale = setlocale (LC_CTYPE , " en_IN.UTF -8");
✌
✆
The function setlocale() is defined in the macro “locale.h”. If native locale doesn’t use
UTF-8 encoding it need to replace the empty string with a locale like “en IN.UTF-8”.
Localisation environment has following parameters
✞
1 ANG=en_US
LC_CTYPE ="en_US"
3 LC_NUMERIC ="en_US"
LC_TIME=" en_US"
5 LC_COLLATE ="en_US"
LC_MONETARY ="en_US"
7 LC_MESSAGES ="en_US"
LC_PAPER ="en_US"
9 LC_NAME=" en_US"
LC_ADDRESS ="en_US"
11 LC_TELEPHONE ="en_US"
LC_MEASUREMENT ="en_US"
13 LC_IDENTIFICATION ="en_US"
LC_ALL=
✌
✆
User can change any specific environmental parameter by using method given above or
setting all environment to locals by setting ‘LC ALL’ as shown below.
✞
char *locale = setlocale (LC_ALL , "en_IN.UTF -8");
✌
✆
An example is
✞
1 #include <stdio.h>
#include <wchar.h>
3 #include <stdlib.h>
#include <locale.h>
5
int main (void ) {
7 /* If your native locale doesn’t use UTF -8 encoding *
* you need to replace the empty string with a *
186 Basic C
9 * locale like "en_US.utf8 " */
char * locale = setlocale (LC_CTYPE , "en_IN.UTF -8");
11 FILE *in = fopen("a.txt", "r");
13 wint_t c;
while ((c = fgetwc(in)) != WEOF )
15 putwchar (c);
fclose(in);
17
return EXIT_SUCCESS ;
19 }
✌
✆
1.10 Procedures & Functions
A function is often executed (called) several times, called from different locations, during
a single execution of the program. After finishing a subroutine, the program will branch
back (return) to the point after the call. A function is like a black box. It takes inputs,
does something with them, then spits out an answer.
✞
1 #include <stdio.h>
3 void P_Loop(void ) {
int i;
5 for (i = 1; i <= 5; i++) {
printf("%d ", i * i);
7 }
}
9
int main (void ) {
11 P_Loop ();
printf("n");
13 P_Loop ();
return 0;
15 }
✌
✆
The output is
✞
1 4 9 16 25
1 4 9 16 25
✌
✆
1.10.1 Code Optimisation
It is very common that in a program, there are excess lines of script or it has time/memory
consuming algorithm. Ultimately program takes longer time for execution. By using ad-
vance methods of algorithm and script writing we can reduce the size as well as execution
time of the program. It is known as code optimization. In other words, code optimization
is a method of code modification to improve code quality and efficiency. A program may
1.10. PROCEDURES & FUNCTIONS 187
be optimized so that it becomes a smaller size, consumes less memory, executes more
rapidly or performs fewer input/output operations.
Illustrated Example Assume that we have to find all the prime numbers within 1 to
20. We write a program in which each number is divided by all numbers less than to it.
For example, to check whether 19 is a prime or not, it is divided by integers started from
2 to 19 and if any of the divisor returns the zero as remainder then the number 19 is not
prime.
✞
#include <stdio.h>
2 #include <stdlib.h>
4 int main () {
int n, i = 1, j, m = 0;
6 printf("Enter Limit of Prime Number : ");
scanf("%d", &n);
8 while (i <= n) {
int k = 0;
10 for (j = 2; j < i; j++) {
if (i % j == 0) {// line to be optimised
12 k++;
}
14 }
if (k == 0) {
16 m++;
printf("%d is a prime number .n", i);
18 }
i++;
20 }
printf("Total %d primes are found.n", m);
22 return 0;
}
✌
✆
Another concept is that, if a number, ‘n’, is not divisible by a maximum integer value of
‘n/2’ then it is not divisible by any integers larger ‘n/2’. For example if 19 is not divisible
by maximum integer value of 19/2, ie 9 then 19 never be completely divisible by 10 or
more. By this method we reduce the iteration loops in the program. Above example can
be rewritten as
✞
1 #include <stdio.h>
#include <stdlib.h>
3
int main () {
5 int n, i = 1, j, m = 0;
printf("Enter Limit of Prime Number : ");
7 scanf("%d", &n);
while (i <= n) {
9 int k = 0;
for (j = 2; j <= i/2; j++) {// line is optimised
11 if (i % j == 0) {
k++;
188 Basic C
13 }
}
15 if (k == 0) {
m++;
17 printf("%d is a prime number .n", i);
}
19 i++;
}
21 printf("Total %d primes are found.n", m);
return 0;
23 }
✌
✆
By this way we have reduce the execution time of the program (better performance)
without compromising its output. Again if a number ‘n’ is divisible by ‘2’, above program
checks the divisibility upto maximum integer value of ‘n/2’ by several iteration even if it
was confirm that the number ‘n’ is not prime in first iteration. To enhance the performance
of the program, we can again optimize the code by using break-continue function when
number is checked and confirmed that it is not prime in first iteration.
✞
1 #include <stdio.h>
#include <stdlib.h>
3
int main () {
5 int n, i = 1, j, m = 0;
printf("Enter Limit of Prime Number : ");
7 scanf("%d", &n);
while (i <= n) {
9 int k = 0;
for (j = 2; j <= i / 2; j++) {
11 if (i % j == 0) {
k++;
13 break;/* no further check that the number*
*is primeif it is declared not a *
15 *prime in first few iterations . */
}else {
17 continue ;
}
19 }
if (k == 0) {
21 m++;
printf("%d is a prime number .n", i);
23 }
i++;
25 }
printf("Total %d primes are found.n", m);
27 return 0;
}
✌
✆
It again enhance the performance of program by multiple times. Similarly, if given number
is even number then it shall never be prime and if given number is odd number then it
shall not be prime if it has a perfect square-root. Again, square-root of odd number is
1.10. PROCEDURES & FUNCTIONS 189
only odd number. It means we have to check the divisibility of given number by all odd
numbers less than or equal to square root of the given number. By this way we can
further optimize the code for prime numbers.
✞
#include <math .h>
2 #include <stdio.h>
4 int main () {
int n = 147853;
6 int x, y = 1;
int sq = sqrt (n) + 1;
8 if (n < 2)
y = 0;
10 if (n == 2 || n == 3)
y = 1;
12 if (n % 2 == 0)
y = 0;
14 for (x = 3; x <= sq; x += 2) {
if (n % x == 0)
16 y = 0;
}
18 if (y == 1) {
printf("A primen");
20 } else {
printf("Not A primen");
22 }
return 1;
24 }
✌
✆
Execution Time In good programming practices, codes are written in such manner
that they took least execution time with optimum performance. Using clock() function,
we can get the execution time of the program. A simple example is given below.
✞
#include <stdio.h>
2 #include <stdlib.h>
#include <time .h>
4
int main () {
6 clock_t startTime = clock();
int n = 1000000 , i = 1;
8 while (i <= n) {
i++;
10 }
clock_t endTime = clock();
12 double td = (endTime - startTime ) / (double) CLOCKS_PER_SEC ;
printf("Program has run for %5.8 f secondsn", td);
14 return 0;
}
✌
✆
✞
Program has run for 0.00000200 seconds
✌
✆
190 Basic C
Additional to this, some time it is required to know the local time (computer clock time)
for best performance of the program. Here is an example that uses time.h header file to
get the local time. The code line
✞
1 time_t time (time_t *seconds );
✌
✆
returns the time lapsed since the mid night of January 1, 1970, measured in seconds. If
‘seconds’ is not NULL, the return value is also stored in variable ‘seconds’.
✞
1 #include <stdio.h>
#include <time .h>
3
int main () {
5 time_t seconds;
7 seconds = time (NULL );
printf("Hours since January 1, 1970 = %ldn", seconds / 3600);
9
return (0);
11 }
✌
✆
✞
Hours since January 1, 1970 = 405089
✌
✆
Another example is
✞
1 #include <time .h>
#include <stdlib.h>
3 #include <stdio.h>
5 int main (void ) {
time_t current_time ;
7 char * c_time_string ;
int i = 5;
9 while (i > 0) {
sleep (1);
11 /* Obtain current time . */
current_time = time (NULL );
13 /* Convert to local time format. */
c_time_string = ctime(& current_time );
15 printf("Current time is %d, %s", current_time ,
c_time_string );
i--;
17 }
return EXIT_SUCCESS ;
19 }
✌
✆
✞
Current time is 1458321446 , Fri Mar 18 22:47:26 2016
Current time is 1458321447 , Fri Mar 18 22:47:27 2016
Current time is 1458321448 , Fri Mar 18 22:47:28 2016
Current time is 1458321449 , Fri Mar 18 22:47:29 2016
1.10. PROCEDURES & FUNCTIONS 191
Current time is 1458321450 , Fri Mar 18 22:47:30 2016
✌
✆
Specifier Output Format
%a Short weekday name
%A Full weekday name
%b Short month name
%B Full month name
%c Time stamp
%d Day of the month
%H Hour in 24h format
%I Hour in 12h format
%j Day of the year
%m Month as a decimal number
%M Minutes
%p AM or PM
%S Seconds
%U Week number, first day of first week is Sunday
%w Weekday as a decimal number with Sunday as 0 (0-6)
%W Week number, first day of first week is Monday
%x Date representation
%X Time representation
%y Two digit Year format (00-99)
%Y Four digit Year format
%Z Timezone name
%% A % sign
Table 1.22: Date & time format specifiers.
1.10.2 Increments & Decrements
The character set ‘++’ is used to increase the value by one and −− is used to decrease
the value by one of the variable with which the character set is prefixed or post-fixed.
There are two ways to use these notations. One is ‘++n’ and other is ‘n++’. Both have
same meaning but first is used where value is to be used after one increment while later
is used where value is to be increase by one after using it.
192 Basic C
✞
1 #include <stdio.h>
#include <stdlib.h>
3
int main (void ) {
5 int i = 0;
printf("use of ++i n");
7 while (i < 3) {
/* calling & placing at same place.*/
9 printf("%d => %d n", i, ++i);
}
11 printf("use of i++ n");
int j = 0;
13 while (j < 3) {
printf("%d => %d n", j, j++);
15 }
return EXIT_SUCCESS ;
17 }
✌
✆
✞
use of ++i
1 => 1
2 => 2
3 => 3
use of i++
1 => 0
2 => 1
3 => 2
✌
✆
If increment or decrements is used inside a loop, there are no difference in the use of ‘i++’
or ‘++i’.
✞
#include <stdio.h>
2 #include <stdlib.h>
4 int main (void ) {
int i = 0;
6 printf("Use of i++ in while loop n");
while (i < 3) {
8 /* first increment .*/
i++;
10 /* then use.*/
printf(":-> %dn", i);
12
}
14 printf("Use of ++i in while loop n");
int j = 0;
16 while (j < 3) {
/* first increment .*/
18 ++j;
/* then use.*/
20 printf(":-> %dn", j);
1.10. PROCEDURES & FUNCTIONS 193
22 }
return EXIT_SUCCESS ;
24 }
✌
✆
✞
Use of i++ in while loop
:-> 1
:-> 2
:-> 3
Use of ++i in while loop
:-> 1
:-> 2
:-> 3
✌
✆
This increment operator can not be used in variable initialization or with constants like
3 + + or directly in output stream functions like printf. The following type of syntax are
illegal.
✞
int i=2++; // illegal coding
2 printf("Increment of 2 is %dn" ,2++);// illegal coding
✌
✆
The same methods can be used for decrements operator. In increments or decrements
operations, value of variable i is incremented by one and then the result is assigned to
variable i. This is why, constant values can not be used with this unary operator, i.e.
5 + + and + + 5 cause compile time errors. See another example for i + + and + + j
unary operators.
✞
#include <stdio.h>
2
int main (int argc , char ** argv ) {
4 int i = 0;
while (i < 3) {
6 printf("i is %dn", i++);/* started from 0*/
}
8 printf("n");
int j = 0;
10 while (j < 3) {
printf("j is %dn", ++j);/* started from 1*/
12 }
return 0;
14 }
✌
✆
✞
i is 0
i is 1
i is 2
j is 1
j is 2
j is 3
✌
✆
194 Basic C
Again, before summing up this section, always remember that k + 1 and k + + results
increment of variable ‘k’ by one. But first expression is purely different to second ex-
pression. In first expression, the value of ‘k’ remains unchanged only results reflects to
increment by one, while in second expression, value of ‘k’ is incremented by one and again
assigned to it.
✞
1 #include <stdio.h>
3 int main (int argc , char ** argv ) {
int k = 0, l = 0;
5 printf("k+1 is %d and l++ is %dn", k+1, l++);
printf("k+1 is %d and l++ is %dn", k+1, l++);
7 printf("k+1 is %d and l++ is %dn", k+1, l++);
return 0;
9 }
✌
✆
✞
k+1 is 1 and l++ is 0
k+1 is 1 and l++ is 1
k+1 is 1 and l++ is 2
✌
✆
When increment and decrements operators are used simultaneously, then increment and
decrements is performed simultaneous in order.
✞
1 #include <stdio.h>
#include <stdlib.h>
3
int myF(int i) {
5 int j = 1, re , r = 2;
while (j < i) {
7 re = (r++) *(++ r);//re = (2) * (4); r = 4;
j++;
9 }
return re;
11 }
13 int main () {
int i = 5, j = 3;
15 printf("%d", myF (5));
17 return 0;
}
✌
✆
✞
80
✌
✆
In above program, in each loop, first value of r in r++ is used and then it is incremented.
The value of r in ++r is incremented and then used. Therefore, in first loop, the equivalent
expression shall be
✞
1 re = (2) * (4);
✌
✆
1.10. PROCEDURES & FUNCTIONS 195
And for next loop, the new value of r is 4. In case of increment operator is used with
array elements like
✞
1 a[i]=i++;
✌
✆
In this case, initial value of ‘i’ is taken and incremented by one. This original value
is stored as element of array ‘a’, at index position given by incremented ‘i’, i.e. ‘i+1’.
Actually, for any value of ‘i’ above expression becomes
✞
1 a[i+1]= i;
✌
✆
See the example below
✞
1 #include <stdio.h>
3 int main (int argc , char *argv []) {
int i = 80;
5 int j = i;
char a[100];
7 /*In following expression , first value of i*
*is used and then it is incremented . Value*
9 *of i stored at array element as a[i++]= i */
a[i] = i++;
11 /* Actual i and equivalent char */
printf("%d=>%cn", j, j);
13 /* Values stored in array as its*
*element for initial i values */
15 printf("a[%d]=%cn", j, a[j]);
/* Actual array element values*/
17 printf("a[%d]=%cn", i, a[i]);
return 0;
19 }
✌
✆
✞
80=>P
a[80]=(
a[81]=P
✌
✆
Again see the following example, in which we try to get the result 110 by multiplying
increment operators.
✞
1 #include <stdio.h>
3 int main (int argc , char *argv []) {
int i = 10;
5 printf("%dn", i++ * i++);
return 0;
7 }
✌
✆
✞
100
✌
✆
196 Basic C
But actual result is 100 rather than 110. It means after using the current value of ‘i’, ‘i’
does not goes increment for next use of ‘i’. It reason is that, C does not guaranteed to
increment the value of ‘i’ just after using it but it increments value of ‘i’ sometime before
the expression is considered “finished” or just before the next “sequence point”.
1.10.3 Static Function
In a program, if a function is declared as static then it can only be called from the same
file in which it is declared. It can not called from the other files. The syntax of static
function is
✞
1 static int compare(int a, int b) {
return (a + 4 < b) ? a : b;
3 }
✌
✆
An example of static function is
✞
1 #include <stdio.h>
3 static int compare(int a, int b) {
return (a > b) ? a : b;
5 }
7 int main () {
int j;
9 j = compare (2, 4);
printf(":-> %d.n", j);
11 return 0;
}
✌
✆
✞
:-> 4.
✌
✆
1.10.4 Function with Variable Arguments
A static function can be called by its prototype. Normally in static functions number
of arguments remain fix but variable number of arguments can also be passed to the
function. Calling of a function with variable arguments is given in following example.
✞
1 #include <stdlib.h>
3 #define MAXARGS 3
int var_arg ();
5
int main () {
7 var_arg (1, 2, 3);
return 0;
9 }
11 int var_arg (int a) {
1.10. PROCEDURES & FUNCTIONS 197
int i = 0;
13 while (i < MAXARGS) {
printf("%d argument is %d.n", i, (&a)[i]);
15 i++;
}
17 return a;
}
✌
✆
A ‘var arg’ function is defined in prototype as null variables
✞
int var_arg ();
✌
✆
This prototype function is defined as single argument list.
✞
1 int var_arg (int a)
✌
✆
When function is called with three integer arguments, this argument list is passed to the
function definition as a list.
✞
1 var_arg (1, 2, 3);
✌
✆
Following line in the program
✞
1 printf("%d argument is %d.n", i, (&a)[i]);
✌
✆
prints the each element of the variable list of ‘a’. Second method uses macros defined in
the header file <stdarg.h>.
✞
1 #include <stdio.h>
#include <stdarg.h>
3
void varStrings (const char *f, ...) {
5 int max_args = 5;
va_list args ;
7 va_start (args , max_args );
printf("%sn", f);
9 while (max_args --)
puts (va_arg(args , const char *));
11 va_end(args );
}
13
int main () {
15 varStrings ("f", "Mary ", "had", "a", "little", "lamb ");
return 0;
17 }
✌
✆
The syntax variable argument function requires at least one fixed argument before the
‘...’. Here ‘va list’ creates memory for the variable list ‘valist’. ‘va start’ function accepts
arguments and stores in the variable list ‘valist’ memory. ‘va arg’ function returns the
variable value from variable list ‘valist’. ‘va end’ function cleans the memory reserved
for valist. In pursuance to standard method of programming, in a function with variable
198 Basic C
arguments, first argument/element should be an integer, representing the number of ar-
guments to be passed to the function. In following example, sum of integers by passing
variable arguments is obtained.
✞
1 #include <stdarg.h>
3 int sum(int num , ...) {
va_list ap;
5 int total = 0;
va_start (ap , num);
7 while (num > 0) {
total += va_arg(ap , int);
9 num --;
}
11 va_end(ap);
return total;
13 }
15 int main () {
/* First argument determines the number of **
17 ** following arguments , those shall be used **
** in the sum function . Here it is 5. */
19 int a = sum(5, 1, 2, 3, 4, 6);
21 /* First argument determines the number of **
** following arguments , those shall be used **
23 ** in the sum function . Here it is 2. */
int b = sum(2, 3, 5, 8);
25 printf("Sums are %d and %dn", a, b);
return 0;
27 }
✌
✆
✞
Sums are 16 and 8 respectively .
✌
✆
1.10.5 Indirect Call of Function
In C, the input is considered as string even though input contains the name of inbuilt
functions or operators. For example, input “sin(90)” is considered as string which is a
group of ‘s’, ‘i’, ‘n’, ‘(’, ‘9’, ‘0’, ‘)’ and NULL characters rather than sine operator on
operand ‘90’. Using indirect call of a function, we can execute a function by supplying
function name as string input.
✞
1 #include <stdio.h>
#include <stdlib.h>
3 #include <math .h>
5 double Equ1 (double x) {
return x;
7 }
1.10. PROCEDURES & FUNCTIONS 199
9 double Equ2 (double x) {
return x * x;
11 }
13 double Equ3 (double x) {
return log(x);
15 }
17 typedef double (* Eqn)(double);
19 int main () {
int i;
21 double ic;
23 const char *EqnNames [3] = {
"Equ1 ", "Equ2 ", "Equ3 "
25 };
Eqn FEqu [ ] = {Equ1 , Equ2 , Equ3 };
27
for (i = 0; i < (sizeof (FEqu ) / sizeof (Eqn)); i++) {
29 ic = (* FEqu [i])(i + 1);
printf("Eqn Name = %5s : a=%d : Result=%lfn",
31 EqnNames [i], i + 1, ic);
}
33 return 0;
}
✌
✆
✞
Eqn Name = Equ1 : a=1 : Result =1.000000
Eqn Name = Equ2 : a=2 : Result =4.000000
Eqn Name = Equ3 : a=3 : Result =1.098612
✌
✆
1.10.6 Preprocessor Macros
Preprocessors are used to define macros or manifest constants and are included in the
header of source file. Preprocessors can be defined separately in a file having extensions
‘.h’ or in the same source file. Some of the useful pre-processors are explained below.
Literals
The token reserved for the preprocessor is the octothorp, #, and the preprocessor makes
three entirely different uses of it. Using, this token we can put the macros within the
function. Whitespace before the # is ignored. Next use of # in a macro makes input a
string, known as compound literal. See the example below:
✞
1 #include <stdio.h>
#define myMacro (v) printf (#v " : %dn", v);
3
int main () {
200 Basic C
5 myMacro (10 / 5);
myMacro (15 / 5);
7 return 0;
}
✌
✆
✞
10 / 5 : 2
15 / 5 : 3
✌
✆
Tokens
Body of a macro is considered as a string of tokens rather than a string of characters. C
preprocessor tokens are the separate “words” in the body of a macro definition. They are
separated from one another by white spaces. For example, the definition
✞
#define FOUR 2*2
✌
✆
has one token-the sequence 2*2, but the definition
✞
1 #define SIX 2 * 3
✌
✆
has three tokens 2, *, and 3. Character, strings and token strings differ from each other.
It depends on how how multiple spaces are treated in a macro body. The preprocessor
doesn’t make calculations; it just substitutes strings. For example
✞
1 #include <stdio.h>
3 #define SQUARE(X) X*X
5 int main (void ) {
int x = 4;
7 printf("x = %dn", x);
printf("SQUARE(x): %d", SQUARE(x));
9
/* Above statement is equivalent to *
11 * printf (" SQUARE(x): %d", x*x); */
return 0;
13 }
✌
✆
✞
x = 4
SQUARE(x): 16
✌
✆
In above example value of ‘x’ is passed to predefined function ‘SQUARE(X)’ and the
function replaces ‘X’ by ‘x’ as ‘x*x’ and ultimately ‘4*4’. Now the result is ‘16’. If the
‘x’ passed to the function as shown in the given example then
✞
#include <stdio.h>
2
#define SQUARE(X) X*X
Ad

More Related Content

What's hot (20)

C tech questions
C tech questionsC tech questions
C tech questions
vijay00791
 
C interview question answer 2
C interview question answer 2C interview question answer 2
C interview question answer 2
Amit Kapoor
 
Fp201 unit5 1
Fp201 unit5 1Fp201 unit5 1
Fp201 unit5 1
rohassanie
 
FP 201 - Unit 3 Part 2
FP 201 - Unit 3 Part 2FP 201 - Unit 3 Part 2
FP 201 - Unit 3 Part 2
rohassanie
 
C aptitude scribd
C aptitude scribdC aptitude scribd
C aptitude scribd
Amit Kapoor
 
FP 201 - Unit 6
FP 201 - Unit 6FP 201 - Unit 6
FP 201 - Unit 6
rohassanie
 
7 functions
7  functions7  functions
7 functions
MomenMostafa
 
4 operators, expressions &amp; statements
4  operators, expressions &amp; statements4  operators, expressions &amp; statements
4 operators, expressions &amp; statements
MomenMostafa
 
8 arrays and pointers
8  arrays and pointers8  arrays and pointers
8 arrays and pointers
MomenMostafa
 
Python unit 3 and Unit 4
Python unit 3 and Unit 4Python unit 3 and Unit 4
Python unit 3 and Unit 4
Anandh Arumugakan
 
FP 201 Unit 2 - Part 3
FP 201 Unit 2 - Part 3FP 201 Unit 2 - Part 3
FP 201 Unit 2 - Part 3
rohassanie
 
9 character string &amp; string library
9  character string &amp; string library9  character string &amp; string library
9 character string &amp; string library
MomenMostafa
 
1 introducing c language
1  introducing c language1  introducing c language
1 introducing c language
MomenMostafa
 
C aptitude.2doc
C aptitude.2docC aptitude.2doc
C aptitude.2doc
Srikanth
 
Captitude 2doc-100627004318-phpapp01
Captitude 2doc-100627004318-phpapp01Captitude 2doc-100627004318-phpapp01
Captitude 2doc-100627004318-phpapp01
ManjeeraBhargavi Varanasi
 
Inheritance and polymorphism
Inheritance and polymorphismInheritance and polymorphism
Inheritance and polymorphism
mohamed sikander
 
2.overview of c++ ________lecture2
2.overview of c++  ________lecture22.overview of c++  ________lecture2
2.overview of c++ ________lecture2
Warui Maina
 
C++ Pointers
C++ PointersC++ Pointers
C++ Pointers
Chaand Sheikh
 
Maharishi University of Management (MSc Computer Science test questions)
Maharishi University of Management (MSc Computer Science test questions)Maharishi University of Management (MSc Computer Science test questions)
Maharishi University of Management (MSc Computer Science test questions)
Dharma Kshetri
 
6 c control statements branching &amp; jumping
6 c control statements branching &amp; jumping6 c control statements branching &amp; jumping
6 c control statements branching &amp; jumping
MomenMostafa
 
C tech questions
C tech questionsC tech questions
C tech questions
vijay00791
 
C interview question answer 2
C interview question answer 2C interview question answer 2
C interview question answer 2
Amit Kapoor
 
FP 201 - Unit 3 Part 2
FP 201 - Unit 3 Part 2FP 201 - Unit 3 Part 2
FP 201 - Unit 3 Part 2
rohassanie
 
C aptitude scribd
C aptitude scribdC aptitude scribd
C aptitude scribd
Amit Kapoor
 
FP 201 - Unit 6
FP 201 - Unit 6FP 201 - Unit 6
FP 201 - Unit 6
rohassanie
 
4 operators, expressions &amp; statements
4  operators, expressions &amp; statements4  operators, expressions &amp; statements
4 operators, expressions &amp; statements
MomenMostafa
 
8 arrays and pointers
8  arrays and pointers8  arrays and pointers
8 arrays and pointers
MomenMostafa
 
FP 201 Unit 2 - Part 3
FP 201 Unit 2 - Part 3FP 201 Unit 2 - Part 3
FP 201 Unit 2 - Part 3
rohassanie
 
9 character string &amp; string library
9  character string &amp; string library9  character string &amp; string library
9 character string &amp; string library
MomenMostafa
 
1 introducing c language
1  introducing c language1  introducing c language
1 introducing c language
MomenMostafa
 
C aptitude.2doc
C aptitude.2docC aptitude.2doc
C aptitude.2doc
Srikanth
 
Inheritance and polymorphism
Inheritance and polymorphismInheritance and polymorphism
Inheritance and polymorphism
mohamed sikander
 
2.overview of c++ ________lecture2
2.overview of c++  ________lecture22.overview of c++  ________lecture2
2.overview of c++ ________lecture2
Warui Maina
 
Maharishi University of Management (MSc Computer Science test questions)
Maharishi University of Management (MSc Computer Science test questions)Maharishi University of Management (MSc Computer Science test questions)
Maharishi University of Management (MSc Computer Science test questions)
Dharma Kshetri
 
6 c control statements branching &amp; jumping
6 c control statements branching &amp; jumping6 c control statements branching &amp; jumping
6 c control statements branching &amp; jumping
MomenMostafa
 

Similar to Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 2 of 5 by Arun Umrao (20)

Operators in C++.pptx
Operators in C++.pptxOperators in C++.pptx
Operators in C++.pptx
ssuser41748c
 
booksoncprogramminglanguage-anintroductiontobeginnersbyarunumrao4-21101016591...
booksoncprogramminglanguage-anintroductiontobeginnersbyarunumrao4-21101016591...booksoncprogramminglanguage-anintroductiontobeginnersbyarunumrao4-21101016591...
booksoncprogramminglanguage-anintroductiontobeginnersbyarunumrao4-21101016591...
GkhanGirgin3
 
6 operators-in-c
6 operators-in-c6 operators-in-c
6 operators-in-c
Rohit Shrivastava
 
6 operators-in-c
6 operators-in-c6 operators-in-c
6 operators-in-c
Rohit Shrivastava
 
introduction to c programming and C History.pptx
introduction to c programming and C History.pptxintroduction to c programming and C History.pptx
introduction to c programming and C History.pptx
ManojKhadilkar1
 
Bit manipulation
Bit manipulationBit manipulation
Bit manipulation
UthraSowrirajan1
 
C operators
C operatorsC operators
C operators
Rupanshi rawat
 
C Operators and Control Structures.pptx
C Operators and Control Structures.pptxC Operators and Control Structures.pptx
C Operators and Control Structures.pptx
ramanathan2006
 
C programming(Part 1)
C programming(Part 1)C programming(Part 1)
C programming(Part 1)
Dr. SURBHI SAROHA
 
C Operators and Control Structures.pdf
C Operators and Control Structures.pdfC Operators and Control Structures.pdf
C Operators and Control Structures.pdf
MaryJacob24
 
btwggggggggggggggggggggggggggggggisop correct (1).pptx
btwggggggggggggggggggggggggggggggisop correct (1).pptxbtwggggggggggggggggggggggggggggggisop correct (1).pptx
btwggggggggggggggggggggggggggggggisop correct (1).pptx
Orin18
 
Chapter 5
Chapter 5Chapter 5
Chapter 5
EasyStudy3
 
Control Flow Statements and Datatypes in C
Control Flow Statements and Datatypes in CControl Flow Statements and Datatypes in C
Control Flow Statements and Datatypes in C
PRABHAKARK24
 
ICP - Lecture 5
ICP - Lecture 5ICP - Lecture 5
ICP - Lecture 5
Hassaan Rahman
 
Theory3
Theory3Theory3
Theory3
Dr.M.Karthika parthasarathy
 
Expressions using operator in c
Expressions using operator in cExpressions using operator in c
Expressions using operator in c
Saranya saran
 
Python : basic operators
Python : basic operatorsPython : basic operators
Python : basic operators
S.M. Salaquzzaman
 
C++ revision add on till now
C++ revision add on till nowC++ revision add on till now
C++ revision add on till now
AmAn Singh
 
C++ revision add on till now
C++ revision add on till nowC++ revision add on till now
C++ revision add on till now
AmAn Singh
 
C++ chapter 2
C++ chapter 2C++ chapter 2
C++ chapter 2
SHRIRANG PINJARKAR
 
Operators in C++.pptx
Operators in C++.pptxOperators in C++.pptx
Operators in C++.pptx
ssuser41748c
 
booksoncprogramminglanguage-anintroductiontobeginnersbyarunumrao4-21101016591...
booksoncprogramminglanguage-anintroductiontobeginnersbyarunumrao4-21101016591...booksoncprogramminglanguage-anintroductiontobeginnersbyarunumrao4-21101016591...
booksoncprogramminglanguage-anintroductiontobeginnersbyarunumrao4-21101016591...
GkhanGirgin3
 
introduction to c programming and C History.pptx
introduction to c programming and C History.pptxintroduction to c programming and C History.pptx
introduction to c programming and C History.pptx
ManojKhadilkar1
 
C Operators and Control Structures.pptx
C Operators and Control Structures.pptxC Operators and Control Structures.pptx
C Operators and Control Structures.pptx
ramanathan2006
 
C Operators and Control Structures.pdf
C Operators and Control Structures.pdfC Operators and Control Structures.pdf
C Operators and Control Structures.pdf
MaryJacob24
 
btwggggggggggggggggggggggggggggggisop correct (1).pptx
btwggggggggggggggggggggggggggggggisop correct (1).pptxbtwggggggggggggggggggggggggggggggisop correct (1).pptx
btwggggggggggggggggggggggggggggggisop correct (1).pptx
Orin18
 
Control Flow Statements and Datatypes in C
Control Flow Statements and Datatypes in CControl Flow Statements and Datatypes in C
Control Flow Statements and Datatypes in C
PRABHAKARK24
 
Expressions using operator in c
Expressions using operator in cExpressions using operator in c
Expressions using operator in c
Saranya saran
 
C++ revision add on till now
C++ revision add on till nowC++ revision add on till now
C++ revision add on till now
AmAn Singh
 
C++ revision add on till now
C++ revision add on till nowC++ revision add on till now
C++ revision add on till now
AmAn Singh
 
Ad

More from ssuserd6b1fd (20)

Notes for c programming for mca, bca, b. tech cse, ece and msc (cs) 1 of 5 by...
Notes for c programming for mca, bca, b. tech cse, ece and msc (cs) 1 of 5 by...Notes for c programming for mca, bca, b. tech cse, ece and msc (cs) 1 of 5 by...
Notes for c programming for mca, bca, b. tech cse, ece and msc (cs) 1 of 5 by...
ssuserd6b1fd
 
Decreasing increasing functions by arun umrao
Decreasing increasing functions by arun umraoDecreasing increasing functions by arun umrao
Decreasing increasing functions by arun umrao
ssuserd6b1fd
 
Distribution of normal data understanding it numerical way by arun umrao
Distribution of normal data   understanding it numerical way by arun umraoDistribution of normal data   understanding it numerical way by arun umrao
Distribution of normal data understanding it numerical way by arun umrao
ssuserd6b1fd
 
Decreasing and increasing functions by arun umrao
Decreasing and increasing functions by arun umraoDecreasing and increasing functions by arun umrao
Decreasing and increasing functions by arun umrao
ssuserd6b1fd
 
What is meaning of epsilon and delta in limits of a function by Arun Umrao
What is meaning of epsilon and delta in limits of a function by Arun UmraoWhat is meaning of epsilon and delta in limits of a function by Arun Umrao
What is meaning of epsilon and delta in limits of a function by Arun Umrao
ssuserd6b1fd
 
Notes for GNU Octave - Numerical Programming - for Students 01 of 02 by Arun ...
Notes for GNU Octave - Numerical Programming - for Students 01 of 02 by Arun ...Notes for GNU Octave - Numerical Programming - for Students 01 of 02 by Arun ...
Notes for GNU Octave - Numerical Programming - for Students 01 of 02 by Arun ...
ssuserd6b1fd
 
Notes for C++ Programming / Object Oriented C++ Programming for MCA, BCA and ...
Notes for C++ Programming / Object Oriented C++ Programming for MCA, BCA and ...Notes for C++ Programming / Object Oriented C++ Programming for MCA, BCA and ...
Notes for C++ Programming / Object Oriented C++ Programming for MCA, BCA and ...
ssuserd6b1fd
 
Think Like Scilab and Become a Numerical Programming Expert- Notes for Beginn...
Think Like Scilab and Become a Numerical Programming Expert- Notes for Beginn...Think Like Scilab and Become a Numerical Programming Expert- Notes for Beginn...
Think Like Scilab and Become a Numerical Programming Expert- Notes for Beginn...
ssuserd6b1fd
 
Think Like Scilab and Become a Numerical Programming Expert- Notes for Beginn...
Think Like Scilab and Become a Numerical Programming Expert- Notes for Beginn...Think Like Scilab and Become a Numerical Programming Expert- Notes for Beginn...
Think Like Scilab and Become a Numerical Programming Expert- Notes for Beginn...
ssuserd6b1fd
 
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 1 of 5 by...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 1 of 5 by...Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 1 of 5 by...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 1 of 5 by...
ssuserd6b1fd
 
Notes and Description for Xcos Scilab Block Simulation with Suitable Examples...
Notes and Description for Xcos Scilab Block Simulation with Suitable Examples...Notes and Description for Xcos Scilab Block Simulation with Suitable Examples...
Notes and Description for Xcos Scilab Block Simulation with Suitable Examples...
ssuserd6b1fd
 
Work and Energy Notes by Arun Umrao
Work and Energy Notes by Arun UmraoWork and Energy Notes by Arun Umrao
Work and Energy Notes by Arun Umrao
ssuserd6b1fd
 
Notes of Units, Dimensions & Errors for IIT JEE by Arun Umrao
Notes of Units, Dimensions & Errors for IIT JEE by Arun UmraoNotes of Units, Dimensions & Errors for IIT JEE by Arun Umrao
Notes of Units, Dimensions & Errors for IIT JEE by Arun Umrao
ssuserd6b1fd
 
Physics dictionary for CBSE, ISCE, Class X Students by Arun Umrao
Physics dictionary for CBSE, ISCE, Class X Students by Arun UmraoPhysics dictionary for CBSE, ISCE, Class X Students by Arun Umrao
Physics dictionary for CBSE, ISCE, Class X Students by Arun Umrao
ssuserd6b1fd
 
Java Programming Notes for Beginners by Arun Umrao
Java Programming Notes for Beginners by Arun UmraoJava Programming Notes for Beginners by Arun Umrao
Java Programming Notes for Beginners by Arun Umrao
ssuserd6b1fd
 
Notes of 8085 micro processor Programming for BCA, MCA, MSC (CS), MSC (IT) &...
Notes of 8085 micro processor Programming  for BCA, MCA, MSC (CS), MSC (IT) &...Notes of 8085 micro processor Programming  for BCA, MCA, MSC (CS), MSC (IT) &...
Notes of 8085 micro processor Programming for BCA, MCA, MSC (CS), MSC (IT) &...
ssuserd6b1fd
 
Notes of 8051 Micro Controller for BCA, MCA, MSC (CS), MSC (IT) & AMIE IEI- b...
Notes of 8051 Micro Controller for BCA, MCA, MSC (CS), MSC (IT) & AMIE IEI- b...Notes of 8051 Micro Controller for BCA, MCA, MSC (CS), MSC (IT) & AMIE IEI- b...
Notes of 8051 Micro Controller for BCA, MCA, MSC (CS), MSC (IT) & AMIE IEI- b...
ssuserd6b1fd
 
Modlica an introduction by Arun Umrao
Modlica an introduction by Arun UmraoModlica an introduction by Arun Umrao
Modlica an introduction by Arun Umrao
ssuserd6b1fd
 
Maxima CAS an introduction
Maxima CAS an introductionMaxima CAS an introduction
Maxima CAS an introduction
ssuserd6b1fd
 
Maxima & Minima of Functions - Differential Calculus by Arun Umrao
Maxima & Minima of Functions - Differential Calculus by Arun UmraoMaxima & Minima of Functions - Differential Calculus by Arun Umrao
Maxima & Minima of Functions - Differential Calculus by Arun Umrao
ssuserd6b1fd
 
Notes for c programming for mca, bca, b. tech cse, ece and msc (cs) 1 of 5 by...
Notes for c programming for mca, bca, b. tech cse, ece and msc (cs) 1 of 5 by...Notes for c programming for mca, bca, b. tech cse, ece and msc (cs) 1 of 5 by...
Notes for c programming for mca, bca, b. tech cse, ece and msc (cs) 1 of 5 by...
ssuserd6b1fd
 
Decreasing increasing functions by arun umrao
Decreasing increasing functions by arun umraoDecreasing increasing functions by arun umrao
Decreasing increasing functions by arun umrao
ssuserd6b1fd
 
Distribution of normal data understanding it numerical way by arun umrao
Distribution of normal data   understanding it numerical way by arun umraoDistribution of normal data   understanding it numerical way by arun umrao
Distribution of normal data understanding it numerical way by arun umrao
ssuserd6b1fd
 
Decreasing and increasing functions by arun umrao
Decreasing and increasing functions by arun umraoDecreasing and increasing functions by arun umrao
Decreasing and increasing functions by arun umrao
ssuserd6b1fd
 
What is meaning of epsilon and delta in limits of a function by Arun Umrao
What is meaning of epsilon and delta in limits of a function by Arun UmraoWhat is meaning of epsilon and delta in limits of a function by Arun Umrao
What is meaning of epsilon and delta in limits of a function by Arun Umrao
ssuserd6b1fd
 
Notes for GNU Octave - Numerical Programming - for Students 01 of 02 by Arun ...
Notes for GNU Octave - Numerical Programming - for Students 01 of 02 by Arun ...Notes for GNU Octave - Numerical Programming - for Students 01 of 02 by Arun ...
Notes for GNU Octave - Numerical Programming - for Students 01 of 02 by Arun ...
ssuserd6b1fd
 
Notes for C++ Programming / Object Oriented C++ Programming for MCA, BCA and ...
Notes for C++ Programming / Object Oriented C++ Programming for MCA, BCA and ...Notes for C++ Programming / Object Oriented C++ Programming for MCA, BCA and ...
Notes for C++ Programming / Object Oriented C++ Programming for MCA, BCA and ...
ssuserd6b1fd
 
Think Like Scilab and Become a Numerical Programming Expert- Notes for Beginn...
Think Like Scilab and Become a Numerical Programming Expert- Notes for Beginn...Think Like Scilab and Become a Numerical Programming Expert- Notes for Beginn...
Think Like Scilab and Become a Numerical Programming Expert- Notes for Beginn...
ssuserd6b1fd
 
Think Like Scilab and Become a Numerical Programming Expert- Notes for Beginn...
Think Like Scilab and Become a Numerical Programming Expert- Notes for Beginn...Think Like Scilab and Become a Numerical Programming Expert- Notes for Beginn...
Think Like Scilab and Become a Numerical Programming Expert- Notes for Beginn...
ssuserd6b1fd
 
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 1 of 5 by...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 1 of 5 by...Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 1 of 5 by...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 1 of 5 by...
ssuserd6b1fd
 
Notes and Description for Xcos Scilab Block Simulation with Suitable Examples...
Notes and Description for Xcos Scilab Block Simulation with Suitable Examples...Notes and Description for Xcos Scilab Block Simulation with Suitable Examples...
Notes and Description for Xcos Scilab Block Simulation with Suitable Examples...
ssuserd6b1fd
 
Work and Energy Notes by Arun Umrao
Work and Energy Notes by Arun UmraoWork and Energy Notes by Arun Umrao
Work and Energy Notes by Arun Umrao
ssuserd6b1fd
 
Notes of Units, Dimensions & Errors for IIT JEE by Arun Umrao
Notes of Units, Dimensions & Errors for IIT JEE by Arun UmraoNotes of Units, Dimensions & Errors for IIT JEE by Arun Umrao
Notes of Units, Dimensions & Errors for IIT JEE by Arun Umrao
ssuserd6b1fd
 
Physics dictionary for CBSE, ISCE, Class X Students by Arun Umrao
Physics dictionary for CBSE, ISCE, Class X Students by Arun UmraoPhysics dictionary for CBSE, ISCE, Class X Students by Arun Umrao
Physics dictionary for CBSE, ISCE, Class X Students by Arun Umrao
ssuserd6b1fd
 
Java Programming Notes for Beginners by Arun Umrao
Java Programming Notes for Beginners by Arun UmraoJava Programming Notes for Beginners by Arun Umrao
Java Programming Notes for Beginners by Arun Umrao
ssuserd6b1fd
 
Notes of 8085 micro processor Programming for BCA, MCA, MSC (CS), MSC (IT) &...
Notes of 8085 micro processor Programming  for BCA, MCA, MSC (CS), MSC (IT) &...Notes of 8085 micro processor Programming  for BCA, MCA, MSC (CS), MSC (IT) &...
Notes of 8085 micro processor Programming for BCA, MCA, MSC (CS), MSC (IT) &...
ssuserd6b1fd
 
Notes of 8051 Micro Controller for BCA, MCA, MSC (CS), MSC (IT) & AMIE IEI- b...
Notes of 8051 Micro Controller for BCA, MCA, MSC (CS), MSC (IT) & AMIE IEI- b...Notes of 8051 Micro Controller for BCA, MCA, MSC (CS), MSC (IT) & AMIE IEI- b...
Notes of 8051 Micro Controller for BCA, MCA, MSC (CS), MSC (IT) & AMIE IEI- b...
ssuserd6b1fd
 
Modlica an introduction by Arun Umrao
Modlica an introduction by Arun UmraoModlica an introduction by Arun Umrao
Modlica an introduction by Arun Umrao
ssuserd6b1fd
 
Maxima CAS an introduction
Maxima CAS an introductionMaxima CAS an introduction
Maxima CAS an introduction
ssuserd6b1fd
 
Maxima & Minima of Functions - Differential Calculus by Arun Umrao
Maxima & Minima of Functions - Differential Calculus by Arun UmraoMaxima & Minima of Functions - Differential Calculus by Arun Umrao
Maxima & Minima of Functions - Differential Calculus by Arun Umrao
ssuserd6b1fd
 
Ad

Recently uploaded (20)

UPMVLE migration to ARAL. A step- by- step guide
UPMVLE migration to ARAL. A step- by- step guideUPMVLE migration to ARAL. A step- by- step guide
UPMVLE migration to ARAL. A step- by- step guide
abmerca
 
Final Evaluation.docx...........................
Final Evaluation.docx...........................Final Evaluation.docx...........................
Final Evaluation.docx...........................
l1bbyburrell
 
Botany Assignment Help Guide - Academic Excellence
Botany Assignment Help Guide - Academic ExcellenceBotany Assignment Help Guide - Academic Excellence
Botany Assignment Help Guide - Academic Excellence
online college homework help
 
Ancient Stone Sculptures of India: As a Source of Indian History
Ancient Stone Sculptures of India: As a Source of Indian HistoryAncient Stone Sculptures of India: As a Source of Indian History
Ancient Stone Sculptures of India: As a Source of Indian History
Virag Sontakke
 
*"Sensing the World: Insect Sensory Systems"*
*"Sensing the World: Insect Sensory Systems"**"Sensing the World: Insect Sensory Systems"*
*"Sensing the World: Insect Sensory Systems"*
Arshad Shaikh
 
Cultivation Practice of Garlic in Nepal.pptx
Cultivation Practice of Garlic in Nepal.pptxCultivation Practice of Garlic in Nepal.pptx
Cultivation Practice of Garlic in Nepal.pptx
UmeshTimilsina1
 
History Of The Monastery Of Mor Gabriel Philoxenos Yuhanon Dolabani
History Of The Monastery Of Mor Gabriel Philoxenos Yuhanon DolabaniHistory Of The Monastery Of Mor Gabriel Philoxenos Yuhanon Dolabani
History Of The Monastery Of Mor Gabriel Philoxenos Yuhanon Dolabani
fruinkamel7m
 
CNS infections (encephalitis, meningitis & Brain abscess
CNS infections (encephalitis, meningitis & Brain abscessCNS infections (encephalitis, meningitis & Brain abscess
CNS infections (encephalitis, meningitis & Brain abscess
Mohamed Rizk Khodair
 
All About the 990 Unlocking Its Mysteries and Its Power.pdf
All About the 990 Unlocking Its Mysteries and Its Power.pdfAll About the 990 Unlocking Its Mysteries and Its Power.pdf
All About the 990 Unlocking Its Mysteries and Its Power.pdf
TechSoup
 
E-Filing_of_Income_Tax.pptx and concept of form 26AS
E-Filing_of_Income_Tax.pptx and concept of form 26ASE-Filing_of_Income_Tax.pptx and concept of form 26AS
E-Filing_of_Income_Tax.pptx and concept of form 26AS
Abinash Palangdar
 
What is the Philosophy of Statistics? (and how I was drawn to it)
What is the Philosophy of Statistics? (and how I was drawn to it)What is the Philosophy of Statistics? (and how I was drawn to it)
What is the Philosophy of Statistics? (and how I was drawn to it)
jemille6
 
Myasthenia gravis (Neuromuscular disorder)
Myasthenia gravis (Neuromuscular disorder)Myasthenia gravis (Neuromuscular disorder)
Myasthenia gravis (Neuromuscular disorder)
Mohamed Rizk Khodair
 
Form View Attributes in Odoo 18 - Odoo Slides
Form View Attributes in Odoo 18 - Odoo SlidesForm View Attributes in Odoo 18 - Odoo Slides
Form View Attributes in Odoo 18 - Odoo Slides
Celine George
 
How to Manage Amounts in Local Currency in Odoo 18 Purchase
How to Manage Amounts in Local Currency in Odoo 18 PurchaseHow to Manage Amounts in Local Currency in Odoo 18 Purchase
How to Manage Amounts in Local Currency in Odoo 18 Purchase
Celine George
 
How to Create Kanban View in Odoo 18 - Odoo Slides
How to Create Kanban View in Odoo 18 - Odoo SlidesHow to Create Kanban View in Odoo 18 - Odoo Slides
How to Create Kanban View in Odoo 18 - Odoo Slides
Celine George
 
LDMMIA Reiki Yoga S5 Daily Living Workshop
LDMMIA Reiki Yoga S5 Daily Living WorkshopLDMMIA Reiki Yoga S5 Daily Living Workshop
LDMMIA Reiki Yoga S5 Daily Living Workshop
LDM Mia eStudios
 
How to Configure Public Holidays & Mandatory Days in Odoo 18
How to Configure Public Holidays & Mandatory Days in Odoo 18How to Configure Public Holidays & Mandatory Days in Odoo 18
How to Configure Public Holidays & Mandatory Days in Odoo 18
Celine George
 
antiquity of writing in ancient India- literary & archaeological evidence
antiquity of writing in ancient India- literary & archaeological evidenceantiquity of writing in ancient India- literary & archaeological evidence
antiquity of writing in ancient India- literary & archaeological evidence
PrachiSontakke5
 
Chemotherapy of Malignancy -Anticancer.pptx
Chemotherapy of Malignancy -Anticancer.pptxChemotherapy of Malignancy -Anticancer.pptx
Chemotherapy of Malignancy -Anticancer.pptx
Mayuri Chavan
 
Cultivation Practice of Onion in Nepal.pptx
Cultivation Practice of Onion in Nepal.pptxCultivation Practice of Onion in Nepal.pptx
Cultivation Practice of Onion in Nepal.pptx
UmeshTimilsina1
 
UPMVLE migration to ARAL. A step- by- step guide
UPMVLE migration to ARAL. A step- by- step guideUPMVLE migration to ARAL. A step- by- step guide
UPMVLE migration to ARAL. A step- by- step guide
abmerca
 
Final Evaluation.docx...........................
Final Evaluation.docx...........................Final Evaluation.docx...........................
Final Evaluation.docx...........................
l1bbyburrell
 
Botany Assignment Help Guide - Academic Excellence
Botany Assignment Help Guide - Academic ExcellenceBotany Assignment Help Guide - Academic Excellence
Botany Assignment Help Guide - Academic Excellence
online college homework help
 
Ancient Stone Sculptures of India: As a Source of Indian History
Ancient Stone Sculptures of India: As a Source of Indian HistoryAncient Stone Sculptures of India: As a Source of Indian History
Ancient Stone Sculptures of India: As a Source of Indian History
Virag Sontakke
 
*"Sensing the World: Insect Sensory Systems"*
*"Sensing the World: Insect Sensory Systems"**"Sensing the World: Insect Sensory Systems"*
*"Sensing the World: Insect Sensory Systems"*
Arshad Shaikh
 
Cultivation Practice of Garlic in Nepal.pptx
Cultivation Practice of Garlic in Nepal.pptxCultivation Practice of Garlic in Nepal.pptx
Cultivation Practice of Garlic in Nepal.pptx
UmeshTimilsina1
 
History Of The Monastery Of Mor Gabriel Philoxenos Yuhanon Dolabani
History Of The Monastery Of Mor Gabriel Philoxenos Yuhanon DolabaniHistory Of The Monastery Of Mor Gabriel Philoxenos Yuhanon Dolabani
History Of The Monastery Of Mor Gabriel Philoxenos Yuhanon Dolabani
fruinkamel7m
 
CNS infections (encephalitis, meningitis & Brain abscess
CNS infections (encephalitis, meningitis & Brain abscessCNS infections (encephalitis, meningitis & Brain abscess
CNS infections (encephalitis, meningitis & Brain abscess
Mohamed Rizk Khodair
 
All About the 990 Unlocking Its Mysteries and Its Power.pdf
All About the 990 Unlocking Its Mysteries and Its Power.pdfAll About the 990 Unlocking Its Mysteries and Its Power.pdf
All About the 990 Unlocking Its Mysteries and Its Power.pdf
TechSoup
 
E-Filing_of_Income_Tax.pptx and concept of form 26AS
E-Filing_of_Income_Tax.pptx and concept of form 26ASE-Filing_of_Income_Tax.pptx and concept of form 26AS
E-Filing_of_Income_Tax.pptx and concept of form 26AS
Abinash Palangdar
 
What is the Philosophy of Statistics? (and how I was drawn to it)
What is the Philosophy of Statistics? (and how I was drawn to it)What is the Philosophy of Statistics? (and how I was drawn to it)
What is the Philosophy of Statistics? (and how I was drawn to it)
jemille6
 
Myasthenia gravis (Neuromuscular disorder)
Myasthenia gravis (Neuromuscular disorder)Myasthenia gravis (Neuromuscular disorder)
Myasthenia gravis (Neuromuscular disorder)
Mohamed Rizk Khodair
 
Form View Attributes in Odoo 18 - Odoo Slides
Form View Attributes in Odoo 18 - Odoo SlidesForm View Attributes in Odoo 18 - Odoo Slides
Form View Attributes in Odoo 18 - Odoo Slides
Celine George
 
How to Manage Amounts in Local Currency in Odoo 18 Purchase
How to Manage Amounts in Local Currency in Odoo 18 PurchaseHow to Manage Amounts in Local Currency in Odoo 18 Purchase
How to Manage Amounts in Local Currency in Odoo 18 Purchase
Celine George
 
How to Create Kanban View in Odoo 18 - Odoo Slides
How to Create Kanban View in Odoo 18 - Odoo SlidesHow to Create Kanban View in Odoo 18 - Odoo Slides
How to Create Kanban View in Odoo 18 - Odoo Slides
Celine George
 
LDMMIA Reiki Yoga S5 Daily Living Workshop
LDMMIA Reiki Yoga S5 Daily Living WorkshopLDMMIA Reiki Yoga S5 Daily Living Workshop
LDMMIA Reiki Yoga S5 Daily Living Workshop
LDM Mia eStudios
 
How to Configure Public Holidays & Mandatory Days in Odoo 18
How to Configure Public Holidays & Mandatory Days in Odoo 18How to Configure Public Holidays & Mandatory Days in Odoo 18
How to Configure Public Holidays & Mandatory Days in Odoo 18
Celine George
 
antiquity of writing in ancient India- literary & archaeological evidence
antiquity of writing in ancient India- literary & archaeological evidenceantiquity of writing in ancient India- literary & archaeological evidence
antiquity of writing in ancient India- literary & archaeological evidence
PrachiSontakke5
 
Chemotherapy of Malignancy -Anticancer.pptx
Chemotherapy of Malignancy -Anticancer.pptxChemotherapy of Malignancy -Anticancer.pptx
Chemotherapy of Malignancy -Anticancer.pptx
Mayuri Chavan
 
Cultivation Practice of Onion in Nepal.pptx
Cultivation Practice of Onion in Nepal.pptxCultivation Practice of Onion in Nepal.pptx
Cultivation Practice of Onion in Nepal.pptx
UmeshTimilsina1
 

Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 2 of 5 by Arun Umrao

  • 1. 1.4. C OPERATORS 101 Operator Description << Left shift >> Right shift In the following figure, a character byte is shifted by one bit in right ward. After shifting of bits of the byte, new value is different from the old value. 1 0 0 1 1 0 1 1 ch 0 1 0 0 1 1 0 1 1 ch >> 1 One byte Above, a byte is shifted rightward by one place. Note that, in computer memory, data is arranged in continuous memory bytes. Here, the LSB bit, that is shifted rightward appears that it takes place of its neighbouring bit which is beyond the range of original memory byte. But actually, in bit shift, shifted bit does not over write to the data stored in its neighbouring memory byte but it is eliminated from its original place to create space for storing of its leftward bit. 1 0 0 1 1 0 1 1 ch 1 0 0 1 1 0 1 1 0 0 ch << 1 One byte Figure 1.3: Left shift of bits by one place. Above, a byte is shifted leftward by one place. In the similar principle to the rightward bitshift, shifted bit does not over write to the data stored in its neighbouring memory byte but it is eliminated from its original place to create space for storing of its rightward bit. Example is given below: ✞ 1 #include <stdio.h> 3 int main () { /* Bit pattern of decimal 4 is *
  • 2. 102 Basic C 5 *equivalent to binary 100 */ int i = 4; 7 /* Number of places take place by binary shift.*/ int j = 2; 9 /* << makes 100 to 10000 & print "16" */ printf("<< of %d, %d is %d.n", i, j, i << j); 11 /* >> makes 100 to 1 & print "1"*/ printf(">> of %d, %d is %d.n", i, j, i >> j); 13 return 0; } ✌ ✆ ✞ << of 4, 2 is 16. >> of 4, 2 is 1. ✌ ✆ If a data type is unsigned type and it is assigned a negative number then its bit shift takes placed for whole bits as shown in the following example. Note that, the vacated bits are filled with zero bits. ✞ #include <stdio.h> 2 int main () { 4 unsigned char f = 0, c = -16; printf("Original Number %dn", c); 6 f = c >> 2; printf(">> shifts number and number becomes %dn", f); 8 f = c << 2; printf("<< shifts number and number becomes %dn", f); 10 return 0; } ✌ ✆ ✞ Original Number 240 >> shifts number and number becomes 60 << shifts number and number becomes 192 ✌ ✆ If a data type is signed type and it is assigned a negative number then its bit shift takes placed for whole bits except the sign bit (MSB) as shown in the following example. Note that, the vacated bits are filled with zero bits. ✞ 1 #include <stdio.h> 3 int main () { signed char f = 0, c = -16; 5 printf("Original Number %dn", c); f = c >> 2; 7 printf(">> shifts number and number becomes %dn", f); f = c << 2; 9 printf("<< shifts number and number becomes %dn", f); return 0; 11 } ✌ ✆
  • 3. 1.4. C OPERATORS 103 ✞ Original Number -16 >> shifts number and number becomes -4 << shifts number and number becomes -64 ✌ ✆ Bitwise AND & XOR relations may also be used to add two number. AND operation tells the positions of bits where carry generated and this carry is to be shifted/added to leftside bit. XOR operation is used to get the binary addition ignoring carry generated if anywhere. ✞ 1 #include <stdio.h> 3 int main () { unsigned int x = 30, y = 1, sum , carry; 5 /* ---------------------------** * Decimal 30 is binary 11110 7 * Decimal 01 is binary 00001 * XOR Operation is 9 * 11110 * 00001 11 * --------- * S= 11111 13 **--------------------------- */ sum = x ^ y; 15 /* ---------------------------** * Decimal 30 is binary 11110 17 * Decimal 01 is binary 00001 * AND Operation is 19 * 11110 * 00001 21 * ---------- * C = 00000 23 **--------------------------- */ carry = x & y; 25 /* Performed loop until last carry is not zero .*/ while (carry != 0) { 27 /* ----------------------------------------** * Left shift of carry is 29 * C_s = 000000 * This operation is performed to shift 31 * the carry left hand side by one place * to add it with next higher place value. 33 **---------------------------------------- */ carry = carry << 1; 35 /* Take x as sum value from XOR Operation .*/ x = sum; 37 /* Take y as carry value form * * left shift of AND Operation .*/ 39 y = carry; /* Take XOR Operation of x and y*/ 41 sum = x ^ y; /* Get the next carry.*/
  • 4. 104 Basic C 43 carry = x & y; } 45 /* Print the sum 31. */ printf("Sum of %d and %d is : %dn", x, y, sum); 47 return 0; } ✌ ✆ ✞ Sum of 30 and 1 is 31 ✌ ✆ Binary shift operation can be performed in characters and strings. It is explained in the example given below. ✞ 1 #include <stdio.h> 3 int main () { char a[ ]="a";/* Binary equivalent -1100001 */ 5 char b[ ]="b";/* Binary equivalent -1100010 */ char c[ ]="c";/* Binary equivalent -1100011 */ 7 /* ----------------------------------------------* << of a by 16 places 11000010000000000000000 9 << of b by 8 places 110001000000000 << of a by 0 places 1100011 11 ---------------------------------------------- OR Operation 11000010110001001100011 13 Hexadecimal 616263 *---------------------------------------------- */ 15 printf("Left binary bit shift %xhn") printf (*a << 16 | *b <<8 | *c); 17 return 0; } ✌ ✆ ✞ Left binary bit shift is 616263h ✌ ✆ The unary operator ‘∼’ returns the one’s complements of an integer by changing bit ‘0’ into ‘1’ and viceversa. ✞ 1 #include <stdio.h> #include <stdlib.h> 3 int main (void ) { 5 int j = 0; printf("Bitwise ~ operation on an integer .n"); 7 while (j < 3) { printf("%d => %dn", j,~j); 9 j++; } 11 return EXIT_SUCCESS ; } ✌ ✆
  • 5. 1.4. C OPERATORS 105 ✞ Bitwise ~ operation on an integer. 0 => -1 1 => -2 2 => -3 ✌ ✆ Note that, shift operator is applied only to those byte(s) which are pointed by the variable. On shift operation, values of neighbouring bytes remain unaffected and un-altered. It means, in shift operation, bits are neither borrows nor carryover from or to neighbouring memory bytes. See the example below: ✞ #include <stdio.h> 2 int main () { 4 int a = 320; /* Integer 320 = binary 00000001 01000000 */ 6 char *ptr; ptr = (char *) &a; 8 char ca = *ptr; /* Get 01000000 as decimal 64*/ 10 char cb = *(++ ptr); /* Get 00000001 as decimal 1*/ 12 printf("%d ", ca); printf("%d ", cb); 14 cb = (cb << 5); /* Shift the value of cb.*/ 16 printf("%d ", ca);/* Print 01000000 as decimal 64*/ 18 printf("%d ", cb);/* Print 00100000 as decimal 32*/ 20 return 0; } ✌ ✆ ✞ 64 1 64 32 ✌ ✆ In above example, bit shift of ‘cb’ does not affects the value of ‘ca’ any way. 1.4.9 Condition & Relation Operators If a condition is true then successive value is taken otherwise next value. The simplest form of this operator is ✞ 1 x ? y : z ✌ ✆ See the example below: ✞ 1 #include <stdio.h> #include <io.h> 3 /* Return true if file exist other wise return false. */
  • 6. 106 Basic C 5 int file_exists (char *filename ) { return (access(filename , 0) == 0); 7 } 9 main () { printf("Does myfile.au exist: %sn", 11 file_exists ("myfile.au") ? "YES" : "NO"); } ✌ ✆ ✞ Does myfile.au exist: NO ✌ ✆ 1.4.10 Lexical Comparison Lexical comparison is performed between two strings having alpha-numeric and special characters. Both strings are compared character-by-character and comparison is done between the charcter codes. For example, ‘a’ and ‘A’ are same characters but their character codes are 97 and 65 respectively. Therefore, in lexical comparison, character ‘a’ is larger than ‘A’. s i m p l e str1 s i M p l e str2 Lexical comparision between strings “simple” and “siMple” is taken character by character. In ASCII character codes, character “M” came before to “m”, this is why in character by character comparison, ‘str1’ is greater than the ‘str2’. 1.4.11 Arithmetic Operators Arithmetic operators are given in the following table.
  • 7. 1.4. C OPERATORS 107 Operator Description + Addition operator. It adds the right value with left value. − Subtraction operator. It subtracts the right value from left value. / Division operator. It divides the left value with right value. Returns the quotient. If, both left and right values are integer then decimal part of the re- sult is truncated. ∗ Multiplication operator. It multiply the left value with right value. Returns product of two numbers. % It is modulus operator. It returns the remainder of division between two num- bers. It accepts only integer type val- ues as its operands. = Assignment operator. A variable, at left side to it, is assigned the value at the right side of it. Table 1.15: Arithmetic operators. See the example below, in which addition and subtraction operators are used in a single expression. ✞ 1 #include <stdio.h> 3 int main () { int y; 5 /* In first step 5+3=8. In * * second step 8-4 = 4. As * 7 * + has higher precedence */ y = 5 + 3 - 4; 9 printf("Result is : %dn", y); return 0; 11 } ✌ ✆ ✞ Result is : 4 ✌ ✆ The grouping of terms in a mathematical expression, using parentheses is required to get correct result when an arithmetic operator is used multiple times. If grouping is not done then result is different. ✞ 1 #include <stdio.h>
  • 8. 108 Basic C 3 int main () { float a; 5 /* / operator is used thrice.* 7 *will be solved from L to R.*/ a = 20.0 / 10.0 / 2.0; 9 printf("Result is %fn", a); 11 /* First 10.0 is divided by 20.0 and* *then result will divide to 20.0 */ 13 a = 20.0 / (10.0 / 2.0) ; 15 printf("Result is %fn", a); return 0; 17 } ✌ ✆ ✞ Result is 1.000000 Result is 4.000000 ✌ ✆ If grouping is not done, i.e. there is no parentheses, then in C, expression is solved from left to right maintaining the precedence for mathematical operators. ✞ #include <stdio.h> 2 int main () { 4 float a; 6 /* / operator is used thrice.* *will be solved from L to R.*/ 8 a = 20.0 / 10.0 / 2.0; printf("Result is %fn", a); 10 a = 2.0 / 10.0 / 20.0; 12 printf("Result is %fn", a); return 0; 14 } ✌ ✆ ✞ Result is 1.000000 Result is 0.010000 ✌ ✆ Note that if operators in an expression or in a term of the expression are in same prece- dence level/order then they all are solved from left to right in the given expression. ✞ #include <stdio.h> 2 int main () { 4 int a; 6 /*Here , /, * and % operators are *
  • 9. 1.4. C OPERATORS 109 *in same precedence order. */ 8 a = 2 * 10 / 20 % 5; printf("Result is %dn", a); 10 a = 2 % 10 * 20 / 5; 12 printf("Result is %dn", a); return 0; 14 } ✌ ✆ ✞ Result is 1 Result is 8 ✌ ✆ Take another example as given below: ✞ #include <stdio.h> 2 int main () { 4 int a = 1, b = 2, c = 3; printf("%d", c > b > a); 6 return 0; } ✌ ✆ ✞ 0 ✌ ✆ In above case, first value of ‘c’ is compared with value of ‘b’ which is false as per expression, hence the result is ‘0’. Now this value is compared with value of ‘a’ which is again false as per expression, hence the final result is ‘0’. Now, modify the above example as given below: ✞ 1 #include <stdio.h> 3 int main () { int a = -1, b = 2, c = 3; 5 printf("%d", c > b > a); return 0; 7 } ✌ ✆ ✞ 1 ✌ ✆ Here first value of ‘c’ is compared with value of ‘b’ which is false as per expression, hence the result is ‘0’. Now this value is compared with value of ‘a’ which is true as per expression, hence the final result is ‘1’. 1.4.12 Relational Operators The relation and assignment operators are given in the table 1.16. The level of precedence of the operators given in table 1.16 are equal, hence, they are solved from left to right in an expression where they are present. See the following example, in which application of ‘+=’ operator is explained.
  • 10. 110 Basic C Operator Description == It accepts two operands and it meant that the operands are exactly equal. ∗ = Product and equal. Current value of left side is multiply by right side value and result is assigned to the left side variable. / = Divide and equal. Current value of left side is divided by right side value and result is assigned to the left side vari- able. + = Add and equal. Current value of left side is added by right side value and result is assigned to the left side variable. − = Subtract and equal. Current value of left side is subtracted by right side value and result is assigned to the left side variable. <<= Left shift and equal. It makes left shift to the current value of the left side variable by the exactly equal places to the number given in right side. Its operands are either integer or character only and shall not be precision values. >>= Right shift and equal. It makes right shift to the current value of the left side variable by the exactly equal places to the number given in right side. Its operands are either integer or character only and shall not be precision values. & = AND and equal. Perform AND operation between current value of left hand side variable and right hand side value and assign the result to left hand side variable. ˆ= Exclusive OR and equal. Perform Exclusive OR operation between current value of left hand side variable and right hand side value and assign the result to left hand side vari- able. | = Inclusive OR and equal. Perform Inclusive OR operation between current value of left hand side variable and right hand side value and assign the result to left hand side vari- able. Table 1.16: Relation & assignment operators.
  • 11. 1.4. C OPERATORS 111 ✞ 1 #include <stdio.h> 3 int main () { int y = 1; 5 y += 2;/*It is equal to y = y + 2;*/ printf("y is %dn", y); 7 int z = 1; z -= 2; /*It is equal to z = z - 2;*/ 9 printf("z is %dn", z); return 0; 11 } ✌ ✆ ✞ y is 3 z is -1 ✌ ✆ Following example is for ‘/=’ operator. ✞ #include <stdio.h> 2 int main () { 4 double y = 2.0; y /= 3.0; /* It is equal to y = y / 3.0; */ 6 printf("y is %fn", y); return 0; 8 } ✌ ✆ ✞ y is 0.66666 ✌ ✆ Example of left shift & equal and right shift & equal operators is given below. ✞ 1 #include <stdio.h> 3 int main () { int y = 9; 5 y <<= 2; /*It is equal to y = y << 2;*/ printf("y is %dn", y); 7 int z = 10; z >>= 2; /*It is equal to z = y >> 2;*/ 9 printf("z is %dn", z); return 0; 11 } ✌ ✆ ✞ y is 36 z is 2 ✌ ✆
  • 12. 112 Basic C 1.4.13 Bit Field A bit field is just a set of neighboring bits within a signed integer or an unsigned integer. The syntax of the bit field structure is ✞ struct { 2 unsigned int <field name > : <bit size >; unsigned int <field name > : <bit size >; 4 }; ✌ ✆ Or ✞ struct { 2 unsigned <field name > : <bit size >; unsigned <field name > : <bit size >; 4 }; ✌ ✆ Always remember that, bit size of field declared inside the bit field structure, can not be larger than the size of field. And unsigned integer is 4 byte long, hence bit size of it can not be larger than 8 × 4 = 32 bits. A bit field is set up with a structure declaration that labels each field and determines its width. ✞ struct { 2 unsigned int boldface : 1; unsigned int slant : 1; 4 } font ; ✌ ✆ This structure definition causes ‘font’ to contain two 1-bit fields. We can assigned the value to these structure field by ✞ font .slant =0; 2 font .boldface =1; ✌ ✆ It can be “pad” a field structure with unnamed holes by using unnamed field widths. Using an unnamed field width of 0 forces the next field to align with the next integer. ✞ struct { 2 unsigned int f1 : 1; unsigned int : 2; 4 unsigned int f2 : 3; } field; ✌ ✆ Often bit fields are used as a more compact way of storing data. ✞ 1 #include <stdio.h> 3 struct employee { unsigned id : 8;/* Or use unsigned int id :8;*/ 5 unsigned sex : 1;/* Or use unsigned int sex :1;*/ unsigned age : 7;/* Or use unsigned int age :7;*/ 7 };
  • 13. 1.4. C OPERATORS 113 9 int main () { struct employee EmpNo; 11 EmpNo.id = 102; EmpNo.sex = 1; 13 EmpNo.age = 15; printf("%dt%dt%dn", EmpNo.id , EmpNo.sex , EmpNo.age); 15 return 0; } ✌ ✆ ✞ 102 1 15 ✌ ✆ In above example, bits are filed from right to left direction. Here 8 bits are used for id, 1 bit for sex and 7 bit for age. In following example, natural color is made of three prime colors red, green and blue. To store these colors in program a three bit data storage is used. Bit Pattern Decimal Color 000 0 Black 001 1 Red 010 2 Green 011 3 Yellow 100 4 Blue 101 5 Magenta 110 6 Cyan 111 7 White Table 1.17: Bit color storing. These colors are used in structure ‘colstr’ and #define is used to create symbolic constants for the possible member values. ✞ 1 #include <stdio.h> #define BLUE 4 3 #define GREEN 2 #define RED 1 5 /* mixed colors */ #define BLACK 0 7 #define YELLOW (RED | GREEN) #define MAGENTA (RED | BLUE ) 9 #define CYAN (GREEN | BLUE ) #define WHITE (RED | GREEN | BLUE ) 11 const char * colors [8] = {"black", "red", "green", "yellow", "blue ", "magenta", "cyan ", "white"}; 13
  • 14. 114 Basic C struct colstr { 15 unsigned int fill_color : 2; unsigned int border_color : 4; 17 }; 19 void show_colrs (const struct colstr * pb); 21 int main (void ) { /* create and initialize box_props structure */ 23 struct colstr box = {YELLOW , GREEN}; printf("Original box settings :n"); 25 show_colrs (& box); box.fill_color = WHITE; 27 box.border_color = MAGENTA; printf("nModified box settings :n"); 29 show_colrs (& box); return 0; 31 } 33 void show_colrs (const struct colstr * pb) { printf("The fill color is %s.n", colors[pb ->fill_color ]); 35 printf("The border color is "); switch (pb ->border_color ) { 37 case MAGENTA: printf("magenta .n"); break; 39 case RED: printf("red.n"); break; 41 default : printf("unknown color.n"); break; 43 } } ✌ ✆ ✞ Original box settings : The fill color is yellow. The border color is unknown color. Modified box settings : The fill color is yellow. The border color is magenta . ✌ ✆ Size of bit field structure is determined by the number of fields and bit size of the fields. An unsigned integer is of word size of 4 byte. Hence minimum size of bit field structure is 4 byte. If there are four fields in a bit field structure then first four byte space is allotted to accommodate total bits of the fields of the bit field structure. If size of bits of all fields in a bitfield structure is larger than the 4 bytes then next four byte space is added to accommodate the all bits of fields of the bit field structure. Following examples clarify it correctly. ✞ 1 #include <stdio.h>
  • 15. 1.4. C OPERATORS 115 3 struct bitfield { /* First four byte (size of int) is allocated . */ 5 unsigned int a : 2; //2 bits + unsigned int b : 2; //2 bits +-> Total 5 bits < 32 bits 7 unsigned int c : 1; //1 bits + /* Though there are int fields but all* 9 * bits are accomodated in four bytes ,* * only four byte space is allocated . */ 11 }; 13 int main () { struct bitfield bF; 15 printf("Size of bitfield struct is : %d", sizeof (bF)); return 0; 17 } ✌ ✆ ✞ Size of bitfield struct is : 4 ✌ ✆ In following example the bit size of variables ‘a’, ‘b’ and ‘c’ are changed to 12, 12 and 1 respectively. Total sum of bits is 25 which is much lesser than 32. Hence size of structure is 4 byte. ✞ 1 #include <stdio.h> 3 struct bitfield { /* First four byte (size of int) is allocated .*/ 5 unsigned int a : 12; //12 bits + unsigned int b : 12; //12 bits +-> Total 25 bits < 32 bits 7 unsigned int c : 1; // 1 bits + /* Though there are int fields but all* 9 * bits are accomodated in four bytes ,* * only four byte space is allocated . */ 11 }; 13 int main () { struct bitfield bF; 15 printf("Size of bitfield struct is : %d", sizeof (bF)); return 0; 17 } ✌ ✆ ✞ Size of bitfield struct is : 4 ✌ ✆ In following example the bit size of variables ‘a’, ‘b’ and ‘c’ are changed to 12, 12 and 10 respectively. Total sum of bits is 34 which is larger than 32. Hence size of structure is 8 byte. ✞ 1 #include <stdio.h> 3 struct bitfield { /* First four byte (size of int) is allocated . */
  • 16. 116 Basic C 5 unsigned int a : 12; //12 bits + unsigned int b : 12; //12 bits +-> Total 34 bits > 32 bits 7 unsigned int c : 10; //10 bits + /* Though there are int fields but all * 9 * bits can not be accommodated in four * * bytes. Hence extra four bytes space * 11 * is allocated . Here total allocated * * space is 8 bytes long . Net bitfield * 13 * struct size is 8 bytes long . */ }; 15 int main () { 17 struct bitfield bF; printf("Size of bitfield struct is : %d", sizeof (bF)); 19 return 0; } ✌ ✆ ✞ Size of bitfield struct is : 8 ✌ ✆ A field of a bit field struct is assigned a numeric value, it is accepted as binary number. As the bit field is restricted to specific size, hence number of bits of a number equal to the size of bit field are taken. Counting of bits of given number is started from right to left upto the bit size of the bit field. Rest of the bits are truncated. These bits are stored in the structure memory space allocated previously. The order of storing data in memory space is from right to left and first field data is stored at right most and subsequent field data is stored leftword respectively. See following examples for clarification of this para. ✞ 1 #include <stdio.h> 3 struct bitfield { /* Last three bits 001 of binary * 5 * 00000001 are omitted and stored */ unsigned int a : 3; 7 /* Last three bits 100 of binary * * 00000100 are omitted and stored */ 9 unsigned int b : 3; /* Last three bits 111 of binary * 11 * 00110111 are omitted and stored */ unsigned int c : 3; 13 }; 15 int main () { /* Four byte space is created. */ 17 struct bitfield bF; bF.a = 1; /* Binary equivalent to 00000001 */ 19 bF.b = 4; /* Binary equivalent to 00000100 */ bF.c = 55;/* Binary equivalent to 00110111 */ 21 printf("Size of bitfield struct is : %dn", sizeof (bF)); printf("Bit field c has value : %dn", bF.c); 23 return 0;
  • 17. 1.4. C OPERATORS 117 } ✌ ✆ ✞ Size of bitfield struct is : 4 Bit field c has value : 7 ✌ ✆ In following example, bit size of bit field ‘c’ is changed to 5. Now the stored value in bit field ‘c’ is different to the data stored in previous example. ✞ #include <stdio.h> 2 struct bitfield { 4 /* Last three bits 001 of binary * * 00000001 are omitted and stored */ 6 unsigned int a : 3; /* Last three bits 100 of binary * 8 * 00000100 are omitted and stored */ unsigned int b : 3; 10 /* Last five bits 10111 of binary * * 00110111 are omitted and stored */ 12 unsigned int c : 5; }; 14 int main () { 16 struct bitfield bF; bF.a = 1; /* Binary equivalent to 00000001 */ 18 bF.b = 4; /* Binary equivalent to 00000100 */ bF.c = 55;/* Binary equivalent to 00110111 */ 20 printf("Size of bitfield struct is : %dn", sizeof (bF)); printf("Bit field c has value : %dn", bF.c); 22 return 0; } ✌ ✆ ✞ Size of bitfield struct is : 4 Bit field c has value : 23 ✌ ✆ In following example, it is try to explain that how bit field data is stored in the memory with help of pointer. The bitfield data is stored in memory created by struct from left to right. ✞ #include <stdio.h> 2 struct bitfield { 4 /* Last three bits 001 of binary * * 00000001 are omitted and stored */ 6 unsigned int a : 3; /* Last three bits 100 of binary * 8 * 00000100 are omitted and stored */ unsigned int b : 3; 10 /* Last five bits 10111 of binary * * 00110111 are omitted and stored */
  • 18. 118 Basic C 12 unsigned int c : 5; }; 14 int main () { 16 struct bitfield bF; bF.a = 1; /* Binary equivalent to 00000001 */ 18 bF.b = 4; /* Binary equivalent to 00000100 */ bF.c = 55;/* Binary equivalent to 00110111 */ 20 /* In memory the structure data * * is stored as 10111 100 001 * 22 * read data without white spaces */ char *p; 24 p = &bF; /* In memory the structure data is stored * 26 * as 10111 100 001*[<- pointer is here ] * * Above read data without white spaces */ 28 p++; /* 101*[<- pointer jumps here ] 11 100 001 */ 30 printf("Size of bitfield struct is : %dn", sizeof (bF)); /* Next 8 bit data is read from pointer location . * 32 * Here it is 00000 101 (Binary equivalent to 5 */ printf("Pointer value is : %dn", *p); 34 return 0; } ✌ ✆ ✞ Size of bitfield struct is : 4 Pointer value is : 5 ✌ ✆ Following example is extended form of above example. ✞ #include <stdio.h> 2 struct bitfield { 4 /* Last five bits 00001 of binary * * 00000001 are omitted and stored */ 6 unsigned int a : 5; /* Last five bits 00100 of binary * 8 * 00000100 are omitted and stored */ unsigned int b : 5; 10 /* Last five bits 10111 of binary * * 00110111 are omitted and stored */ 12 unsigned int c : 5; }; 14 int main () { 16 struct bitfield bF; bF.a = 1; /* Binary equivalent to 00000001 */ 18 bF.b = 4; /* Binary equivalent to 00000100 */ bF.c = 55;/* Binary equivalent to 00110111 */ 20 /* In memory the structure data * * is stored as 10111 00100 00001*/
  • 19. 1.5. PRECEDENCE OF OPERATORS 119 22 char *p; p = &bF; 24 /* In memory the structure data is stored as * * 10111 00100 00001*[ < - pointer is here ] * 26 * Above read data without white spaces */ p++; 28 /* 10111 00*[<- pointer jumps here ] 100 00001* * Above read data without white spaces */ 30 printf("Size of bitfield struct is : %dn", sizeof (bF)); /* Next 8 bit data is read from pointer location . * 32 * Here it is 010111 00 (Binary equivalent to 92)*/ printf("Pointer value is : %dn", *p); 34 return 0; } ✌ ✆ ✞ Size of bitfield struct is : 4 Pointer value is : 92 ✌ ✆ Bitwise operators enable us to control the access and manipulation of individual bits of a flag byte. these operators are very useful in controlling of bits of a flag register. For example, in 8085 microprocessor, there are Sign, Zero, Reserve, Auxiliary Carry, Reserve, Parity, Reserve and Carry bits. When all flag are high, then they form binary 11010101, that is equal to decimal 213. If we want to change Zero bit to low from high, then we do AND operation with the decimal 149, i.e. binary 10010101. It will change the Zero bit low keeping other bits high. ✞ 11010101 ; decimal 213 2 10010101 ; decimal 149 -------------; AND operator 4 10010101 ; Zero bit is low ✌ ✆ 1.5 Precedence of Operators Precedence of operators is order of execution of C operators presence in an expression. For example, in an expression y = 5 + 3 − 4%2 We expect the result by addition of 5 + 3 = 8 which gives 8 − 4 = 4. The modulus of 4 by 2 as 4%2 = 0. Hence the final result is zero. But it is not true. Because addition can not be performed before operation of modulus operator. Subtraction comes at last. It means the expression can be written as y = ((5 + 3) − (4%2)) On solving it, the final result is 8. ✞ #include <stdio.h> 2 int main () {
  • 20. 120 Basic C 4 int y; y = 5 + 3 - 4 % 2; 6 printf("Result is : %dn", y); return 0; 8 } ✌ ✆ ✞ Result is : 8 ✌ ✆ To use the lower order operator before the upper order operator, parentheses are used. Rewriting above example: ✞ 1 #include <stdio.h> 3 int main () { int y; 5 /*+ operator is put above the %* *operator by using parentheses .*/ 7 y = (5 + 3 - 4) % 2; printf("Result is : %dn", y); 9 return 0; } ✌ ✆ In this example at first (5 + 3 − 4) is calculated which is 4 and its modulus with 2 is 4%2 = 0. Therefore the output of this example is ✞ Result is : 0 ✌ ✆ 1.5.1 Precedence of Arithmetic Operators Arithmetic problems are not solved from left to right in the sequence the expression is written. But some rules are used. For example, parentheses are solved first, then division, multiplication, addition and subtraction. Thus, arithmetic operators have some precedence. Operators in order of decreasing precedence are given in table below. Operators Associativity () Left to right +, – (unary) Right to left *, /, % (modulo) Left to right +, – (binary) Left to right = Right to left Table 1.18: Precedence of arithmetic operators from top to bottom in high to low order. The precedence of the binary relational operators is less than that of the arithmetic operators. This means, for example, x > y + 2 is same as x > (y + 2) and x = y > 2
  • 21. 1.5. PRECEDENCE OF OPERATORS 121 is same as x = (y > 2). It means, in an expression, order of evaluation of operators is arithmetic operators, relational operators and assignment operators respectively. ✞ 1 #include <stdio.h> 3 int main () { int x = 4, y = 1; 5 /*x > y + 2*/ /*x > 1 + 2*/ 7 /*x > 3 */ /*4 > 3 (true )*/ 9 if (x > y + 2) { printf("Expression Passed."); 11 } else { printf("Expression Failed."); 13 } return 0; 15 } ✌ ✆ ✞ Expression Passed. ✌ ✆ Here is another example. ✞ 1 #include <stdio.h> #include <stdlib.h> 3 int main (int argc , char *argv [ ]) { 5 int y; /* Order of arithmetic operators * 7 * are /, *, +, -, =. So first 12* * is divided by 5 and answer is * 9 * 2.4. 6 is multiply by 2.4 and * * result is 14.4. It is added to* 11 * 20 and 10 is subtracted * * The answer is 14.4+20 -10=24.4 */ 13 y = 6 * 12 / 5 + 20 - 10; /* In result only 24 is printed. * 15 * Decimal is truncated . */ printf("Expression result is %dn", y); 17 return 0; } ✌ ✆ ✞ Expression result is 24 ✌ ✆ In an expression, if there is a relational operator, then in the decreasing precedence of operators, the relational operator comes above the assignment operator but below the arithmetic operators. ✞ 1 #include <stdio.h> #include <stdlib.h>
  • 22. 122 Basic C 3 int main (int argc , char *argv [ ]) { 5 int y; /* First 6*12 and 5*20 are evaluated .* 7 *6*12 is 72 while 5*20 is 100. Now * *relation operator < returns true * 9 *as 72 is less than 100. This true * *value is assigned to variable y. */ 11 y = 6 * 12 < 5 * 20; printf("%dn", y); 13 return 0; } ✌ ✆ ✞ 1 ✌ ✆ 1.5.2 Precedence of Relational Operators The operator precedence of relation & unary operators from top to bottom as high to low order is given below. Operators Associativity ( ) LR –, +, ++, – –, sizeof (type), (all unary) RL *, /, % (modulo) LR +, – (binary) LR <, >, <=, >= LR ==, != LR = RL From above table, it is seen that parentheses has highest priority among all the re- lational and unary operators, after that, increment and unary operators. Arithmetic operators and comparative operators has next. Assignment operator (=) has lowest pri- ority. See the example below. ✞ 1 #include <stdio.h> 3 int main () { int y=8; 5 /* First % operator is evaluated . As it has * *highest priority . Next comes + and - and* 7 *in last , += operators . Using this order * *the result of expression is y = 16. */ 9 y += 5 + 3 - 4 % 2; printf("Result is : %dn", y);
  • 23. 1.5. PRECEDENCE OF OPERATORS 123 11 return 0; } ✌ ✆ ✞ Result is : 16 ✌ ✆ 1.5.3 Precedence of All Operators In the following table, the precedence of all C operators are given. One should memorize precedence of all operators if possible for quick troubleshooting and optimization of C codes. Operators Associativity ++ (postfix), – – (postfix), ( ), [ ], {}, . (dot), -> L-R ++ (prefix), – – (prefix), –, +, ˜, ! R-L *, /, % (modulo) LR +, – (both binary) L-R <<, >> L-R <, >, <=, >= L-R ==, != L-R & L-R ˆ L-R | L-R && L-R || L-R ?: (conditional expression) R-L =, *=, /=, %=, +=, –=, <<=, >>=, &=, |=, ˆ= R-L , (comma operator) L-R Table 1.19: Operator precedence of all C operators from top to bottom from high to low order. From above table, asterisk (*) has lower preference than square brackets ([ ], also called array notation). This is why, to define the precedence order, parentheses are used. Remember that, if comma used in an expression then C evaluates expression from left- to-right direction, but the commas separating the arguments in a function call are not comma operators.
  • 24. 124 Basic C 1.5.4 Precedence in Assignment Precedence order is also obeyed in assigning a value to a variable. In example ✞ 1 #include <stdio.h> 3 int main () { int a; 5 a = 10, 20, 30; printf("a=%dn", a); 7 a = (10, 20, 30); printf("a=%dn", a); 9 return 0; } ✌ ✆ in code line ✞ a = 10, 20, 30; ✌ ✆ assigned value 10 to variable ‘a’ as ‘=’ has higher precedence over the ,(comma). Similarly in code line ✞ 1 a = (10, 20, 30); ✌ ✆ assigned value 30 to variable ‘a’ as parentheses has highest precedence over the ,(comma) and ‘=’. This is why, the output of above example is ✞ a=10 a=30 ✌ ✆ 1.5.5 Unary & Binary Operators In C, there are some unary operators and some binary operators. Unary operators require only one operand, while binary operators need two operands. Now, if there are both, unary and binary operators in same expression, then evaluation of operators is take place according their precedence order. To understand it, we take following example ✞ #include <stdio.h> 2 #include <stdlib.h> 4 int main (int argc , char ** argv ) { int i = 5; 6 int y; y = ++i * ++i* ++i; 8 printf("Result is %d.", y); return 0; 10 } ✌ ✆ ✞ Result is 392. ✌ ✆
  • 25. 1.5. PRECEDENCE OF OPERATORS 125 Here, expression y has two operators, one ++ and other product (∗). In precedence order of operators, increment operator (++) has higher precedence than product operator (∗). An arithmetic expression is evaluated from left-to-right sequence according the precedence order of operators. Sequence of evaluation of given expression is shown below: ✞ 1 y = ++i * ++i * ++i; ------------------------------- 3 1. y = ++i //i=6 2. y = ++i * //i=6 5 3. y = ++i * ++i //i=7 4. y = 7 * 7 * ++i //i=7 7 5. y = 49 * ++i //i=8 6. y = 49 * 8 = 392 ✌ ✆ The evaluation is First Step: + + i is evaluated and it makes i = 6. Second Step: + + i∗ is not evaluated as product operator (∗) needs two operands and it has only left side operand. It wait for its right side operands. Value of i has no change, and it is i = 6. Third Step: ++i∗++i is evaluated. Right side ++i to product operator makes i = 7. There are two operands for product operator, hence arithmetic evaluation is performed. Now, it is 7 ∗ 7 = 49. Remember, left and right side to product operator are variable i hence both side the updated values are taken for product operation. Rest of Steps: Now, + + i ∗ + + i ∗ + + i is evaluated. In this step, the expression is like 49 ∗ + + i. There is of third + + i no effect on + + i ∗ + + i as it is already evaluated. Therefore, final evaluation is 49 ∗ 8 = 392. This is final answer. ✞ #include <stdio.h> 2 #include <stdlib.h> 4 int main (int argc , char ** argv ) { int i = 3; 6 int y; y = ++i * ++i + ++i; 8 printf("Result is %d.", y); return 0; 10 } ✌ ✆ The initial program is now modified as given above. We have replace last product operator with sum operator in the expression. The output of above program is ✞ Result is 31. ✌ ✆ Here ++ has higher precedence than product operator (∗). Product operator has higher precedence than sum operator (+). Product and sum operators are evaluated, after their left and right operand’s evaluation. Steps of evaluation of arithmetic expression of above program is given below:
  • 26. 126 Basic C ✞ 1 /* * has higher precedence than + */ y = ++i * ++i + ++i; 3 --------------------------------------- 1. y = ++i //i=4 5 2. y = ++i * //i=4 3. y = ++i * ++i //i=5 7 4. y = 5 * 5 + ++i //i=6; //On evaluation , product operator has 9 // higher precedence than sum operator 5. y = 25 + ++i //i=6 11 6. y = 25 + 6 = 31 ✌ ✆ Again, take the same program with modifications as given below. We have replace first product operator with sum operator in the expression. ✞ 1 #include <stdio.h> #include <stdlib.h> 3 int main (int argc , char ** argv ) { 5 int i = 3; int y; 7 y = ++i + ++i * ++i; printf("Result is %d.", y); 9 return 0; } ✌ ✆ The output of above program is ✞ Result is 42. ✌ ✆ It has different result than previous program. The evaluation of program is started from left to right. Sum operator does not evaluated until product operator is not evaluated due to precedence order. Steps of evaluation of expression of above program is given below: ✞ 1 /* * has higher precedence than + */ y = ++i + ++i * ++i; 3 -------------------------------------- 1. y = ++i //i=4 5 2. y = ++i + //i=4 3. y = ++i + ++i //i=5; 7 /* Wait for Evaluation , product operator * * has higher precedence than sum operator */ 9 4. y = ++i + ++i * ++i //i=6 5. y = ++i + 6 * 6 //i=6, use and increment 11 6. y = 6 + 36 = 42 ✌ ✆ 1.5.6 Associativity The associativity of an operator is a property that determines how operators of the same precedence are grouped in the absence of parentheses. Operators may be associative, left-
  • 27. 1.6. CONDITIONS 127 associative, right-associative or non-associative. The associativity and precedence of an operator is a part of the definition of the programming language; different programming languages may have different associativity and precedence for the same type of operator. For example, aˆbˆc has left associativity as the expression is solved from left to right and a=b=c to be interpreted as a=(b=c) and it has right associativity where both ‘a’ and ‘b’ to the value of ‘c’. A chained comparison like a<b<c is interpreted as (a<b) and (b<c), it is not equivalent to either (a<b)<c or a<(b<c). It is called non-associativity. 1.6 Conditions Conditions are the comparison statements those controls the execution of codes inside the conditional blocks. 1.6.1 If Condition if () provides a way to instruct the program to execute a block of code only if certain conditions have been met, i.e. conditions given true result. In if condition of C language, true is represented by ‘1’. The syntax of if () construct is ✞ 1 if(/* conditions */) // if condition is true then statement // execute the condition . ✌ ✆ ✞ #include <stdio.h> 2 int main () { 4 int b = 2, c = 3; if (c > b) { 6 printf("True -%dn", c > b); // true case } else { 8 printf("False -%dn", c > b); // false case } 10 return 0; } ✌ ✆ ✞ True -1 ✌ ✆ Note that, the equal comparison in C is ‘==’ and not ‘=’. The later symbol is assignment operator that assigns the its right side value to left side variable and if assignment is successful, it returns true. See the following simple example: ✞ 1 #include <stdio.h> 3 int main () { int i = 10; 5 int j = 20; 7 /* In if statement , there is assignment not * * comparison . This is why , if has true state.*/
  • 28. 128 Basic C 9 if (i = j) printf("Is i equal to j?n"); // Printed. 11 /* Exact comparison . */ 13 if (i == j) printf("i is perfectly equal to j.n"); // Printed. 15 } ✌ ✆ ✞ Is i equal to j? i is perfectly equal to j. ✌ ✆ 1.6.2 If-else Condition if-else provides a way to instruct the program to execute a block of code only if certain conditions have been met otherwise execute other block. All the conditions, except than certain one defined for if, are true for else statement. This is why else has infinite numbers of true conditions. The syntax of if-else construct is ✞ if(/* conditions */) // if condition is true then 2 statement one // execute the statement one. else // otherwise if condition is false 4 statement two // execute the statement two. ✌ ✆ A simple example is ✞ #include <stdio.h> 2 int main () { 4 int i = 10; int j = 20; 6 if (i == j) printf("i is perfectly equal to j.n"); 8 else printf("i is not perfectly equal to j.n"); 10 } ✌ ✆ If number of lines in a statement is more than one then these lines should be grouped together by using curly braces i.e. { ..multi line statements.. }. ✞ #include <stdio.h> 2 int main () { 4 int i = 10; int j = 20; 6 if (i == j){// Grouping by bracing for if condition printf("i is perfectly equal to j.n");// Line No. 1 8 printf("Conditions are met.n");// Line No. 2 }else // Single line else condition is not braced here 10 printf("i is not perfectly equal to j.n");
  • 29. 1.6. CONDITIONS 129 } ✌ ✆ A short hand for of if-else condition is ✞ 1 int a=(b > c) ? d : e; ✌ ✆ Above statement is similar to the statement of “return d if b is greater than c else return e”. if - else - if - else - if - else statement can be used successively. See the simple example as given below: ✞ 1 #include <stdio.h> 3 int main () { int i = 10; 5 int j = 20; if (i == j) 7 printf("i is perfectly equal to j.n"); else if (i > j) 9 printf("i is greater than j.n"); else if (i < j) 11 printf("i is lesser than j.n"); // Printed . else 13 printf("i is not equal to j.n"); return 0; 15 } ✌ ✆ ✞ i is lesser than j. ✌ ✆ 1.6.3 If-else-if Case Two if () conditions can be linked by else keyword. If-Else-If provides a way to instruct the program to execute a block of code only if certain conditions have been met otherwise execute other block conditionally. All the conditions, except than certain ones defined for the first if, are true for else if statement. This is why, else if has infinite numbers of true conditions. These infinite numbers of conditions are again checked for if statement and the corresponding block is executed if certain conditions are met, otherwise these conditions are skipped to next else if statement. The syntax of the linked if conditions is ✞ 1 if(/* condition 1*/) <expressions 1> 3 else if(/* condition 2*/) <expressions 2> 5 else if(/* condition 2*/) <expressions 3> ✌ ✆ There may be end of this condition by else keyword or not. The example is
  • 30. 130 Basic C ✞ #include <stdio.h> 2 void main () { 4 int i, j; i = 10; 6 j = 20; if (i == 10) {// print it 8 printf("i is %dn", i); } else if (j == 20) { 10 printf("j is %dn", j); } 12 } ✌ ✆ ✞ i is 10 ✌ ✆ Above example is modified so that the conditions are true for else if statement. ✞ 1 #include <stdio.h> 3 void main () { int i, j; 5 i = 11; // value is changed from 10 to 11 j = 20; 7 if (i == 10) {// skip to next else -if printf("i is %dn", i); 9 } else if (j == 20) { // print it printf("j is %dn", j); 11 } } ✌ ✆ ✞ j is 20 ✌ ✆ Above example is modified as shown below so that comparative conditions are neither true for if () conditions or for else if condition. The program skips to both if () and else if () and prints nothing in output console. ✞ 1 #include <stdio.h> 3 void main () { int i, j; 5 i = 11; // value is changed from 10 to 11 j = 21; // value is changed from 20 to 21 7 if (i == 10) {// skip to next else -if printf("i is %dn", i); 9 } else if (j == 20) { // skip to next else -if printf("j is %dn", j); 11 } } ✌ ✆
  • 31. 1.6. CONDITIONS 131 ✞ ✌ ✆ See the example below: ✞ 1 #include <stdio.h> 3 int main (int argc , char *argv []) { int i = 10; 5 if (i == 10) { // First if case printf("1 : %dn", i); 7 } if (i == 11) { // Second if case 9 printf("2 : %dn", i); } else { // Corresponding else to second if 11 printf("3 : %dn", i); } 13 return 0; } ✌ ✆ It result is ✞ 1 : 10 3 : 10 ✌ ✆ There is only one true condition in the above program for variable ‘i’ but result obtained twice. The reason is that the compiler checks the condition for first if case, which is true and the result is obtained. Now the compiler checks the condition for second if statement, which is false and the control is transferred to corresponding else statement and program gives result again. If above program is rewritten as ✞ #include <stdio.h> 2 int main (int argc , char *argv []) { 4 int i = 10; if (i == 10) { // First if case , here true 6 printf("1 : %dn", i); } else if (i == 11) { //on false , second if case 8 printf("2 : %dn", i); } else { // Corresponding else to second if 10 printf("3 : %dn", i); } 12 return 0; } ✌ ✆ The result is ✞ 1 : 10 ✌ ✆ Here from first if statement is true hence corresponding else-if statement is skipped by the compiler and there is only one result.
  • 32. 132 Basic C 1.6.4 Switch & Case Use of a long chain as if-else-if-else-if-else-if-else is very complex and less readable. There’s a solution to it and we may use switch & case construct. A switch statement is similar to if statement except that switch accepts single argument and compare it with a range of defined values. It executes the block of statements for which case is matched. if case is fixed executes only single block of statements. The basic syntax of this construction is given below. ✞ 1 switch (<case variable >) { case 1: 3 <first statements > break; 5 case 2: <second statements > 7 break; case 3: 9 <third statements > break; 11 default : <default statements > 13 break; } ✌ ✆ Here default case is executed if none of the cases is matched with case variable value. If switch statement has one case or default case then it behaves like if statement. ✞ switch (<case variable >) { 2 case 1: <first statements > 4 break; } /*if like */ ✌ ✆ Or ✞ 1 switch (<case variable >) { default : 3 <default statements > break; 5 } /*if like */ ✌ ✆ Note that, the switch parameter takes only integer or character type values. It can not be used with float type switch parameter. Following is working example ✞ 1 #include <stdio.h> /* fprintf */ #include <stdlib.h> /* malloc , free , exit */ 3 int grade; 5 int main (void ) { 7 printf("Enter the grade : "); // get the switch case value
  • 33. 1.6. CONDITIONS 133 scanf("%d", &grade); // recognise the supplied variable . 9 switch (grade) { 11 case 1: printf("An"); 13 break; case 2: 15 printf("Bn"); break; 17 case 3: printf("Cn"); 19 break; case 4: 21 printf("Dn"); break; 23 default : // if none of the above cases are matched. printf("Fn"); 25 break; } 27 /* Exiting program */ exit ( EXIT_SUCCESS ); 29 } ✌ ✆ When program is run and input 1 is supplied, the output is ✞ A ✌ ✆ Here operator ‘break’ plays an important role. If break operator is not used in block of ‘case’ then all the successive blocks are executed successively. The reason behind is that, ‘break’ inside the ‘case’ exits from the switch block from the current loop. ✞ 1 #include <stdio.h> 3 int main () { int i = 0; 5 switch (i) { /* for first loop , i=0.* 7 * Case 0 is executed . */ case 0:i += 2; 9 /* No following break operator . Switch* * passes to the next case . Here i = 2*/ 11 case 1:i += 2; /* No following break operator . Switch* 13 * passes to the next case . Here i=4. */ case 5:i += 2; 15 /* No following break operator . Switch* * passes to the next case . Here i=6.*/ 17 default : i += 2; /* Here i=8.*/ 19 break; /* Exit the switch */ }
  • 34. 134 Basic C 21 /* Print the 8*/ printf("%dt", i); 23 return 0; } ✌ ✆ ✞ 8 ✌ ✆ Now, the break operator is inserted after case 1 in above example. The result is different from the above example. It is so, because break operator let the exit of switch when case is matched. ✞ 1 #include <stdio.h> 3 int main () { int i = 0; 5 switch (i) { /* for first loop , i=0.* 7 * Case 0 is executed . */ case 0:i += 2; 9 /* No following break operator . Switch* * passes to the next case . Here i = 2*/ 11 case 1:i += 2; /* break operator exit switch * 13 * from current loop . Here i=4*/ break; 15 case 5:i += 2; /* Never executed .*/ default :/* Never executed .*/ 17 i += 2; break; 19 } /* Print the 4*/ 21 printf("%dt", i); return 0; 23 } ✌ ✆ ✞ 4 ✌ ✆ For a given switch more than one similar case conditions can not be allowed. For example: ✞ 1 switch (v){ case 0 : break; 3 case 1 : break; case 0 : break; // Error!! case 0 is redefine 5 } ✌ ✆ returns the compile time error as case ‘0’ is defined twice.
  • 35. 1.6. CONDITIONS 135 1.6.5 Goto Keyword It is a jump operator. It transfers control unconditionally to another part of a program. The statement used for goto operator is given below: ✞ 1 goto <identifier >; ✌ ✆ The identifier must be a label followed by a colon and statement. C language has a unary && operator that returns the address of a label. This address can be stored in a void* variable type and may be used later in a goto instruction. ✞ 1 void *ptr = && JUMP1; 3 JUMP1: printf("hi "); goto *ptr; ✌ ✆ ✞ #include <stdio.h> 2 #include <stdlib.h> 4 int main (void ) { int i = 0; 6 LOOP : if (i == 100) { 8 exit (0); } 10 while (i < 100) { i++; 12 if (i % 2 == 0) goto JUMP1; 14 else goto JUMP2; 16 } 18 JUMP1: printf("%d is Even Numbern", i); 20 goto LOOP ; 22 JUMP2: printf("%d is Odd Numbern", i); 24 goto LOOP ; return EXIT_SUCCESS ; 26 } ✌ ✆ 1.6.6 Break Keyword break keyword is used to break a loop or continuous operation. It is always used within loop and its use outside the loop cause compile time error. ✞ #include <stdio.h> 2
  • 36. 136 Basic C int ix; 4 int main (void ) { for (ix = 1; ix <= 10; ix ++) { 6 /* First hello , world!*/ printf("%d Hello , world!", ix); 8 break; } 10 return 0; } ✌ ✆ The output of above program is ✞ 1 Hello , world! ✌ ✆ In above example, loop is iterated only once. During the first loop of for block, break stops the further execution of for loop. In a simple program we can use blank line for offset to make the programming code readable. 1.7 Iteration Iteration is a process in which code statements are executed more than once. For example, to print a line ten times, either the line is written ten times one after another or a loop is used to print the line ten times. Most common iteration/loop functions are for and while. 1.7.1 For Loop The syntax of for loop is ✞ 1 for(initialization ; test ; increment ) { /* code */ 3 } ✌ ✆ The function for, first initializes the variable and then conditions are checked according the ‘test’. If initialized value of the variable passed the ‘test’, expressions or codes in- side the function body are executed. After each successful execution of loop, variable is incremented according the relation of ‘increment’. See example given below: ✞ 1 #include <stdio.h> 3 main (void ) { int a, b; 5 b = 15; for (a = 10; a < b; a++) { 7 printf("The number a is %d.n", a); } 9 } ✌ ✆ The output is
  • 37. 1.7. ITERATION 137 ✞ The number a is 10. The number a is 11. The number a is 12. The number a is 13. The number a is 14. ✌ ✆ The declaration cum initialization of variable inside the for parentheses is allowed only in C99 or C11 standards. All C standards older than C99 need pre-declaration of variable before they are initialized inside for parentheses. ✞ 1 for(int initialization ; test ; increment ) { /* code */ 3 } ✌ ✆ Example of above for syntax is given below: ✞ 1 #include <stdio.h> 3 main (void ) { int b = 15; 5 for (int a = 10; a < b; a++) {/* C99 & C11 Standards .*/ printf("The number a is %d.n", a); 7 } } ✌ ✆ The value of variable may also be changed from the function body. See example below: ✞ #include <stdio.h> 2 int main () { 4 int i; for (i = 1; i < 10; i += 2) { 6 if (i == 3) i--; 8 printf("%d, ", i); } 10 return 0; } ✌ ✆ ✞ 1, 2, 4, 6, 8, ✌ ✆ The initialization statement is executed exactly once. It is used to assign an initial value to some variable. The test expression is evaluated each time before the code in the for loop executes. If this expression evaluates as 0 (false), the loop is not (re)enter into the for loop. And execution of program carry on to the code immediately following the for loop. If the expression is non-zero (ie true), the loop is (re)enter inside the for loop. After each iteration of the loop, the increment statement is executed. In last iteration, required conditions are not satisfied and loop exits after execution of increment. This is often used to increment the loop index.
  • 38. 138 Basic C ✞ 1 #include <stdio.h> 3 int main (int argc , char ** argv ) { int i; 5 for (i=0;i<5;i++); // only increment index , i=5 printf("i is %d.", i); 7 return 0; } ✌ ✆ ✞ i is 5. ✌ ✆ An infinite loop is executed if for is defined as shown below. ✞ 1 for (;;) { /* statements / codes */ 3 } ✌ ✆ Multiple initialization can be used by separating them by comma. ✞ 1 for(initialization one , /* First var initialized */ initialization two; /* Second var initialized */ 3 test of initializers ;/* Test the condition of variables */ increment one , /* Increment of first variable */ 5 increment two) { /* Increment of second variable */ 7 /* expressions / statements / codes */ 9 } ✌ ✆ ✞ 1 #include <stdio.h> #include <stdlib.h> 3 int main (void ) { 5 int i, j; for (i = 1, /* First var initialized */ 7 j = 2; /* Second var initialized */ i < 5, /* Test first variable */ 9 /* Here comma mean OR */ j < 11;/* Test second variable */ 11 i++, /* Increment of first variable */ j = j + 2) /* Increment of second variable */{ 13 printf("Product of i=%d & j=%d is %dn", i, j, i * j); } 15 return 0; } ✌ ✆ ✞ Product of i=1 & j=2 is 2 Product of i=2 & j=4 is 8 Product of i=3 & j=6 is 18
  • 39. 1.7. ITERATION 139 Product of i=4 & j=8 is 32 Product of i=5 & j=10 is 50 ✌ ✆ ✞ 1 #include <stdio.h> #include <stdlib.h> 3 int main (void ) { 5 int i, j; for (i = 1, /* First var initialized */ 7 j = 2; /* Second var initialized */ i < 5 /* Test first variable */ 9 && /* AND test for i and j*/ j < 11; /* Test second variable */ 11 i++, /* Increment of first variable */ j = j + 2)/* Increment of second variable */{ 13 printf("Product of i=%d & j=%d is %dn", i, j, i * j); } 15 return 0; } ✌ ✆ ✞ Product of i=1 & j=2 is 2 Product of i=2 & j=4 is 8 Product of i=3 & j=6 is 18 Product of i=4 & j=8 is 32 ✌ ✆ An example containing the conditional for is ✞ #include <stdio.h> 2 main (void ) { 4 int a, b; a = 10, b = 15; 6 for (a = 10; a < 30 && b != a; a++) { printf("The number a is %d.n", a); 8 } } ✌ ✆ The output is ✞ The number a is 10. The number a is 11. The number a is 12. The number a is 13. The number a is 14. ✌ ✆ There is an example of finding prime numbers by using for loops. ✞ 1 /* For the square root function sqrt () */ #include <math .h> 3 #include <stdio.h>
  • 40. 140 Basic C 5 int is_prime (int n); 7 int main () { /* Enter a number. Only integer.*/ 9 printf("Write an integer : "); /* Scan the integer.*/ 11 int var; scanf("%d", &var); 13 /* Defining output */ if (is_prime (var) == 1) { 15 printf("A primen"); } else { 17 printf("Not a primen"); } 19 return 1; } 21 int is_prime (int n) { 23 int x; int sq = sqrt (n) + 1; 25 /* Checking the trivial cases first*/ if (n < 2) 27 return 0; if (n == 2 || n == 3) 29 return 1; /* Check whether n is divisible by 2 or is an* 31 *odd number between 3 and square root of n.*/ if (n % 2 == 0) 33 return 0; for (x = 3; x <= sq; x += 2) { 35 if (n % x == 0) return 0; 37 } 39 return 1; } ✌ ✆ ✞ Write an integer: 12 Not a prime ✌ ✆ Variables used in for control function, can also be assigned a character code if a character is enclosed inside single quote. In following example, 26 English characters in lower case form are printed by using for loop. ✞ #include <stdio.h> 2 int main (void ) { 4 int i; printf("26 english letters : n"); 6 for (i = ’a’; i < (’a’ + 26); i++) {
  • 41. 1.7. ITERATION 141 printf("%3d = %c,t", i, i); 8 if ((i - ’a’ + 1) % 5 == 0) printf("n"); 10 } return 0; 12 } ✌ ✆ ✞ 97 = a, 98 = b, 99 = c, 100 = d, 101 = e, 102 = f, 103 = g, 104 = h, 105 = i, 106 = j, 107 = k, 108 = l, 109 = m, 110 = n, 111 = o, 112 = p, 113 = q, 114 = r, 115 = s, 116 = t, 117 = u, 118 = v, 119 = w, 120 = x, 121 = y, 122 = z, ✌ ✆ 1.7.2 While Loop A while() loop is the most basic type of loop. It will run as long as the condition returns non-zero (ie true) value. At false state, while loop exits. ✞ #include <stdio.h> 2 #include <string.h> #include <stdlib.h> 4 int a = 1; 6 int main (void ) { /* Loops until the break statement in the loop is executed */ 8 while (42) { printf(":-> a is %d n", a); 10 a = a * 2; if (a > 100) { 12 break; } else if (a == 64) { 14 /* Immediately restarts at while , skips next step */ continue ; 16 } printf(":-> a is NOT 64n"); 18 } exit ( EXIT_SUCCESS ); 20 } ✌ ✆ ✞ :-> a is 1 :-> a is NOT 16 :-> a is 2 :-> a is NOT 16 :-> a is 4 :-> a is NOT 16 :-> a is 8 :-> a is 16 ✌ ✆
  • 42. 142 Basic C 1.7.3 For As While The syntax of for loop as ✞ for(; <test > ; ) ✌ ✆ is similar to the while loop ✞ 1 while (<test >) ✌ ✆ Following is an example which shows that for loop is similar to the while loop. ✞ 1 #include <stdio.h> 3 int main () { int i = 0; 5 for (; i < 5;) { printf("%dt", i); 7 i++; } 9 printf("n"); int j = 0; 11 while (j < 5) { printf("%dt", j); 13 j++; } 15 printf("n"); return 0; 17 } ✌ ✆ ✞ 0 1 2 3 4 0 1 2 3 4 ✌ ✆ 1.7.4 Do While do-while loop is similar to the while loop except at least one loop is executed before the conditional test is checked. So while loop is used where execution of loops is required after test and do-while loop is used where at least one loop is must before conditional check. This loop has syntax like ✞ do{ 2 <loop body > }while(<conditional check >) ✌ ✆ The comparative example of while and do-while loops is given below: ✞ 1 #include <stdio.h> 3 int main (void ) { /*do - while loop */
  • 43. 1.8. STRINGS 143 5 int i = 0; printf("Do -while Loop : n"); 7 do {/* One output loop */ printf("i = %dn", i); 9 i++; } while (i < 0); 11 /* while loop */ i = 0; 13 printf("nWhile Loop : n"); while (i < 0) {/*No outputs */ 15 printf("i = %dn", i); i++; 17 } return 0; 19 } ✌ ✆ ✞ Do -while Loop : i = 0 While Loop : ✌ ✆ 1.8 Strings The string constant “x” is not the same as the character constant i.e. ‘x’. One difference is that ‘x’ is a basic type (char), but “x” is a derived type, an array of char. A second difference is that “x” really consists of two characters, ‘x’ and ‘0’, the null character. ✞ 1 char ch=’x’; // valid assignment char str [2]= "x"; // valid assignment ✌ ✆ x ch x 0 str Again, a chacter inside the single quote is integer type while same character inside double quote is of char * type. It is implementation method that whether string variable may or may not be assigned single quote strings. ✞ char str [2]= ’x’; // Valid assignment with warning as ’x’ is int type 2 char *str =’x’ // Valid assignment with warning as ’x’ is int type ✌ ✆ String with single quote has special meaning. See the example given below: ✞ #include <stdio.h> 2 int main () { 4 char *ch=’1234 ’; printf("%d",ch);
  • 44. 144 Basic C 6 return 0; } ✌ ✆ ✞ 825373492 ✌ ✆ Here, each character is converted into its equivalent char code and then char codes are placed in sequential memory bytes. Note that there is no null terminator, hence there is no end of this string. Compiler will reach beyond the limit of string when read it. So, when we dereference this string variable as string, error of segmentation fault is returned by the compiler. Again, when we dereference the string variable as integer, it returns the decimal number created from first four memory bytes started from the address of string variable. A string in C is merely an array of characters. The length of a string is determined by a terminating null character: ‘0’. So, a string with the contents, say, “abc” has four characters: ‘a’, ‘b’, ‘c’, and the terminating null character ‘0’. ✞ 1 char str [4]= "abc"; ✌ ✆ a b c 0 str In C, string constants (literals) are surrounded by double quotes (“...”), e.g. “Hello world!” and are compiled to an array of the specified char values with an additional null terminating character (0-valued) code to mark the end of the string. Note that, if the size of character array is larger than the size of string stored, the remaining bytes after null terminator are part of the array but not the part of string. ✞ 1 char str [7]= "abc"; ✌ ✆ a b c 0 ? ? ? str The type of a string constant is char *. String literals may not directly in the source code contain embedded newlines or other control characters, or some other characters of special meaning in string. To include such characters in a string, the backslash escapes may be used, like this:
  • 45. 1.8. STRINGS 145 Escape Meaning Literal backslash " Double quote ’ Single quote n Newline (line feed) r Carriage return b Backspace t Horizontal tab f Form feed a Alert (bell) v Vertical tab ? Question mark (used to escape trigraphs) nnn Character with octal value nnn xhh Character with hexadecimal value hh Table 1.20: Escape characters in C. A simple example is ✞ 1 #include <stdio.h> 3 int main () { int i; 5 while (i < 10) { printf("%i.nav",i); 7 i++; } 9 return (0); } ✌ ✆ An equivalent hexadecimal value of a charcode as hexadecimal escape character format (xhh) can be put in the output console of C by using printf function. ✞ #include <stdio.h> 2 int main (void ) { 4 char *s = "x41x42x54"; printf("s = %sn", s); 6 return 0; } ✌ ✆ ✞ s = ABT ✌ ✆
  • 46. 146 Basic C Multi-bytes hexadecimal character string can be assigned to a char type variable by using ‘wchar t’ keyword. The value assigned to the variable must be preceded with character ‘L’ as shown in the following example. ✞ 1 #include <stdio.h> #include <wchar.h> 3 int main (void ) { 5 wchar_t *s = L"x4142x4344"; printf("s = %sn", s); 7 return 0; } ✌ ✆ ✞ s = BADC ✌ ✆ 1.8.1 Character Encoding char and wchar t are not specified in the C standards. Except that the value ‘0×00’ and ‘0×0000’ specify the end of the string and not a character. Input and output codes are directly affected by the character encoding. Other code should not be too affected. The editor should also be able to handle the encoding if strings shall be able to written in the source code. There are three major types of encoding: 1. One byte per character. Normally based on ASCII. There is a limit of 255 different characters plus the zero termination character. 2. Variable length character strings, which allows many more than 255 different char- acters. Such strings are written as normal char-based arrays. These encoding are normally ASCII-based and examples are UTF-8 or Shift JIS. 1.8.2 String Literal In Expression When a string appears in an expression it is considered as a pointer and indices or indirection rules can be applied on it. See the example given below: ✞ 1 #include <stdio.h> 3 int main (int argc , char ** argv ) { printf("%dn", "xyz"); // pointer 5 printf("%dn", *"xyz"); // pointer to characters printf("%dn", ("xyz"[1] + 1)); // sum of ’y’ and 1 7 return 0; } ✌ ✆ ✞ 4202528 120 122 ✌ ✆
  • 47. 1.8. STRINGS 147 In first case, string literal represents to a pointer and return the address to which this string literal is pointing. In second and third case, string literals are converted into “pointer to character”, therefore it returns the value of first character of what it points, i.e. ‘x’. In third case, sum of char value of character at indices 1 (i.e. ‘y’), and one is returned. 1.8.3 String Functions The nine most commonly used functions in the string library are strcat This function concatenate the string source object with destination object. The size of destination object shall be sufficiently large to hold all the supplied strings from source object. If size of string variable is deficient to space, an overflow error occurs. The synopsis of the strcat function is ✞ 1 char *strcat(char * restrict s1 , const char * restrict s2); ✌ ✆ strcat(str1, str2) a b c 0 str1 A B C 0 str2 After catenation of the strings, ‘str1’ variable points to the strings as shown below: a b c A B C 0 str1 It is recommended that strncat() or strlcat() should be used instead of strcat(), in order to avoid buffer overflow. A simple example is ✞ 1 #include <stdio.h> #include <string.h> 3 int main () { 5 /* initialize a char variable */ char str [80]; 7 /* copy string The to variable .*/ strcpy(str , "The "); 9 /* concate the string India with The */ strcat(str , "India "); 11 strcat(str , "is "); strcat(str , "developing .");
  • 48. 148 Basic C 13 /* put output at the console */ puts (str); 15 return 0; } ✌ ✆ ✞ The India is developing . ✌ ✆ strchr The synopsis of the strchr function is ✞ 1 char *strchr(const char *s, int c); ✌ ✆ The strchr() function shall locate the first occurrence of ‘c’ (converted to a char) in the string pointed-by ‘s’. A simple example is ✞ 1 #include <stdio.h> #include <string.h> 3 int main () { 5 char str[ ] = "This is my country "; char * pch; 7 printf("Geting char s in "%s". n", str); pch = strchr(str , ’s’); 9 while (pch != NULL ) { printf("’s’ char is at position %dn", pch - str + 1); 11 pch = strchr(pch + 1, ’s’); } 13 return 0; } ✌ ✆ ✞ Geting char s in "This is my country ". ’s’ char is at position 4 ’s’ char is at position 7 ✌ ✆ strcmp The strcmp synopsis is ✞ 1 int strcmp(const char *s1 , const char *s2); ✌ ✆ A rudimentary form of string comparison is done with the strcmp() function. It takes two strings as arguments and returns a negative value if the first is lexographically less than the second, a value greater than zero if the first is lexographically greater than the second, or zero if the two strings are equal. The comparison is done by comparing the coded (ascii) value of the characters in character-by-character manner. A simple example is
  • 49. 1.8. STRINGS 149 ✞ 1 #include <stdio.h> #include <string.h> 3 int main () { 5 char Key[ ] = "apple"; char Input [80]; 7 do { printf("Guess my favourite fruit? "); 9 gets (Input); } while (strcmp(Key , Input) != 0); 11 puts ("Correct answer!"); return 0; 13 } ✌ ✆ ✞ Guess my favourite fruit? apple Correct answer! ✌ ✆ This is another example in which two strings are compared without using strcmp() func- tion. ✞ #include <stdio.h> 2 int Compare_Main_Sub (char *, char *); 4 int main () { 6 char MainStr [100] , SubStr [100] , CnF; 8 printf("Enter Main string : n"); gets ( MainStr); 10 printf("Enter Sub string : n"); 12 gets ( SubStr); 14 CnF = Compare_Main_Sub (MainStr , SubStr); 16 if (CnF == 0) printf("Both strings are same .n"); 18 else printf("Entered strings are not equal.n"); 20 return 0; 22 } 24 int Compare_Main_Sub (char *MainStr , char *SubStr) { while (* MainStr == * SubStr) { 26 if (* MainStr == ’0’ || *SubStr == ’0’) break; 28 MainStr ++; 30 SubStr ++;
  • 50. 150 Basic C } 32 if (* MainStr == ’0 ’ && *SubStr == ’0’) return 0; 34 else return -1; 36 } ✌ ✆ ✞ Enter Main string : a Enter Sub string : a Both strings are same . ✌ ✆ C has no dedicated boolean procedure. Hence in string comparison, return value is 0 on true and other value on false. In case of != comparison C fails to check condition. See example ✞ 1 #include <stdio.h> 3 int main () { char c[2]; 5 printf("Type ’e’ for encrypt & ’d’ for decrypt : "); scanf("%s", c); 7 if (strcmp(c, "e") != 0 || strcmp(c, "d") != 0) { printf("Unknown procedure .n"); 9 } return 0; 11 } ✌ ✆ ✞ Type ’e’ for encrypt & ’d’ for decrypt : f Unknown procedure . ✌ ✆ ✞ Type ’e’ for encrypt & ’d’ for decrypt : e Unknown procedure . ✌ ✆ In these type of problems, try to use the false statement. ✞ #include <stdio.h> 2 int main () { 4 char c[2]; printf("Type ’e’ for encrypt & ’d’ for decrypt : "); 6 scanf("%s", c); if (strcmp(c, "e") == 0 || strcmp(c, "d") == 0) { 8 } else { printf("Unknown procedure .n"); 10 } return 0; 12 } ✌ ✆
  • 51. 1.8. STRINGS 151 ✞ Type ’e’ for encrypt & ’d’ for decrypt : e ✌ ✆ ✞ Type ’e’ for encrypt & ’d’ for decrypt : f Unknown procedure . ✌ ✆ strcpy This function copies the string from source into destination. The size of the destination object shall be sufficiently large to hold the source string. If size of destination object is deficient of space, an overflow error occurs. The syntax of strcpy() is ✞ char *strcpy(char *restrict dest , 2 const char *restrict src); ✌ ✆ Note, source of strcpy should be string. It is recommended that strncpy() should be used instead of strcpy(), to avoid buffer overflow. A simple example is ✞ #include <stdio.h> 2 #include <string.h> 4 int main () { /* initialize a char variable */ 6 char str [80]; /* copy string The to variable .*/ 8 strcpy(str , "The "); /* concate the string India with The */ 10 strcat(str , "India "); strcat(str , "is "); 12 strcat(str , "developing ."); /* put output at the console */ 14 puts (str); return 0; 16 } ✌ ✆ ✞ The India is developing . ✌ ✆ An example which copies the contents of one array into other array without using strcpy() function is given below. In this example, one by one character of array ‘strA’ are copied into array ‘strB’. When array ‘strA’ encounters the null character, copying is halted. ✞ 1 #include <stdio.h> 3 int main () { char strA [50], strB [50]; 5 int i; printf("nEnter string s1: "); 7 scanf("%s", strA ); /* Copy one by one character into strB .*/
  • 52. 152 Basic C 9 for (i = 0; strA [i] != ’0’; i++) { strB [i] = strA [i]; 11 } /* Add null character to strB at the end.*/ 13 strB [i] = ’0’; printf("nString s2: %s", strB ); 15 return 0; } ✌ ✆ Following is a strcpy() example that is used to trim the white spaces from the left and right hand side of a string. ✞ #include <stdio.h> 2 #include <string.h> #include <ctype.h> 4 /* Trimming leading and trailing white spaces. */ 6 char *trim (char * s) { /* Initialize start , end pointers */ 8 char *s1 = s, *s2 = &s[strlen(s) - 1]; 10 /* If last char is a white space and there* * is a previous char that is also a white* 12 * space then reduce the pointer by one * * for each white space. */ 14 while (( isspace (*s2)) && (s2 >= s1)) s2 --; 16 /* Finally we find the pointer value for * * last character other than a white space.*/ 18 /* Add end of line . */ 20 *(s2 + 1) = ’0’; 22 /* If first char is a white space and there* * is next char that is also a white space * 24 * then increase the pointer position by * * one for each white space. */ 26 while (( isspace (*s1)) && (s1 < s2)) s1 ++; 28 /* Copy rest of string to s */ 30 strcpy(s, s1); return s; 32 } 34 int main (int argc , char *argv [ ]) { char *s; 36 char string [100] = " 1arun2 "; printf("The original string is :%s:n", string); 38 s = trim (string); printf("The trimmed string is :%s:n", s);
  • 53. 1.8. STRINGS 153 40 return 0; } ✌ ✆ ✞ The original string is : 1arun 2 : The trimmed string is :1 arun 2: ✌ ✆ strlen Synopsis of strlen() function is ✞ size _t strlen(const char *s); ✌ ✆ The strlen() function shall compute the number of bytes in the string to which ‘s’ points, not including the terminating null byte. It returns the number of bytes in the string. No value is used to indicate an error. A simple example is ✞ 1 #include <stdio.h> #include <string.h> 3 int main () { 5 char Input [256]; printf("Enter a string : "); 7 gets ( Input); printf("The string length is %u characters long .n", 9 (unsigned ) strlen(Input)); return 0; 11 } ✌ ✆ ✞ Enter a string : a The string length is 1 characters long . ✌ ✆ strlen() counts only those cells in which string or character is stored. The counting of strlen() is stopped when, it encountered the cell of null character. We can used several methods to find the string length without using strlen function. ✞ #include <stdio.h> 2 #include <stdlib.h> 4 int main (void ) { int n = 0, c; 6 /* get string to be counted */ printf("Enter the string : "); 8 while ((c = getchar ()) != ’n’) { n++; 10 } printf("The string length is %d.n", n); 12 return 0; } ✌ ✆
  • 54. 154 Basic C ✞ Enter the string : arun kumar The string length is 10. ✌ ✆ A new example that uses array and strlen() function to get reverse of the supplied string. Actually in this example, strlen() function is used to get the length of the string. After that the characters of the string are printed in reverse order. ✞ #include <stdio.h> 2 #include <stdlib.h> 4 int main (void ) { char rs [1000]; // string to reversed . 6 /* get string to be reversed */ printf("Enter the string to be reversed : "); 8 scanf("%s", rs); printf("The reversed string is : "); 10 /* While array is not triggered with space*/ int n = strlen(rs); 12 while (n > 0) { printf("%c", rs[n - 1]); 14 n--; } 16 return 0; } ✌ ✆ ✞ Enter the string to be reversed : arun The reversed string is : nura ✌ ✆ In following example, classical method is used to find the length of a string. In this example, we count the characters in a string until a null terminating character is not obtained. After each counting, counter is increased by one. At last the counting value is the actual length of the string. ✞ #include <stdio.h> 2 int main (void ) { 4 char name [ ] = "NAME arun kr"; int i = 0; 6 while (name [i] != NULL ) i++; 8 printf("The length of string "%s" is %d.", name , i); return 0; 10 } ✌ ✆ ✞ The length of string "NAME arun kr" is 12. ✌ ✆ The following example is rewritten in which string pointer is passed to a function where string length is computed. The string length is returned to the main function and printed in output console.
  • 55. 1.8. STRINGS 155 ✞ 1 #include <stdio.h> 3 int StrLen(char * str) { int i = 0; 5 while (str[i] != ’0 ’) { i++; 7 } return i; 9 } 11 int main () { char str[ ] = "This is my string."; 13 int i; i = StrLen(str); 15 printf("The length of string is %d.n", i); return 0; 17 } ✌ ✆ ✞ The length of string is 18. ✌ ✆ The memory used by given string may also be retrieve by using keyword ‘sizeof’ as shown in example below. ✞ 1 #include <stdio.h> #include <string.h> /* provides strlen () prototype */ 3 #define PRAISE "Hi!" 5 int main (void ) { char name [40]; 7 printf("What ’s your name ?n"); scanf("%s", name ); 9 printf("Hello , %s. %sn", name , PRAISE); printf("Name has %d letters & occupies %d memory cells.n", 11 strlen(name ), sizeof name ); printf("The praise has %d letters ",strlen(PRAISE)); 13 printf("and occupies %d memory cells.n", sizeof PRAISE); return 0; 15 } ✌ ✆ ✞ What ’s your name ? Arun Hello , Arun . Hi! Name has 4 letters & occupies 40 memory cells. The praise has 3 letters and occupies 4 memory cells. ✌ ✆ strncat strncat() function concatenate specific number of characters into destination from the source. Synopsis of this function is
  • 56. 156 Basic C ✞ 1 char *strncat (char *s1 , const char *s2 , size_t n); ✌ ✆ The strncat() function shall not append more than ‘n’ bytes. A simple example is ✞ 1 #include <stdio.h> 3 int main () { char str1 [20]; 5 char str2 [20]; 7 strcpy(str1 , "Hello"); strcpy(str2 , "Worlddddddddd "); 9 printf("Concatenated string is : %sn", strncat (str1 , str2 , 4)); 11 printf("Final string is : %sn", str1 ); 13 return 0; } ✌ ✆ ✞ Concatenated string is : HelloWorl Final string is : HelloWorl ✌ ✆ strncmp The strncmp function syntax is ✞ int strncmp (const char *s1 , const char *s2 , size_t n); ✌ ✆ The strncmp() function shall compare not more than n bytes (bytes that follow a null byte are not compared) from the array pointed-by ‘s1’ into the array pointed-by ‘s2’. The sign of a non-zero return value is determined by the sign of the difference between the values of the first pair of bytes (both interpreted as type unsigned char) that differ in the strings being compared. See strcmp() for an explanation of the return value. This function is as useful in comparisons, as the strcmp function is. A simple example is ✞ 1 #include <stdio.h> #include <string.h> 3 int main () { 5 if (strncmp ("arun ", "Arun ", 2) ==0) { printf("Two strings are equal."); 7 } else { printf("Two strings are not equal."); 9 } return (0); 11 } ✌ ✆ ✞ Two strings are not equal. ✌ ✆
  • 57. 1.8. STRINGS 157 strncpy The syntax of strncpy() function is ✞ 1 char *strncpy (char *s1 , const char *s2 , size_t n); ✌ ✆ The strncpy() function shall copy not more than ‘n’ bytes (bytes that follow a null byte are not copied) from the array pointed-by ‘s2’ into the array pointed-by ‘s1’. A simple example is ✞ 1 #include <stdio.h> #include <string.h> 3 int main () { 5 /* initialize an experimental string */ char str[ ] = "This is a simple string"; 7 char * pch; /* get first occurace of simple*/ 9 pch = strstr(str , " simple"); /* copy NAGPUR from the point of simple upto two places.*/ 11 strncpy (pch , "NAGPUR", 2); /* copy NAGPUR from the point of simple upto four places.*/ 13 strncpy (pch , "NAGPUR", 4); puts (str); 15 /* copy NAGPUR from the point of simple upto six places.*/ strncpy (pch , "NAGPUR", 6); 17 puts (str); return 0; 19 } ✌ ✆ ✞ This is a NAmple string This is a NAGPle string This is a NAGPUR string ✌ ✆ In the above program, line ✞ 1 strncpy(pch , "NAGPUR", 2); ✌ ✆ copied first two characters from the “NAGPUR” at 11th and 12th place of the string ‘str’ as shown below: strncpy(pch, “NAGPUR”, 2) s i m p l e s N A G P U R 0 Similarly, in the above program, line ✞ 1 strncpy(pch , "NAGPUR", 6); ✌ ✆
  • 58. 158 Basic C copied first six characters from the “NAGPUR” into ‘str’ from 11th to 16th place of the string ‘str’ as shown below: strncpy(pch, “NAGPUR”, 6) s i m p l e s N A G P U R 0 During the copying of strings, size of strings should be clearly defined, otherwise the actual string may terminate shortly as null terminator is added within the actual string as shown in the following example. ✞ 1 #include <stdio.h> #include <string.h> 3 int main () { 5 /* initialize an experimental string */ char str[ ] = "This is a simple string"; 7 char * pch; /* get first occurace of simple*/ 9 pch = strstr(str , " simple"); /* copy NAGPUR from the point of simple upto seven places.*/ 11 strncpy (pch , "NAGPUR", 7); puts (str); 13 return 0; } ✌ ✆ ✞ This is a NAGPUR ✌ ✆ strncpy(pch, “NAGPUR”, 7) s i m p l e s N A G P U R 0 strrchr The strrchr() function searches string for the last occurrence of a character. The null character that represents to the termination of string, is also included in the search. The prototype of strrchr() function is ✞ 1 char *strrchr (const char *s, int c); ✌ ✆ strrchr is similar to strchr(), except the string is searched right to left. A simple example is
  • 59. 1.8. STRINGS 159 ✞ 1 #include <stdio.h> 3 int main () { char *s; 5 char buf [ ] = "This is a testing "; 7 s = strrchr (buf , ’t’); 9 if (s != NULL ) printf("found a ’t’ at %sn", s); 11 return 0; 13 } ✌ ✆ ✞ found a ’t’ at ting ✌ ✆ Here is another example that returns the position in a string where a delimiter is found. ✞ 1 #include <stdio.h> #include <string.h> 3 int main () { 5 char str[ ] = "This is my string"; char match[ ] = "i"; 7 int i; int c = 0; 9 for (i = 0; i < strlen(str); i++) { if (str[i] == match[c] && c < strlen(match)) { 11 c++; } else { 13 c = 0; } 15 if (c == strlen(match)) { printf("Pattern matched after %d charsn", 17 i - strlen(match) + 1); } 19 } return 0; 21 } ✌ ✆ ✞ Pattern matched after 2 chars Pattern matched after 5 chars Pattern matched after 14 chars ✌ ✆ strstr The syntax of strstr() function is
  • 60. 160 Basic C ✞ 1 char *strstr(const char *string , const char *sub -str); ✌ ✆ The strstr() function shall locate the first occurrence in the string pointed-by ‘string’ of the sequence of bytes (excluding the terminating null byte) in the string pointed-by ‘sub-str’. It returns the pointer (or may say the address) of the first occurrence of the sub-string. A simple example is ✞ 1 #include <stdio.h> #include <string.h> 3 int main () { 5 /* initialize an experimental string */ char str[ ] = "This is a simple string"; 7 char * pch; /* get first occurance of simple */ 9 pch = strstr(str , " simple"); puts (pch); 11 return 0; } ✌ ✆ ✞ simple string ✌ ✆ pch = strstr(str, ”simple”); T h i s i s a s i m p l e s t r i n g 0 pch s i m p l e s t r i n g 0 strtok The syntax of strtok function is ✞ 1 char *strtok(char *restrict s1 , const char *restrict delimiters ); ✌ ✆ A sequence of calls to strtok() breaks the string pointed-by ‘s1’ into a sequence of tokens, each of which is delimited by a byte from the string pointed-by delimiters. This function returns the address of memory location where tokenised string is stored. first cA simple example is ✞ 1 #include <stdio.h> #include <string.h> 3 int main () { 5 /* experimental string */ char str[ ] = "- This is my country .";
  • 61. 1.8. STRINGS 161 7 /* pointer for string tokenization */ char * pch;/*Do not need memory allocation , as it* 9 *has to point the memory address * *being returned by strtok function . */ 11 printf("String "%s" is splitted into tokens:n", str); /* break experimental string with * 13 * spacecomma dot and doublequote */ pch = strtok(str , " ,.-"); 15 while (pch != NULL ) { printf("%sn", pch); 17 pch = strtok(NULL , " ,.-"); } 19 return 0; } ✌ ✆ ✞ String "- This is my country ." is splitted into into tokens: This is my country ✌ ✆ Here is an example which splits the string by a delimiter without using strtok() function. In this example, a string is read character by character and when a read character is equal to the delimiter, a new line is started. ✞ 1 #include <stdio.h> 3 int main (int argc , char *argv [ ]) { if (argv [1] == NULL ) { 5 printf("Use <utility .exe > <string in double quote > <delimiter >.n"); exit (0); 7 } /* get the commandline string*/ 9 char *Str = argv [1]; char *Del = argv [2]; 11 printf("The delimiter is ’%s ’.n", Del); printf("The broken strings are : nn", Del); 13 int i = 0; while (Str[i] != NULL ) { 15 if (Str[i] == Del [0]) { printf("n"); 17 i++; } 19 printf("%c", Str[i]); i++; 21 } printf("nnThe length of string supplied is %d.n", i); 23 return 0; } ✌ ✆
  • 62. 162 Basic C ✞ executable .exe "This is my name " " " This is my name The length of string supplied is 15. ✌ ✆ strtod The strtod(), strtof (), and strtold() functions convert the initial portion of the string pointed-by pointer to double, float, and long double representation, respectively. The return value is numerical value and pointer stores the rest of string. ✞ 1 #include <stdio.h> #include <stdlib.h> 3 int main () { 5 char str [30] = "20.30300 Rs are spent."; char *ptr; 7 double ret; 9 ret = strtod(str , &ptr); printf("The Rs in ( double) is %lfn", ret); 11 printf("|%s|n", ptr); 13 return (0); } ✌ ✆ ✞ The Rs in (double) is 20.303000 | Rs are spent.| ✌ ✆ 1.9 Function Function in C a group of statements and expressions which accepts inputs, analyse them according to the statements and expressions, and return the result. ✞ int sum(int a, int b){ 2 <function body expressions > } ✌ ✆ A function is like a black box. It takes inputs and do something and throws an output. A function may be declared with or without definition as shown below: ✞ 1 int myFunc (); // Function declared without definition int myFunc (){} // Function declared with definition ✌ ✆
  • 63. 1.9. FUNCTION 163 1.9.1 Function Arguments A functions accepts inputs through its arguments. A function with two arguments (or parameters) is defined as ✞ int sum(int a, int b); ✌ ✆ These parameters in a function definition are called formal arguments. Here, int a, int b are known as formal arguments. During the defining of a function, each argument must be identified by its type. For example, to supply two integer arguments to a function, it shall be defined like ✞ 1 int sum(int a, int b); ✌ ✆ while, the definition of function as given below is illegal. ✞ 1 int sum(int a, b);// Illegal definition ✌ ✆ Here, second argument ‘b’ is type unidentified. A function can be called from anywhere by supplying actual arguments. The supplied argument to a function are type casted according to the type of the function argument. For example, when a function type ✞ 1 int sum(int a, int b); ✌ ✆ is called as ✞ 1 sum (2.5, 2); ✌ ✆ then the function accepts argument value (or actual arguments) 2.5 as a = 2 because, ar- gument a is an integer type and supplied argument is float type. While, b = 2. Therefore, decimal part of the float value is truncated. See example below. ✞ 1 #include <stdio.h> 3 /* Sum function with formal arguments */ int sum(int a, int b) { 5 int f; f = a + b; 7 return f; } 9 int main (int argc , char *argv [ ]) { 11 int g; /* Sum function with actual arguments */ 13 g = sum (2.5, 2); printf("Sum of %f and %d is %dn", 2.5, 2, g); 15 return 0; } ✌ ✆ ✞ Sum of 2.5 and 2 is 4 ✌ ✆
  • 64. 164 Basic C Two dimensional arrays of integer type may also be passed as function argument. Two dimensional, integer type and static size array is passed to function as shown below: ✞ 1 #include <stdio.h> 3 void myFunc(int myArray [3][3]) { int i, j; 5 for (i = 0; i < 3; i++) { for (j = 0; j < 3; j++) { 7 printf("%d t", myArray[i][j]); } 9 printf("n"); } 11 } 13 int main () { int myArray [][3] = { 15 {1, 2, 3}, {4, 5, 6}, 17 {7, 8, 9} }; 19 myFunc(myArray); return 0; 21 } ✌ ✆ ✞ 1 2 3 4 5 6 7 8 9 ✌ ✆ If height of the two dimensional array is dynamic and only width is fixed then two dimensional integer type array is passed to a function. The unknown dimension of the array should be passed to the function as its another parameter. ✞ 1 #include <stdio.h> 3 void myFunc(int myArray [][3] , int m) { int i, j; 5 for (i = 0; i < m; i++) { for (j = 0; j < 3; j++) { 7 printf("%d t", myArray[i][j]); } 9 printf("n"); } 11 } 13 int main () { int myArray [3][3] = { 15 {1, 2, 3}, {4, 5, 6}, 17 {7, 8, 9} };
  • 65. 1.9. FUNCTION 165 19 myFunc(myArray , 3); return 0; 21 } ✌ ✆ ✞ 1 2 3 4 5 6 7 8 9 ✌ ✆ A dynamic two dimensional integer type array may passed to a function as its argument in pointer form. Remember that as two dimensional array passed to function a pointer only and the called function does not know the actual size of the passed array. Therefore, dimensions of the array must be passed as another parameters of the function. ✞ 1 #include <stdio.h> 3 /* Catch myArray pointer as parameter of * * function . myr parameter points to passed* 5 * array as 1D array not as 2D array. */ void myF(int *mAr , int m, int n) { 7 int i, j; for (i = 0; i < m; i++) { 9 for (j = 0; j < n; j++) { /* Print the array elements row by row.*/ 11 printf("%d ", *(( mAr + i * n) + j)); } 13 printf("n"); } 15 } 17 int main () { int myArray [][3] = { 19 {4, 5, 6}, {1, 2, 3}, 21 {9, 8, 7} }; 23 /* Pass myArray as a pointer. */ myF(( int *) myArray , 3, 3); 25 return 0; } ✌ ✆ ✞ 4 5 6 1 2 3 9 8 7 ✌ ✆
  • 66. 166 Basic C myArray[m][n]= 11 12 13 14 15 21 22 23 24 25 31 32 33 34 35 41 42 43 44 45 51 52 53 54 55 i j myF((int *) myArray, ...) Pass Array to Function In above example, array is passed as pointer and the address of the array pointer is catches by the function as its parameter. Notice that, inside the function, array pointer does not represents to two dimensional array but represents to one dimensional array as a group of bytes in row by row order. This is why, in this function the dimensions of the array are passed via two additional parameters. These parameters are used to control the printing of each element of the passed array. void myF(int *mAr, ...){...} 11 12 13 14 15 21 22 23 24 25 ... *((mAr+i*n)+j) *((mAr+i*n)+j) Array as Argument Now, again, in C, a function without any argument can be compiled ans run by calling with any number of arguments. See the example below: ✞ 1 #include <stdio.h> 3 void testFun () { } // Function declared without arguments 5 int main (void ){ // Function called with three argument . 7 testFun (10, "x", "Y"); return 0; 9 } ✌ ✆ But if the argument of prototype function is void type then the program fails to compile and run. See below: ✞ 1 #include <stdio.h> 3 void testFun (void ) { } // Function declared with void arguments 5 int main (void ){ // Function called with three argument . 7 testFun (10, "x", "Y"); return 0; 9 } ✌ ✆
  • 67. 1.9. FUNCTION 167 1.9.2 Function Prototype The declaration of a function prototype tell the compiler three important things about it: 1. to expect to encounter them further down the program; 2. the return types of the function, e.g. void, int or double; 3. the number and kind of arguments the function is to handle; The parameter names listed in a function’s prototype may be same as in the function’s declaration or not. Function prototype allows to omit the variable name in its arguments. The legal function prototyping are ✞ 1 int sum(int , int); /* Legal prototype .*/ int sum(int a, int b); /* Legal prototype .*/ 3 int sum(a, int b); /* Illegal prototype .*/ int sum(int *, int *a); /* Legal prototype with pointer array.*/ 5 int sum(int *, int &a); /* Illegal prototype with address of a*/ int sum(int [ ], int a[ ]); /* Legal prototype with array.*/ ✌ ✆ Function prototyping is required when a function is called from the body of another function which is defined above the called function. It also needed to be declared if function is envoked before its definition as shown in the below example. ✞ #include <stdio.h> 2 /* Prototype is required .*/ void swap (int * u, int * v); 4 int main (void ) { 6 int x = 5, y = 10; printf("Originally x = %d and y = %d.n", x, y); 8 swap (&x, &y); /* Send addresses to function */ printf("Now x = %d and y = %d.n", x, y); 10 return 0; } 12 void swap (int * u, int * v) { 14 int temp ; temp = *u; /* temp gets value that u points to */ 16 *u = *v; /* Store the value of v at address of x*/ *v = temp ; /* Store the value of u at address of y*/ 18 } ✌ ✆ ✞ Originally x = 5 and y = 10. Now x = 10 and y = 5. ✌ ✆ If prototype is not declared, then the compiler shows errors as in the following example, function is envoked before the definition of the function.
  • 68. 168 Basic C ✞ #include <stdio.h> 2 /* Prototype is disabled .*/ // void swap (int * u, int * v); 4 int main (void ) { 6 int x = 5, y = 10; printf("Originally x = %d and y = %d.n", x, y); 8 swap (&x, &y); /* send addresses to function */ printf("Now x = %d and y = %d.n", x, y); 10 return 0; } 12 void swap (int * u, int * v) { 14 int temp ; temp = *u; /* temp gets value that u points to */ 16 *u = *v; /* Store the value of v at address of x*/ *v = temp ; /* Store the value of u at address of y*/ 18 } ✌ ✆ Again, if a function is called from the body of another function which is defined below to the called function, then declaration of prototype is not required. ✞ #include <stdio.h> 2 void swap (int * u, int * v) { 4 int temp ; temp = *u; /* temp gets value that u points to */ 6 *u = *v; /* Store the value of v at address of x*/ *v = temp ; /* Store the value of u at address of y*/ 8 } 10 int main (void ) { int x = 5, y = 10; 12 printf("Originally x = %d and y = %d.n", x, y); swap (&x, &y); /* send addresses to function */ 14 printf("Now x = %d and y = %d.n", x, y); return 0; 16 } ✌ ✆ ✞ Originally x = 5 and y = 10. Now x = 10 and y = 5. ✌ ✆ Another point is to be remembered that C compiler assumes a function as integer return type by default. If user defined function is declared as integer type, then C compiler does not failed to compile a function without prototype declaration. If user defined function returns other values then compiler fails to compile the program. The following example compiled successfully. ✞ #include <stdio.h> 2 /* Declaring prototype */
  • 69. 1.9. FUNCTION 169 char myFunc (); 4 int main (void ) { 6 /* Calling function of integer type return.*/ printf("Calling function myFunc()n"); 8 printf("Returned value is %c", myFunc ()); return 0; 10 } 12 /* Declaring function of char type return.*/ char myFunc () { 14 return ’A’; } ✌ ✆ ✞ Calling function myFunc () Returned value is A ✌ ✆ Above function is re-written without declaring prototype. This program is failed to compile. ✞ #include <stdio.h> 2 int main (void ) { 4 /* Calling function of integer type return.*/ printf("Calling function myFunc()n"); 6 printf("Returned value is %c", myFunc ()); return 0; 8 } 10 /* Declaring function of char type return.*/ char myFunc () { 12 return ’A’; } ✌ ✆ There is no problem if the function is declared with integer return type. See the example below which is modified form of above function. ✞ 1 #include <stdio.h> 3 int main (void ) { /* Calling function of integer type return.*/ 5 printf("Calling function myFunc()n"); printf("Returned value is %c", myFunc ()); 7 return 0; } 9 /* Declaring function of integer type return.*/ 11 int myFunc () { return ’A’; 13 } ✌ ✆
  • 70. 170 Basic C ✞ Calling function myFunc () Returned value is A ✌ ✆ Compiler does not care about parameters of the declared function prototype. The com- piler will not be able to perform compile-time checking of argument types. The validity of arguments is checked during the program run time and sometime program returns garbage value. ✞ #include <stdio.h> 2 int main (void ) { 4 /* Calling function of integer type return.*/ printf("Calling function myFunc()n"); 6 printf("Returned value is %c", myFunc (65) ); return 0; 8 } 10 /* Declaring function of integer type return.*/ int myFunc(int i, int j) { 12 return i + j; } ✌ ✆ 1.9.3 Function Types In old C standards, each function was considered as integer type, while in new implemen- tation of C standards, the type of the function may be integer, float, double, character or void. Declaration of a function type is based on the return value of the function not on the argument type. See example below: ✞ 1 #include <stdio.h> /* Integer type function .*/ 3 int max(int a, int b) { if (a > b) 5 return a; else 7 return b; } 9 int main (int argc , char *argv [ ]) { 11 /* integer specifier required to * *print return value from function .*/ 13 printf("Max of %d and %d is %dn", 2, 3, max(2, 3)); return 0; 15 } ✌ ✆ ✞ Max of 2 and 3 is 3 ✌ ✆
  • 71. 1.9. FUNCTION 171 In function ‘max’, two arguments are taken as inputs as integer and between them, greater is returned as integer. Hence, here the function is declare as integer type. If the same function is declared as float type then return value is a float value not integer value. ✞ 1 #include <stdio.h> /* Float type function .*/ 3 float max(int a, int b) { if (a > b) 5 return a; else 7 return b; } 9 int main (int argc , char *argv [ ]) { 11 /* Float specifier required to print* *return value from function . */ 13 printf("Max of %d and %d is %fn", 2, 3, max(2, 3)); return 0; 15 } ✌ ✆ ✞ Max of 2 and 3 is 3.0000 ✌ ✆ In case of void functions, the function should return with NULL value even if return keyword is used inside the function. This type of function do something according to its expression and stores the result in global variable. ✞ 1 #include <stdio.h> int f; 3 void sum(int a, int b) { 5 f = a+b; /* Use of return keyword without any value.*/ 7 return; } 9 int main (int argc , char *argv [ ]) { 11 sum(2, 3); printf("Sum of %d and %d is %dn", 2, 3, f); 13 return 0; } ✌ ✆ ✞ Sum of 2 and 3 is 5 ✌ ✆ Use of return keyword in following manner are valid in void type functions. ✞ 1 return; /* Legal return*/ return ""; /* Legal return */ 3 return NULL ; /* Legal return */ return "; /* Illegal , " is null character code */ ✌ ✆
  • 72. 172 Basic C return keyword is somewhat like exit keyword. After return keyword, anything inside an expression block is skipped during program execution. Function returns the assigned value and exits. ✞ #include <stdio.h> 2 int ret(); 4 int main (void ) { 6 ret(); return 0; 8 } 10 int ret() { int i = 0; 12 int loops = 15; printf("Loop count is %dn", loops); 14 while (i < loops) { printf("i is %dn", i); 16 if (i == 7) { printf("Returning from the function at i=%dn", i); 18 printf("reaching before the loop value %dn", loops); return 0; 20 } i++; 22 } return 0; 24 } ✌ ✆ ✞ Loop count is 15 i is 0 i is 1 i is 2 i is 3 i is 4 i is 5 i is 6 i is 7 Returning from the function at i=7 reaching before the loop value 15 ✌ ✆ A function with void return type can not be called through printf. For example ✞ 1 #include <stdio.h> #include <stdlib.h> 3 /* function return type is void */ 5 void myF() { printf("myF"); 7 }
  • 73. 1.9. FUNCTION 173 9 int main () { int i = 5, j = 3; 11 /* invalid use of void type function */ printf("%s", myF()); 13 return 0; 15 } ✌ ✆ program failed to compile and returns compile time error “invalid use of void”. Never Reach Condition A function with return keyword, returns either NULL or some alpha-numeric value after successful execution. Execution of function-script is terminated after first successful return. If a function is designed in such manner that it has to reached to only fixed return keywords then other return keywords if used are never reached by the compiler. See the example given below: ✞ 1 #include <stdio.h> 3 int executeMe (int i) { if (i <= 10) { /* If i is less than or equal to 10 */ 5 return 0; } else { /* Otherwise */ 7 return 1; } 9 return -1; /* Mever reached */ } 11 int main () { 13 printf("%dn", executeMe (10) ); printf("%dn", executeMe (15) ); 15 printf("%dn", executeMe (1)); return 0; 17 } ✌ ✆ ✞ 0 1 0 ✌ ✆ 1.9.4 Function Recursion In C, a function can be called recursively, i.e. in nested form from within its body, without using loop functions, i.e. for, while or do-while etc. See the example given below: ✞ 1 #include <stdio.h> int recFunc (int i, int j); 3 int recFunc (int i, int j) { 5 if (i == 0) { return (2 + j);
  • 74. 174 Basic C 7 } else { return recFunc(i - 1, j + 1); 9 } } 11 int main (int argc , char ** argv ) { 13 int k = recFunc (4, 6); printf("%d", k); 15 return 0; } ✌ ✆ ✞ 12 ✌ ✆ In above example, function ‘recFunc’ takes two arguments and checks the conditions for its first argument. If it is true then it returns the sum of ‘2’ and second argument and exits. Otherwise it returns the function ‘recFunc’ with new values of its two arguments. As function calls itself, hence a loop like recursion is observed. There should be a condition to be met and break the function recursion otherwise there shall be no return value. See the following examples, ✞ 1 #include <stdio.h> int recFunc (int i, int j); 3 /* This type of recursion is not acceptable .*/ 5 int recFunc (int i, int j) { /*No Condition , No return value.*/ 7 return recFunc(i - 1, j + 1); } 9 int main (int argc , char ** argv ) { 11 int k = recFunc (4, 6); printf("%d", k); 13 return 0; } ✌ ✆ If condition in the recursive function is not met then there is no return value from the function. In the following example, if condition is never met therefore, there shall be no return value from the recursive function. ✞ #include <stdio.h> 2 int recFunc (int i, int j); 4 int recFunc (int i, int j) { /* Condition never met. No returned value.*/ 6 if (i == 0) { return (2 + j); 8 } else { return recFunc(i, j + 1); 10 } }
  • 75. 1.9. FUNCTION 175 12 int main (int argc , char ** argv ) { 14 int k = recFunc (1, 6); printf("%d", k); 16 return 0; } ✌ ✆ There shall be no output on running of above two program. 1.9.5 Function As Argument A function can pass to another function as its argument. The synopsis of the passing of a function as argument to the other function tFunc() is given below: ✞ 1 void tFunc(<data type > (*< func pointer >)()); ✌ ✆ See the example : ✞ 1 #include <stdio.h> #include <math .h> 3 /* Here *fp is pointer of the function sqrt */ 5 void tFunc(char *name , double (*fp)()) { int n; 7 printf("Testing function %s:n", name ); printf("%s: %10sn", "n", "Square Root "); 9 printf(" --------------n"); for (n = 0; n < 10; n++) { 11 printf("%d: %11.6fn", n, (*fp)(( double) n)); } 13 } 15 int main () { tFunc("square root ", sqrt ); 17 return 0; } ✌ ✆ ✞ Testing function square root : n: Square Root -------------- 0: 0.000000 1: 1.000000 2: 1.414214 3: 1.732051 4: 2.000000 5: 2.236068 6: 2.449490 7: 2.645751 8: 2.828427 9: 3.000000 ✌ ✆
  • 76. 176 Basic C 1.9.6 Function Callback A callback is a piece of executable code that is passed as an argument to other code, which is expected to call back (execute) the argument at some convenient time. In C, there is no “callback” yet they are implemented by using function pointers. Following example shows the possible call back. ✞ 1 #include <stdio.h> 3 /* This function is calledback from other function .*/ int DoubleIt (int a) { 5 return 2 * a; } 7 /* Pass DoubleIt function as argument named fPar .* 9 *The argument should be as function prototype . */ int myFunc(int (* fPar )(int)) { 11 int i = 10; fPar (i); 13 } 15 int main () { /* Pass function DoubleIt to myFunc */ 17 printf("Result is : %dn", myFunc(DoubleIt )); return 0; 19 } ✌ ✆ ✞ Result is : 20 ✌ ✆ The same above example is given in pointer format. ✞ 1 #include <stdio.h> 3 /* This function is calledback from other function .*/ int *DoubleIt (int a) { 5 int *i; i = (2 * a); 7 } 9 /* Pass DoubleIt function as argument named fPar .* *The argument should be as function prototype . */ 11 int *myFunc(int (* fPar )(int )) { int i = 10; 13 (* fPar )(i); } 15 int main () { 17 /* Pass function DoubleIt to myFunc */ printf("Result is : %dn", myFunc(DoubleIt )); 19 return 0; } ✌ ✆
  • 77. 1.9. FUNCTION 177 ✞ Result is : 20 ✌ ✆ A function may be called from its pointer index if function pointer is saved in function symbol table. See the example given below: ✞ 1 #include <stdio.h> #include <stdlib.h> 3 #include <dlfcn.h> 5 /* Memory allocation for 5 Function Pointers */ int (*FP [5]) (); 7 main (int argc , char **argv ) { 9 int i = 0; void * myLib; 11 /* Function pointer */ 13 void *fptr ; 15 /* Load function library */ myLib = dlopen("libtestdll .dll", RTLD_LAZY ); 17 /* Find the function object of function "bar"*/ 19 fptr = dlsym(myLib , "bar"); 21 /* Assign address of library function "bar"* *to all indexed function pointers (FP) */ 23 for (i = 0; i < 5; i++) { FP[i] = fptr ; 25 } 27 /* Call function from second FP address */ FP [1](); 29 /* Close Library */ 31 dlclose (myLib); 33 return 0; } ✌ ✆ ✞ called bar function from dll. ✌ ✆ 1.9.7 Memory Function Memory functions in C, deals with memory. These functions are used to store, copy and move data from one memory location to other memory location.
  • 78. 178 Basic C mmap To read or write to same file by two or more processes, mmap() function is used. Before mapping a file to memory, file descriptor is obtained by using open() function as given below: ✞ 1 int fd; fd=open ("<file name >", "<mode >"); ✌ ✆ The open function returns the file descriptor as integer value. ‘-1’ if it failed to open the file otherwise a positive integer as file handle. Now, mmap() is called to map the file as ✞ data = mmap (<address >, <size >, <prot >, <flags >, <file id >, <offset >); ✌ ✆ ‘address’ is the memory address where we want to mapped a file. By default its value is ‘0’ for automatic selection of address by the OS. ‘size’ is length of data of the file to be mapped. ‘prot’ is a kind of access/permission to the file. Its values are PROT READ for read only permission, PROT WRITE for write only permission and PROT EXEC for execute permissions. ‘flags’ controls the sharing of changes or just keep them private. The flag values are MAP SHARED or MAP PRIVATE for sharing and private mode respectively. ‘offset’ is initial position of the file from where mapping of file data to memory started. This value must be a multiple of the virtual memory page size. To get the page size, getpagesize() function is used. See the example below: ✞ 1 #include <stdio.h> #include <stdlib.h> 3 #include <sys/mman .h> #include <fcntl.h> 5 int main (int argc , char *argv []) { 7 int fd; char *data ; 9 /* Read only mode of file .*/ if ((fd = open ("a.txt", O_RDONLY )) == -1) { 11 printf("Unable to open file "); return 1; 13 } /* Map file in memory with read only permissions */ 15 data = mmap (0, 1024, PROT_READ , MAP_SHARED , fd , 0); if (* data == -1) { 17 printf("Unable to map file "); return 1; 19 } printf("Byte at offset %d is ’%c ’n", 0, data [0]) ; 21 return 0; } ✌ ✆ ✞ Byte at offset 0 is ’s’ ✌ ✆
  • 79. 1.9. FUNCTION 179 Each file which is mapped must be freed by using munmap function as ✞ 1 int munmap(<address >, <size >); ✌ ✆ Once the file is unmapped, data access with old file descriptor is not possible and will return segmentation fault error. If multiple protected access permissions are granted by using OR (|) operator in mmap() function, then the file access mode should be according the access granted. See the example below in which protected access mode is grated for read and write. Therefore, the file access mode in open() function is “rw” type (i.e. read and write type via O RDWR). ✞ 1 #include <stdio.h> #include <stdlib.h> 3 #include <sys/mman .h> #include <fcntl.h> 5 int main (int argc , char *argv []) { 7 int fd; char *data ; 9 /* Read and write mode of file .*/ if ((fd = open ("a.txt", O_RDWR)) == -1) { 11 printf("Unable to open file "); return 1; 13 } /* Map file in memory with read & write permissions */ 15 data = mmap (0, 1024, PROT_READ |PROT_WRITE , MAP_SHARED , fd , 0); if (* data == -1) { 17 printf("Unable to map file "); return 1; 19 } printf("Byte at offset %d is ’%c ’n", 0, data [0]) ; 21 data [10] = ’1’; printf("Byte at offset %d is ’%c ’n", 10, data [10]); 23 return 0; } ✌ ✆ ✞ Byte at offset 0 is ’a’ Byte at offset 10 is ’1’ ✌ ✆ File Mode Key Numeric Description O RDONLY 0 Read only access to file. O WRONLY 1 Write only access to file. O RDWR 2 Read and write access to file. Table 1.21: File access mode.
  • 80. 180 Basic C A segment of file may be mapped by using mmap function with setting file pointer by lseek function as given below: ✞ .... 2 for (j = 0; j <= bk; j++) { /* Map file for block size ‘bks’ from ‘offset’*/ 4 data = mmap (0, bks , PROT_READ | PROT_WRITE , MAP_SHARED , fd , offset); 6 /* Chagne file pionter ‘fd’ to next block */ int offset=lseek(fd , bks , SEEK_CUR ); 8 } .... ✌ ✆ File Access Modes The protection and permission codes of a file in Linux OS system are given in the following table. Mode Permission Value Protection Value NONE 0 0 READ 4 1 WRITE 2 2 EXEC 1 4 Permission to a file in Linux OS system for a user, group or system is managed by chmod command. This command accepts the file protection mode in numeric form as given below: ✞ 1 chmod 777 <file or dir > ✌ ✆ In Linux OS system, a file has three levels of discretionary protection and permission. permission to a file in Linux OS system is represented by a string that looks like “Zrwxr- wxrwx”, in which first character, ‘Z’ defined type of directory or file, i.e. ‘d’ for directory, ‘l’ for linked file, ‘s’ for setuid bit, ‘t’ for the sticky bit etc. Next three characters (triads) are protection/permission mode for owner, second is for group and third is for all other users. Character ‘r’, ‘w’ and ‘x’ represents to read, write and execute modes respectively. If user has readonly permission to a file then three characters shall be looked like ‘r – –’ where dashes represent no write and no execute permissions to the user for the given file or directory. The permission code in chmod command, as given above is splited in all possible combinations before defining user’s permission and execution of chmod com- mand. Note that, in permission code ‘777’, first ‘7’ is for owner second ‘7’ is for group and third ‘7’ is for all other users. For example, ‘7’ is splitted in 4+2+1 form to mark a file as read-write-exec. ‘3’ as 0+2+1, i.e. read-write- –. ‘5’ as 4+0+1, i.e. read- – - exec. Permission with ‘–’ means files can not be either read, write or permissioned and directories can not be permissioned with cd command. If there is no valid combinations
  • 81. 1.9. FUNCTION 181 are made from permission code, then invalid mode error is thrown by the system. The permission string can be equivalently computed with binary values as shown below: ✞ 1 -rwxrwxrwx ; permission string 111111111 ; Binary values ✌ ✆ The triad values for owner (let) are computed for read permission as 1002 = 410, for write permission as 0102 = 210, for read-write 1102 = 610 and so on. memset Syntax of memset() function is ✞ void *memset(void *s, int c, size_t n); ✌ ✆ The memset() function converts ‘c’ into unsigned char, then stores the character into the first ‘n’ bytes of memory pointed-by ‘s’. A simple example is ✞ 1 #include <stdio.h> #include <string.h> 3 int main () { 5 /* iniitalized a string */ char str1 [ ] = "These is memset !!!! "; 7 /* memset first six characters of the string*/ memset(str1 , ’-’, 6); 9 puts (str1 ); /* iniitalized a string */ 11 char str2 [ ] = "These is memset !!!! "; /* memset first three characters of the string*/ 13 memset(str2 , ’-’, 3); puts (str2 ); 15 /* iniitalized a string */ char str3 [ ] = "These is memset !!!! "; 17 /* memset first four characters of the string*/ memset(str3 , ’-’, 4); 19 puts (str3 ); return 0; 21 } ✌ ✆ ✞ ------is memset !!!! ---se is memset !!!! ----e is memset !!!! ✌ ✆ memcpy The memcpy() function shall copy n bytes from the object pointed to by ‘source’ into the object pointed to by ‘destination’. If copying takes place between objects that overlap, the behavior is undefined. The function returns ‘destination’. Syntax of the function is
  • 82. 182 Basic C ✞ 1 void *memcpy(void * restrict <destination >, const void * restrict <source >, size_t <n>); ✌ ✆ Because the function does not have to worry about overlap, it can do the simplest copy it can. ✞ #include <stdio.h> 2 #include <string.h> 4 int main () { const char src [50] = "Experimental string."; 6 char dest [50]; 8 printf("Before memcpy destination is : %sn", dest ); memcpy(dest , src , strlen(src) + 1); 10 printf("After memcpy destination is : %sn", dest ); 12 return (0); } ✌ ✆ ✞ Before memcpy destination is : After memcpy destination is : Experimental string. ✌ ✆ memcpy() function is very useful when a user defined function pointer is required to return the local pointer defined inside the function. ✞ #include <stdio.h> 2 char *toLower (char str[ ]) { 4 /* Initiate local string pointer */ char *s = NULL ; 6 /* Allocate memory for local pointer */ s = malloc(sizeof (char )*(1024)); 8 int i = 0; /* Create a local array for storing * 10 * modified string received from * * from function argument . */ 12 char st [1024]; while (str[i] != ’0 ’) { 14 /* Capital letters starts from * * char code 65 to 90. While * 16 * small letters starts from 97* * to 122. A difference of +32 */ 18 if (str[i] >= 65 && str[i] <= 90) { st[i] = str[i] + 32; 20 } else { st[i] = str[i]; 22 } i++; 24 }
  • 83. 1.9. FUNCTION 183 st[i] = ’0’; 26 /* Copy array into memory as a pointer . */ memcpy(s, st , 1024); 28 /* Return function pointer.*/ return s; 30 /* Free allocated memory.*/ free (s); 32 } 34 int main (void ) { char str[ ] = "This iS MY striNg."; 36 printf("Actual string is :"); printf(""%s"n",str); 38 printf("Lower case string is :"); printf(""%s"", toLower (str)); 40 return 0; } ✌ ✆ ✞ Actual string is : "This iS MY striNg ." Lower case string is : "this is my string ." ✌ ✆ memmov The memmove() function shall copy n bytes from the object pointed to by ‘source’ into the object pointed to by ‘dest’. Copying takes place as if the n bytes from the object pointed to by ‘source’ are first copied into a temporary array of n bytes that does not overlap the objects pointed to by ‘dest’ and ‘source’, and then the n bytes from the temporary array are copied into the object pointed to by ‘dest’. The function returns the value of ‘dest’. The easy way to implement this without using a temporary array is to check for a condition that would prevent an ascending copy, and if found, do a descending copy. Unlike the memcpy(), this function guaranteed to move contents from source to destination even if the memory regions pointed by ‘source’ and ‘dest’ overlaps. Its syntax is ✞ void *memmove (void * <dest >, const void *<source >, size_t <n>); ✌ ✆ ✞ 1 #include <stdio.h> #include <string.h> 3 int main () { 5 char str[ ] = "Experimental string"; memmove (str + 10, str + 5, 5); 7 puts (str); return 0; 9 } ✌ ✆ ✞ Experimentimentring ✌ ✆
  • 84. 184 Basic C memchr The memchr() function shall locate the first occurrence of ‘c’ (converted to an unsigned char) in the initial n bytes (each interpreted as unsigned char) of the object pointed to by ‘string’. If ‘c’ is not found, memchr() returns a null pointer. Its syntax is ✞ 1 void *memchr(const void *<string >, int <c>, size_t <n>); ✌ ✆ ✞ 1 #include <stdio.h> #include <string.h> 3 int main () { 5 char * pch; char str[ ] = "Example string"; 7 pch = (char *) memchr(str , ’e’, strlen(str)); if (pch != NULL ) 9 printf("’e’ found at position %d.n", pch - str + 1); else 11 printf("’e’ not found.n"); return 0; 13 } ✌ ✆ ✞ ’e’ found at position 7. ✌ ✆ memcmp The memcmp() function shall compare the first n bytes (each interpreted as unsigned char) of the object pointed to by ‘mem1’ to the first n bytes of the object pointed to by ‘mem2’. The sign of a non-zero return value shall be determined by the sign of the difference between the values of the first pair of bytes (both interpreted as type unsigned char) that differ in the objects being compared. ✞ 1 int memcmp(const void *<mem1 >, const void *<mem2 >, size_t <n>); ✌ ✆ ✞ 1 #include <stdio.h> #include <string.h> 3 int main () { 5 char buff [ ] = "Artificial "; char buff2[ ] = "ARtificial "; 7 int n; 9 n = memcmp(buff , buff2 , sizeof (buff )); 11 if (n > 0) 13 printf(" ’%s’ is greater than ’%s ’.n", buff , buff2); else if (n < 0) 15 printf(" ’%s’ is less than ’%s ’.n", buff , buff2);
  • 85. 1.9. FUNCTION 185 else 17 printf(" ’%s’ is the same as ’%s ’.n", buff , buff2); 19 return 0; } ✌ ✆ ✞ ’Artificial ’ is greater than ’ARtificial ’. ✌ ✆ 1.9.8 Unicode Support C provides unicode support for the native operating systems which have their own unicode support. To set the native local language ✞ 1 char *locale = setlocale (LC_CTYPE , " en_IN.UTF -8"); ✌ ✆ The function setlocale() is defined in the macro “locale.h”. If native locale doesn’t use UTF-8 encoding it need to replace the empty string with a locale like “en IN.UTF-8”. Localisation environment has following parameters ✞ 1 ANG=en_US LC_CTYPE ="en_US" 3 LC_NUMERIC ="en_US" LC_TIME=" en_US" 5 LC_COLLATE ="en_US" LC_MONETARY ="en_US" 7 LC_MESSAGES ="en_US" LC_PAPER ="en_US" 9 LC_NAME=" en_US" LC_ADDRESS ="en_US" 11 LC_TELEPHONE ="en_US" LC_MEASUREMENT ="en_US" 13 LC_IDENTIFICATION ="en_US" LC_ALL= ✌ ✆ User can change any specific environmental parameter by using method given above or setting all environment to locals by setting ‘LC ALL’ as shown below. ✞ char *locale = setlocale (LC_ALL , "en_IN.UTF -8"); ✌ ✆ An example is ✞ 1 #include <stdio.h> #include <wchar.h> 3 #include <stdlib.h> #include <locale.h> 5 int main (void ) { 7 /* If your native locale doesn’t use UTF -8 encoding * * you need to replace the empty string with a *
  • 86. 186 Basic C 9 * locale like "en_US.utf8 " */ char * locale = setlocale (LC_CTYPE , "en_IN.UTF -8"); 11 FILE *in = fopen("a.txt", "r"); 13 wint_t c; while ((c = fgetwc(in)) != WEOF ) 15 putwchar (c); fclose(in); 17 return EXIT_SUCCESS ; 19 } ✌ ✆ 1.10 Procedures & Functions A function is often executed (called) several times, called from different locations, during a single execution of the program. After finishing a subroutine, the program will branch back (return) to the point after the call. A function is like a black box. It takes inputs, does something with them, then spits out an answer. ✞ 1 #include <stdio.h> 3 void P_Loop(void ) { int i; 5 for (i = 1; i <= 5; i++) { printf("%d ", i * i); 7 } } 9 int main (void ) { 11 P_Loop (); printf("n"); 13 P_Loop (); return 0; 15 } ✌ ✆ The output is ✞ 1 4 9 16 25 1 4 9 16 25 ✌ ✆ 1.10.1 Code Optimisation It is very common that in a program, there are excess lines of script or it has time/memory consuming algorithm. Ultimately program takes longer time for execution. By using ad- vance methods of algorithm and script writing we can reduce the size as well as execution time of the program. It is known as code optimization. In other words, code optimization is a method of code modification to improve code quality and efficiency. A program may
  • 87. 1.10. PROCEDURES & FUNCTIONS 187 be optimized so that it becomes a smaller size, consumes less memory, executes more rapidly or performs fewer input/output operations. Illustrated Example Assume that we have to find all the prime numbers within 1 to 20. We write a program in which each number is divided by all numbers less than to it. For example, to check whether 19 is a prime or not, it is divided by integers started from 2 to 19 and if any of the divisor returns the zero as remainder then the number 19 is not prime. ✞ #include <stdio.h> 2 #include <stdlib.h> 4 int main () { int n, i = 1, j, m = 0; 6 printf("Enter Limit of Prime Number : "); scanf("%d", &n); 8 while (i <= n) { int k = 0; 10 for (j = 2; j < i; j++) { if (i % j == 0) {// line to be optimised 12 k++; } 14 } if (k == 0) { 16 m++; printf("%d is a prime number .n", i); 18 } i++; 20 } printf("Total %d primes are found.n", m); 22 return 0; } ✌ ✆ Another concept is that, if a number, ‘n’, is not divisible by a maximum integer value of ‘n/2’ then it is not divisible by any integers larger ‘n/2’. For example if 19 is not divisible by maximum integer value of 19/2, ie 9 then 19 never be completely divisible by 10 or more. By this method we reduce the iteration loops in the program. Above example can be rewritten as ✞ 1 #include <stdio.h> #include <stdlib.h> 3 int main () { 5 int n, i = 1, j, m = 0; printf("Enter Limit of Prime Number : "); 7 scanf("%d", &n); while (i <= n) { 9 int k = 0; for (j = 2; j <= i/2; j++) {// line is optimised 11 if (i % j == 0) { k++;
  • 88. 188 Basic C 13 } } 15 if (k == 0) { m++; 17 printf("%d is a prime number .n", i); } 19 i++; } 21 printf("Total %d primes are found.n", m); return 0; 23 } ✌ ✆ By this way we have reduce the execution time of the program (better performance) without compromising its output. Again if a number ‘n’ is divisible by ‘2’, above program checks the divisibility upto maximum integer value of ‘n/2’ by several iteration even if it was confirm that the number ‘n’ is not prime in first iteration. To enhance the performance of the program, we can again optimize the code by using break-continue function when number is checked and confirmed that it is not prime in first iteration. ✞ 1 #include <stdio.h> #include <stdlib.h> 3 int main () { 5 int n, i = 1, j, m = 0; printf("Enter Limit of Prime Number : "); 7 scanf("%d", &n); while (i <= n) { 9 int k = 0; for (j = 2; j <= i / 2; j++) { 11 if (i % j == 0) { k++; 13 break;/* no further check that the number* *is primeif it is declared not a * 15 *prime in first few iterations . */ }else { 17 continue ; } 19 } if (k == 0) { 21 m++; printf("%d is a prime number .n", i); 23 } i++; 25 } printf("Total %d primes are found.n", m); 27 return 0; } ✌ ✆ It again enhance the performance of program by multiple times. Similarly, if given number is even number then it shall never be prime and if given number is odd number then it shall not be prime if it has a perfect square-root. Again, square-root of odd number is
  • 89. 1.10. PROCEDURES & FUNCTIONS 189 only odd number. It means we have to check the divisibility of given number by all odd numbers less than or equal to square root of the given number. By this way we can further optimize the code for prime numbers. ✞ #include <math .h> 2 #include <stdio.h> 4 int main () { int n = 147853; 6 int x, y = 1; int sq = sqrt (n) + 1; 8 if (n < 2) y = 0; 10 if (n == 2 || n == 3) y = 1; 12 if (n % 2 == 0) y = 0; 14 for (x = 3; x <= sq; x += 2) { if (n % x == 0) 16 y = 0; } 18 if (y == 1) { printf("A primen"); 20 } else { printf("Not A primen"); 22 } return 1; 24 } ✌ ✆ Execution Time In good programming practices, codes are written in such manner that they took least execution time with optimum performance. Using clock() function, we can get the execution time of the program. A simple example is given below. ✞ #include <stdio.h> 2 #include <stdlib.h> #include <time .h> 4 int main () { 6 clock_t startTime = clock(); int n = 1000000 , i = 1; 8 while (i <= n) { i++; 10 } clock_t endTime = clock(); 12 double td = (endTime - startTime ) / (double) CLOCKS_PER_SEC ; printf("Program has run for %5.8 f secondsn", td); 14 return 0; } ✌ ✆ ✞ Program has run for 0.00000200 seconds ✌ ✆
  • 90. 190 Basic C Additional to this, some time it is required to know the local time (computer clock time) for best performance of the program. Here is an example that uses time.h header file to get the local time. The code line ✞ 1 time_t time (time_t *seconds ); ✌ ✆ returns the time lapsed since the mid night of January 1, 1970, measured in seconds. If ‘seconds’ is not NULL, the return value is also stored in variable ‘seconds’. ✞ 1 #include <stdio.h> #include <time .h> 3 int main () { 5 time_t seconds; 7 seconds = time (NULL ); printf("Hours since January 1, 1970 = %ldn", seconds / 3600); 9 return (0); 11 } ✌ ✆ ✞ Hours since January 1, 1970 = 405089 ✌ ✆ Another example is ✞ 1 #include <time .h> #include <stdlib.h> 3 #include <stdio.h> 5 int main (void ) { time_t current_time ; 7 char * c_time_string ; int i = 5; 9 while (i > 0) { sleep (1); 11 /* Obtain current time . */ current_time = time (NULL ); 13 /* Convert to local time format. */ c_time_string = ctime(& current_time ); 15 printf("Current time is %d, %s", current_time , c_time_string ); i--; 17 } return EXIT_SUCCESS ; 19 } ✌ ✆ ✞ Current time is 1458321446 , Fri Mar 18 22:47:26 2016 Current time is 1458321447 , Fri Mar 18 22:47:27 2016 Current time is 1458321448 , Fri Mar 18 22:47:28 2016 Current time is 1458321449 , Fri Mar 18 22:47:29 2016
  • 91. 1.10. PROCEDURES & FUNCTIONS 191 Current time is 1458321450 , Fri Mar 18 22:47:30 2016 ✌ ✆ Specifier Output Format %a Short weekday name %A Full weekday name %b Short month name %B Full month name %c Time stamp %d Day of the month %H Hour in 24h format %I Hour in 12h format %j Day of the year %m Month as a decimal number %M Minutes %p AM or PM %S Seconds %U Week number, first day of first week is Sunday %w Weekday as a decimal number with Sunday as 0 (0-6) %W Week number, first day of first week is Monday %x Date representation %X Time representation %y Two digit Year format (00-99) %Y Four digit Year format %Z Timezone name %% A % sign Table 1.22: Date & time format specifiers. 1.10.2 Increments & Decrements The character set ‘++’ is used to increase the value by one and −− is used to decrease the value by one of the variable with which the character set is prefixed or post-fixed. There are two ways to use these notations. One is ‘++n’ and other is ‘n++’. Both have same meaning but first is used where value is to be used after one increment while later is used where value is to be increase by one after using it.
  • 92. 192 Basic C ✞ 1 #include <stdio.h> #include <stdlib.h> 3 int main (void ) { 5 int i = 0; printf("use of ++i n"); 7 while (i < 3) { /* calling & placing at same place.*/ 9 printf("%d => %d n", i, ++i); } 11 printf("use of i++ n"); int j = 0; 13 while (j < 3) { printf("%d => %d n", j, j++); 15 } return EXIT_SUCCESS ; 17 } ✌ ✆ ✞ use of ++i 1 => 1 2 => 2 3 => 3 use of i++ 1 => 0 2 => 1 3 => 2 ✌ ✆ If increment or decrements is used inside a loop, there are no difference in the use of ‘i++’ or ‘++i’. ✞ #include <stdio.h> 2 #include <stdlib.h> 4 int main (void ) { int i = 0; 6 printf("Use of i++ in while loop n"); while (i < 3) { 8 /* first increment .*/ i++; 10 /* then use.*/ printf(":-> %dn", i); 12 } 14 printf("Use of ++i in while loop n"); int j = 0; 16 while (j < 3) { /* first increment .*/ 18 ++j; /* then use.*/ 20 printf(":-> %dn", j);
  • 93. 1.10. PROCEDURES & FUNCTIONS 193 22 } return EXIT_SUCCESS ; 24 } ✌ ✆ ✞ Use of i++ in while loop :-> 1 :-> 2 :-> 3 Use of ++i in while loop :-> 1 :-> 2 :-> 3 ✌ ✆ This increment operator can not be used in variable initialization or with constants like 3 + + or directly in output stream functions like printf. The following type of syntax are illegal. ✞ int i=2++; // illegal coding 2 printf("Increment of 2 is %dn" ,2++);// illegal coding ✌ ✆ The same methods can be used for decrements operator. In increments or decrements operations, value of variable i is incremented by one and then the result is assigned to variable i. This is why, constant values can not be used with this unary operator, i.e. 5 + + and + + 5 cause compile time errors. See another example for i + + and + + j unary operators. ✞ #include <stdio.h> 2 int main (int argc , char ** argv ) { 4 int i = 0; while (i < 3) { 6 printf("i is %dn", i++);/* started from 0*/ } 8 printf("n"); int j = 0; 10 while (j < 3) { printf("j is %dn", ++j);/* started from 1*/ 12 } return 0; 14 } ✌ ✆ ✞ i is 0 i is 1 i is 2 j is 1 j is 2 j is 3 ✌ ✆
  • 94. 194 Basic C Again, before summing up this section, always remember that k + 1 and k + + results increment of variable ‘k’ by one. But first expression is purely different to second ex- pression. In first expression, the value of ‘k’ remains unchanged only results reflects to increment by one, while in second expression, value of ‘k’ is incremented by one and again assigned to it. ✞ 1 #include <stdio.h> 3 int main (int argc , char ** argv ) { int k = 0, l = 0; 5 printf("k+1 is %d and l++ is %dn", k+1, l++); printf("k+1 is %d and l++ is %dn", k+1, l++); 7 printf("k+1 is %d and l++ is %dn", k+1, l++); return 0; 9 } ✌ ✆ ✞ k+1 is 1 and l++ is 0 k+1 is 1 and l++ is 1 k+1 is 1 and l++ is 2 ✌ ✆ When increment and decrements operators are used simultaneously, then increment and decrements is performed simultaneous in order. ✞ 1 #include <stdio.h> #include <stdlib.h> 3 int myF(int i) { 5 int j = 1, re , r = 2; while (j < i) { 7 re = (r++) *(++ r);//re = (2) * (4); r = 4; j++; 9 } return re; 11 } 13 int main () { int i = 5, j = 3; 15 printf("%d", myF (5)); 17 return 0; } ✌ ✆ ✞ 80 ✌ ✆ In above program, in each loop, first value of r in r++ is used and then it is incremented. The value of r in ++r is incremented and then used. Therefore, in first loop, the equivalent expression shall be ✞ 1 re = (2) * (4); ✌ ✆
  • 95. 1.10. PROCEDURES & FUNCTIONS 195 And for next loop, the new value of r is 4. In case of increment operator is used with array elements like ✞ 1 a[i]=i++; ✌ ✆ In this case, initial value of ‘i’ is taken and incremented by one. This original value is stored as element of array ‘a’, at index position given by incremented ‘i’, i.e. ‘i+1’. Actually, for any value of ‘i’ above expression becomes ✞ 1 a[i+1]= i; ✌ ✆ See the example below ✞ 1 #include <stdio.h> 3 int main (int argc , char *argv []) { int i = 80; 5 int j = i; char a[100]; 7 /*In following expression , first value of i* *is used and then it is incremented . Value* 9 *of i stored at array element as a[i++]= i */ a[i] = i++; 11 /* Actual i and equivalent char */ printf("%d=>%cn", j, j); 13 /* Values stored in array as its* *element for initial i values */ 15 printf("a[%d]=%cn", j, a[j]); /* Actual array element values*/ 17 printf("a[%d]=%cn", i, a[i]); return 0; 19 } ✌ ✆ ✞ 80=>P a[80]=( a[81]=P ✌ ✆ Again see the following example, in which we try to get the result 110 by multiplying increment operators. ✞ 1 #include <stdio.h> 3 int main (int argc , char *argv []) { int i = 10; 5 printf("%dn", i++ * i++); return 0; 7 } ✌ ✆ ✞ 100 ✌ ✆
  • 96. 196 Basic C But actual result is 100 rather than 110. It means after using the current value of ‘i’, ‘i’ does not goes increment for next use of ‘i’. It reason is that, C does not guaranteed to increment the value of ‘i’ just after using it but it increments value of ‘i’ sometime before the expression is considered “finished” or just before the next “sequence point”. 1.10.3 Static Function In a program, if a function is declared as static then it can only be called from the same file in which it is declared. It can not called from the other files. The syntax of static function is ✞ 1 static int compare(int a, int b) { return (a + 4 < b) ? a : b; 3 } ✌ ✆ An example of static function is ✞ 1 #include <stdio.h> 3 static int compare(int a, int b) { return (a > b) ? a : b; 5 } 7 int main () { int j; 9 j = compare (2, 4); printf(":-> %d.n", j); 11 return 0; } ✌ ✆ ✞ :-> 4. ✌ ✆ 1.10.4 Function with Variable Arguments A static function can be called by its prototype. Normally in static functions number of arguments remain fix but variable number of arguments can also be passed to the function. Calling of a function with variable arguments is given in following example. ✞ 1 #include <stdlib.h> 3 #define MAXARGS 3 int var_arg (); 5 int main () { 7 var_arg (1, 2, 3); return 0; 9 } 11 int var_arg (int a) {
  • 97. 1.10. PROCEDURES & FUNCTIONS 197 int i = 0; 13 while (i < MAXARGS) { printf("%d argument is %d.n", i, (&a)[i]); 15 i++; } 17 return a; } ✌ ✆ A ‘var arg’ function is defined in prototype as null variables ✞ int var_arg (); ✌ ✆ This prototype function is defined as single argument list. ✞ 1 int var_arg (int a) ✌ ✆ When function is called with three integer arguments, this argument list is passed to the function definition as a list. ✞ 1 var_arg (1, 2, 3); ✌ ✆ Following line in the program ✞ 1 printf("%d argument is %d.n", i, (&a)[i]); ✌ ✆ prints the each element of the variable list of ‘a’. Second method uses macros defined in the header file <stdarg.h>. ✞ 1 #include <stdio.h> #include <stdarg.h> 3 void varStrings (const char *f, ...) { 5 int max_args = 5; va_list args ; 7 va_start (args , max_args ); printf("%sn", f); 9 while (max_args --) puts (va_arg(args , const char *)); 11 va_end(args ); } 13 int main () { 15 varStrings ("f", "Mary ", "had", "a", "little", "lamb "); return 0; 17 } ✌ ✆ The syntax variable argument function requires at least one fixed argument before the ‘...’. Here ‘va list’ creates memory for the variable list ‘valist’. ‘va start’ function accepts arguments and stores in the variable list ‘valist’ memory. ‘va arg’ function returns the variable value from variable list ‘valist’. ‘va end’ function cleans the memory reserved for valist. In pursuance to standard method of programming, in a function with variable
  • 98. 198 Basic C arguments, first argument/element should be an integer, representing the number of ar- guments to be passed to the function. In following example, sum of integers by passing variable arguments is obtained. ✞ 1 #include <stdarg.h> 3 int sum(int num , ...) { va_list ap; 5 int total = 0; va_start (ap , num); 7 while (num > 0) { total += va_arg(ap , int); 9 num --; } 11 va_end(ap); return total; 13 } 15 int main () { /* First argument determines the number of ** 17 ** following arguments , those shall be used ** ** in the sum function . Here it is 5. */ 19 int a = sum(5, 1, 2, 3, 4, 6); 21 /* First argument determines the number of ** ** following arguments , those shall be used ** 23 ** in the sum function . Here it is 2. */ int b = sum(2, 3, 5, 8); 25 printf("Sums are %d and %dn", a, b); return 0; 27 } ✌ ✆ ✞ Sums are 16 and 8 respectively . ✌ ✆ 1.10.5 Indirect Call of Function In C, the input is considered as string even though input contains the name of inbuilt functions or operators. For example, input “sin(90)” is considered as string which is a group of ‘s’, ‘i’, ‘n’, ‘(’, ‘9’, ‘0’, ‘)’ and NULL characters rather than sine operator on operand ‘90’. Using indirect call of a function, we can execute a function by supplying function name as string input. ✞ 1 #include <stdio.h> #include <stdlib.h> 3 #include <math .h> 5 double Equ1 (double x) { return x; 7 }
  • 99. 1.10. PROCEDURES & FUNCTIONS 199 9 double Equ2 (double x) { return x * x; 11 } 13 double Equ3 (double x) { return log(x); 15 } 17 typedef double (* Eqn)(double); 19 int main () { int i; 21 double ic; 23 const char *EqnNames [3] = { "Equ1 ", "Equ2 ", "Equ3 " 25 }; Eqn FEqu [ ] = {Equ1 , Equ2 , Equ3 }; 27 for (i = 0; i < (sizeof (FEqu ) / sizeof (Eqn)); i++) { 29 ic = (* FEqu [i])(i + 1); printf("Eqn Name = %5s : a=%d : Result=%lfn", 31 EqnNames [i], i + 1, ic); } 33 return 0; } ✌ ✆ ✞ Eqn Name = Equ1 : a=1 : Result =1.000000 Eqn Name = Equ2 : a=2 : Result =4.000000 Eqn Name = Equ3 : a=3 : Result =1.098612 ✌ ✆ 1.10.6 Preprocessor Macros Preprocessors are used to define macros or manifest constants and are included in the header of source file. Preprocessors can be defined separately in a file having extensions ‘.h’ or in the same source file. Some of the useful pre-processors are explained below. Literals The token reserved for the preprocessor is the octothorp, #, and the preprocessor makes three entirely different uses of it. Using, this token we can put the macros within the function. Whitespace before the # is ignored. Next use of # in a macro makes input a string, known as compound literal. See the example below: ✞ 1 #include <stdio.h> #define myMacro (v) printf (#v " : %dn", v); 3 int main () {
  • 100. 200 Basic C 5 myMacro (10 / 5); myMacro (15 / 5); 7 return 0; } ✌ ✆ ✞ 10 / 5 : 2 15 / 5 : 3 ✌ ✆ Tokens Body of a macro is considered as a string of tokens rather than a string of characters. C preprocessor tokens are the separate “words” in the body of a macro definition. They are separated from one another by white spaces. For example, the definition ✞ #define FOUR 2*2 ✌ ✆ has one token-the sequence 2*2, but the definition ✞ 1 #define SIX 2 * 3 ✌ ✆ has three tokens 2, *, and 3. Character, strings and token strings differ from each other. It depends on how how multiple spaces are treated in a macro body. The preprocessor doesn’t make calculations; it just substitutes strings. For example ✞ 1 #include <stdio.h> 3 #define SQUARE(X) X*X 5 int main (void ) { int x = 4; 7 printf("x = %dn", x); printf("SQUARE(x): %d", SQUARE(x)); 9 /* Above statement is equivalent to * 11 * printf (" SQUARE(x): %d", x*x); */ return 0; 13 } ✌ ✆ ✞ x = 4 SQUARE(x): 16 ✌ ✆ In above example value of ‘x’ is passed to predefined function ‘SQUARE(X)’ and the function replaces ‘X’ by ‘x’ as ‘x*x’ and ultimately ‘4*4’. Now the result is ‘16’. If the ‘x’ passed to the function as shown in the given example then ✞ #include <stdio.h> 2 #define SQUARE(X) X*X
  翻译: