Exploring c
Exploring c
And after this there was no looking back, as more and more computer
professionals switched over to C. Today there are C compilers
available under every conceivable environment from DOS to Win-
dows to Unix, and on all sizes of computers from micros to
mainframes. Power, portability, performance and flexibility are pos-
sibly the four most important reasons for C's popularity. C has been
designed to have a relatively good progamming efficiency as com-
pared to Machine oriented languages like Assembly or Machine
language, and a relatively good machine efficiency as compared to
Problem oriented languages like COBOL and FORTRAN.
i=5
The chars and ints can also be expressed in hexadecimal and octal
notations. For example, 16 can be expressed in hex as 0x10, and as
020 in octal. Similarly, 22 can be expressed in hex as 0x16, and as
026 in octal. A hex number is always preceded by Ox or OX whereas
an octal is preceded by 0 ( zero, not o or O ). C doesn't accept floats
in hex or octal.
With constants out of the way, let us now take a look at the variables.
Certain rules have been framed to create variable names. A variable
4 Exploring C
with a proviso that the first character is an alphabet. The length of the
variable is a compiler dependent feature. Turbo C accepts a variable
name upto 32 characters.
The ABC Of C 5
Operations on Data
C programs are concise partly because of the large number of
operators available with it. There are as many as 45 operators avail-
able in C. For starters we will concentrate only on arithmetic and
assignment operators..These are shown in the Figure 1.2. Operators
are classified as unary, binary or ternary depending on the number of
operands they operate upon. For example, + is a binary operator since
it operates on two operands that it adds.
Assuming the value of name as 'A', that of age as 23, and that of sal
as 1500.00, the output of the above printf( )s would be
A 23 1500.000000
name = A age = 23 salary = 1500.000000
name=A
age = 23
salary = 1500.000000
The first printf() prints the values of the variables name, age and
sal. As against this, the second would print messages against each
value displayed. In the third printf(), the \n is used to send the cursor
to the next line, hence the three values are printed on three different
lines.
scant ("%d%f,&a,&b);
>
The general form of scanf() is almost similar to printf( ), except for
two important differences:
(a) Within the pair of double quotes there should occur only format
specifications like %c, %d, %f etc.
(b) The variable names must always be preceded by the 'address
of operator &.
The ABC OfC 9
Exercise
[A] Complete the following:
[B] Point out which of the following variable names are invalid:
gross-salary
INTEREST
salary of emp
avg.
thereisagirlinmysoup
124.567
0001
0xbc40
0Xbc40
0x12.45
Oxfgff
10 Exploring/C
.001
-12e-12
(1) main()
{
printf ("%d %d %d %d", 72,072,0x72,0X72);
}
(2) main()
.{
printf("%d%o%x",72,72,72);
}
(3) main()
{
char ch;
inta;
float b;
printf ("bytes occupied by ch = %d\n", sizeof (ch));
printf ("bytes occupied by a = %d\n", sizeof ( a ) ) ;
printf ("bytes occupied by b = %d\n", sizeof ( b ) ) ;
}
(4) main()
{
printf ("char occupies %d bytes\n", sizeof (char));
printf ("int occupies %d bytes\n", sizeof (int));
printf ("float occupies %d bytes\n"„sizeof (float));
}
main()
(6) main()
{
char ch = 291;
printf ("%d %d %c", 32770, ch, ch);
}
(7) main()
{
printf ("%d%c\n");
printf ("%d%c\n");
}
(8) main()
{
int a = 33000;
float b = 3.4e100;
printf("a = %db = %f\n",a,b);
printf ("%d %d", sizeof (a), sizeof ( b ) ) ;
}
(9) main()
{
int a, b;
a = -3--3;
b = -3--(-3);
printf("a = %db = %d",a,b);
}
(10) main()
{
intx;
x = 3*4%5;
printf ("x = %d",x);
12 Exploring C
(11) main()
{
intx;
x = 3 + 4-7*8/5%10;
printf ("x = %d", x ) ;
}
(12) main()
{
intx;
x = -3 + 4 - 7 * 8 / 5 % 1 0 ;
printf ("x = %d",x)i
}
(13) main()
{
intx;
x = 4%5 + 6%5;
printf (*x = %d",x);
}
(14) main()
{
intx;
x = -3M%-6/-5;
printf ("x = %d",x);
}
(15) main()
{
printf ("%d ",4/3);
printf ("%d", 4 / - 3 ) ;
printf ("%d ",-4/3);
printf ("%d",-4/-3);
The ABC Of C 13
(16) main()
{
printf ("%d", 4% 3 ) ;
printf ("%d ",4%-3);
M
printf ("%d , -4 % 3 ) ;
printf ("%d ",-4%-3);
(17) main()
{
float a = 5, b = 2;
int c;
c = a%b;
printf ("%d", c ) ;
(18) main()
{
int x;
A
x = 3**4-7 8;
printf ("x = %d",x);
(19) main()
{
int g = 300 * 300/300;
printf ("g = %d",g);
}
(20) main()
{
floata=1.5;
int b = 3;
a = b/2 + b * 8 / b - b + a / 3 ;
14 Exploring C
u ,
printf ( a = %f a ) ;
I
(21) main()
{
int i = 3, a = 4, n;
float t = 4.2.;
n = a * a / i + i/2*t + 2 + t;
printf ("n = %d", n ) ;
}
(22) main()
{
int q = 2, d = 3, st;
st = q*d/4-12/12+ 12/3*16/d
printf ("st = %d", st);
}
(23) main()
{
int a, b;
a = 5.999999;
b = 5.000001;
printf {"a = %d b = %d", a, b ) ;
}
(24) main()
{
float a;
a=4/2;
printf("%f%f,a,4/2);
}
(25) main()
{
printf ("%d %An", 4 , 4 ) ;
printf ("%d%f\n", 4.0,4.0);
}
(26) main()
{
float a = 4;
inti = 2;
printf ("%f %d", i/a, i / a ) ;
printf ("%d%f,i/a,i / a ) ;
(27) main()
{
printf ("%d Vsizeof (4) / sizeof (2.0));
printf ("%d", sizeof (2.0) / sizeof ( 4 ) ) ;
}
(28) main()
{
printf ("nn \n\n nn\n");
printf ("nn /n/n nn/n");
}
(29) main()
{
int p, q;
scanf ("Enter values of p and q %d %d", &p, &q);
printf ("p = %d q = %d", p,q);
}
(30) main()
{
int a, b;
printf ("Enter values of a and b " ) ;
scanf (" %d%d ",&a,&b);
printf ("a = %d b = %d",
16 Exploring C
(31) main()
{
int p, q;
printf ("Enter values of p and q");
scant ("%d\n\n%d", &p,&q);
printf ("p = %d q = %d", p, q ) ;
}
(32) main()
{
int p, q;
printf ("Enter values of p and q");
scant ("%d % d \ p , q ) ;
printf ("p = %dq = %d", p,q);
}
(33) main()
{
/* This program attempts to find what happens when
integer range I* -32768 to +32767 */ is exceeded */
int a = 330000;
float b = 3.4e100;
printf("a = %db = %f\n" a,b);
I
(34) main()
{
printf ("Menu is a list of options you have at a \
particular point in a program. It is just \
like a restaurant menu - everything has a \
misleading name and what you want is never \
available.");
}
fE] Attempt the following:
(4) Write a program to find out how many days and how many
weeks have passed between the dates 01/01/92 to 31/05/92.
Also find out how many days could not get evened out into
weeks.
18 Exploring C
Answers
Answers to [A]
101111 1010
2 F A
Figure 1.4
(3) 32 characters
(4) alphabet
(5) sensitive. This means that variables sal, Sal and SAL would
be treated as different variables in C.
20 Exploring C
char ch;
, 1
ch = A ;
Answers to [B]
Answers to [C]
Answers to fD]
(1) Output
Explanation
(2) Output
7211048
Explanation
(3) Output
bytes occupied by ch = 1
bytes occupied by a = 2
bytes occupied by b = 4
Explanation
(4) Output
Explanation
(5) Output
Explanation
float a = 0.7;
printf (*%d %d", sizeof (a), sizeof (0.7));
(6) Output
-32766 35 #
Explanation
Same thing happens to 291, which also falls outside the range
of char ( -128 to +127 ), hence goes to the other side and
becomes 35, which is then printed. The third output is the hash
character. This is nothing but the character corresponding to
ascii value 35. %c always prints the character corresponding
to the ascii value.
(7) Output
-22A
-22A
Explanation
printf ("%f%f);
(8) Output
a = -32536b = +INF
24
Explanation
(9) Output
a = 0b = -6
Explanation
(10) Output
x= 2
Explanation
(1.1) Output
x=6
Explanation
x =3 + 4-56/5%10 operation: *
x =3 + 4-ll%10 operation:/
x =3 + 4 -1 operation : %
x =7 -1 operation : +
x =6 operation : -
26 Exploring C
Note that 5 6 / 5 yields 11, since 56 and 5 both are integers, and
hence must yield an integer on performing any arithmetic
operation on them.
(12) Output
x=0
Explanation
x = - 3 + 4 - 7 * 8 / 5 % 10 operation : unary
minus
x = -3 + 4 - 56 / 5 % 10 operation: *
x = -3 + 4 - 1 1 % 10 operation:/
x = -3 + 4 - 1 operation : %
x = 1 -1 operation: +
x =0 operation : -
(13) Output
x=5
Explanation
(14) Output
x=0
Explanation
x = -3 * -4 % -6 / -5 operation: unary
minuses
x = 12%-6/-5 operation: *
x = 0 / -5 operation: %
x= 0 operation: /
(15) Output
1-1-11
Explanation
(16) Output
11-1-1
28 Exploring C
Explanation
(17) Output
Explanation
(18) Output
Explanation
A
The culprits here are ** and . Unlike many other languages
A
where exponentiation operator ( usually ** or ) is available,
C doesn't offer this facility. An omission which seems all the
more surprising when weighed against the fact that C offers as
many as 45 operators!
(19) Output
g = 81
Explanation
The ABC Of C 29
(20) Output
6.500000
Explanation
a 3 / 2 + 3 * 8 / 3 - 3 + 1.5/3
a 1 + 3 * 8 / 3 - 3 + 1.5/3 operation: /
a 1 + 2 4 / 3 - 3 + 1.5/3 operation: *
a 1 + 8 - 3 + 1.5/3 operation: /
a .1 + 8 - 3 + 0.5 operation: /
a 9 - 3 + 0.5 operation: +
a 6 + 0.5 operation: -
a 6.5 operation: +
30 Exploring C
(21) Output
n = 15
Explanation
n = 4 * 4 / 3 + 3 / 2 * 4 . 2 + 2 + 4.2
n = 1 6 / 3 + 3 / 2 * 4 . 2 + 2 + 4.2 operation:
n = 5 + 3 / 2 * 4 . 2 + 2 + 4.2 operation: /
n = 5 + 1 * 4.2 + 2 + 4.2 operation: /
n = 5 + 4.2 + 2 + 4.2 operation:
n = 9.2 + 2 + 4.2 operation: +
n = 11.2 + 4.2 operation: +
n = 15.4 operation: +
(22) Output
st = 21
Explanation
St = 2 * 3 / 4 - 1 2 / 1 2 + 1 2 / 3 * 1 6 / 3
The ABC Of C 31
st = 6 / 4 - 1 2 / 1 2 + 1 2 / 3 * 16/3 operation: *
st = 1-12/12 + 1 2 / 3 * 16/3 operation: /
st = 1-1 + 1 2 / 3 * 1 6 / 3 operation: /
st = 1 - 1 + 4 * 16/3 operation: /
st = 1-1 + 6 4 / 3 operation: *
st = 1 - 1 + 21 operation : /
st = 0 + 21 operation: -
st = 21 operation: +
(23) Output
a=5b=5
Explanation
(24) Output
2.000000-1.4746701 e+308
Explanation
(25) Output
4 512.000001
04.000000
Explanation
In the first printf(), the first output (i.e. 4 ) is alright but the
second one, 512.000001, is unexpected. Reason is, we left it
to printf( ) to first convert 4 to 4.0 and then print it out as a
float using %f. And here lies the mistake. The printf() is not
intelligent enough to perform this conversion properly, and
hence we get the absurd result. Same is the story of the second
printf(). Here, the first output is faulty, whereas the second is
as expected. Once again for the same reasons - a misplaced
trust in printf( ) to carry out the conversion before printing.
(26) Output
0.500000 0
00.000000
Explanation
If the first printf( )'s output is 0.500000 and 0, then its natural
for us to expect the second printf( )'s output to be 0 0.500000.
However, the results above do not confirm this. The reason is,
once printf( ) messes up one conversion the output of the
subsequent variables to be printed in that printf() are likely to
get messed up too.
(27) Output
04
Explanation
printf ("%d", 2 / 8 ) ;
printf ("%d", 8 / 2 ) ;
which results into 0 and 4, which are then printed out. Notice
that in 2/8, since both are integers, the result is an integer.
(28) Output
nn
nn
nn /n/n nn/n
Explanation
34 Exploring C
(29) Output
p = 1562 q = 1686
Explanation
(30) Output
No output
Explanation
The scanf() just doesn't seem to work. Once again the reason
is the spaces immediately after the " " and the spaces immedi-
The ABC Of C 35
<space><space>10 20<spacexspace>
(31) Output
Explanation
(32) Output
Explanation
(33) Output
Explanation
(34) Output
Explanation
Solutions to [E]
(1) Program
The ABC Of C 37
main()
{
int i, j, k;
printf ("\nEnter values of i and j");
scant ("%d%d*,&i,&j);
k = i + j-i%j;
printf ("\nNext largest multiple = %d", k);
}
Sample run
(2) Program
main()
{
float f, c;
printf ("Enter temperature in farenheit degrees");
scant ("%f,&f);
c = 5/9.0*(f-32);
printf ("Temp, in centigrade degrees = %f, c);
\
38 Exploring C
Sample run
Explanation
(3) Program
main()
{
int a = 10, b = 20;
a = a+ b;
b = a-b;
a = a-b;
B
printf ("a = %d b = %d , a, b) ;
}
Sample run
Before interchanging
a = 1 0 b = 20
After interchanging
a = 20b = 10
Explanation
(4) Program
main()
{
int days, weeks, leftoverdays;
Sample run
days = 152
weeks = 21
left over days = 5
Explanation
if (condition)
{
statement 1;
statement 2;
false true statement3;
else
statement 4;
statements statements;
statements
4 and 5 1, 2 and 3
x==y x is equal to y
x != y x is not equal to y
x <y x is less than y
x >y x is greater than y
x <= y x is less than or equal to y
x >= y . x is greater than or equal to y
Points to Note
(c) The group of statements after the if, upto and not including the
else is known as the "if block". Similary, the statements after
the else form the "else block".
(d) If there is only one statement in the if block then the pair of
braces can be dropped.
(e) If there is only one statement in the else block then the pair of
braces can be dropped.
Here there are four conditions being checked. They have been
split into two groups by the || operator. "Whisky is Risky"
would be printed if any one group evaluates to true. In each
group there are two conditions separated by && operator. For
each group to evaluate to true, both the conditions in the group
must be satisfied.
!(y<10)
if (I flag)
if (flag ==0)
Operands Results
X y !x Jy x && y x||y
0 0 1 l 0 0
0 non-zero 1 0 0 0
non-zero 0 0 I 0 1
non-zero non-zero 0 0 1 1
Since we have now added the logical operators to the list of operators;
that we know, it is probably time to review all these operators and
their priorities. Figure 2.4 summarizes the operators we have learnt
so far. The higher an operator is in the table, the higher is its priority.
A full-fledged precedence table is given in Chapter 3.
a = (y!=3)&&(3 + 4 > x ) ;
rf(a==4||(b = x + y > 3 ) )
printf ("C it for yourself);
rf (x||y&&(a + b > = c * d / e ) )
printf ("Foxed?");
Steering the Control 47
Operators Type
Logical NOT
*/% Arithmetic and modulus
+- Arithmetic
<><=>= Relational
== != Relational
&&|| Logical AND and OR
Assignment
ti
What this expression says is: "if expression 1 is true (that is, if its
value is non-zero ), then the value returned will be expression 2,
otherwise the value returned will be expression 3".
y = (x>5?3:4);
(a) Its not necessary that the conditional operators should be used
only in arithmetic statements. This is illustrated in the follow-
ing examples:
Exercise
[A] What will be the output of the following programs:
(1) main()
{
intx = 10,y = 5, p,q;
p=x>9;
q = x>3&&y!=3;
printf ("p = %d q = %d", p, q);
(2) main()
{
int a = 30, b = 40, x;
x = (a!=10)&&(b = 50);
printf ("x = %d",x);
(3) main()
{
int a = 100, b = 200, c;
c = (a==100||b>200);
printf ("c = %d",c);
(4) main()
{
intx = 11,y = 6,z;
z = x == 51| y != 4 ;
printf ("z = %d",z );
}
(5) main()
{
50 Exploring C
(6) main()
{
int a = 500, b = 100,c;
if(!a>=400)
b = 300;
c = 200;
printf ("b = %dc = %d",b,c);
(7) main()
{
intx = 10,y = 100%90;
if(x!=y);
printf ("x = %d y = %d", x, y ) ;
}
(8) main()
{
int x = 10, y = -20;
x = !x;
y=!y;
printf ("x = %dy = %d\n",x,y);
(9) main()
{ .
int x = 0, y = 1;
y = !x;
x = !y;
Steering the Control 51
(10) main()
{
if (13.14)
printf ("I have robbed and killed...");
else
printf ("Until my evil purse was filled");
}
(11) main()
{
int x = 3, y = 4, z = 4;
printf("ans = %d",z>=y&&y>=x?1:0);
}
(12) main()
{
int x = 3, y = 4, z = 4;
printf("ans = %d", (z>=y>=x?100:200));
}
(13) main()
{
float a = 12.25, b= 13.65;
if (a = b)
printf ("a and b are equal");
else
printf ("a and b are not equal");
}
(14) mainQ
{
if('Z'<'z')
printf ("Pilots are on strike...");
52 Exploring C
else
printf ("for absolutely outlandish demands")
}
(15) main()
{
int x = 10;
if x >= 2
printf ("%d\n",x);
}
(16) main()
{
int i = 10, j = 40;
if((j-i)%10)
printf ("man sees your actions..");
else
printf ("god sees your motives..");
(17) main()
{
inti = -4, j, num = 10;
j = i%-3;
j = (j ? 0: num * num);
printf ("j = %d",j);
i
/
(18) main()
{
float a = 0.7;
if (a< 0.7)
printf ("Stoned");
else
printf ("Avenged");
Steering the Control 53
(19) main()
{
inti = 400 * 400/400;
if (i == 400)
printf ("Filibusters");
else
printf ("Sea gherkins");
(20) main()
{
intk = 12,n = 30;
k = (k>5&&n = 4?100:200);
printf ("k = %d*,k);
(21) main()
{
int c = 0, d = 5, e = 10, a;
a = c> 1 ? d > 11| e > 1 ? 100:200:300;
printf ("a = %d", a ) ;
(22) main()
{
inta = 10, b = 10;
printf ("ans = %d", a > b ? a * a : b / b ) ;
}
(23) main()
{
intx = 10, y = 20;
x = !x;
y = !x&&!y;
printf ("x = %d y = %d", x,y);
54 Exploring C
(24) MAIN()
{
INT X = 10, Y = 20;
IF (! (!X) && X)
PRINTF ("X = %D",X);
ELS©
PRINTF ("Y = %D",Y);
}
(25) MAIN()
{
FLOAT A = 0.5, B = 0.9;
IF (A && B > 0.9)
PRINTF ("IDLENESS IS A VIRTUE..");
ELSE
PRINTF ("..SO IS STUPIDITY!");
}
(26) MAIN()
{
INTX = 100;
IF (!!X)
PRINTF ("X = %D", !X);
ELSE
PRINTF ("X = %D",X);
}
(1) MAIN()
{
INT I = 10;
IF(I>10)
i
ELSE
Steering the Control 55
(2) main()
{
int i = 5, j = 30, k = 5;
if (i < 30)
{
if (j < 20 > ;
{
if (k == 40)
printf ("Hi Computerist!");
else
t
}
else
»
}
}
else
i
Write a program that reads the type of the customer, the type
of the product, the amount of the order, and prints the net
amount payable by the customer.
If the age of the driver is less than 25 years, the car is manufac-
tured in India and the accident record of the car is good, the
premium charged is 6 % ofthe declared value of the car and a
comprehensive policy is issued with the holder paying the first
100 rupees of a claim.
If the age of the driver is less than 25 years, the car is not
manufactured in India and the accident record of the car is
good, the premium charged is 8 % of the declared value of the
car, the policy holder pays the first 100 rupees of any claim
and a comprehensive policy is issued. If the accident record is
not good and all other conditions apply, then considering the
risk, no policy car be taken out.
Assume that if a person has not had an accident in the last three
years then the condition of the car is considered good. Write a
program to output the following:
Answers
Answers to [A]
(1) Output
p=1q=1
Explanation
In the statement,
q = x>3&&y !=3;
(2) Output
x= 1
Explanation
X = 1 && 50
(3) Output
C=1
Explanation
(4) Output
Z= 1
Explanation
Z = 0||1
(5) Output
B = 300C = 200
Explanation
1(1)
B = 300;
(6) Output
B = 100C = 200
Explanation
(7) Output
x = 10y = 10
Steering the Control 61
Explanation
Since the variables x and y both have the same value the
condition ( x != y ) fails. Therefore the control jumps to the
printf( ) and prints out values of x and y. Note that there is a ;
after the if. This is called a null statement. Due to the ; the
condition becomes:
if(x!=y)
B n
printf ( x = %d y = %d ,
(8) Output
x=0y=0
Explanation
(9) Output
x= 0y= 1
62 Exploring C
Explanation
(10) Output
Explanation
(11) Output
ans = 1
Explanation
4>=4&&4>=3
Since both the conditions are true and they have been combined
using &&, the whole thing evaluates to true. This is deduced
fmm the fact that
Steering the Control 63
yields truth.
(12) Output
ans = 200
Explanation
(z>=y>=x?100:200)
(1 >=x?100 : 200)
(13) Output
Explanation
To begin with a and b are not equal. The catch here is the
assignment operator used in the if statement. It simply assigns
the value of b to a, and hence the condition becomes,
if (13.65)
(14) Output
Explanation
if ( 9 0 < 122)
(15) Output
Explanation
must. The cryptic error message says that the i f statement used
in function m a i n ( ) has a missing parentheses.
(16) Output
Explanation
1(0)
(17) Output
1=0
Explanation
j = -4%^3
(18) Output
Stoned
Explanation
The output is very surprising! 0.7 is never less than 0-.7, so the
condition should evaluate to false. But that doesn't happen.
Reason is, when 0.7 stored in a, due to precision considera-
tions, it is stored as something less than 0.7. Naturally, when
value stored in a is compared with 0.7, the condition evaluates
to true and 'stoned' gets printed.
long double a ;
(19) Output
Steering the Control 67
Sea gherkins
Explanation
(20) Output
Explanation
k = (k>5&&n = 4?100:200);
(k>5&&n)=4
k = (k>5&&(n = 4)?100:200);
(21) Output
a = 300
Explanation
(22) Output
ans = 1
Explanation
Since the condition a > b fails, the statement after the :, i.e. b
/ b is evaluated and its result is printed by printf().
(23) Output
x=0y=0
Explanation
y = !x && !y
y = !0&&!20
y = 1 && 0
x = 10
Explanation
!(0) yields a 1. Note that the value of x is still 10, hence the
condition becomes,
Since both conditions yield truth and they have been combined
using &&, the whole thing is treated as true, and hence the first
printf() is executed, printing the value of x in the process.
Output
..so is stupidity!
Explanation
if (truth &&falsity)
(26) Output
x=0
Explanation
x = !x;
72 Exploring C
Solutions to [B]
(1) main()
{
int i = 1 0 ;
if(i*=10)
printf ("Hello Cocaine!");
}
Explanation
(2) main()
{
int i 5, j = 30, k = 5 ;
=
Explanation
Solutions to IC]
(1) Program
main()
Steering the Control 73
char customer;
float order, discount = 0, amt;
int mptype;
if (mptype = = 3 2 )
{
if (customer == 'if)
discount = 7.3;
if (customer =='f)
{
if (order < 50000)
discount = 5 ;
else
discount = 7.5;
if (customer =='g')
{
if (order < 50000)
discount = 6.5;
else
discount = 8.5;
if (mptype = = 1 6 )
{
if (order > 10000)
{
if (customer == 'u' || customer == T )
» discount = 5 ;
else
discount = 6 ;
}
}
if (mptype == 8 )
discount = 1 0 ;
Sample run
Explanation
(2) Program
mainQ
{
int age, acc, excess = 0 ;
float cost, prper, amt;
char type, inout;
if (age >= 2 5 )
{
if (inout == T )
{
if (acc = = 0 )
prper = 6 ;
else
{
prper = 7 ;
excess = 1 0 0 ;
}
type = C ' ;
,
}
else
{
if (acc == 0 )
76 Exploring C
prper = 6 ;
,
type = C
excess = 1 0 0 ;
}
else
{
prper = 7;
type = T ;
}
}
}
else
{
if(inout==T)
{
rf ( a c c = = 0 )
{
prper = 6 ;
type = 'C;
excess = 1 0 0 ;
}
}
else
{
if ( a c c = = 0 )
type = 'C;
else
type = 'R';
prper = 8 ;
excess = 1 0 0 ;
}
}
amt = cost *prper/100;
printf ("\nC - Comprehensive T - Third party");
printf ("\nR - Risk, no policy");
printf ("\n\nType of policy = %c", type);
printf ("\nAmount of premium = %f, a m t ) ;
if (excess != 0 )
printf ("\nExcess amount on claim = %d", excess);
Sample run
(3) Program
main()
{
int n, count = 1 ;
78 Exploring C
n = n/10;
if(n!=0)
count = count + 1 ;
n = n/10;
if(n!=0)
count = count + 1 ;
n = n/10;
if ( n t= 0 )
count = count + 1 ;
n = n/10;
if ( n != 0 )-
count = count + 1 ;
Sample run
Explanation
Any while, for and do-while loops would more or less take the form
shown in Figure 3.1. The initialisation, testing and incrementation
hold the key to the working of the loop. Before we complete out
discussion of loops it would be worthwhile to imbibe the following
details:
start ) start
>
i= !--> is I no
1 = 1
1 i=j+n ' < i i i —
yes (stop)
no
<i < 11 > /
yes | C
i =i+ l|
N o t e s N o t e s N o t e s
- I n i t i a l i z a t i o n , t e s t i n g - I n i t i a l i z a t i o n , t e s t i n g - I n i t i a l i z a t i o n , t e s t -
l o o p c o u n t e r d o n e i n l o o p c o u n t e r d o n e i n t i o n o f l o o p
s e p a r a t e s t e p s . s a m e s t a t e m e n t . c o u n t e r d o n e i n
s e p a r a t e s t e p s .
- C o n d i t i o n t e s t e d - C o n d i t i o n t e s t e d b e f o r e
b e f o r e e x e c u t i n g e x e c u t i n g b o d y - C o n d i t i o n t e s t e d
b o d y o f t h e l o o p . o f t h e l o o p . a f t e r e x e c u t i n g
b o d y o f t h e l o o p .
For example,
is the same as
main()
{
int i = 1 ;
for(;;)
{
printf ("%d", i ) ;
i = i+ 1 ;
if ( i > 10)
break; /* takes control out of the loop */
}
}
In the for loop, more than one variable can be initialised and
incremented. While doing so the multiple initialisations ( or
the multiple incrementations ) must be separated by the comma
( , ) operator. For example,
main()
{
int i, j ;
for(i = 1,j = 1 0 ; i + j < 2 5 ; i = i + 1 , j = j + 1)
printf ("%d % d \ i , j ) ;
}
More Operators
main() main()
{
int i = 1; ^ inti = 1;
while (i<= 10) while (i<= 10)
{
{
Drintf ("%d", i); printf ("%d", i);
i+=1;
Precedence of Operators
Following figure shows the precedence of all the operators covered
so far. Unary operators have the highest precedence, whereas the
comma operator has the lowest precedence.
main() main()
{
inti;
MIL I , int i;
for (i = 1 ; i < = 1 0 ; i + + ) for (i = 1 ; i < = 1 0 ; i + + )
else
printf ("%d\n", in-
printf ("Hello"); }
}
fl) mainQ
{
char j = 1 ;
while ( j < = 255)
{
printf ("%d\n",j);
j=j + 1;
Y
}
(2) main()
{
intj = 1 ;
while ( j <= 2 5 5 ) ;
{
printf ( " % c % d \ n " , j , j ) ;
}
}
(3) main()
{
intj = 1 ;
while ( j < = 2 5 5 )
printf ("%d\n", + + j ) ;
}
(4) main()
{
int.a;
for ( a = 1 ; a <= 32767; a++)
Merry go Round 89
(5) main()
{
inti;
for ( i = 1 ; i++ <= 5 ; printf ("%d", i ) ) ;
}
(6) main()
{
inti = 1, j = 1 ;
for ( ; j ; printf ("%d%d\n ,
I i,j))
j = i++ < = 5 ;
}
(7) main()
{
int i = 1 ;
for { ; i + + ; )
printf ( " % d i ) ;
}
(8) main()
{
int a = 5 ;
do
{
printf ("%d\n", a ) ;
a=-1;
}while(a>0);
(9) main()
{
int a = 3, b = 4 ;
90 Exploring C
b%=3+4;
a*=a + 5;
printf( "b = %d a = %d", b , a ) ;
(10) main()
{
int x = 3 ;
x*=x + 4;
printf ( x = %d", x ) ;
B
(11) main()
{
int x = 3, y, z ;
z=y=x;
z *= y = x * x |
printf ("x = %'d y = %d z = %d", x, y, z )
(12) main()
{
int x = 3, y, z ;
z=y=x;
z *= y /= x',
printf ("x = %d y = %d z = %d", x, y, z )
(13) main()
{
int x = 1, y = 5 ;
y * = x'
printf ("x = % d y = %d", x , y ) ;
Merry go Round 91
(14) mainf)
{
int x = 3, y, z;
z=y=x;
z = y+=x=-z;
printf ("x = % d y = % d z = %d", x, y , z ) ;
(15) main()
{
int x = 5 ;
x++;
printf ("x = % d \ n " , x ) ;
++x;
printf ("x = %cf\n",x);
(16) main()
{
int x = 3, z ;
z = x++ + 1 0 ;
printf {"x = %d z = %d", x, z ) ;
(17) mainQ
{
int x = 3, z ;
z = ++x+ 1 0 ;
printf ("x = % d z = %d", x , z ) ;
(18) main()
{
int x = 3, z ;
z = x-111;
printf ("x = % d z = %d", x , z ) ;
92 Exploring C
(19) main()
{
int x = 3, z ;
z = x— - 1 ;
printf ("x = % a z = %d", x , z )
(20) main()
{
intx = 3 , z ;
z = x++ + x + + ;
printf ("x = % d z = % d , x , z )
,
(21) main()
{
int x = 3, z ;
z = x++ + ++x;
printf ("x = % d z = %d", x , z )
(22) main()
{
int x = 3, z ;
z = x—1;
printf ("x = % d z = % d " , x , z )
(23) main()
{
int x = 3, z ;
z = x/++x;
printf ("x = % d z = %d", x , z )
Merry go Round 93
(24) main()
{
inti = 3 , j ;
j = ++i*++i*++i;
printf ( " % d " , j ) ;
(25) main()
{
int x = 3, y = 3, z = 3 ;
z -= - X " - —y j
printf ("x = % d y = %dz=%d", x , y , z ) ;
(26) main()
{
int x = 10, y = x, z = x ;
y-=x;
z = -x;
t=-x;
printf ("y = % d z = %dt = % d " , y , z , t ) ;
(27) main()
{
int x = 10, y, z ;
z=y=x;
y - = x--;
z -= --x;
x -= --x - x - ;
printf ("y = %d z = %d x = %d", y, z, x ) ;
(28) main()
{
int x = 4, y = 3, z ;
94 Exploring C
z = x---y;
printf ("x = % d y = % d z = % d , x , y z ) ;
,
1
(29) main()
{
intx,y,z;
x=y=z=1;
i = ++x || ++y && + + z ;
printf ("x = % d y = % d z = %d\n",x, y , z ) ;
}
(30) main()
{
intx,y,z;
x =y =z = 1;
z = ++x && ++y j) + + z ;
printf ( " x ^ % d y = % d z = % d \ n " x , y , z ) ;
)
(31) main()
{
intx,y,z;
x=y=z=1;
z =++x &&++y & & + + z ;
printf ("x = %d y = %d z = %d\n", x, y, z ) ;
}
(32) main()
{
int x, y, z ;
x =y = z = -1;
z = ++x && ++y || + + z ;
printf ("x = % d y = % d z = % d \ n " , x , y , z ) ;
}
Merry go Round 95
(33) main{)
{
int x, y, z ;
x=y=z= - 1 ; .
(34) main()
{
intx,y,z;
x =y =z = -1;
z = ++x && ++y && ++z;
printf ("x = %d y = %d z = %d\n", x, y, z ) ;
(35) main()
/
i
int i ;
for ( i = - 1 ; i <= 1 0 ; i++)
{
if(i<5)
continue;
else
break;
printf ("Gets printed only once!!");
}
(36) main()
{
intx = 10, y ;
y = - - X - - ;
(37) main()
{
int i = 2;
printf ( V = % d " , i - ) ;
}
Assume that initially there are 10,000 rabbits and 1000 wolves.
Write a program to calculate populations of rabbits and wolves
over a 1000-day period. Have the program print the popula-
tions every 25 days. See what happens when you start with 500
wolves instead of 1000. Try starting with 2000 wolves too.
Merry go Round 97
2 2 2
(3) The equation x + y = r represents a circle with centre at
origin and radius r. Write a program that reads r from the
keyboard and prints the number of points with integer coor-
dinates that lie within the circle.
(4) Write a program that, for all positive integers i, j , k, and 1 from
1 through 1000, finds and prints all combinations of i, j , k, and
I such that i + j + k = 1 and i < j < k < I.
(5) Write a program which finds four digit perfect squares where
the number represented by the first two digits and the number
represented by the last two digits are also perfect squares.
(6) Write a program which finds a four digit number AABB which
is a perfect square. A and B represent different digits.
98 Exploring C
Answers
Answers to [A]
(1) Output
1
2
3
127
-128
-127
-126
0
1
Explanation
(2) Output
No output
Explanation
(3) Output
2
3
256
Explanation
(4) Output
Explanation
for(a = 0;a<32767;a++)
printf ("%d",a+1);
(5) Output
23456
Explanation
Let us isolate the condition in the for loop for closer examina-
tion:
i++ <= 5
Output
21
31
41
51
61
70
Explanation
(7) Output
Explanation
Since i++ is being used in the for loop, two operations are being
carried out. Firstly i is tested for truth or falsity, and then it is
incremented. To begin with, as i is equal to 1, the test results
into a truth and then i is incremented to 2. This 2 is then printed
through printf(). Next time when the control reaches
since i is 2, the test once again results into truth, i is incremented
to 3 and printed out. This goes on smoothly till i becomes
32767. When i is 32767, it evaluates to truth and ++ tries to
make it 32768, which being an int it cannot become. Therefore
the number from the negative side of the range ( - 32768 ) is
assigned to i, which is then printed out. This goes on and then
sometime later i becomes - 1 . With i as -1 the test results into a
truth and i++ makes the value of i as 0. This value is printed
Merry go Round 103
out and once again the control reaches the test in the for loop.
This time, however, the test fails since value of i is 0. Therefore
the loop is terminated and the execution comes to an end.
(8) Output
Explanation
(9) Output
b = 4 a = 24
Explanation
(10) Output
x = 21
104 Exploring C
Explanation
(11) Output
x = 3y = 9z = 27
Explanation
(12) Output
x=3y=1z=3
Explanation
(13) Output
Explanation
(14) Output
x = - 3 y = 0z = 0
Explanation
(15) Output
x=6
x=7
Explanation
(16) Output
x = 4z=»13
Explanation
(17) Output
x = 4z = 14
Explanation
(18) Output
x = 2z = -108
Explanation
Merry go Round 107
(19) Output
x=2z=4
Explanation
(20) Output
x = 5z = 6
Explanation
(21) Output
X = 5z = 8
108 Exploring C
Explanation
(22) Output
Explanation
(23) Output
x=4z=1
Explanation
Merry go Round 109
(24) Output
216
Explanation
(25) Output
x=2y=2z=8
Explanation
(26) Output
y = 0z = -l0t = -lu
110 Exploring C
Explanation
(21) Output
y_=0z = 2 x = 6
Explanation
(28) Output
x=3y=3z=1
Explanation
(29) Output
x = 2y = 1z = 1
Explanation
(30) Output
x=2y=2z=1
112 Exploring C
Explanation
(2&&2)
&& requires a truth value to its left and right for the whole
statement to evaluate to true. In this case since there are truth
values on left and right of && the statement is treated as true
and hence 1 is assigned to z. Since the first condition has
evaluated to true the second condition is not evaluated at all.
(31) Output
x=2y=2z=1
Explanation
Since ++x, ++y and ++z are all combined using && operators,
to check the truth or falsity of the statement x, y and z are first
incremented, resulting in they taking a value 2 each. Thus the
condition becomes,
z = 2&&2&&2
(32) Output
Merry go Round 113
x = 0y = -1z = 0
Explanation
Since priority of && is higher than that of ||, the first condition
to be evaluated is ( ++x && ++y ). If this condition turns out
to be true, then a truth value, 1, is assigned to z. If this turns
out to be false, then the second condition is evaluated.
(33) Output
x=0y=0z=0
Explanation
(34) Output
x = 0y = -1 z = 0
Explanation
For the entire condition to evaluate to true, ++x, ++y and ++z
all must evaluate to true. So to test the condition, Firstly ++x is
performed, which results into a 0. Now, since ++x has
evaluated to 0, irrespective of the results of ++y and ++z, the
whole condition is going to evaluate to false. Therefore C
doesn't bother to evaluate ++y and ++z, and assigns a falsity
value, i.e. 0, to the variable z. Thus x has become 0 due to
incrementation, z has become 0 due to evaluation of the whole
condition to falsity, whereas y doesn't get a chance to change
at all, and hence remains at -1.
(35) Output
No output
Explanation
(36) Output
Explanation
(37) Output
i~ = 2
Explanation
Solutions to [B]
(1) Program
main()
{
float a = 0.01, b = 0.005, c = 0.00001, d = 0 . 0 1 ;
int r1 = 10000, w1 = 2000, r2, w 2 ;
int i:
for ( i = 1 ; i < = 1 0 0 0 ; i + + )
{
r2 = ( 1 + a ) * r 1 - c * r 1 * w 1 ;
w2 = ( 1 - b ) * w 1 + c * d * M * w 1 ;
(f(i%25==0)
printf ("\nAfter %d days R = %d W = %d", i, r2, w 2 )
r1 = r 2 ;
w1 = w 2 ;
}
}
Sampu run
Explanation
Merry go Round 117
(2) Program
main()
{
float opercost = 10000, pps = 500, adv = 1000;
float curprof, newprof;
int sale = 100;
curprof = (sale*pps)-(opercost + a d v ) ;
while ( 1 )
{
adv*=2;
sale = ( sale* 1 2 0 / 1 0 0 ) ;
newprof = ( s a l e * p p s ) -(opercost + a d v ) ;
curprof = newprof;
}
Sample run
Sale = 296
Advertising expenses = 64000
Profit = 81500
Explanation
(3) Program
main()
{
float r;
int x, y, points = 0, i;
points++;
}
}
points = points * 4 + 1 ;
printf( "No. of points inside the circle = %d", points);
}
Sample run
Explanation
(4) Program
main()
{
120 Exploring C
int i, j, k, I;
1+2 + 3 = 6
1+2+4=7
1+3+4=8
1+2+5=8
2+3+4=9
1+3+5=9
Explanation
then the condition ( i < j < k < 1 ) would get violated. The f o r
loops thus have been written such that the condition is met at
all times. Within the innermost loop, if the other condition ( i
+ j + k = = 1 ) is satisfied, the values of i, j , k and I get printed,
otherwise the control loops around to try the condition for the
next set of values.
(5) Program
#include "math.h"
mainQ
{
int i, a, num, d1, d2, d3, <J4, nleft, nright, x, y;
if(i==a*a)
{
num = i ;
d4 = n u m % 1 0 ;
num = num/10;
d3 = num % 10;
num = num/10;
d2 = num%10;
num = num/10;
d1 =num%10;
)
}
}
Sample run
Explanation
Inside the for loop, first we get the square root of i and test
whether i is a perfect square or not. If it is a perfect square, then
we segregate the four digits of this number into variables dl,
d2, dJl and d4. Next we construct two numbers nleft and might
from the first two and the last two digits of the four digit
number. Having done this, we test whether these two numbers
are perfect squares or not. If they turn out to be perfect squares
then we have met the number satisfying our requirements.
Hence we print it out. It is necessary to include the file "math.h"
for the sqrt( ) function to work.
(6) Program
include •math.h'
main()
{
{
num = i ;
d4 = num % 1 0 ;
num = n u m / 1 0 ;
d3 = num% 1 0 ;
num = n u m / 1 0 ;
62 = num % 1 0 ;
num = n u m / 1 0 ;
dl = n u m % 1 0 ;
Sample run
Explanation
s t a r t
switch (choice)
( ) {
case 1 :
stat. 1 ;
Yes break;
3 stat. 1
case 2 :
stat. 2 ;
break;
Yes J case 3 :
% stat. 2 |—3 stat. 3 ;
break;
Yes
j stat. 3 | - 3
( s t
°P )
goto
tionally, so a different path for the execution of the program is set up.
The following program illustrates the use of goto.
I* Use of goto*/
mainQ
{
printf ("Hope is hoping against hope...');
goto hope;
printf ("even if it seems hopeless.');
hope:
exit(O);
}
The second part of the message will not get printed, as due to the
goto, control skips to the label hope and execution is terminated due
to the exit(O) present here. Had there been any executable statements
after hope, those would have got executed.
Exercise
[A] What will be the output of the following programs:
(1) main()
{
inti;
printf ("Enter any number");
scanf ( " % d \ & i ) ;
switch ( i )
{
easel:
printf ("Do");
case 2 :
printf ("Re");
case 3 :
printf ("Me"),
case default:
printf(*FaSol_aTiDo");
1
}
(2) main()
{
int i = 3 ;
switch ( i )
{
easel:
printf ("au revoir!");
case 2 :
printf ("adieu!");
break;
case 3 :
continue;
default:
130 Exploring C
(3) main()
{
chars = 3 ;
switch ( s )
{
case T :
printf( "Seagherkins\n");
case '2':
printf( "Baboons\n");
default:
printf( "Bucaneers\n");
}
printf("Gallowsfodder");
}
(4) main()
{
int k = -2, j = 4;
switch ( k / = j / k )
{
default:
printf ("All are same!\n");
case 0:
printf ("Happy birthday\n");
case 1:
printf ("A punch on the mouth\n") ;
case 2:
printf ("A kick in the back\n");
}-
(5) main()
A Multi-point Switch 131
{
int j, x = 0 ;
for ( j = 0 ; j <= 5 ; j++)
{
switch ( j - 1 )
{
caseO:
case - 1 :
x+=1;
break;
easel:
case 2 :
case 3 :
x+=2;
break;
default:
x+=3;
}
printf C % d " , x ) ;
}
}
(6) main()
{
inti;
for ( i = 2 ; i <= 1 0 ; i++)
{
switch ( i )
{
case 2 :
printf ( " 0 " ) ;
continue;
case 3 :
break;
case 4 :
case 5 :
printf ( " H " ) ;
132 Exploring C
break;
default:
printf ( T ) ;
}
}
}
(7) main()
{
charch = 'E';
switch ( c h )
{
case(ch>=65&&ch<=90):
printf ("Capital Letter");
break;
case (ch >= 97 && ch <= 1 2 2 ) :
printf ("Small case Letter");
break;
case(ch>=48&&ch<=57):
printf ("Digit");
break;
default:
printf ("Any other character*);
}
}
(8) main()
{
int i;
for ( i = 1 ; i <= 5 ; i++)
{
if(i*i>=121)
goto there;
else
printf("%d",i);
}
there:
A Multi-point Switch 133
(9) main()
{
int i, j ;
for(j = 1 ; j < = 1 0 ; j + + )
{
for ( i = 1 ; i < = 1 0 ; i + + )
{
if(j<10)
goto out;
}
printf ("Murphy's first law\n");
printf ("If the price of the PC is a dream...\n");
printf ( t h e n the service would be a nightmare");
}
out:
printf ("Dream about a nightmare");
(10) main()
{
int i, j, k;
for ( j = 1 ; j < = 4 ; j + + )
{
if(j*j==16)
goto secretplace;
}
for ( i = 1 ; i <= 5 ; i++)
{
k = i*i;
j=k+2;
secretplace:
printf ("Murphy's second law\n");
printf ("Good computers are always priced...\n");
714 Exploring C
switch ( i )
{
easel :
printf ("\nEnter any alphabet...");
fflush(stdin);
scant ("%c",&j);
switch ( j )
{
case'a':
printf ("\nlf you love something...");
goto out;
case'b':
printf ("\nSet it free...");
break;
}
break;
case 2 :
printf ("\nlf it returns, its yours....");
}
out:
printf ("\nElse it was never meant to be.");
}
(12) main()
A Multi-point Switch 135
int i, k = 1 ;
here:
if(k>2)
goto out;
there:
k++ ;
goto there;
out:;
}
(13) main()
{
int i = 1 ;
switch ( i )
{
case 1 :
goto label;
label:
case 2:
printf ("He looks like a Saint...");
break;
}
printf ("\nA Saint Bernard!");
}
Answers
Answers to [A]
(1) Output
Explanation
(2) Output
Explanation
(3) Output
Bucaneers
Gallows fodder
Explanation
(4) Output
Explanation
k/=(4/-2)
k/=-2
which evaluates to 1.
Note that in the switch the very first case is the default case.
This is perfectly acceptable.
A Multi-point Switch 139
(5) Output
x= 1
x=2
x=4
x=6
x=8
x = 11
Explanation
...
j j l case satisfied Value of x outputted
0 -1 case -1 1
1 0 case 0 2
2 1 case 1 4
3 2 case 2 6
4 3 case 3 8
5 4 default 11
Figure 4.2
(6) Output
OHHII!!!
140 Exploring C
Explanation
The following figure lists out the values printed for each ease.
....
i case satisfied output
2 case 2 0
3 case 3 No value is printed
4 case 4 H
5 case 5 H
6 default !
7 default !
8 default !
9 default !
10 default !
Figure 4.3
(7) Output
Explanation
(8) Output
1 2345
A Multi-point Switch 141
Explanation
(9) Output
Explanation
Can we abruptly break out of the loop using goto? Yes. In fact
goto can take the control anywhere in the program. Here, first
time through the loop itself the condition is satisfied, and goto
takes the control directly to the label out, where the printf()
gets executed.
(10) Output
Explanation
142 Exploring C
Look at the first for loop. The moment j * j equals 16, the goto
statement is executed, which takes the control to secretplace
inside the second for loop. This is perfectly acceptable, goto
can virtually take the control anywhere - even deep inside a for
loop. Having reached the secretplace, Murphy's second law
is printed out and then the control reaches the closing brace of
the for loop. As a result, control jumps to the beginning of loop
i.e. to which increments i and then the condition i <= 5 is
tested. Whether the condition is satisfied or not depends upon
the garbage value that was picked up for i. Why garbage value?
Because we entered the loop directly at secretplace as a result
of which i = 1 couldn't get executed. Hence a garbage value
of i is assumed. Thus after printing Murphy's law once, how
many more times it would get printed entirely depends upon
the garbage-value that has been picked up for i.
(11) Output
Explanation
(12) Output
12345123451234512345
Explanation
(13) Output
Explanation
Solutions to [B]
(1) Program
main()
{
unsigned int num, num2, no_dig = 0, p-;
int i;
num2 = num;
do
{
no_dig++;
num2 = n u m 2 / 1 0 ;
} while (num2 != 0 ) ;
switch (num / p)
{
case 0 :
printf ( " Z E R O " ) ;
break;
case 1 :
printf ( " O N E " ) ;
break;
case 2 :
printf("TWO");
break;
case 3 :
printf ( " T H R E E " ) ;
break;
case 4:
printf ( " F O U R " ) ;
break;
case 5 :
printf ( " F I V E " ) ;
break;
case 6 :
printf ( " S I X " ) ;
break ;
case 7:
printf ("SEVEN");
break;
case 8 :
printf ("EIGHT");
break;
case 9 :
printf ("NINE");
break;
}
- }
}
146 Exploring C
Sample run
Explanation
(2) Program
main()
{ •
unsigned int num, num2, no_dig = 0, p, base;
inti;
num2 = num;
do
{
no_dig++;
, num2 = num2 / base;
} while (num2 != 0 ) ;
{
p = i;
for ( i = no_dig - 1 ; i > 0 ; i-)
p = p*base;
if (base = = 1 6 )
printf ("%X", n u m / p ) ;
else
printf ("%d", n u m / p ) ;
}
}
Sample run
Explanation
Note that if the base of the numbering system is 16, then the
format specification %X is used to print hexadecimal digits.
5
Functioning
with Functions
A
C program, except for the simplest one, cannot handle all
the tasks by itself. Instead, it requests other program-like
entities - 'functions' - to get its tasks done. Functions
provide the mechanism for producing programs that are easy to write,
read, understand, debug, modify and maintain.
main() ,
{ I
message(); brings the
printf ("Study hard!"); control here
} «
returns the
message() * control back
{
printf ("Don't let sleep be the weak link..");
}
Notes
- A function gets called if the function name is followed by a semicolon.
- A function gets defined if the function name is not followed by a semi-
colon.
7
igure 5.1 Calling and defining functions
Functioning with Functions 151
Let's now assimilate a few facts about functions and lay them out
neat and clear.
(c) The order in which the functions get called and the order in
which they are defined in a program need not necessarily be
same.
Not only can one function call another, if needed we can pr.ss values
to and fro between functions. Following figure shows this mechanism
of passing and returning values between functions.
152 Exploring C
main()
int a, b, c, sum;
printf ("Enter any three numbers");
scanf ("%d%d%d",&a,&b, & c ) ;
sum = calsum (a, b , c ) ;
l—i—i
printf ("Sum = %d", sum); values of a, b, c get
this } , passed to x, y, z
value is .—|—,
returned calsum (x, y, z )
and col- i n t x y
1
z ;
lected r
x
in sum • „.
int s;t
s=x+y+z;
return ( s ) ;
J I
Figure 5.2 Passing values between functions.
Pointers
main()
154 Exploring C
int i = 3 0 ;
int*j,**k;
j = &i; /* store address of i in j */
k = &j; I* store address of j in k */
printf ("Address of i = %d %d %d\n", &i, j, * k ) ;
printf ("Address of j = %d %d\n", &j, k ) ;
printf ("Address of k = %d\n", & k ) ;
printf ("Value of i = %d %d %d %d", i, *(&i), *j, * * k ) ;
int i = 3 0 ;
k
30 1
6484 9006 9888
integer variable pointer to an pointer to an
integer variable integer pointer
Having had a tryst with the pointers now let us get back to where we
had left off - the function calls. Functions can be called in two ways:
either by passing values of arguments or by passing addresses of
arguments. The former is called a 'Call by Value' and the latter a
Call by Reference'. These calls are illustrated in the following figure.
156 Exploring C
swapv(a,b); swapr(&a,&b);
printf ( a = % d b = % d W , a, b ) ;
i
printf( a = % d b = % d \ n , a , b ) ;
, ,
swapv(x,y) swapr(x,y)
jntx,y; int*x,*y;
{
irrtt; intt;
t=x; t =*x;
x=y; *x = * y ;
y=t; *y=t;
^ printf('x=%dy = % d \ n , x , y ) ;
,
printf ("*x = %d*y = %d\n", *x, * y ) ;
}
Output Output
x=20y=10 *x = 2 0 * y = 1 0
a = 1 0 b = 20 a = 20b=10
Notes Notes
- Changes made in x and y in - Changes made in swapr() using
swapv( ) are not reflected back x and y are reflected back in a
in a and b. and b.
Recursion
When some statement in a function calls the same function it is in,
we say that recursion has occurred. Such a function is called a
recursive function. Taking the example of calculating the factorial of
a number, let us see the working of a recursive function.
Functioning with Functions 157
main()
{
int a, fact;
fact = rec ( a ) ;
printf ("Factorial value = %d", fact);
}
rec(x)
intx;
{
int f;
if ( x == 1 )
return ( 1 ) ;
else
f = x * rec ( x - 1 ) ;
return ( f ) ;
}
Assume that the number entered is 3. Using Figure 5.6, we try to
visualise what exactly happens when the recursive function rec()
gets called.
Go through the figure carefully. The first time when rec() is called
from main(), x collects 3. From here, since x is not equal to 1, the if
block is skipped and rec() is called again with argument (x - 1 ) , i.e.
2. This is a recursive call. Since x is still not equal to 1, rec() is called
yet another time, with argument ( 2 - 1 ) . This time as x is 1, control
goes back to the previous rec( ) with the value 1, and f is evaluated
as 2. Similarly, each rec() evaluates its f from the returned value,
and finally 6 is returned to main(). The sequence would be grasped
better by following the arrows in Figure 5.6. Let it be clear that while
executing the program there do not exist so many copies of the
function rec(). These have been shown in the figure just to help you
keep track of how the control flows during successive recursive calls.
frommain()
to main()
Exercise
[A] What will be the output of the following programs:
(1) main() .
{
int i = 45;
float c ;
c = check ( i ) ;
printf ("c = % f , c ) ;
}
check ( c h )
int ch;
{
ch >= 45 ? return (3.14): return (6.28);
}
(2) main()
{
int area;
float radius = 2.0;
area = areacircle (radius);
printf ("area = %f, a r e a ) ;
}
areacircle ( r )
float r;
{
float a ;
a = 3.14*r*r;
printf ("a = %An", a ) ;
return ( a ) ;
}
160 Exploring C
(3) main()
{
int c ;
printf ("c before call = %d\n", c ) ;
c = message();
printf I "c after call = %d\n", c ) ;
}
messageQ
{
printf ("Live and let live\n");
}
(4) main()
{
C()
{
c()
{
printf("CisaC...\n");
}
printf ("..isac...\n");
}
printf ("..is a sea afterall!");
}
(5) main()
{
int i = 3 k, I;
(
k = add ( + + i ) ;
I = add (i++);
printf ("i = %dk = %d I = %d", i; k , l ) ;
}
add(ii)
int ii; <
{
++ii;
Functioning with Functions 161
return ( i i ) ;
}
(6) main()
{
int i = 135, a = 135, k;
k = function (!++i, ! a + + ) ;
printf ("i = %d a = %d k = %<f, i, a, k ) ;
}
function (j, b)
intj,b;
{
intc;
c = j + b;
return ( c ) ;
}
(7) main()
{
int k = 35, z ;
k = fund ( k = func1 ( k = fund ( k ) ) ) ;
printf ("k = % d " , k ) ;
}
fund ( k )
intk;
{
k++;
return ( k ) ;
}
(8) main()
{
int k = 35, z ;
z = func ( k ) ;
printf ("z = % d " , z ) ;
tunc ( m )
intm;
{
++m;
return ( m = fund ( + + m ) ) ;
}
fund ( m )
int m ;
{
m++;
return ( m ) ;
}
(9) main()
{
void message();
intc;
printf ("c before call = %d\n", c ) ;
c = message();
printf ("c after call = % d " , c ) ;
}
void message()
{
printf ("Only he will survive who is C-fit")
}
(10) main()
{
int p = 2 3 , f = 2 4 ;
packman (p, f ) ;
printf ("p = %df = %d", p , f ) ;
}
packrrjan (q, h)
int q, h;
{
q=q+a;
Functioning with Functions 163
return ( q ) ;
return ( h ) ;
}
(11) main()
{
int i = 3, j ;
j = add ( + + i + + ) ;
printf ("i = % d j = %d\n", i , j ) ;
}
add(ii)
int ii;
{
ii++;
printf ("ii = %d\n", i i ) ;
}
(12) main()
{
inti = 10, j = 20, k;
k = addsub (i, j ) ;
printf ("k = %d", k ) ;
}
addsub (c, d )
int c, d ;
{
int x, y ;
x = c - d;
y=c+d;
return (x, y ) ;
}
(13) main()
{
inti = 10,j = 2 0 , k ;
display ( i ) ;
164 Exploring C
show(i,j);
}
display (c, d )
int c, d ;
{
printf ("%d%d " , c , d ) ;
}
show ( c )
int c ;
{
printf ( " % d " , c ) ;
}
(14) main()
{
chara = 65 ch = 'C';
p
printit ( a , c h ) ;
}
printit ( a , ch)
{
printf ("a = %dch = % c " , a , c h ) ;
}
(15) main()
{
float a = 3.14;
inti = 9 9 ;
pri(U);
printit (a, i ) ;
}
pri(i,a)
{
printf ("i = %d a = %f\n", i , a ) ;
printf ("a = %f i = %d\n\n", a , i ) ;
}
printit ( a , i)
float a ;
Functioning with Functions 165
(16) main()
{
int k = 35, z ;
z = check ( k ) ;
printf ("z = %d", z ) ;
}
cheek(m)
{
intm;
if ( m > 4 0 )
return ( ! m + + ) ;
else
return (!++m) ;
}
(17) main()
{
intk = 3 5 , * z , * y ;
z = &k; I* suppose address of k is 1008 */
y = z;
*z++ = *y++;
k++;
printf ("k = %d z = %d y = %d", k, z, y ) ;
a 8) main()
{
int a = 100, *b,**c, * * * d ;
b = &a;
c = &b;
d = &c;
166 Exploring C
(19) main()
{
int z = 4;
printf ("%d", printf ("%d %d", z, z ) ) ;
}
(20) main()
{
int i = -5, j = - 2 ;
junk (i, & j ) ;
printf ("i = %dj = % d " , i , j ) ;
}
junk (i, j )
int i, * j ;
{
i = i*i;
(21) main()
{
float a = 7.999999;
float *b, * c ;
b = &a;
c = b;
printf ("%d %d %d\n", &a, b, c ) ;
printf ("%d %d %d %d\n", a, *(&a), *b, * c ) ;
}
(22) main()
{
int * c ;
c = check { 1 0 , 2 0 ) ;
Functioning with Functions 167
(23) main()
{
float *jamboree();
float p = 23.5, * q ;
q = &p;
printf ("q before call = %d\n", q ) ;
q = jamboree ( & p ) ;
printf ("q after call = %d\n", q ) ;
}
float *jamboree ( r )
float *r;
{
r = r+ 1 ;
return ( r ) ;
(24) main()
{
inti;
printf ("In the year of lord\n");
for ( i = 1 ; i < = 1 0 ; i + + )
main();
(25) main()
168 Exploring C
{
inti;
for (t = 1 ; i < = 1 0 ; i + + )
main();
printf ("In the year of lord\n");
(26) main()
{
if (printf ("C for yourself how it works\n"))
main();
}
(27) main()
{
message();
printf ("..selling cocaine jn Xolombo");
}
message()
{
printf ("making a fast buck. An"),
main();
}
(28) main()
{
int i = 1 ;
if(!i)
printf ("Recursive calls are real pain!");
else
{
i = 0;
printf ("Recursive calls are challenging\n");
main();
}
}
Functioning with Functions 169
(2) There are three pegs labelled A, B and C. Four disks are placed
on peg A. The bottom-most disk is largest, and disks go on
decreasing in size with the topmost disk being smallest. The
objective of the game is to move the disks from peg A to peg
C, using peg B as an auxiliary peg. The rules of the game are
as follows:
(3) Write a program to obtain the sum of the first ten terms of the
following series using recursion.
X
i. I £ I
+ +
3! 5! 7! 9! •"•
Answers
Answers to [A]
(1) Output
c = 3.000000
Explanation
(2) Output
a = 12.560000
area = 12.000000
Explanation
(3) Output
c before call = 34
Live and let live
c after call = 457
Explanation
(4) Output
Explanation
(5) Output
i = 5k = 5l = 5
Explanation
(6) Output
i = 1 3 6 a = 136k = 0
Explanation
(7) Output
k = 38
Explanation
(8) Output
2 = 38
Explanation
(9) Output
Explanation
(10) Output
p = 2 3 f = 24
Explanation
(11) Output
Explanation
(12) Output
k = 30
Explanation
(13) Output
1045710
Explanation
(14) Output
a = 65ch = C
Explanation
(15) Output
i = 99 a = 0.000000
a = 0.000000 i = 99
a = 3.14i = 99
i = 9 9 a = 3.14
Explanation
(16) Output
Explanation
17) Output
k = 3 6 z = 1010y = 1010
Explanation
(18) Output
100100100100
Explanation
a b c d
Figure 5.7
(19) Output
443
Explanation
(20) Output
i = -5j = 4
Explanation
main()'s i, j mainO's i, j
J J
4008 25 4008
Figure 5.8
(21) Output
420042004200
024576-316415
Explanation
int i = 7 ;
printf ("%f", i ) ;
182 Exploring C
(22) Output
Explanation
The reason for the error is simple. The integers being passed
to check() are collected in i and j , and then their addresses are
assigned to p and q. Then in the next statement the conditional
operators test the value of i against 45, and return either the
address stored in p or the address stored in q. It appears that
this address would be collected in c in main(), and then would
be printed out. And there lies the error. The function check()
is not capable of returning an integer pointer. All that it can
return is an ordinary integer. Thus just declaring c as an integer
pointer is not sufficient. We must make the following
modifications in the program to make it work properly.
main()
f
int*c;
int *check();
c = check (10,20);
printf ("c = %d",ch
}
int *check (i, j)
int i, j ;
{
(23) Output
Explanation
(24) Output
Explanation
(25) Output
No output
Explanation
First time the control reaches the for loop main() gets called.
once again. The control again reaches the for loop and for value;
of i equal to 1, main() is called yet another time, so on and so [
forth. This continues until the stack becomes full or until the,
user aborts the program through Ctrl scroll-lock.
(26) Output
Explanation
true, hence main( ) gets called. Next time around exactly the
same thing happens. This goes on and on till either the user
interrupts through Ctrl scroll-lock or a stack overflow occurs.
(27) Output x
Explanation
(28) Output
Explanation
Solutions to [B]
(1) Program
main()
{
int sum, notes = 0 ;
Sample run
Explanation
(2) Program
main()
{
int n = 4;
move ( n , ' A ' , ' S V C ' ) ;
}
move(n, sp, ap, ep)
int n ;
char sp, ap, e p ;
{
if(n«1)
printf (*\n Move from %c to %c", sp, e p ) ;
else
{
m o v e ( n - 1 , sp, ep, a p ) ;
move(1,sp,",ep);
m o v e ( n - 1 , ap, sp, e p ) ;
}
188 Exploring C
Sample run
Move from A to B
Move from A to C
Move from B to C
Move from A to B
Move from C to A
Move from C to B
Move from A to B
Move from A to C
Move from B to C
Move from B to A
Move from C to A
Move from B to C
Move from A to B
Move from A to C
Move from B to C
Explanation
The three pegs are denoted by 'A', ' B ' and ' C . The recursive
function move() is called with different combinations of these
pegs as starting, auxiliary and ending pegs. Going through the
following figure would be the best way to sort out how the
control flows through the program.
Functioning with Functions 189
y move(l,A,C,B) A-B
move(2,A,B,C) A-C A-C
\ move(13AC) B C
A-B A-B
move(l,C,B,A) C-A
/
move(2,C,AB> C-B C-B
x
move(l,A,C,B) A-B
move(4,AB,Q A-C
y move(l,B,AQ B-C
move(2,B,C,A) B- A B- A
\ move(l,C,B,A) C-A
B-C B-C
ymove(l,AQB) A-B
move(2,AB,C) A-C A-C
- \ move(l,B,AC) B-C
Figure 5.9
(3) Program
main()
{
190 Exploring C
float x ;
float sum_series();
float sum_series ( x )
float x ;
{
static int i, sign = 1 ;
float p,f;
static float sum;
int j, k;
if ( i < 10)
{
j= 1+2*i;
P=f=i;
sum += ( ( p / f ) * sign);
i++;
sign *= - 1 ;
sum series ( x ) ;
}
return ( s u m ) ;
Functioning with Functions 191
Sample run
Explanation
(4) Program
main()
{
int d1, m l , y1, d2, m2, y2, days, dm ;
days = 1 ;
dm = 0 ;
192 Exploring C
dm = daysinmonth ( m l , y 1 ) ;
while ( 1 )
{
days = days + 1 ;
d1 = d1 + 1 ;
if(m1 > 1 2 )
{
ml = 1 ;
yi=yi + i;
}
dm = daysinmonth ( m l , y 1 ) ;
}
daysinmonth (m, y )
int m, y ;
{
Functioning with Functions 193
int d m ;
if(m==2)
{
dm = 28;
if ( ( y % 400 == 0) || ( y % 100 f= 0 && y % 4 == 0))
dm = 29;
}
return ( d m ) ;
Sample run
Explanation
Storage Classes in C
(a) Memory
(b) CPU registers
(a) What is the default initial value, i.e. the value assumed when
a variable has not been initialised
(b) What is the scope of the variable, i.e. in which functions the
value of the variable is available
(c) What is the scope of the variable
198 Exploring C
The features of all the storage classes have been given in the follow-
ing figure.
auto float a ;
register int b;
static irit c ;
Datatypes-The Building blocks 199
extern double d ;
Here are a few things that you must keep in mind about storage
classes.
Exercise
[A] What will be the output of the following programs:
(1) main()
{
int i;
for ( i = 1 ; 1 0 0 ; i + + )
printf ("%d\n", i ) ;
}
(2) main()
{
char c h ;
for (ch = 6 5 ; ch <= 2 5 5 ; ch++)
printf ("%d%c\n", ch, c h ) ;
1
(3) main()
{
unsigned char c h ;
for (ch = 6 5 ; ch <= 2 5 5 ; ch++)
printf ("%d %c\n", ch, c h ) ;
}
(4) main()
{
unsigned int ch = 0 ;
for (ch = 6 5 ; ch <= 2 5 5 ; )
printf ("%d %c\n", ch, c h + + ) ;
}
(5) main()
{
float a = 0.7;
202 Exploring C
doumeb = 0.7;
long double c = 0.7;
if ( a == b || b == c )
printf ("Condition satisfied");
else
printf ("Condition not satisfied");
printf( "a = %f b = %lf c = %Lf, a, b, c ) ;
(6) main()
{
float y = 0.9;
long double z = 0.9;
if(y==z)
printf ("Diamonds are forever...");
else
printf ("forever... forever... forever");
(7) main()
{
int i;
float f;
double d ;
long I;
i = I = f = d = 100/3;
printf ("%d%ld%f%lf\n", i , l , f , d ) ;
f = i = d = I = 100/3;
printf ("%f%d%lf%ld\n",U d , l ) ;
| = i = d = f = 100/3;
printf ("%ld%d%lf%f\n",l, i, d , f ) ;
d = I = f = i = 100/3;
printf ("%lf%ld%f%d\n", d , l , f , i ) ;
Datatypes-The Building blocks 203
(8) main()
{
auto inti = 10?
register int j = 2 0 ;
printf ("main's i and j are %d %d\n", i, j ) ;
change();
printf ("main's i and j are %d %d\n", i, j ) ;
}
change()
{
auto int i = 100;
register int j = 2 0 0 ;
printf ("change's i and j are %d %d\n", i, j ) ;
(11) main()
{
int z, y ;
z = recsum ( 1 ) ;
y = recsum ( 1 ) ;
printf ("z = %c\ny = % d " , z , y ) ;
}
recsum ( i )
inti;
{
static int sum = 0 ;
if(i==3)
return ( s u m ) ;
else
{
sum = sum+ 1 0 ;
i++;
recsum ( i ) ;
}
(12) inti = 0 ;
main()
{
printf ("main's i = %d\n", i ) ;
i++;
val();
printf ("main's i = %d\n", i ) ;
val();
Datatypes-The Building blocks 205
}
val()
{
i = 100;
printf ("val's i = %d\n", i ) ;
i++;
(13) main()
{
int y, s = 2, t = 5 ;
y = fun ( s + 1 ) ;
printf ("s = %dt = %dy = % d \ s , t , y ) ;
}
intt = 8 ;
fun ( s )
ints;
{
s++;
t++;
return ( s + 1 ) ;
114) main()
{
double x, d = 4.4;
int i = 2, y ;
x = (y = d / i ) * 2 ;
printf ("x = %lfy = %d\n", x , y ) ;
y = (x = d / i ) * 2 ;
printf ("x = %lfy = %d\n", x , y ) ; .
(15) main()
{
double x, d = 5.0;
206 Exploring C
inty;
x = d*(x = 2 . 5 / d ) ;
printf ("x = %lf\n",xj;
x = d*(y = ( i n t ) 2 . 5 + 1 . 5 ) ;
printf ("x = %lfy = %d\n",x,y);
(16) main()
{
static int c = 5 ;
printf ("c = %cf\n", c - ) ;
if(c)
mainQ
(17) main()
i
int c = 5 ;
printf Cc = %d\n",c-);
if ( c )
main();
(18) int i;
main()
{
intj;
for(;;)
{
if (j = function (i))
printfn = %d\n\j);
else
break;
}
}
function (x)
Datatypes-The Building blocks 207
intx;
{
static int v = 2 ;
v--;
return(v-x);
}
(19) mairrO
{
long num = 2 ;
short n = 2 ;
signed no = 2 ;
printf ("num = %ld n = %d no = %d", num, n, no);
}
(20) main()
{
char ch = 122, ch1 ='z';
printf ("ch = %c",ch);
printf Cch1=%d", chl);
}
(21) main()
{
unsigned int a = 2 5 ;
unsigned b = 2 5 ;
long unsigned c = 345L;
long signed d = 345L;
printf("a = % u b = %u*,a,b);
printf ("c = %lu d = %W",
}
(22) main()
. {
printf ("in main i = %d\n", i);
fund();
208 Exploring C
}
int i = 5 ;
func1()
{
printf ("In fund i = %d\n", i ) ;
}
(23) main()
{
register float r = 3.14;
register double y = 3.4;
printf ("r = %fy = % l f , r , y ) ;
(24) main()
{
auto int i = 100;
printf ("i = %d\n",i);
{
int i = 1 ;
printf ("i = %d\n",i);
{
i+=1;
prinrf("i = %d\n",i);
}
printf ("i = %d\n",i);
}
printf ("i = %d\n",i);
(25) i = 0;
main()
{
printf ("in main i = %d\n", i ) ;
i++;
val();
Datatypes-The Building, blocks 209
(a) main()
{
register int i;
for ( i = 1 ; i <= 100; i++)
printf("%d\n",i);
}
(b) main()
{
auto int i;
for ( i = 1 ; i < = 1 0 0 ; i + + )
printf("%d\n",i);
}
(1) For every non-zero odd number there exist two consecutive
numbers which form a pythagorian triplet. For example, 3, 4,
5 form a pythagorian triplet where 3 is an odd number, whereas
4 and 5 are consecutive numbers. Another example is 9, 40,
41. Write a program to find all such pythagorian triplets for all
odd numbers in the range 1 to 10.
Answers
Answers to [A]
(1) Output
1
2
32767
-32768
-32767
Explanation
(2) Output
65 A
66 B
125}
126-
-128 C
-126-
-125}
-2
-1
65 A
66 B
Explanation
Now look at the for loop and you would not be surprised to
find that ch is being assigned a value 65, even though it has
been declared as a char. Since 65 is less than 255, the condition
is satisfied and the control reaches the printf(). %d prints the
Datatypes-The Building blocks 213
(3) Output
65 A
€6B
125}
126-
255
65 A
66 B
Explanation
(4) Output
65 A
66B
125}
126-
255
Explanation
The for loop begins with 65 and goes uptil 255, printing each
of these numbers alongwith their corresponding characters.
The incrementation of ch is being done in printf(). Since ++
comes after ch, firstly its value would be used to carry out the
printing, and then it would be incremented. Since ch has been
declared as an unsigned int there is no question of exceeding
the range, as the range of an unsigned int is 0 to 65535.
(5) Output
Explanation
(6) Output
Explanation
(7) Output
33 33 331000000 33.000000
33.000000 33 33.000000 33
33 33 33.000000 33.000000
33.000000 33 33.000000 33
Explanation
(8) Output
Explanation
(9) Output
i= 1 j=2 k= 3
i = 10 j = 20 k = 30
Explanation
(10) Output^
1 =1
j=2
j=3
num = 3
Explanation
Since num has been declared outside all functions, its storage
class is assumed to be extern, and its initial value is assumed
to be 0. Through the for loop, when increment() is called for
the first time, num is incremented to 1 and this value is
returned, to be collected in j . This value is then printed out
through the printf(). Subsequent calls to increment) through
the for loop would increment num every time and return this
incremented value, only to be printed through the printf().
Finally, the value of num is printed in main(). Note that num
is available to both the functions: main() as well as incre-
ment ).
(11) Output
z = 20
y = 40
Explanation
(12) Output
main's i = 0
val'si = 100
main's i = 101
val's i = 100
Explanation
latest value of i, i.e. 101. After this once again val() gets called,
where i is reinitialised to 100 and then printed out.
(13) Output
s = 2t = 5y = 17
Explanation
(14) Output
x = 4.000000y = 2
x = 2.200000y = 4
Explanation
Datatypes-The Building blocks 221
x = (y = 4.4/2)*2
x = (y = 2.2)*2
x = 2*2
X=4
y = (x = d / i ) * 2
y = (x = 2.2)*2
y = 2.2*2
y = 4.4
(15) Output
x = 2.500000
x=15.000000y = 3
Explanation
x = d*(x = 2.5/d)
x = 5.0*(x = 2.5/5.0)
x = 5.0*(x = 0.5)
x = 2.5
222 Exploring C
What does the expression ( i n t ) 2.5 do? It casts the value 2.5
as an integer. This process is often called typecasting and it can
be applied to any datatype. For example, (long ) 123 would
cast 123 as a long integer.
(16) Output
c=5
c=4
c=3
c=2
c= 1
Explanation
(17) Output
c = 5
C = 5
c = 5
Explanation
(18) Output
i= i
Explanation
(19) Output
num = 2 n = 2no = 2
Explanation
(20) Output
ch = zch1 =122
Explanation
Datatypes-The Building blocks 225
Does chl = V really store the character 'z' in chl? Not really.
What is stored in chl is the ascii value of ' z \ which is 122.
Understand that a char variable never holds characters. It can
hold only values in the range -128 to +127. Once this fact sinks
in, the output of the program can be easily understood. The first
printf( ) prints out a character corresponding to the value
stored in ch, whereas the second printf( ) prints the value
stored in chl.
(21) Output
a = 25 b = 25 C = 345 d = 345
Explanation
The first two declarations make one fact very clear - while
declaring a variable to be of the type unsigned int, the int can
as well be dropped from the declaration. Observe that in the
next two declarations too the word int has been dropped. In
these declarations a capital L occurs after 345. This ensures
that 345 is treated as a long int. In place of a capital L a lower
case 1 is also acceptable. Also observe the format specifications
used in printf(): %u for an unsigned int, %luforan unsgined
long int and %ld for a long signed int.
(22) Output
Explanation
(23) Output
r = 3.140000 y = 3.400000
Explanation
(24) Output
i = 100
i=1
i=2
i=2
i = 100
Explanation
Datatypes-The Building blocks 227
(25) Output
Explanation
(26) Output
1
2
3
228 Exploring C
99
100
Explanation
Solutions to [B]
(1) Program
main()
{
unsigned int i, j, k;
for(i = 1 ; i < = 9 ; i = i + 2 )
{
for (j = 1
{
k=j + 1;
if(i*i + j * j = = k * k )
{
printf ("\n%u%u%u", i , j , k ) ;
break;
Datatypes-The Building blocks 229
}
}
}
}
Sample run
1 3276832769
345
51213
7 24 25
94041
Explanation
Here i is being used for the odd number whereas j and k signify
the consecutive numbers. Since i represents the odd number,
it varies from 1 to 9 in steps of 2. If sum of squares of i and j
equals the square of k, then i, j , k forms a pythagorian triplet.
The moment such a triplet is encountered it is printed out. Note
that i, j and k have been declared as unsigned ints. This is
because the range of such integers is 0 to 65535. In this program
we do need a range bigger than -32768 to +32767.
(2) Program
main()
{
unsigned long num, mum, square, rsquare, n2, num2;
intd1,d2,d3,d4, d5;
num2 = n u m 2 / 1 0 ;
d2 = n u m 2 % 1 0 ;
num2 = n u m 2 / 1 0 ;
d3 = n u m 2 % 1 0 ;
num2 = n u m 2 / 1 0 ;
d4 = num2% 1 0 ,
num2 = n u m 2 / 1 0 ;
d5 = num2;
while (mum % 10 = = 0 )
rnum = m u m / 1 0 ;
d1 = square % 1 0 ;
square = square/10;
d2 = square % 1 0 ;
square = square/10;
d3 = square % 1 0 ;
square = square/10;
d4 = square % 1 0 ;
square = square/10;
d5 = square;
n2 = d5 + d 4 * 10 + d 3 * 100 + d 2 * 1000L +d1 * 10000L;
while ( n 2 % 10 = = 0 )
n2 = n 2 / 1 0 ;
if (rsquare == n2)
printf ("\n%lu", n u m ) ;
}
}
Datatypes-The Building blocks 231
Sample run
10
11
12
13
20
21
22
30
31
100
Explanation
Within the for loop, firstly the digits of the number ( say, 12)
are separated out into variables d l through d5, and then using
these, the reversed number ( say 21) is constructed and stored
in the variable rnum. The while loop that follows trims any
trailing zeroes from this reversed number. Then squares of the
original number ( 12 ) and the reversed number ( 21 ) are
calculated. The set of statements that follow segregate the
digits of the square of the original number ( 144 ) and then
using these segregated digits, it constructs the reverse of the
square ( 441). The while loop then trims out any trailing zeroes
that might be present in this reverse of square of original
number. Now if this number is same as rsquare calculated
earlier, then the number in question satisfies the property and
hence is printed out.
Macro Expansion
#defineNUM100
#defineSQUARE(x)(x*x)
main()
{
int i = 5;
f
The C Preprocessor 235
The first two statements in the program are called macro definitions.
They comprise of 'macro templates' NUM and SQUARE(x) and
their corresponding 'macro expansions', 100 and ( x * x ). During
preprocessing, the macio templates are replaced by their correspond-
ing macro expansions. The first macro expansion is a simple macro,
whereas the second one is said to be taking an argument x. (Note that
there is no space between SQUARE and (x) ). In our program, we
have chosen the argument to be i, so the preprocessor expands the
macro in terms of i.
File Inclusion
fflnclude "ac" This commands the preprocessor to look for the file
a.c in the current directory as well as the specified
list of directories mentioned in the search path that
might have been set up.
include <ac> The file a.c is looked up only in the specified list of
directories.
Conditional Compilation
#ifdef LABEL
statement 1 ;
statement 2 ;
#endif
will ensure that statements 1 and 2 will get compiled only if LABEL
has been #defined. If LABEL has not been defined as a macro, the
two statements won't be sent for compilation at all. Conditional
compilation can be used to make a program portable. For two
different makes of computers, we can write a single program and
conditionally compile only the code pertaining to either of the two
machines. The program would look like:
. main()
{
#ifdefPCAT
code for a PC/AT
#else
code for a PC/XT
#endif
code common to both the computers
}
The C Preprocessor 237
Exercise
[A] What will be the output of the following programs:
(2) #defineNO
#defineYES
main()
{
int i = 5, j ;
if(i>5)
j = YES;
else
j = NO;
printf ("%d",j);
}
(4) #defineGOTONEXTUNEprintf("\n")
The C Preprocessor 239
main()
{
printf ("It's better to keep your mouth shut..") ;
GOTONEXTUNE;
printf (".. and have people think you are a fool..");
GOTONEXTUNE;
printf (".. than to open it and remove all doubt!");
}
(7) #defineTHIS
#defineTHAT
main()
{
#ifdefTHIS
#ifdefTHAT
240 Exploring C
(8) #defineTHIS
#defineTHAT
main()
{
#ifdef THIS && THAT
printf ("Defintions are hard to digest");
#else
printf ("But once mugged up, hard to forget");
#endif
}
(9) #defineMEAN(a,b,c,d,e)(a+b + c + d + e ) / 5
main()
{
int a, b, c, d, e, m ;
a =1
b = 2;
c = 3;
d-4;
e = 5;
m = MEAN(a, b,c, d , e ) ;
printf ("Mean of the five numbers is = %d") ;
}
(10) #defineCUBE(X)(X*X*X)
main()
{
int a ;
a = 27/CUBE(3);
printf ("%d", a ) ;
The C Preprocessor 241
(11) #defineCUBE(X) ( X * X * X )
main()
{
int a, b;
b = 3;
a = CUBE(b++)/b++;
printf ("a = % d b = %d", a, b ) ;
}
(12)
#defineCUBE(X)(X*X*X)
main()
{
int a, b = 3 ;
a = CUBE(++b)/++b;
printf("a = % d b = % d " , a , b ) ;
}
(15) #defineCOND(a)if(a>=65&&a<=90)
main()
{
charch = 'R';
COND(ch)
printf ("Uppercase");
else
printf ("Lowercase");
}
(20) #defineAND&&
#defineOR||
#define LE <=
#define GE >=
main()
{
char ch = 'D';
if ( ( c h GE 65 AND ch LE 90) OR (ch GE 97 AND ch LE 122))
printf ("Alphabet");
else
printf ("Not an alphabet");
}
int m, x = 5, y = 6 ;
m = M A X ( x + y, 1 0 ) ;
printf ("%d", m ) ;
m = MAX(x,y)*100;
printf ("\n%d", m ) ;
}
(28) main()
{
window ( 2 0 , 1 0 , 4 0 , 1 5 ) ;
#include "conio.h"
cprintf ("The love in your heart was not put to stay...");
cprintf ("Love is not love till you give it away.");
246 Exploring C
Answers
(1) Output
square of i = 4
Explanation
(2) Output
Explanation
(3) Output
mm
Explanation
The C Preprocessor 247
(4) Output
Explanation
(5) Output
m
m
Explanation
main()
{
printf( "m");
printf("\n");
printf( "m");
248 Exploring C
(6) Output
Explanation
The first and second macros have the criteria for checking
whether their argument x is an upper or a lower case alphabet.
These two criteria have been combined in the third macro,
ISALPHA. Thus when the program goes for compilation, the
if statement has been converted to the form:
(7) Output
Explanation
(8) Output
Explanation
(9) Output
Explanation
(10) Output
Explanation
a = 27/(3*3*3)
a = 27/27
a= 1
(11) Output
a=9b=7
Explanation
(12) Output
a = 49b = 7
Explanation
i
a = (++b*++b*++b)/++b
a=(7*1*1)11
a = 343/7
a = 49
(13) Output
UPPERCASE
Explanation
(14) Output
ch is in upper case
Explanation
if(ch>=65&&ch<=90)
(15) Output
Upper case
Explanation
(16) Output
int = 3
Explanation
(17) Output
var = 49.920013ormat
var = 3.140000ormat
Explanation
Look at the first output. Where did ' f go? And why were the
numbers printed at all? This has the simple explanation that
our argument format happened to have as its first letter, an T .
The printf() interpreted %f as the format specification, and
'ormat' as something we wanted to write on the screen literally.
Note that we got the expected value for a, a float, but an absurd
one for int i, since the printf() attempted to- print out an int
using %f.
(18) Output
a = 1 0 b = 20
Explanation
(19) Output
A
The C Preprocessor 255
Explanation
(20) Output
Alphabet
Explanation
(21) Output
Leap year
256 Exploring C
Explanation
The macro ISLP(y) takes as its argument any year y, and tests
if the year is a leap year or not. For a year to be leap, either it
should be an integral multiple of 400, or if the year is not
divisible by 100, an integral multiple of 4. Why is this so and
why we are not told this in school, I leave for you to figure out.
The year 1992 is not divisible by 400, hence the first condition
fails, but the second part of the condition holds good. Hence
the output that the year is indeed a leap year is obtained.
(22) Output
11
600
Explanation
m = (((x + y ) > ( 1 0 ) ) ? ( x + y ) : ( 1 0 ) ) ;
m = (((x)>(y))?(x):(y))*100;
(23) Output
Explanation
(24) Output
No output
Explanation
(25) Output
To be or not to be...
Explanation
From the above program we can gather that macros need not
necessarily be defined in capital letters. Capital letters are used
only to facilitate our comprehension of the program; i.e. to
make out which is a variable and which is a macro. After
executing the first printf(), the compiler finds the exit(0), as
substituted by the preprocessor, and hence terminates the ex-
ecution.
(26) Output
Explanation
(27) Output
Explanation
(28) Output
Explanation
With the basics of arrays under our belt, let's delve into a few smaller
issues.
int num[6]= { 2 , 4 , 1 2 , 5 , 4 5 , 5 } ;
int n[] = { 2 , 4 , 1 2 , 5 , 4 5 , 5 } ;
float press[ ] = {12.3,34.2 -23.4, -11.3};
Let's venture further and see how arrays and functions interact with
one another. How do we pass array elements to a function? Naturally,
by value and/or by reference. The following figure shows both these
calls at work.
264 Exploring C
s(k)
INT*K;
{
PRINTF ("%D",*K);
Let us now digress a bit and see what lies below the outer garb of
pointers. Having explored that, we would once again get back to
arrays, better equipped.
We had our first tryst with pointers in Chapter 5. We may recall that
a pointer is a variable which stores the address of other variables. If
a pointer variable stores the address of a char variable, we call it a
char pointer. Same logic applies to an int pointer or a float pointer.
With this much knowledge under our belt, its time to have a closer
look at pointers and how they relate to arrays.
A Tryst with Arrays 265
1.5
4001
6485
] On incrementing
4003
6485
*j = 23 *j =34
main()
main()
{
ints[4][2],i;
for ( i = 0 ; i <= 3 ; )
{
printf ("\nEnter roll no. and marks");
scanf ( %d%d",&s[i][0] &s[i][1]);
,
1
The program is fairly simple. Through the first for loop, we read the
values of roll no. and marks into the two-dimensional array s[4][2]
and through the second for loop we print out these values.
(a) Before using the 2-D array its dimension must be mentioned.
This has been done in our program by the statement int s[4] [2].
(b) The elements of the 2-D array s[ ] [ ] can be accessed using the
subscript notation s[i]|j], where i represents the row number
and j represents the column number in which the element is
present.
268 Exploring C
(d) A 2-D array can be declared and initialised at the same place.
When this is done, mentioning the row dimension is optional.
Such a declaration would look like:
Array of Pointers
The way there can be an array of ints or an array of floats, similarly
there can be an array of pointers. Since a pointer variable always
contains an address, an array of pointers would be nothing but a
collection of addresses. The addresses present in the array of pointers
could be addresses of isolated variables or addresses of array ele-
ments or any other addresses. All rales that apply to an ordinary array
apply in toto to the array of pointers as well. The following figure
shows the contents and arrangements of an array of pointers called
arr. As you can observe, arr contains addresses of isolated int
variables i, j , k and I.
I J K 1
» 1
4008
5
5116
19
6010
71
7118
Suppose the following statements are now executed:
Exercise
[A] What will be the output of the following programs:
(1) main()
{
int a[5], i ;
static int b[5];
for ( i = 0 ; i < 5 ; i++)
printf ("%d %d %d\n", i,a[i], b[i]);
(2) main()
{
static int sub[5] = {10,20,30,40,50};
inti;
for ( i = 0; i <= 4; i + + ) ;
{
if(i<=4)
{
sub[i] = i * i;
printf ("%d\n", sub[i]);
}
}
(4) main()
{
static float arr[] = { 1 . 2 , 1 2 , 2 . 4 , 2 4 , 3 . 5 , 3 5 } ;
int i;
for ( i = 0 ; i <= 5 ; i++)
printf ("%f", arr[i]);
}
(5) main()
{
int size = 1 0 ;
int arr[size];
for ( i = 1 ; i <= size; i++)
{ '
scanf ("%d",&arr[i]);
printf ("\n%d", arrp]);
}
}
(6) main()
{
int i, j = 10, arrsize;
int arr[arrsize];
if (j == 10)
arrsize = 2 0 ;
else
arrsize = 4 0 ;
for ( i = 0 ; i < arrsize; i++)
arrp] = 100;
}
(7) main()
{
intarr1[10],arr2[10], i;
for ( i = 0 ; i <= 9 ; i++)
{
272 Exploring C
arr1[0 = 'A' + i;
arr2[i] = 'a' + i;
printf ("%d", arr2[i]-arr1[i]);
}
}
(8) main()
{
static intb[] = { 1 0 , 2 0 , 3 0 , 4 0 , 5 0 } ;
inti;
for ( i = 0 ; i <= 4 ; i++)
printf ("%d", i[b]);
(9) main()
{
static int array[10] = { 1 , 2 , 3 , 4 , 5 , 6 } ;
inti;
for (i = 0 ; i <= 9 ; i++)
printf ("%d",array[ij);
(10) main()
{
static i n t a ( ] = { 2 , 3 , 4 , 5 , 6 } ;
inti;
for ( i = 5 ; i > 0 ; )
printf ("%d " , a [ - i ] ) ;
(11) main()
{
static inta[5] = { 5 , 1 0 , 1 5 , 2 0 , 2 5 } ;
int i, j, m, n ;
i = ++a[l];
j = a[1]++;
A Tryst with Arrays 273
1 =1;
m = a[i++];
printf ("i = %d m = %d\n", i, m ) ;
i = 2;
n = a[++i];
printf ("i = % d n = %d", i , n ) ;
(12) main()
{
int arr(25), i;
for ( i = 0 ; t <= 100; t++)
{
arr(i) = 100;
printf ( " % d a r r ( i ) ) ;
}
(13) main()
{
static int a[ ] = { 1 0 , 2 0 , 3 0 , 4 0 , 5 0 } ;
int j ;
for ( j = 0 ; j < 5 ; j++)
{ '
printf ("%d",*a);
a++;
}
}
(14) main()
{
Static float a[] = {13.24,1.5,1.5, 5.4,3.5};
float *j, *k;
274 Exploring C
j = a;
k=a+4;
H*2;
k=k/2;
printf ("%f%f",*j,*k);
(15) main()
{
int n[25];
n[0] = 100;
n[24] = 2 0 0 ;
printf ("%d %d", *n, * ( n + 2 4 ) + *( n + 0 ) ) ;
(16) main()
{
static int b[] = { 1 0 , 2 0 , 3 0 , 4 0 , 5 0 } ;
int i, * k ;
k-&b[4]-4;
for ( i = 0 ; i <= 4 ; i++)
{
printf ( " % d " , * k ) ;
k++ ;
}
(17) main()
{
static inta[] = { 2 , 4 , 6 , 8 , 1 0 } ;
inti;
for ( i = 0 ; i <= 4 ; i++)
I
* ( a + i ) = a [ i ] + i[a];
printf ("%d", * ( i + a ) ) :
}
(18) main()
{
static int a[5] = { 2 , 4 , 6 , 8 , 1 0 } ;
int i, b = 5 ;
for ( i = 0 ; i < 5 ; i++)
{
f(a[g,&b);
printf ("%d%d\n",a[i],b);
}
f(x,y)
int x, * y ;
{
x = *(y)+=2;
}
(19) main()
{
static int a[5] = { 2 , 3 , 4 , 5 , € } ;
inti;
change ( a ) ;
for ( i = 4 ; i = 0 ; i-)
prinrf( "%d", a(0);
change ( b )
int * b ;
{
int i ;
for (i = 0 ; i <= 4 ; i++)
{
*b = *b + 1 ;
b++;
}
276 Exploring C
(20) main()
{
int arr[] = { 0 , 1 , 2 , 3 , 4 } ;
int i, *ptr;
for (ptr = &arr[0]; ptr <= &arr[4]; ptr++)
printf ("%d ",*ptr);
}
(21) main()
{
intarr[) = { 0 , 1 , 2 , 3 , 4 } ;
int i, *ptr;
for {ptr = &arr[0], i = 0 ; i <= 4 ; i++)
printf ("%d",ptr[i));
}
(22) main()
{
int arr[] = { 0 , 1 , 2 , 3 , 4 } ;
int i, * p ;
for ( p = arr, i = 0 ; p + i <= arr + 4 ; p++, i++)
printf ("%d",*(p + i ) ) ;
)
(23) main()
{
int arr[] = { 0 , 1 , 2 , 3 , 4 } ;
int i, *ptr;
for (ptr = arr + 4 ; ptr = arr; ptr--)
printf ("%d ",*ptr);
}
(24) main()
{
A Tryst with Arrays 277
int arr[] = { 0 , 1 , 2 , 3 , 4 } ;
int i, *ptr;
for (ptr = arr + 4, i = 0 ; i <= 4 ; i++)
printf ("%d", ptr[-0);
(25) main()
{
int arr[] = { 0 , 1 , 2 , 3 , 4 } ;
int *ptr, i;
for (ptr = arr + 4 ; ptr >= arr; ptr-)
printf ("%d", arr [ p t r - a r r ] ) ;
(26) main()
{
static int a[] = { 0 , 1 , 2 , 3 , 4 } ;
static int *p[ ] = { a , a + 1 , a + 2, a + 3, a + 4 } ;
int **ptr = p;
printf ("%d%d\n", a, * a ) ;
printf ("%d %d %d\n", p,*p,**p);
printf ("%d %d %d\n", ptr,'*ptr, **ptr);
(27) main()
{
static int a [ ] = { 0 , 1 , 2 , 3 , 4 } ;
static int *p[ ] = { a , a + 1, a + 2, a + 3, a + 4 } ;
int **ptr = p;
ptr++;
*ptr++;
*++ptr;
278 Exploring C
++*ptr;
printf ("%d %d %d\n", ptr - p, *ptr - a, **ptr);
}
(28) main()
{
static int a[] = { 0 , 1 , 2 , 3 , 4 } ;
static int*p[] = {a, a + 1 , a + 2, a + 3, a + 4 } ;
int **ptr;
ptr = p;
**ptr++;
printf ("%d %d %d\n", ptr - p, *ptr - a, **ptr);
*++*ptr;
printf ("%d %d %d\n", ptr - p, *ptr - a, **ptr);
++**ptr;
printf ("%d %d %d\n", ptr - p, *ptr - a, **ptr);
}
(29) main()
{
static int n[3][3] = {
2,4,3,
6, 8, 5,
3, 5,1
};
(30) main()
{
static int n[3][3] « {
A Tryst with Arrays 279
2,4,3,
6, 8, 5,
3,5,1
};
int i, *ptr;
ptr = n ;
printf ("%d", n[2]);
printf ("%d", ptr[2]);
printf ("%d", *( ptr + 2 ) ) ;
(31) main()
{
static intn[3][3] = {
2,4,3,
6, 8, 5,
3, 5,1
};
int i, j ;
for(i = 2 ; i = 0;i--)
{
for(j = 2 ; j = 0 ; j ~ )
printf ("%d %d\n". n[i][fl, *(*( n + i) + j > ) ;
}
}
(32) main()
{
static inta[3][3] = {
1,2,3,
4, 5,6,
7, 8,9
};
int*ptr[3] = {a(0],a[1],a[2)};
int **ptr1 = ptr;
int i;
for ( i = 0 ; i <= 2 ; i++)
280 Exploring C
printf ( V ) ;
for ( i = 0; i <= 2; i++)
printf ("%d Y * a [ g ) ;
printf ("\n");
for ( i = 0; i <= 2 ; i++)
{
printf ("%d ",**ptr1);
ptr1++;
}
(33) main()
{
static int t[3][2][4] = {
{
2,4,3,6,
1,6,7,9
},
{
8,2,1,1,
2, 3, 7, 3
{
1,6, 2,4,
0, 7, 9. 5
}
};
printf f % d \ t[2j[1]l3], *( *( *( t + 2) + 1 ) + 3)) ;
}
(3) A square matrix, that is, one having the same number of rows
and columns, is called a diagonal matrix if its only non-zero
elements are on the diagonal from upper left to lower right. It
is called upper triangular, if all elements below the diagonal
are zeroes, and lower triangular, if all elements above the
diagonal are zeroes. Write a program that reads a matrix and
determines if it is one of these three special matrices.
Your program should match each person with the three most
compatible persons of the opposite sex, and should print the
code number of the applicants along with the code numbers of
their prospective mates. As a measure of compatibility of two
persons, use the cosine of difference between the responses;
the larger the cosine, the more compatible the couple.
8 1 6
3 5 7
4 9 2
Place initial number in the middle of the top row. Then after
integer k has been placed, move up one row and one column
A Tryst with Arrays 283
(a) If a move takes you above the top row in the j * column,
move to the bottom of the j * column and place the
integer there.
(b) If a move takes you outside to the right of the square in
the i* row, place the integer in the i* row at the left side.
(c) If a move takes you to an already filled square or if you
move out of the square at the upper-right-hand corner,
place k + 1 immediately below k.
Answers
Answers to [A]
(1) Output
01000
1 -750
21230
312450
43470
Explanation
Since the storage class of the array a[ ] has not been mentioned,
the default storage class auto is assumed for it. As against this,
the storage class of b[] has been explicitly mentioned as static.
The default value of auto storage class variables is any garbage
value and the default value of static storage class variables is
0. Therefore all zeroes are printed out for b[ ], whereas garbage
values are printed out for a[ ].
(2) Output
No output
Explanation
This loop repeats the null statement ( ; ) 5 times and then the
control comes out of the loop. At this time the value of i has
become 5 and hence the if condition fails and the control
reaches the closing brace of main(). The execution is therefore
terminated without any output to the screen. Take care not to
place a semicolon after for. If you do so, now you know whom
to blame.
(3) Output
00
00
00
00
00
Explanation
(4) Output
Explanation
(5) Output
Explanation
(6) Output
Explanation
(7) Output
32323232323232323232
Explanation
(8) Output
10203040 50
288 Exploring C
Explanation
(9) Output
1234560000
Explanation
(10) Output
A Tryst with Arrays 289
65432
Explanation
(11) Output
i = 11 j = 11 a[1] = 12
i = 2 m = 12
i = 3 n = 20
Explanation
(12) Output
Explanation
(13) Output
Explanation
(14) Output
Explanation
(15) Output
100300
Explanation
(16) Output
1020 3040 50
Explanation
10 20 30 40 50 |
Figure 8.8
(17) Output
48121620
Explanation
Imbibe the following two facts and the program becomes very
simple to understand:
294 Exploring C
With those facts clearly laid out, let us now try to understand
the program. Remember that internally C always accesses
array elements using pointers. Thus, when we say a[i], inter-
nally C converts it to *( a + i ) , which means value of i integer
from the base address. Now, if the expression a[i] is same as
*( a + i ) then *( i + a ) must be same as i[a]. But *( a + i ) is
same as *( i + a ) . Therefore afi] must be same as i[a].
(18) Output
27
49
611
813
1015
Explanation
After initialising the array when the control enters the for loop,
the function f() gets called with value of afi] and address of b.
In f() these are collected in variables x and y. Then comes the
expression x = *( y ) + = 2. Here *( y ) + = 2 is evaluated first
A Tryst with Arrays 295
Figure 8.9
(19) Output
76543
Explanation
4002
3
4004
4
Figure 8.10
(20) Output
01234
Explanation
0 1 2 3 4 |
6004 6006 6008 6010 6012
ptr ptr
I Rtr++
6004 J " * 6006 |
Figure 8.11
(21) Output
01234
Explanation
(22) Output
024
Explanation
0 1 2 3
Figure 8.12
Note that in the for loop there are multiple initialisations and
multiple incrementations, each separated by the comma
operator. In initialisation part, p is initialised to the base
address of the array, whereas i is initialised to 0. After these
initialisations the control reaches the condition. The condition
is a little complicated so let us isolate it for a clearer under-
standing.
p + i <= arr + 4
less than 6012, the condition is satisfied and the control reaches
printf(), where value at ( p + i ) , i.e. 0 gets printed. Then the
control reaches the incrementation part of the for loop, where
p++ increments p to 6006, and i++ increments i to 1. Next,
once again the condition is tested. This time p + i gives 6008
(since p is 6006 and i is 1 ) and arr + 4 gives 6012. Since the
condition once again gets satisfied, the printf( ) prints out the
value at ( p + i ) , i.e. 2. Similarly, next time around 4 gets
printed and then the condition fails therefore the execution is
terminated.,
(23) Output
43210
Explanation
O 1 2 3 4 |
Figure 8.13
(24) Output
4321 0
Explanation
L• 6004
1
6006
2
6008
3
6010
4
6012
1
Figure 8.14
(25) Output
4321 0
Explanation
6004
1
6006
2
6008
3
6010
«1
6012
Figure 8.15
prints out 3. This process is repeated till all the integers in the
array have been printed out.
(26) Output
60040
901660040
901660040
Explanation
It prints out the base address of the array a[ ] and the value at
this base address.
A Tryst with Arrays 303
6004
1
6006
2
6008
3
6010
* 1
6012
P[0] rfl] p[2] P[3] P[4]
9016
7888
I
Figure 8.16
printf ("%d%d%d\n",p,*p,**p);
Here p would give the base address of the array p[ ], i.e. 9016;
*p would give the value at this address, i.e. 6004; **p would
give the value at the address given by *p, i.e. value at address
6004, which is 0.
Here ptr contains the base address of the array p[ ], i.e. 9016;
*ptr wouid give the value at this address, i.e. 6004; **ptr
would give the value at the address given by *ptr, i.e. value at
address 6004, which is 0.
(27) Output
11 1
• 222
333
344
Explanation
ptr-p
*ptr-a
Figure 8.17
**ptr
Take a deep breath and then begin with the analysis of *ptr++.
Here * and ++ both are unary operators. Unary operators have
an associativity of right to left, hence ++ is performed before
*. ++ increments ptr such that ptr now contains 9020. Then
•(9020) is performed, which gives the value at 9020. But since
this value is not assigned to any variable, it just gets ignored.
Now with ptr containing 9020, let us once again analyse the
expressions ptr - p, *ptr - a and **ptr.
ptr-p
*ptr-a
**ptr
•ptr gives the value at address 9020, i.e. 6008, and •( 6008)
gives the value at 6008, i.e. 2.
ptr-p
*ptr-a
**ptr
*ptr yields 6012, therefore **ptr would yield the value at *ptr,
or the value at 6012, which is 4.
(28) Output
1 11
122
1 23
Explanation
Figure 8.18
ptr-p
A Tryst with Arrays 309
*ptr- a
**ptr
ptr contains 9018, so *ptr would yield 6006, and hence **ptr
becomes *( 6006 ), which would yield 1.
Now, with ptr containing 9018, let us once again analyse the
expressions ptr - p, ptr - a and **ptr.
Ptr- p
*ptr -a
310 Exploring C
**ptr
•ptr gives the value at address 9018, i.e. 6008, and *( 6008)
gives the value at 6008, i.e. 2.
ptr-p
*ptr -a
**ptr
*ptr gives the value at address 9018, i.e. 6008, and *( 6008)
gives the value at 6008, i.e. 3.
(29) Output
A Tryst with Arrays 311
404 4161
Explanation
1 • N[0][0]
| • N[L][0]
| • N[2][0]
2 4 3 6 8 5 3 5
Figure 8.19
(30) Output
41633
Explanation
312 Exploring C
2 4 3 6 8 5 3 5
Figure 8.20
(31) Output
1 1
55
33
55
88
66
33
44
22
Explanation
2 4 3 6 8 5 3 5
Figure 8.21
(32) Output
147
147
147
Explanation
314 Exploring C
In the next for loop, the values at base addresses stored in the
array a[ ] are printed, which once again turn out to be 1, 4 and
7. The third for loop is also simple. Since ptrl has been
initialised to the base address of the array ptr[ ], it contains the
address 822.
1 2 3 4 5 6 7 8
» 1
404 406 408 410 412 414 416 418 420
ptrl ptrl
Ptrl t +
1 822 I ~" ' I 824 |
Figure 8.22
Therefore *ptrl would give the value at address 822, i.e 404,
and **ptrl would give the value at address given by *ptrl,
i,e. value at 404, which is 1. On incerementing ptrl it points
to the next location after 822, i.e 824. Therefore next time
through the for loop, **ptrl gives value at 410 ( which is
obtained through *ptrl ), i.e. 4. Similarly, last time through
the loop, the value 7 gets printed.
(33) Output
r A Tryst with Arrays 315
55
Explanation
Figure 8.23
Solutions to [B]
(1) Program
316 Exploring C
mainQ
{
int a[25], d1[24], d2[23], d3[22], i;
printf ("\nA:");
for ( i = 0 ; i <= 2 4 ; i++)
printf ("%d", a p ] ) ;
printf ("\nD2:");
for ( i = 0 ; i <= 2 2 ; i++)
{
d2[i] = d1[i+1]-d1[i];
printf ("%d ",d2[Q);
}
printf ( * \ n D 3 : " ) ;
for ( i = 0 ; i <= 2 1 ; i++)
{
d3[i] = d2[i+1]-d2[i];
printf ( " % d d 3 p j ) ;
}
A Tryst with Arrays 317
Sample run
Enter 25 elements
1 24711 162224567891012345626789
A: 1 2 4 711 1 6 2 2 2 4 5 6 7 8 9 1 0 1 2 3 4 5 6 2 6 7 8 9
Explanation
(2) Program
main()
{
int data[50], i;
static intfreq[26];
Sample run
Enter data
1 1 1 2 2 2 3 3 3 4 4 4 4 4 4 4 4 45 45 45 45 2 2 2 2 2 2 2 2
666666666622222221717171717434343
Frequency of occurrence:
1-3
2-10
3-3
4-8
6-10
17-5
22-4
43-3
45-4
Explanation
To begin with, the data is read into the array data[ ] through
the first for loop. As each data item is read, it is tested for
validity and then the appropriate element in the array freq[ ]
is incremented by 1. To ensure that to begin with each element
of the array freq[ ] is 0, it has been declared as static. By the
time the entire data has been read, the freq[ ] array has also
been set up. Through the second for loop, the frequency of the
data items has been printed out. For want of space, frequencies
of only those data items have been printed out which occur at
least once.
A Tryst with Arrays 319
(3) Program
main()
{
int mat[10][10], n, r, c, lowertri = 0, uppertri = 0 ;
if(mat[r][c])
break;
}
if(mat[r][c])
break;
}
if(r==n)
uppertri = 1 ;
Sample run
Diagonal matrix
A Tryst with Arrays 321
Explanation
Similarly, through the next set of for loops, the lower triangle
of the matrix is checked for non-zero elements. If there is a
normal exit from these for loops, then uppertri is set up with
1.
(4) Program
mainQ
{
int saJes[5][10][7];
float wkchip, wkcity, avg_dsales = 0 ;
int i, j, k;
{
printf ("\nCity no: % d " , j ) ;
printf ("\nEnter weekly sale day by day\n");
for (k = 0 ; k < 7 ; k++)
{
scanf ("%d\ &sales[i][fl[k]);
wk_chip += sales[i][j][k] ;
}
}
printf ( " W h i p no. %d sales = %f, i, wk_chip);
avg_dsales += w k c h i p ;
}
avg_dsales/=7;
printf ("\nAverage daily sales = %f, avg_dsales) ;
Explanation
chip, behind that data of another chip and so on. Once this is
understood well, the rest of the program is simple.
In the first set of for loops the outermost loop controls the chip,
the middle loop controls the city, and the innermost loop
controls the daily sale. Through thesp loops the daily sale in
each city for each chip is entered. As each daily sale figure is
entered, a running sum is made using wk_chip. When the
control comes out of the middle loop, wk_chip contains the
total week's sale for a particular chip, which is printed out
before receiving the sales figures for the next chip. Since
wk_chip at this stage contains the total sale of a chip in all
cities, this value is stored in avg_dsales. This variable is
incremented every time by an amount equal to the sale of a chip
in a week as given by wk_chip. Once.the control comes out of
all the three loops, avg_dsales contains the total sale of all
chips in all cities during the week. This is therefore divided by
7 to get the average daily sale of the company in that week.
The next set of for loops calculate the total sale of all chips in
each city. I suppose you can now figure out how these loops
work. Good luck!
(5) Program
include "math.h"
#include "stdio.h"
main()
{
int i, j, ans, k, tcode, t ;
float c, tcosin, factor;
324 Exploring C
cosin[k] = t_cosin;
I*swap codes*/
tcode = t;
t = mcode[i][k];
mcode[i][k] = t_code;
}
}
else
{
for(k = 0 ; k < 3 ; k + + )
cosin[k] = 0 ;
}
}
}
}
}
}
printf ("\nMost compatible female mates for males:");
printf ("\n 0 means no mate");
for ( i = 0 ; i < 5 0 ; i++)
{
if (8ax[0== 'M')
{
printf ("\nMalecode no.: %d", i + 1 ) ;
printf ("\nFemale code nos.:");
printf ("%d %d %d", mcode[i][0], mcode[i][1], mcode[i][2])
}
}
printf ("\nMost compatible male mates for females:");
printf ("\n 0 means no mate") ;
for ( i = 0 ; i < 5 0 ; i++)
{
if(sex[i]== 'F')
{
printf ("\nFemale code no.: %d", i + 1 ) ;
printf ("\nMale code nos.:");
printf ("%d %d %d", fcode[0[O], fcode[i][1], fcode[i][2]);
}
}
}
Explanation
In the first for loop the sex of each applicant and their responses
to the 8 questions are received through the keyboard and stored
in arrays sex[ ] and.sum[ ]. The next for loop is the most
important part of this program. It finds out three most com-
A Tryst with Arrays 327
patible females for each male and stores their code numbers in
the array mcode[ ][ ]. Similarly, it finds the three most com-
patible males for each female and stores their code numbers in
the array fcodef ][ ]. While calculating the most compatible
males for a female ( or vice versa ) the difference of the
responses are used, with a basis that larger the cosine value
more compatible is the couple. Finally, through a set of for
loops the three most compatible females for each male ( and
vice versa ) are printed out.
(6) Program
#include "conio.h"
int a[81];
main()
{
int sr = 5, sc = 30, er, ec;
int n, num, row, col, i, j, I, k, sum = 0 ;
clrscr();
gotoxy(35,1);
er = sr + n * 2 ; /* ending row */
ec = sc + n * 3 ; /* ending column */
i = 1 ; / * top row */
j = 1 + n / 2 ; /* middle of top row*/
if (i == 0 )
i = n;
if(i==n+1)
i = 1;
if (j == 0 )
j = n;
if (j == n + 1 )
j= i;
l = (i-1)*n + (j-1);
if(i>n)
i = i- n;
if(j==0)
j = n;
}
}
for ( i = 0 ; i <= ( n * ( n - 1 ) ) ; i += n)
sum = sum + a[i];
gotoxy (sc, er + 2 ) ;
printf ("Horizontal, Vertical & Diagonal sum = %d", sum)
}
for (j = sr + 1 ; j < e r ; j + + )
{
gotoxy ( i , j ) ;
printf ("%c". 1 7 9 ) ;
}
gotoxy (sc, s r ) ;
printf ("%c", 2 1 8 ) ;
gotoxy (ec, e r ) ;
printf ("%c", 2 1 7 ) ;
A Tryst with Arrays 331
gotoxy (ec, s r ) ;
printf ("%c", 1 9 1 ) ;
gotoxy (sc, e r ) ;
printf ("%c",192);
}
Explanation
Once into the main( ), the size of the matrix and the starting
number of the series is received ihrough the pair of scanf( )s.
Depending upon the size of the square the ending row and
ending column are calculated, and using these and the starting
row and starting column, the box is constructed by calling the
drawbox() function.
4001
a
4002
g
4003
P
4004 4005
u r
4006
»1
4007
main()
static char namefj = "Nagpur";
int i = 0;
whiie(name[i]!='\0')
* printf ("%c", namep]);
i++;
K
1 i n s m
1 a n
main()
main()
{
char name[25];
scant ("%s", n a m e ) ;
printf ("%s", n a m e ) ;
Function Purpose
strlen Finds length of a string
strcpy Copies one string into another
strncpy Copies first n characters of a string at the end of
another
strlwr Converts a string to lower case
strupr Converts a string to upper case
strcmp Compares two strings
strncmp Compares first n characters of two strings
strcat Appends one string at the end of another
strncat Appends first n characters of a string at the end
of another
strstr Finds first occurrence of a given string in
another string
strrev Reverses a string
strset Sets all characters of string to a given character
1001 N a g P u r
I
1008 A g r a •r •••• •
1012
1017
D
C
e
a
1
1
h
c
i
u t
i t a
As can be observed from the figure the strings themselves are stored
at different locations but their base addresses are stored in adjacent
locations in the array of pointers names[ ]. These strings can be
accessed through the array of pointers as shown in the following
program.
main()
338 Exploring C
{
static char *names[] = {
"Nagpur",
"Agra",
"Delhi",
"Calcutta"
};
int i;
Exercise
[A] What will be the output of the following programs:
(1) main()
{
static char s[ ] = "Rendezvous!";
printf ("%d", *( s + strlen ( s ) ) ) ;
}
(2) main()
{
charch[20];
int i;
for(i = 0 ; i < 1 9 ; i + + )
*( ch + i) = 6 7 ;
*(ch + i) = \0';
I
printf ("%s", c h ) ;
(3) main()
{
char str[20];
int i;
for(i = 0 ; i < = 1 8 ; i + + )
i[str] = ' C ;
i[str] = \0';
printf ("%s", s t r ) ;
(4) main()
{
char str[20];
static int i;
for ( ; ; )
340 Exploring C
{
i++[str] = 'A' + 2 ,
if(i==19)
break;
}
i[str] = '\0';
printf ("%s", s t r ) ;
(5) main()
{
static char str[ ] = { 4 8 , 4 8 , 4 8 , 4 8 , 4 8 , 4 8 , 4 8 , 4 8 , 4 8 , 4 8 } ;
char*s;
inti;
s = str;
for ( i = 0 ; i <= 9 ; i++)
{
if(*s)
printf ("%c " , * s ) ;
s++;
}
}
(6) main(}
{
static char str[10] = { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ;
char*s;
int i;
s = str;
for (i = 0 ; i <= 9 ; i++)
{
if(*s)
printf ("%c",*s);
s++;
}
Pulling the Strings 341
(7) main()
{
static char s[ ] = "C smart!!";
inti;
for ( i = 0 ; s[i]; i++)
printf ("%c %c %c %c\n", s[i], *( s + i ) , i[s], *( i + s ) ;
}
(8) main()
{
static char s[ ] = "Oinks Grunts and Guffaws";
printf ("%c\n",*(&s[2]));
printf ("%s\n",s + 5 ) ;
printf ("%s\n",s):
printf ("%c\n",*(s + 2 ) ) ;
printf ("%d\n",s);
}
(9) main()
{
static char s[251 = T h e cocaine man";
int i = 0 ;
char c h ;
ch = s[++i];
printf ("%c%d\n", c h , i ) ;
ch = s[i++];
printf ("%c %d\n", c h , i ) ;
ch = i++[s];
printf ("%c%d\n", ch, i ) ;
ch = ++i[s] ;
printf ("%c%d\n", c h . i ) ;
}
(10) main()
{
static char arr[ ] = "Pickpocketing my peace of mind.."
342 Exploring C
inti;
printf ("%c\n",*arr);
arr++;
printf ("%c\n",*arr);
(11) main()
{
static char str[ ] = "Limericks";
char*s;
s = &str[6] - 6 ;
while (*s)
printf ("%c", * s + + ) ;
,12) main()
{
static char *s[] = {
"ice",
"green",
"cone",
"please"
};
staic char **ptr[ ] = { s + 3 , s + 2 , s + 1 , s } ;
char ***p = ptr;
printf("%s\n",.**++p);
printf("%s\n",*-*++p + 3 ) ;
printf ("%s\n", *p[-2] + 3 ) ;
printf("%s\n",p[-1][-1] + 1 ) ;
}
(13) main()
{
static char s[ ] = "C it for yourself;
int i = 0 ;
while (sp])
Pulling the Strings 343
{
if(s[i]!=")
sfjl = s(0 + 1 ;
i++;
}
printf ( " % s " , s ) ;
(14) main()
{
static char str[ ] = "For your eyes only",
int i;
char*p;
for ( p = str, i = 0 ; p + i <= str + strlen ( s t r ) ; p++, i++)
printf ("%c", *( p + i ) ) ; .
(15) main()
{
static char str[ ] = "MalayalaM";
char*s;
s = str + 8 ;
while ( s >= str)
{
printf ("%c",*s);
s~;
}
}
(16) main()
{
static char a[ ] - "Able was I ere I saw elbA";
char*t, *s, * b ;
s = a;
b = a + strlen ( a ) - 1 ;
t = b;
344 Exploring C
while ( s != t )
{
printf ("%c",*s);
s++;
printf ("%c",*t);
t-;
(17) main()
{
static char str[ ] = "Shall we tell the Deputy Director?";
printf ("%s\n%s\n%s", str, str + 6, str + 9 ) ;
}
(18) main()
{
static char s[ ] = "C is a philosophy of life";
chart[40];
char*ss, *tt;
ss = s ;
tut;.
while (*ss)
*tt++ = *ss++;
*tt = "\0';
printf ( " % s " , t ) ;
(19) main()
{
static char s( [= "Lumps, bumps, swollen veins, new pains";
chart[40];
char*ss,*tt;
tut;
ss = s ;
while (*tt++= *ss+±);
Pulling the Strings 345
printf ( " % s M ) ;
}
(20) main()
{
static char str1[] ='dills";
static char str2[20]; .
static char str3[20] = "Daffo";
inti;
I = strcmp (strcat (str3, strcpy (str2, s t r l ) ) , "Daffodills")
printf ("I = % d " , l ) ;
(21) main()
{
static int arr[12];
printf ("%(T, sizeof ( a r r ) ) - ;
}
(22) main()
{
static char *mess[] = {
"Some love one",
"Some love two",
"I love one",
"That is you"
};
printf ("%d %d", sizeof (mess), sizeof (mess [ 1 ] ) ) ;
}
(23) main()
{
char names[3][20];
inti;
for ( i = 0 ; i <= 2 ; i++)
{
346 Exploring C
(24) main()
{
static char names[5][20] = {
"Roshni",
"Manish",
"Mona",
"Baiju",
"Ritu"
};
int i;
char*t;
i = r,ames[3];
names[3] = names[4];
names[4] = t ;
for ( i = 0 ; i <= 4 ; i++)
printf ("%s\n", namesp]);
}
(25) main()
{
static char mess[6][30] = {
"Don't walk in front of me
"I may not follow;",
"Don't walk behind me..."
"I may not lead;",
"Just walk beside me...",
"And be my friend."
};
printf ("%c %c", *( mess[2] + 9 ) , *( *( mess + 2 ) + 9 ) ) ;
}
Pulling the Strings 347
(26) main()
{
static char mess[2][2][20] = {
{
"A chink in your armour",
"A voice in your mailbox"
}.
{
"Afoot in your tooth",
"A hole in your pocket"
}
};
printf ("%s\n%s", mess[1][0], mess[0][1]);
}
(1) Write a function xstrstr() that will return the position where
one string is present within another string. If the second string
doesn't occur in the first string xstrstr() should return a 0.
(2) Write a program to encode the following string such that it gets
converted into an unrecognizable form. Also write a decode
function to get back the original string.
static char*str[] = {
"AFRiendls...",
"SomEOne Loving AtrUE...",
348 Exploring C
static char*s[] = {
"MalayalaM",
"To really mess things up...",
"One needs to know CH"
"able was I ere I saw elba"
};
(5) Write a program to compress the following string such that the
the multiple blanks are eliminated. Store the compressed mes-
sage in another string. Also write a decompressant program to
get back the original string with all its spaces restored.
Answers
Answers to [A]
(1) Output
Explanation
(2) Output
CCCCCCCCCCCCCCCCCCC
Explanation
Mentioning the name of the array always gives its base address.
Therefore ( ch + i ) would give the address of the i element
th
loop we store 67, which is the ascii value of upper case ' C , in
all the locations of the string. Once the control reaches outside
th
the for loop the value of i would be 19, and in the 19 location
from the base address we store a '\0' to mark the end of the
350 Exploring C
(3) Output
CCCCCCCCCCCCCCCCCCC
Explanation
str[U
*( str + i)
*( i + str)
i[str]
Hence, through the for loop upper case C is stored in all the
elements of the string. A '\0' is stored to mark the end of the
string, and then the string is printed out using printf().
(4) Output
CCCCCCCCCCCCCCCCCCC
f
Pulling the Strings 351
Explanation
Here, the structure of,the for loop has been reduced to only 2
semi-colons. We can afford to do so because all the three tasks
(initialisation, testing and incrementation ) of the for are being
accomplished by three different statements in the program:
declaring i as a static int ensures that i is initialised to 0, the if
condition tests when to get out of the loop, and i++ takes care
of the incrementation part.
18, and each time 'A' + 2 is stored in the string elements. Can
we add a character and an integer? Yes, as any character is
stored as its corresponding ascii value. The ascii value of 'A'
is 65, and on adding 2 to this we get 67, which happens to be
the ascii value of ' C . Thus, upper case ' C is stored in elements
0 to 18 of the string. When i becomes 19, break takes the
control out of the for loop, where a '\0' is inserted in the string
to mark its end. The string is then printed out using printf().
(5) Output
0000000000
Explanation
(6) Output
No output
Explanation
(7) Output
CCCC
Pulling the Strings 353
ssss
mmmm
aaaa
rrrr
tttt
!!!!
Explanation
The above program rubs in the point that s[i], i[s], *( s + i ) and
*( i + s ) are various ways of referring to the same element, that
is the i element of the string s. Each element of the string is
th
printed out four times, till the end of the string is encountered.
Note that in the for loop there is an expression s[i] in the
condition part. This means the loop would continue to get
executed till s[i] is not equal to zero. We can afford to say this
because a string always ends with a ' \ 0 ' , whose ascii value is
0. Thus the for loop will be terminated when the expression
s[i] yields a ' \ 0 ' .
(8) Output
n
Grunts and Guffaws
Oinks Grunts and Guffaws
n
404
Explanation
The third printf() prints the entire string, as the base address
of the string is being passed to it.
(9) Output
hi
h2
e3
! 3
Explanation
(10) Output
Explanation
(11) Output
Limericks
Explanation
strf]
L i m e r i c k s . 1
4001 4002 4003 4004 4005 4006 4007 4008 4009 4010
s s
Figure, 9.5
(12) Output
cone
ase
reen
Explanation
Figure 9.6
*++p
The first one prints out the string starting from the address
**++p. The ++ goes to work first and increments p not to 6021,
but to 6022. The C compiler has been made to understand that
on incrementing a pointer variable, it is to point to the next
location of its iype. The words 'of its type' hold significance
here. A pointer to a char on incrementing goes one byte further,
since a char is a 1-byte entity. A pointer to an int points 2 bytes
further, as an int is a 2-byte entity. Also, a pointer by itself is
Pulling the Strings 359
*-*++p + 3
*p[-2] + 3
PM1M1 + 1
(13) Output
D ju gps zpvstfmg
Explanation
No, your computer hasn't caught a virus! It has done just what
you instructed it to. The while loop tests the value of the I t h
(14) Output
FryuysoJ<space>
Explanation
strTl
F o r y o u r e y e s o n 1 y \0J
4001
4001 |
Figure 9.7
The for loop here hosts two initialisations and two incremen-
tations, which is perfectly acceptable. However, there must
always be a unique test condition.
Since length of str[ ] is 18, str + strlen (str ) would give the
address of '\0' present at the end of the string. If we assume
that the base address of the string is 4001, then the address of
'\0' would be 4019. Since p has been assigned the base address
of the string, in the first go, p + 0 would yield 4001. Since this
362 Exploring C
is less than 4019, the condition holds good, and the character
present at the address ( p + 0 ) , i.e. ' F ' , is printed out. This can
be understood better with the aid of the Figure 9.7.
(15) Output
MalayalaM
Explanation
This way one by one, the elements of the string are printed out
in the reverse order, till s equals str, the address of the zeroth
element. That the output is indeed the reverse of the original
string can be verified if you read "MalayalaM" backwards. You
have been presented with a string that reads the same from
either end. Such strings, incidentally, go by the name
'Palindrome'.
(16) Output
AAbbllee waass II ee
Explanation
Naturally, first time through the while loop since s and t are
not equal, the condition is satisfied. Hence the printf() prints
out the character at which s is pointing. Thus the character 'A'
gets printed. Now s is incremented, so that it points to the
character ' b ' . The next printf() prints the value at the address
contained in t. Therefore another 'A' appears on the screen.
After printing, t is decremented so that it starts pointing to V .
This goes on till s and t meet each other, whence the while
364 Exploring C
ends. At this instance, s and tboth are pointing to 'r', the middle
character of the entire string.
(17) Output
Explanation
(18) Output
C is a philosophy of life
Explanation
the variables, so after ' C has been stored in the first location
of the string t[ ], both ss and tt are incremented, so that both
now point to the first elements of s[ ] and t[ ] respectively. In
the second go, value at the address contained in ss is tested in
the while, and this time a blank is encountered, whose ascii
value is 32. The condition again holds good, therefore the blank
is stored in string t[ ], and ss and tt are incremented. This goes
on till the end of the string is encountered. At the end of any
string, a '\0' is stored. Ascii value of '\0' is 0, which when
tested in the while, evaluates to falsity, and the control comes
out of the loop.
Note that the '\0' has not been stored into string t[ ], hence the
compiler does not know where the string ends. We do so by
inserting a '\0' on leaving the while. Finally, the contents of
the string t[ ] are printed out.
(19) Output
Explanation
(20) Output
1=0
Explanation
(21) Output
24
Explanation
(22) Output
368 Exploring C
82
Explanation
(23) Output
Explanation
Let the base address of the 2-D array, i.e. names be 4001. In
the scanf() and printf() statements, names[i] refers to the
address of the i* string in the array. names[0] refers to the
zeroth element of the 2-D array, or the base address of the string
of characters starting from 4001. names [1] denotes the address
of the first element of the 2-D array, which is 20 bytes ahead,
i.e. 4021, and so on.
Assured that names [i] stands for the base address of the i th
The first time through the for loop, when you are prompted
"ENTER NAME:", say you entered 'Parag'. The scanf( )
accepts this name and stores it at the address given by
names[0]. The printf( ) immediately reads from the same
address name[0], and prints the name starting at this address
on to the screen. This is repeated by incrementing the value of
i each time through the loop. When i is incremented for the
third time, the process is terminated.
(24) Output
Explanation
(25) Output
kk
Explanation
Recall that mess [2] would give the base address of the second
string. If this address turns out to be 4001, then the expression
mess [2] + 9 would become ( 4001 + 9 ), which would give the
address of the ninth character from the address 4001. This
address happens to be the address of the letter 'k' in the string
"Don't walk behind me". Hepce this letter 'k' can be accessed
by the expression *( mess[2] +9). But we already know that
whenever we use the notation mess[2], it is internally con-
verted to *( mess + 2 ) by the compiler. Therefore *( mess[2]
+ 9 ) can also be expressed as *( *( mess + 2 ) + 9 ) .
(26) Output
Explanation
Solutions to [B]
(1) Program
main()
{
static char strl [ ] = "somewhere over the rainbow";
static char str2[ ] = "over";
xstrstr ( s 1 , s 2 )
char*s1,*s2;
{
int i, a, Ien1, Ien2;
372 Exploring C
Ien1 = strlen ( s 1 ) ;
Ien2 = strlen ( s 2 ) ;
if ( a == 0 )
return ( i + 1 ) ;
}
return ( 0 ) ;
}
Sample run
String found at 11
Explanation
Suppose the second string is not present in the first string at all,
then at no time a would contain 0. Thus the return statement
within the for loop would never get executed. In such cases the
return statement after the loop would return 0, signifying that
the second string was not found in the first one.
(2) Program
main()
{
static unsigned char s1 [ ] =" "Man's reach must always \
exceed his grasp.... or what is the heaven for?";
printf ("%s", s 1 ) ;
codestr(s1, s 2 ) ;
printf ( \n%s",s2);
B
decodestr (s2, s 3 ) ;
printf ("\n%s",s3);
}
codestr (s, t)
374 Exploring C
decodestr (s, t )
unsigned char *s, * t ;
{
while (*s)
{
*t = * s - 1 2 7 ;
t++;
s++;
}
*U0;
Sample run
Man's reach must always exceed his grasp.... or what is the heaven
for?
[ graphic characters ]
Man's reach must always exceed his grasp.... or what is the heaven
for?
Pulling the Strings 375
Explanation
In both functions, the while loop tests for the end of the source
string. In codestr(), each character of the source string is given
an offset of 127, and then stored in the target string. If you refer
to the ascii chart in the appendix, you'll find that values 127
onwards correspond to graphic characters. By adding 127 to
any character, we transform the same into some graphic sym-
bol . In this manner, the whole string is transformed into a group
of graphic characters, which you'll appreciate would certainly
be unreadable!
(3) Program
main()
{
static char *str[] = {
"AFRiendiS...",
"SomEOne Loving &trUE...",
"fOr insTance somEONE....",
"exactlYHkEyoU!!"
};
capcount (s, c)
char * * s ;
intc;
{
int i, cap = 0 ;
char *t;
while (*t)
{
i f ( * t > = 6 5 & & * t < = 90)
cap + + ;
t++;
}
}
return ( c a p ) ;
}
Sample run
No. of capitals = 19
Explanation
string is stored in t, the while loop scans the entire string for a
capital letter until t reaches the end of string. Each time the
condition evaluates to true the variable cap, which counts the
number of capital letters, is incremented. Subsequently, the ++
operator increments t, so that it points to the next character in
the string.
(4) Program
main()
{
static char *s[] = {
"MalayalaM",
"to really mess things up...",
"one needs to know CH",
"able was I ere I saw elba"
};
char rev[30];
int i, a ;
if ( a == 0 )
printf ("%s\n",s[i));
}
Sample run
MalayalaM
Explanation
Astring is said to be a 'palindrome' if on reversing it you again
end up with the original string. For instance, 'MalayalaM' on
reversing gives 'MalayalaM' itself.
Our program makes use of the following standard library string
functions:
If s and t are the base addresses of source and target strings
respectively, then the functions work as follows:
to 3. The first time, s[0] provides the base address of the first
string, "MalayalaM", and rev, that of the target string. After
copying "MalayalaM" into rev[ ], rev[ ] is reversed using
strrev(). Now rev[ ] contains the reversed string while the
original string is intact at s[Q. We compare the two strings
making use of strcmp( ), and receive the returned value in the
variable a. a is assigned a value 0 if the string is indeed a
Palindrome. If so, the corresponding string is printed out.
(5) Program
main()
{
static unsigned char strl [] = "Imperial Palace. Rome.
Attention Julius Caesar. Dear Caesar, we have the clarifica-
tion you requested. Details to follow by courier. Meanwhile stay
clear of Brutus.";
printf ("%s\n", s t r l ) ;
compress (str1,str2) ;
printf ("%s\n",str2);
compress (s, t )
unsigned char *s, *t ;
{
int spcount;
while (*s)
{
380 Exploring C
if(*s==")
{
spcount = 1 ;
s++;
while ( * s = = " )
{
spcount++;
s++;
if (spcount = = 1 0 )
{
*t = 2 3 ;
t++;
spcount = 0 ;
}
}-
if (spcount)
{
if (spcount == 1)
{
*t = * s + 127;
s++;
}
else
*t = 13 + spcount;
t++;
}
}
else
{
*t = * s ;
t++;
s++; -
}
}
*t = 0 ;
Pulling the Strings 381
decompress (s, t )
unsigned char *s, * t ;
{
inti;
while ( * s )
{
if (*s >= 127)
{
*t = " ;
t++;
*t = * s - 1 2 7 ;
t++;
}
else
{
if ( * s > 1 3 & & * s < 2 4 )
{
for ( i = 0 ; i< ( * s - 1 3 ) ;i++)
{
*t = " ;
t++;
}
}
else
{
*t = * s ;
t++;
}
}
s++;
}
*t = 0 ;
}
Explanation
382 Exploring C
main()
{
struct account
{
int no;
char acc_name[15];
float bal;
}r
struct account a1, a2, a 3 ;
375 S a m e e r \0 1234.55 |
4001 4003 4018
An Array of Structures
In the above example if we were to store data of 100 accounts, we
would be required to use 100 different structure variables from a l to
alOO, which is definitely not very convenient. A better approach
would be to use an array of structures. The following program shows
how to use an array of structures.
main()
{
struct employee
{
int no;
float bal;
};
struct employee a[10];
int i;
(a) The declaration of structure type and the structure variable can
be combined in one statement. For example,
struct player
{
char name[20];
int age;
};
is same as...
struct player
{
char name[20];
int age;
}p1 = { "Nick Yates", 3 0 } ;
or even...
struct
{
388 Exploring C
char name[20];
int age;
}p1 = { "Nick Yates", 3 0 } ;
struct player
{
char name[20];
int age;
};
struct player p2, p1 = {"Nick Yates", 3 0 } ;
P2 = p1;
struct part
{
char type;
intqty;
};
struct vehicle
{
char maruti[20];
struct part bolt;
};
struct vehicle v ;
v.bolt.qty = 3 0 0 ;
(d) Like an ordinary variable, a structure variable can also be
passed to a function. We may either pass individual structure
elements or the entire structure at one go. If need be we can
Structures and Unions 389
struct player
{
char nam[20];
int age;
};
struct player p1 = {"Nick Yates", 3 0 } ;
struct book
{
char name[25];
int callno;
};
struct book b1 = {"let us C", "C.Iyer", 101};
. struct book *b2;
printf ("%s%d\n", bl.name, b1.callno);
b2 = & b 1 ;
printf ("%s %d", b2->name, b2->callno);
Unions
main()
{
union demo
{
inti;
char ch[2];
};
union demo a ;
a.i = 5 1 2 ;
printf ("a.i = %d\n", a i ) ;
printf ("a.ch[0] = %d\n", a.ch[0]);
printf ("a.ch[1] = %d",a.ch[1]);
}
a i = 512
a.ch[0] = 0
a.ch[1] = 2
Note that the declaration of the datatype union and the union variable
a is just like the way it is done for structures. So is the accessing of
the elements of the union using dot operators. But the analogy ends
here, as the following figure illustrates.
« a.i •
••—a.ch{0]—H a.ch[l] —
OOOOOOOO 00000010 |
Figure 10.3
Structures and Unions 391
Where a structure would have employed a total of four bytes for a.i
and a.ch[ ], the union engages only two bytes. The same two bytes
which comprise a.i also comprise the array a.ch[ ]. Hence, we can
access the two bytes together by mentioning a.i, or individually by
mentioning a.ch[0] and a.ch[l].
On assigning 512 to a.i, the binary equivalent of 512, i.e. 0000 0010
0000 0000 is what is actually stored in the two bytes of the int. Of
the 16 bit number, first the lower 8 bits are stored in ch[0], and next
the higher 8 bits are assigned to ch[l]. Taken bytewise, a.ch[0]
contains decimal 0, and a.ch[l] contains decimal 2.
This datatype proves very useful while interacting with the hardware
of the computer, which lies beyond the scope of this book.
392 Exploring C
Exercise
[A] What will be the output of the following programs:
(1) main()
{
struct employee
{
char name[25];
int age;
float bs;
}
struct employee e ;
e.name = "Hacker" ;
e.age = 2 5 ;
printf ("%s %d", e.name, e.age);
(2) main()
{
struct
{
char name[25];
charlanguage[10].
}a;
staticstructa = {"Hacker","C"};
printf ("%s %s", aname, alanguage);
{
static struct v[0] = {"Yankee Doodle", 1813};
static struct v[1] = {"Dark Avenger", 1795};
int i;
(4) struct s
{
char c h ;
int i;
float a ;
};
main()
{
static struct s var = { ' C , 100,12.55}
f(var);
g(&var);
} .
f(v)
struct s v ;
{
printf ("%c %d %f, v->ch, v->i, v - > a ) ;
}
9(v)
struct s \ ;
{
printf ("%c %d %f, v.ch, v.i, v . a ) ;
}
(5) main()
{
static char strl [ ] = "Ransacked";
394 Exploring C
char str2[20];
struct word
{
char str[20];
};•
strcpy (str2, s t r l ) ;
s2 = s 1 ;
,in()
{
struct
{
int num;
float f;
char mess[50];
m.num = 1 ;
m.f = 3 1 4 ;
strcpy (m.mess, "Everything looks rosy");
(7) main()
{
char name[20];
int age;
struct address
{
char city[20] ;
long int pin;
}a;
(9) main()
{
struct a
{
char ch[7];
char*str;
};
(10) main()
{
struct a
{
char ch[7];
char *str;
};
struct b
{
char*-c;
struct a s s 1 ;
};
(11) main()
{
struct s1
{
char*z;
inti;
struct s1 * p ;
}; ..
static struct s1 a[] = {
{"Nagpur", 1 , a + 1 } ,
{"Raipur", 2, a + 2},
{"Kanpur", 3, a }
};
Structures and Unions 397
struct s1 *ptr = a ;
printf ("%s %s %s\n", a[0].z, ptr->z, a[2].p->z);
}
(12) main()
{
struct s1
{
char*str;
int i;
struct s1 *ptr;
};
static struct s1 a[] = {
{"Nagpur", 1 , a + 1 } ,
{"Raipur",2,a + 2},
{"Kanpur",3,a}
};
struct s1 *p = a ;
intj;
(13) main()
{
struct s1
{
char * z ;
int i;
struct s1 * p ;
};
static struct s1 a[ ] = {
{"Nagpur", 1 , a + 1 } ,
398 Exploring C
{"Raipur", 2, a + 2},
{"Kanpur", 3, a }
};
struct s1 *ptr = a ;
(14) main()
{
struct s1
{
char-*str;
struct s1 *ptr;
};
static struct s1 arr[] = {
{"Nikhil", arr+1},
{"Aditya", arr+2},
{"Sudheer",arr}
};
struct s1 *p[3];
inti;
(15) struct s1
{
char *str;
Structures and Unions 399
struct s1 *next;
};
main()
{
static struct s1 arr[] = {
{"Akhil", arr+1},
{"Nikhil", arr+2},
{"Anant", arr}
};
struct s1 *p[3];
inti;
swap (*p, a r r ) ;
swap(p[0], p[0]->next);
printf ("\n%s",p[0]->str);
printf ("\n%s",(*++p[0]).str);
printf ("\n%s", ++(*++( *p )->next ).str);
swap(p1,p2)
struct s1 *p1,*p2;
{
char *temp;
temp = p1->str;
400 Exploring C
p1->str = p2->str;
p2->str = temp;
}
(16) main()
{
struct node
{
int data;
struct node *link;
};
struct node*p,*q-r
.(17) #defineNULLO
main()
{
struct node
. {
int data;
struct node *link;
};
struct node *p, * q ;
p->data = 3 0 ;
p->link = q ;
q->data = 4 0 ;
q->link = NULL;
Structures-andrUnions 401
printf ("%d",p->data);
p = p->link;
printf ("%d",p->data);
(18) #defineNULLO
main()
{
struct node
{
struct node *previous;
int data;
struct node *next;
}
struct node *p, * q ;
p->data = 7 5 ;
q->data = 9 0 ;
p->previous = NULL;
p->next = q ;
q->previous = p;
q->next = NULL;
while ( p ! = NULL)
{
printf ("%d\n", p->data);
p = p->next;
}
(19) #defineNULL0
main()
402 Exploring C
{
struct node
{
int data;
struct node *next ;
};
struct node *p, * q ;
p->data = 10;
q->data = 20;
p->next = q;
q->next = p;
while ( p ! = NULL)
{
printf ("%d\n", p->data);
p = p->next:
}
(20) main()
{
struct a
{
int i;
char ch[2];
};
union b
{
int i;
char c[2];
};
printf ("%d", sizeof (struct a ) ) ;
printf ("%d", sizeof (union b ) ) ;
Structures and Unions 403
(21) main()
{
union a
{
inti;
char ch[2];
};
union a u;
u.i = 2 5 6 ;
printf ("%d%d%d", u.i, u.ch[0I, uch[1]) ;
}
(22) main()
{
struct a
{
long int i;
char ch[4];
};
struct a s ;
s.i = 512;
printf ("%d %d %d", s.ch[0], s.ch[1], s.ch(3]);
}
(23) main()
{
union a
{
inti;
char ch[2];
};
union a u;
404 Exploring C
u.ch[0] = 3 ;
u.ch[1] = 2 ;
printf ("%d %d %d", u.ch[0], u.ch[1], u.i);
(24) main()
{
struct a
int i;
intj;
/ i
struct b
charx;
chary[3];
J J
union c
struct a a a ;
struct b bb;
union c u;
u.aa.i = 512;
u.aaj = 512;
(25) main()
{
struct a
{
int i;
Structures and Unions 405
intj;
J t
struct b
charx;
chary;
J»
union c
struct a a a ;
struct b bb;
union c u;
u.aa.i = 256;
u.aaj = 512;
(26) main()
{
union
{
unsigned long I;
unsigned int d[2];
char ch[4];
}a;
strcpy (a.ch, "ABC");
printf ("%s\n", a c h ) ;
. printf ("%u %u\n", ad[0], a.d[1]);
printf ("%lu", a l ) ;
}
406 Exploring C
Answers
Answers to [A]
(1) Output
Explanation
(2) Output
Explanation
(3) Output
Explanation
(4) Output
Explanation
The function f(), called from main(), is sent the struct variable
var, which is collected in v. The printf() in f ( ) attempts to
print the structure elements using the arrow operator with v,
wherein lies the first error. On the left of the arrow operator,
there must always be a pointer to a structure. On the other hand,
function g( ) collects a pointer to a structure, which it uses in
conjunction with the dot operator. The dot operator must
always be preceded by a structure variable, never a pointer.
Hence the second error message.
(5) Output
Ransacked Ransacked
Ransacked Ransacked
408 Exploring C
Explanation
The program clearly brings out how the treatment varies for a
string and a structure. strl[ ] and sl.str are both initialised to
store "Ransacked". For copying the contents of one string to
another, we have to use the function strcpy( ). However, the
copying of structure elements is a simple affair: saying s2 = s i
does the trick. For printing strings, only the name of the string
needs to be mentioned, while for accessing the structure ele-
ments the dot operator should be used.
(6) Output
1401 14031407
Explanation
In the elements num and f of the structure, 1 and 3.14 are
stored. For assigning contents to the third element of the
structure, i.e. the array mess[ ], strcpy( ), the string copy
function is used. Why use a string function for this? Could we
not have said:
(7) Output
abhijeet nagpur
Explanation
(8) Output
100410141016
102010301032
410 Exploring C
Explanation
(9) Output
NB
Nagpur Bombay
Explanation
struct a comprises of char array ch[ ] and a char pointer str.
si, a variable of type struct a, is initialised next. Here "Nagpur"
gets stored in the array ch[ ], and "Bombay" gets stored starting
from the address contained in str.
As this array has been assigned the string "Nagpur", the first
character ' N ' is printed out.
(10) Output
Raipur Jaipur
aipuraipur
Explanation
Coming to the printf( )s now, the first one is supplied s2.c and
s2.ssl.str. s2.c gives the base address of "Raipur", and
s2.ssl.str gives the base address of "Jaipur". Since these base
addresses are passed to printf( ),it promptly prints out the two
strings.
(11) Output
Explanation
Figure 10.4
(12) Output
0 agpur
1 aipur
2anpur
Explanation
(13) Output
Structures and Unions 415
agpur
Kanpur
Kanpur
Explanation
| 4000 |
Notes:
- AO denotes address from where "Nagpur" is stored.
- A I denotes address from where "Raipur" is stored.
- A2 denotes address from where "Kanpur" is stored.
Figure 10.5
++(ptr->z)
a[(++ptr)->i ].z
416 Exploring C
a[--(ptr->p->i)].z
(14) Output
Structures andUnions 417
Aditya
Aditya
Aditya
Explanation
struct si c o m p r i s e s o f 2 p o i n t e r s ; o n e a char p o i n t e r a n d
t u r e s , i s d e c l a r e d a n d i n i t i a l i s e d . N e x t , a n a r r a y o f p o i n t e r s t o
s t r u c t u r e s , p[3] i s d e c l a r e d . W h a t t h i s m e a n s i s t h a t e a c h
e l e m e n t o f a r r a y o f p[ ] w i l l h o l d t h e a d d r e s s o f a s t r u c t u r e o f
t h e t y p e struct si.
t u r e s . arr[0].ptr c o n t a i n s t h e a d d r e s s 4 0 0 4 a s p e r t h e f i g u r e
g i v e n b e l o w . L i k e w i s e , p[l] i s a s s i g n e d t h e a d d r e s s 4 0 0 8 a n d
p[2], t h e a d d r e s s 4 0 0 0 .
a r r [ 0 ] . s t r a r r [ 0 ] . p t r a r r [ l ] . s t r a r r [ l ] . p t r a r r [ 2 ] . s t r a r r [ 2 ] . p t r
A O 4 0 0 4 A I 4 0 0 8 A 2 4 0 0 0 |
4 0 0 0 4 0 0 2 4 0 0 4 4 0 0 6 4 0 0 8 4 0 1 0
P [ 0 ] P [ l ] P [ 2 ]
4 0 0 4 4 0 0 8 4 0 0 0
6 0 1 8 6 0 2 0 6 0 2 2
N o t e s :
- A O d e n o t e s a d d r e s s f r o m w h e r e " N i k h i i " i s s t o r e d .
- A I d e n o t e s a d d r e s s f r o m w h e r e " A d i t y a " i s s t o r e d .
- A 2 d e n o t e s a d d r e s s f r o m w h e r e " S u d h e e r " i s s t o r e d .
F i g u r e 1 0 . 6
418 Exploring C
Following this, the printf( )s get executed. In the first one, the
string at p[0]->str is printed. As p[0] is equal to 4004, the
expression refers to the element str of the first structure, which
stores A l , the starting address of "Aditya". Hence the name
"Aditya" gets printed for the first time.
(15) Output
Explanation
Figure 10.7
vice versa. The current contents of the array arr[ ] are now
changed to:
{
{"Nikhil", arr + 1 } ,
{"Akhil", arr + 2},
{"Anant", arr}
}
{
{"Nikhil", a r r + 1 } ,
{"Anant", arr+ 2},
{"Akhil", arr}
}
With this changed array, let's look at the last set of printf( )s.
The first of these is quite simple. p[0]->str, i.e. 4004->str
yields "Anant" in keeping with the latest contents of the array.
(16) Output
22
Explanation
The struct node engages two bytes for data and two for link,
hence the size of struct node is 4. Therefore when the calls to
422 Exploring C
(17) Output
3040
Explanation
Figure 10.8
(18) Output
75
90
Explanation
node •{ \* node
0 75 1 *
90 0
•"
4002 4004 4006 5002 5004 5006
p q
Figure 10.9
(19) Output
10
20
10
20
10
20
Structures and Unions 425
Explanation
P q
4002 | 5002 1
Figure 10.10
The while checks the contents of p for its execution. The first
time since the condition is satisfied, p->data, which is 10, gets
printed. Now p is assigned p->next, which is 5002. Thus p
now points to the second structure. Hence the condition in
while gets satisfied, and so this time p->data yields 20. After
this p is assigned the value of p->next. Since p right now
contains 5002, p- >next this time turns out to be 4002 ( refer
figure ). Thus p is assigned the address 4002, and p now points
to the first structure. The integer data within the first structure
stores 10, which again gets printed when the printf( ) is
executed. Once again the address 5002 is assigned to p through
the statement p = p->next. Thus contents of p toggle between
426 Exploring C
(20) Output
42
Explanation
(21) Output
256 0 1
Explanation
u.i
u x h [ 0 ] - + - u.ch[l]—
00000000 00000001
4501 4502
Figure 10.11
(22) Output
1224 74
Explanation
(23) Output
32515
Explanation
428 Exploring C
« U.1 *
.-u.ch[0]-*t — u.ch[l]-v
00000011 00000010 I
6450 6451
Figure 10.12
(24) Output
0202
u.aa.i - + u.aa.j
u.bb.x —4r- u.bb.y[0]H— u.bb.y[l] -f-u.bb.y[2jH
00000000 00000010 0000 0000 00000010 |
Figure 10.13
(25) Output
256 5 1 2 0 1
Explanation
u.aa.i- u.aa.j
\*— u.bb.x —4*~" u-bb.y —»|
00000000 00000001 00000000 00000010
6501 6502 6503 6504
Figure 10.14
u.aa.i is assigned 256, i.e. binary 0000 0001 0000 0000, and
u.aa.j, 512, i.e. binary 0000 0010 0000 0000. In keeping with
the rule that the lower byte is stored first, 256 actually gets
stored as 0000 0000 0000 0001, and 512 as 0000 OOtO 0000
0010. The first printf( ) is straight forward. It prints out the
two integers 256 and 512. In the second printf(), u.bb.x and
430 Exploring C
(26) Output
ABC
16961 67
4407873
Explanation
a.d[0] refers to the first 2 bytes of the union and a.d[l] to the
next 2. Since the ascii values of ' A ' and ' B ' are 65 and 66
respectively, the first 2 bytes contain 65 and 66 in that order.
Taken as an int, the number in a.d[0] is the binary equivalent
of 66 and 65 taken as a whole, as in an int the lower byte gets
stored first. Binary equivalent of 66 is 0100 0010, and that of
65 is 0100 0001. So when a.d[0] is printed out using %u, the
decimal equivalent of binary 0100 0010 0100 0001,16961 is
displayed. Similarly, while printing out a.d[l], the next two
bytes containing ' C ( decimal 67 or binary 0100 0011 ) and
'\0' ( decimal 0 or binary 0000 0000 ) are used. Hence the
printf( ) outputs 67, which is the decimal equivalent of 0000
0000 01000011.
Structures and Unions 431
Figure 10.15
The following sections deal with each of these categories one by one.
The printf( ) allows us to format the output as we wish with the use
of optional specifiers in the conversion specifications. For example,
saying %10d in a conversion specification would ensure that the
integer value is printed so that it is right aligned in a total of 10
columns, padding the empty columns, if any, on the left of the number
with blank spaces. Similarly, using %-8.2f would mean that the float
value is to have a total field width of 8 columns, and that it shouldbe
printed upto 2 decimal places. The minus sign indicates that within
the 8 columns the float value should be left aligned.
INPUT
Datatype Function Purpose
char getch() Gets a character from the keyboard
as soon as it is typed, no need to hit
Enter
getche() Similar to getch(), except echoes
the character on the screen
fgetchar() Gets the character and echoes it on
the screen, requires Enter key to be
hit
getchar() A macro, works similar to
fgetchar()
string gets() Accepts a string until Enter key is
hit
, .
OUTPUT
Datatype Function Purpose
char pu4ch() Prints the character on the screen.
fputchar( ) Prints the character on the screen.
putchar( ) A macro, works similar to putch()
and fputcharQ.
string puts() Outputs a string to the screen.
We now come to how I/O is tackled with disks. Disk I/O is performed
on entities called files. Accessing the disk every time a read or write
operation is to be performed would be inefficient. Hence a buffer is
used to hold the data in transit to and from a file. In a buffered read
operation from a disk file, a fixed chunk of bytes is read from the disk
into a buffer. The functions requesting data from the file actually read
from the buffer. When the buffer has no characters left, it is automat-
ically refilled by a disk read operation. A similar sequence occurs
when writing to a file. The use of a buffer thus leads to efficient I/O
on disk files because there are fewer disk accesses, which are much
slower than reading from a buffer in memory. The Disk I/O functions
are either High Level ( also called standard I/O or stream I/O) or Low
Level ( or system I/O ). The basic difference between them is that in
the high level functions the buffer management is done by the
functions themselves, whereas in low level functions this is the
responsibility of the programmer.
438 Exploring C
There are a large number of functions available for Disk I/O. The
following figure gives a ready reference of these with respect to the
datatypes they handle.
The files that are to be accessed for I/O must first be opened. The
function fopen() is used to open a file in high level Disk l/0,whereas
the function open() is used in low level Disk I/O. Let us first look at
fopen(). Its syntax is:
H
a+7"ab+" Reading existing contents, ***
appending new contents at
the end offile, cannot
modify existing contents
For opening files for low level I/O a function called open() is used.
Like fopen( ) it takes as its argument the filename and the mode in
which the file is to be opened. The file opening mode is however
specified using the O-flags defined in the file "fcntl.h". Thes< O-flags
are shown in the Figure 11.5. What if we intend to open i file for
reading in binary mode? In such a case we have to com! ine the
O-flags using bitwise | operator. This operator is dealt with in detail
in Chapter 12. The open( ) statement would look like:
440 Exploring C
open ("temp.dat", O R E A D | O B I N A R Y ) ;
Mode Operation
0 . .APPEND Opens a file for appending
0. CREAT Creates a new file for writing
( has no effect if file already
exists )
0_ RDONLY Creates a new file for reading
only
0 . RDWR Creates file for both reading
and writing
0 . .WRONLY Creates file for writing only
0 . BINARY Creates file in binary mode
0 . .TEXT Creates file in text mode
Once the files have been opened we may want to access the specific
part of the file. This is done by positioning the file pointer at the
desired position in the file. This can be achieved through functions
rewind() and fseek(). rewind() positions the file pointer right at
the beginning of the file. fseek() in that sense is more versatile, since
it can place the file pointer virtually anywhere in the file. Its general
form is:
Having opened the files, worked with them, we need to close them
before exiting from the program. The function fclose( j does this for
high level disk I/O, whereas the same is managed through close() for
low level disk I/O.
There are some standard file pointers that do not require the use of
fopen( ). These correspond to devices like the keyboard and the
display monitor, with which the communication is established at all
times. That is, they are permanently open for reading or writing.
These pointers are given in the following figure.
Pointer Device
stdin standard input device (keyboard)
stdout standard output device ( VDU )
stderr standard error device (VDU)
stdaux standard auxiliary device ( serial port)
stdprn standard printing device (parallel printer )
Having seen what Console and Disk I/O have/to offer, let us now turn
our attention to the Port I/O functions. With the earlier two forms of
I/O we were able to access the keyboard, the VDU and the disks.
However, they don't equip us to access peripherals like the speaker
442 Exploring C
or the serial port. For instance, for generating a sound on the IBM PC
compatible we would have to establish communication directly with
the programmable peripheral interface chip present in the computer.
In such cases Port I/O is the only option available. Thus, to beep the
speaker we write data to the port associated with the PPI chip. The
functions available under this category are given in the following
figure.
inportb() and outportb() are used for reading and writing 8 bit data
from or to the port address specified as their arguments. As against
this, inportw() and outportw() are used when we want to receive
or send two bytes of data in a single call.
Input and Output in C 443
Exercise
[A] What will be the output of the following programs:
(1) main()
{
static char str[ ] = "Academy";
printf ("%s\n%s", str, "Academy");
}
(2) main()
{
floata = 3.14;
printf C\na = %f, a ) ;
printf C\na = %6.2T, a ) ;
printf C\na = %-6.2f, a ) ;
printf ("\na = %6.1f, a ) ;
printf ("\na = %6.0f, a ) ;
}
(3) main()
{
printf ("%20s\n "short leg");
,
I
(4) main()
{
printf ("Hello\nHi\n");
printf ("HelkArHi");
}
444 Exploring C
(5) main()
{
printf ("Hello\b\b\b\b\b");
printf ("Hi!\b\b\bBye");
}
(6) main()
{
printf (-"l\tam\ta\tboy");
}
s = str;
while (*s)
{
putch(*s);
s++;
}
printf ( V ) ; -
s = str;
while (*s)
{
putchar(*s);
s++;
}
}
{
char c h ;
inti;
fflush (stdin);
>
(11) main()
{
FILE*fp;
fp = fbpen( "TRIALC", V ) ;
fclose(fp);
}
fp = fopen( "TRIALC", V ) ;
while (fgets (str, 80, fp) != EOF)
puts ( s t r ) ;
char c ;
fp = fopen(TRY.C", V ) ;
if (fp = NULL)
{
puts ("Cannot open file");
exit(1);
}
while ( ( c = g e t c ( f p ) ) ! = EOF)
putch(c);
fclose(fp);
}
fp = fopen("A.C", V ) ;
fs = fopen("B.C", "r");
ft = fopen("C.C", V ) ;
s = str;
while (*s)
{
putc(*s, stdout);
fputchar(*s);
printf ("%c\n",*s);
s++;
}
}
printf ("%s\argv[0]);
}
(21) /* Suppose this program is stored in the file PR.C and its correspond-
ing executable file PR.EXE is executed at DOS prompt by saying,
PR CAT DOG PARROT*/
main(argc, argv)
int argc;
char*argv[];
{
for ( i = 0 ; i < argc; i++)
printf ("%s\n\ argvfjl);
}
(22) main()
{
char ch = 'z';
static char str[ ] = "Zebra";
(23) #include"stdio.h"
450 Exploring C
main()
{
struct a
{
charcity[10];
int pin;
};
static struct a b = {"Udaipur", 2 0 } ;
static char c[ ] = "Bangalore';
FILE *fp;
fp = fopen( TRIAL", "wb");
fwritej&b, sizeof ( b ) , 1 , f p ) ;
fwrite(c, 9 , 1 , f p ) ;
(1) The requirement is that the program should receive a key from
the keyboard. However, the key that is hit should not appear
on the screen. Which of the following functions would you
use?
(a) getch( )
(b)getche()
(c) getchar( )
(d)fgetchar()
(a) putc( )
(b) fprintf( )
(c) fwrite( )
(a) rewind( )
(b) fseek( )
(c)ftell()
(4) Which of the following file opening modes would destroy the
file being opened, if the file already exists on the disk?
(a) V
(b) "wb"
(c) "wb+"
(d) "rb+"
n M
(e) ab+
(5) Which of the following functions are ideally suited for reading
the contents of a file record by record?
(a)getc()
(b)gets()
(c)fread()
(d)fgets()
Answers
Answers to [A]
(1) Output
Academy
Academy
Explanation
(2) Output
a = 3.140000
a = 3.14
a = 3.14
a= 3.1
a= 3
Explanation
field width, i.e. the total number of columns that the value
occupies on the screen, should be 6, and that the value should
have 2 digits after the decimal point. Thus 3.14 is printed with
blank spaces on the left, i.e. with right justification. For left
justification, we use a minus sign with the specifiers, as is done
in the next printf( ). It prints the value of a starting from the
zeroth column, with only 2 decimal digits. The specification
6.1 prints 3.1 with right justification. In the last printf( ), 6.0
specifies zero decimal digits, hence only 3 is displayed right
justified.
(3) Output
short leg
long leg
deep fine leg
backward short leg
legs all the same!
Explanation
(4) Output
Hello
Hi
Hillo
Explanation
The escape sequence '\n', called new line, takes the cursor to
the beginning of the next line. Hence with the first printf()
"Hello" and "Hi" are printed on consecutive lines. A V , on
the other hand, takes the cursor to the beginning of the same
line in which the cursor is currently present. Hence, having
printed "Hello", the cursor is sent back at 'H', and then "Hi" is
printed. The first two letters of "Hello" are therefore written
over, and we get the output as "Hillo".
Output
Byelo
Explanation
Output
I am a boy
Explanation
In our com piler, the tabs had been set up after every 5 columns,
at 0. 5, 10, etc. Hence, while executing printf(), when '\t' is
encountered, the cursor skips to the immediately next column
which is a multiple of 5, and then prints the next word. Thus
th th
"I" is printed from the 0 column, "am" from the 5 , "a" from
the 1 0 , and "boy" from the 1 5 column. Some compilers like
th
th
Turbo C allow you to change the tab settings, so that the tab
widths can be set up as desired.
(7) Output
Explanation
(8) Output
Explanation
(9) Output
Enter a sentence
Nothing succeeds like success.
Nothing
Enter a sentence
Nothing succeeds like success.
Nothing succeeds like success.
Explanation
(10) Output
Explanation
gets( ) and puts( ) cannot take more than one argument at a
time. Though no error message is displayed, whatever is typed
before hitting Enter is accepted by the first argument name[ ],
and the second argument is simply ignored. Thus name[ ]
stores the name "Jaspal Bhatti" and sname gets ignored in both
gets( ) and puts(). That this is indeed so is proved by the output
of printf( ), which prints "Jaspal Bhatti" corresponding to
contents of name[ ], and all garbage values for the string
sname[].
(11) Output
Explanation
(12) Output
No output
Explanation
(13) Output
Explanation
(14) Output
Explanation
Try opening any file using this program and the output would
1
always be the same: "Null pointer assignment '. In the if
condition, instead of comparing fp and NULL, what the single
= does is assign NULL to fp. Replacing the = with the com-
parison operator == would eliminate the bug. On removing the
bug, die program would read the file character by character till
the end of file is reached. Eaeh character read would be
displayed on the screen using the function putch( ).
(15) Output
No output
Explanation
Though you won't get any message here, what you aimed to
do has not been done. Having opened the three files through
calls to fopen(), fclose() goes to work. fclose() can close only
one file at a time. So after taking fs, the first argument in line,
it paid no attention to the remaining two. Thus only the file
"A.C" gets closed, while files ".B.C" and "C.C remain open.
For closing the three files, we must call fclose( ) three times.
If we wish to close all the files through one call, we can make
use of a function called fcloscall(). This closes all the files that
are currently open, except the standard files like stdin, stdout,
etc.
460 Exploring C
(16) Output
Explanation
(17) Output
Sandeep 1500
Sandeep 1500
Input and Output in C 461
Explanation
(18) Output
TTT
rrr
iii
PPP
III
eee
tit
Explanation
The three statements within the while loop do the same job,
i.e. to put the value at address contained in s onto the screen.
What differs is how their arguments are specified. putc(),
unlike fputchar() and printf(), allows you to specify where
the character is to be put. Here, stdout indicates the screen,
hence the output of putc() is sent to the screen. fputchar()
and printf() are programmed to write to the scrt en alone,
hence our output shows the triplets.
(19) Output
1
462 Exploring C
C:\PROBJ=XE
Explanation
(20) Output
C:\PR0B.EXE
Explanation
argc and argv are commonly used variable names assigned to
collect the command line arguments. Here we have given the
variable names as x and y, still we get the same result as with
argc and argv. Hardly surprising, as Shakespeare pointed out
ages ago, what's there in a name!
(21) Output
C:\PR.EXE
CAT
DOG
PARROT
Explanation
Input and Output in C 463
(22) Output
zZebraZebraZebra
Explanation
(23) Output
No output on screen
464 Exploring C
Explanation
Answers to [B]
(1) 00
getch( ) is the answer, as of the four it is the only one that does
not echo the typed character. The functions getche( ) and
fgetchar(), as well as the macro getchar(), all print the typed
character on the screen. getchar( ) and fgetchar( ) suffer from
one more restriction. While using them, having entered a
character, it has to be followed by hitting the Enter key. But
for these subtle differences the working of all the four func-
tions/macro is same.
(2) (c)
(3) (b)
(4) (a),(b);(c)
(5) (c)
Solutions to [C]
(1) Program
#include "stdiah"
main (argc, argv)
int argc;
char*argv[];
{
char ch1, ch2, source[30], target[30];
FILE*fs,*ft;
if (argc != 3 )
else
break;
}
}
J
else
{
putc ( c h l , f t ) ;
putc(ch2,ft);
}
}
else
putc ( c h l , f t ) ;
}
printf ("\nDone!! Press any key...") ;
getch();
fclose(fs);
fclose ( f t ) ;
}
Explanation
(2) Program
#include "stdio.h"
if (argc != 3 )
{
printf ("\nEnter source and target filenames");
scant ("%s %s", source, target);
}
else
{
strcpy (source, argv[1]);
strcpy (target, argv[2]);
}
fclose ( f s ) ;
fclose ( f t ) ;
470 Exploring C
Explanation
Bitwise Operators
c = a St b c = a|b c =a b A
Follow the figure carefully. On left shifting, all the bits are moved
one position to the left, and on right shifting, to the right, with zeroes
being placed wherever spaces are created on shifting of bits. Note
that on left shifting a once, it gets multiplied by 2, and by right shifting
b once, it gets divided by 2. Thus c stores decimal 150 and decimal
89 as a result of the operations a « 1 and b » 1 respectively.
474 Exploring C
However, this is not necessarily true always. This effect is seen only
when no significant Is are lost as a result of bit shifting.
enum rail
{
firstclass,
secondclass,
ac
};
enum rail personl, person2;
Bit^ and Pieces 475
enum rail
{
firstclass = 20,
secondclass = 30,
ac = 40
};
Typedef
Once this is done we can use the sweet and simple F wherever we
intend to use long double. While declaring variables of this type, we
can simply say,
476 Exploring C
Fa,b,c;
Typecasting
Bit Fields
which means we can pack all this information into a single integer,
since an integer is 16 bits long. How to achieve this using bit fields
is shown in the following program:
main()
{
struct num
{
unsigned a : 1;
unsigned b: 2;
unsigned c : 3;
unsigned d : 4;
};
struct num n ;
n.a = 0;
n.b = 2;
n.c = 5;
n.d = 14;
printf ("%d %d %d %d", n.a, n.b, n.c, n.d);
}
Pointers to Functions
mentioning the name of the function yields the address of the func-
tion. Thus, the statement
would print the address of the function demo(). SoTar, for invoking
a function we have used its name. The following program shows how
a pointer can be used for calling a function demo().
main(]
i
intdemoO;
int (*fpointer) ();
fpointer =demo;
(*fpointer) ():
}
(*fpointer)();
Exercise
[A] What will be the output of the following programs:
(1) main()
{
int i = 32, j = 65, k;
k = i|35;
printf ("k = %d\n",k);
k = ~k;
printf ("k = %d\n", k) ;
k=i&i;
printf ("k = %d\n",k);
}
(2) main()
(
inti = 32,j = 65, k;
A
k = j 32;
printf("k = %d\n",k);
k = j « 2;
printf ("k = %d\n", k ) ;
k = i » 5;
printf("k = %d\n",k);
}
(3) main()
{
inta = 3,b = 2,c = 1,d;
d = a|b&c,
printf ("d = %d\n",d);
d = a | b & ~c;
orintf("d = %d\n",d);
}
480 Exploring C
(4) main()
{
int a = Oxff;
if ( a « 4 » 12)
printf ("Leftist");
else
printf"("Rightist");
(5) main()
{
int a = 1 0 ;
if(a&8==8)
printf ("Bit no. 3 is on");
else
printf ("3rd bit is o f f ) ;
(6) main()
{
int a = 12, i = 0 ;
while(a»=i)
{
printf ("a = %d.i = %d\n", a, i ) ;
i++;
}
(7) main()
{
inti = + 1 ;
while (~i)
printf ("vicious circles\n");
}
(8) main()
Bits and Pieces 481
{
int a = OxaO, b = OxOa, c, d ;
c = a|b;
printf ("c = % d " , c ) ;
d=a&b;
printf ("d = %d", d ) ;
(9) main()
{
enum code
{
add,
delete,
modify,
unchanged
};
typedef enum code CODE;
CODE c, d ;
c = add;
d = modify;
printf ("c = % d d = % d " , c , d ) ;
(10) main()
{
enum status {low, medium, high};
enum status rain;
rain = 0 ;
if (rain == low)
printf ("rain = %d", rain);
(11) main()
{
enum status {low = 10, medium = 20, high = 3 0 } ;
482 Exploring C
(12) main()
{
typedef struct
{
char name[20];
int age;
}a;
aemp = {"Sunil",30};
printf ("%s %d", emp.name, emp.age);
}
(13) main()
{
struct address
{
charcity[20];
int pin;
};
typedef struct address * ADDR;
ADDR addr.;
static struct address a = {"Jodhpur", 2 0 } ;
addr = & a ;
printf ("%s %d", addr->city, addr->pin);
}
(14) mainf)
{
printf ("%f (float) ((int) l (float) ((int)6.5/2 + 3.5 \ ) - 3 . 5 ) ) ;
i
Bits and Pieces 483
(15) main()
{
struct num
{
unsigned bitO: 1 ;
unsigned b i t 1 : 1 ;
unsigned b i t 2 : 1 ;
unsigned rest: 5 ;
};
union a
{
struct num n ;
charch;
}b;
b.ch = 3 2 ;
printf ("%d %d %d %d", b.n.bitO, b.n.bitl, b.n.bit2, b.n.rest);
}
(16) main()
{
intshow();
«(*)();
f = show;
printf ("address = %d\n", f ) ;
my.
}
show()
{
printf ("Diamonds are forever");
(17) main()
{
int show();
int(*f)();
484 Exploring C
f = show;
display ( f ) ;
}
showQ
{
printf ('On the rebound...");
}
display (ff)
int(*ff)();
{
(*ff)();
}
(18) main()
{
int i,fun1(), fun2(),fun3();
int(*fl3])();
ffl)] = fun1;
f[1] = fun2;
f[2]=fun3;
for ( i = 0 ; i <= 2; i++)
fun1()
fun2()
fun3()
printf ("viruses!");
Bits and Pieces 485
Answers
Answers to [A]
(1) Output
k = 35
k = -36
k=0
Explanation
Since ints are being considered, all the operations are carried
out on 16-bit binary numbers, i stores 32, which is binary 0000
0000 0010 0000. On ORing it with 35, which is binary 0000
0000 0010 0011, each corresponding pair of bits is compared,
resulting in 1 if at least one of the pair is a 1. The result is easily
envisaged to be 35 itself.
(2) Output
k = 97
k = 260
486 Exploring C
k=1
Explanation
A
The XOR operator yields a 1 only if the 2 bits being compared
are O'and 1, else a 0 results. Thus, 65 and 32 yield 97, which is
binary 0000 0000 0110 0001.
32: 0000000000100000
» 000000000001 0000
» 0000 0000 00001000
» 0000000000000100
» 0000 00000000 0010
» 0000000000000001
(3) Output
d=3
d =3
Bits and Pieces 487
Explanation
(4) Output
Rightist
Explanation
a contains hex ff, i.e. 0000 0000 1111 1111. Firstly the left
shifting operation is carried out, changing the 16 bits to 0000
1111 1111 0000. Following this, right shift is executed 12
times, so that the latter 3 nibbles ( a set of 4 bits is a nibble )
are pushed out, and as many zeroes crop up on the left. As the
2-byte number is now 0, the if condition fails and the printf()
of the else block gets executed.
(5) Output
Bit no. 3 is on
Explanation
(6) Output
a = 12i = 0
a = 6i = 1
a =1i=2
Explanation
(7) Output
vicious circles
vicious circles
Bits and Pieces 489
Explanation
(8) Output
C= 170
d=0
Explanation
a and b are made to store hex numbers aO and 0a. These hex
numbers are nothing but binary 0000 00001010 0000 and 0000
0000 0000 1010. On ORing them bitwise, the 2-byte number
obtained is 0000 0000 1010 1010, which is decimal 170. On
ANDing them, a zero results as in the binary representations
of OxaO and 0x0a, no corresponding pair of bits happen to have
both Is. Hence the output.
(9) Output
c=0d=2
Explanation
490 Exploring C
(10) Output
r a n = 0
Explanation
(11) Output
r a n = 21
Explanation
Bits and Pieces 491
(12) Output
Sunil30
Explanation
(13) Output
Jodhpur20
Explanation
(14) Output
2.500000
Explanation
v !5) Output
0004
Explanation
Figure 12.2
(16) Output
address = 528
Diamonds are forever
Explanation
494 Exploring C
(17) Output
On the rebound...
Explanation
(18) Output
Explanation
for loop, calls are made to each of these functions making use
of their addresses. The first call results in "Hail " being out-
putted. Now, when i is 1, fuu2( ) is called, and "the " is printed.
Finally, for i equal to 2, fun3() gets called, and the printf( )
here displays "viruses!".