You are on page 1of 75

Programming in C

C Language Components
The four main components of C language are
1) The Character Set.
2) Tokens
3) Variables
4) Data Types
1) The Character Set : Character set is a set of valid characters that a language cab recognize. A character
represents any letter, digit or any other sign.
Letters - A,B,CZ or a,b,c z.
Digits - 0,19
Special Symbols - ~!@#$%^&.........
White Spaces - Blank space, horizontal tab, carriage return,
new line, form feed.
2) Tokens: The smallest individual unit in a program is known as a token.
C has five tokens
i. Keywords
ii. Identifiers
iii. Constants
iv. Punctuations
v. Operators
i. Keywords: Keywords are reserved word in C. They have predefined meaning cannot changed. All keywords
must be written in lowercase. Eg:- auto,long,char,short etc.
ii. Identifiers: - Identifiers refer to the names of variable, functions and arrays. These are user-defined names.
An identifier in C can be made up of letters, digits and underscore. Identifiers may start with either alphabets or
underscore. The underscore is used to make the identifiers easy to read and mark functions or library members.
iii. Constants: - Constants in C refers to fixed values that do not change during the execution of a program. C
support several types of constants.
a. Numerical Constants
i. Integer Constant
1. Decimal Constant
2. Octal Constant
3. Hexadecimal Constant
ii. Float Constant

b. Character Constants
i. Single Character Constant
ii. String Constant
Integer Constant: - An integer constant is a whole number without any fractional part. C has three types of
integer constants.
Decimal Constant: - Decimal integers consists of digits from 0 through 9
Eg.: 34,900,3457,-978
Octal Constant: - An Octal integer constant can be any combination of digits from 0 through 7. In C the first
digit of an octal number must be a zero(0) so as to differentiate it from a decimal number. Eg.: 06,034,-07564
Hexadecimal Constant: Hexadecimal integer constants can be any combination of digits 0 through 9 and
alphabets from a through f or A through F. In C, a hexadecimal constant must begin with 0x or 0X
(zero x) so as to differentiate it from a decimal number. Eg:- 0x50,0XAC2 etc
Floating Constants (Real): Real or floating point numbers can contain both an integer part and a fractional part
in the number. Floating point numbers may be represented in two forms, either in the fractional form or in the
exponent form.
A float point number in fractional form consists of signed or unsigned digits including decimal point between
digits. E.g:- 18.5, .18 etc.
Very large and very small numbers are represented using the exponent form. The exponent notation use the E
or e symbol in the representation of the number. The number before the E is called as mantissa and the
number after forms the exponent.
Eg.:-5.3E-5,-6.79E3,78e05
Single Character Constant: - A character constant in usually a single character or any symbol enclosed by
apostrophes or single quotes. Eg.: ch=a
String Constant: - A sequence of character enclosed between double quotes is called string constant. Eg.:
Hello Good Morning
iv) Punctuations: - 23 characters are used as punctuations in C. eg: + _ / ; : > ! etc
v) Operators: - An operator is a symbol that tells the computer to perform certain mathematical or logical
manipulation on data stored in variables. The variables that are operated as operands. C operator can be
classified into 8 types.
i. Arithmetic Operators : + - * / %
ii. Assignment Operators : =
iii. Relational Operators: < > <= >= == !=
iv. Logical Operators:! && ||
v. Conditional Operators: ! :
vi. Increment & Decrement Operator : ++ -vii. Bitwise Operator:! & | ~ ^ << >>
viii. Special Operator : sizeof ,(comma)
Variables: A variable is an object or element that may take on any value or a specified type. Variable are nothing
but identifiers, which are used to identify variables programming elements. Eg: name, sum, stu_name, acc_no
etc.
4) Data types: Data types indicate the types of data a variable can have. A data types usually define a set of
values, which can be stored in the variable along with the operations that may be performed on those values. C
includes two types of data.
Simple or Fundamental data type
Derived data type
Simple Data Types: There are four simple data types in C.

int
char
float
double
int:- This means that the variable is an integer are stored in 2 bytes, may range from -32768 to 32767.
char:- This means that the variable is a character type, char objects are stored in one byte. If unsigned, the
values may be in the range 0 to 255.
Float:- This means that the variable is a real number stored in 4 bytes or 32 bits. The range of floating point
values are between 3.4E-38 to 3.4E38 or 6 significant digits after the decimal point.
Double: This means that the variable is a double precision float type. In most cases the systems allocates 8 bytes
or 64 bits space, between 1.7E-308 to 1.7E308.
Derived Data Types: Derived data types are constructed from the simple data types and or other derived data
types. Derived data include arrays, functions, pointers, references, constants, structures, unions and
enumerations.
Variable Type
Keyword
Bytes Required
Range
Character
char
1
-128 to 127
Unsigned character
unsigned char
1
0 to 255
Integer
int
2
-32768 to +32767
Short integer
short int
2
-32768 to 32767
Long integer
long int
4
-2147483648 to
2147483647
Unsigned integer
unsigned int
2
0 to 65535
Unsigned short integer unsigned short int
2
0 to 65535
long integer
Float
Double

unsigned long int


float
double

4
4
8

Long Double

long double

10

0 to 4294967295
3.4E +/- 38 (7 digits)
1.7E +/- 308 (15
digits)
3.4E-4932 to
1.1E+4932

Precedence of Operators:
Precedence is defined as the order in which the operators in a complex evaluation are evaluated.
Associativity:
When two or more operators have the same precedence then the concept of associativity comes into discussion.
Precedence and Associativity of various operators
Operator
[] . () ++ --

++ -- + - ! ~

() new

Description
access array element
access object member
invoke a method postincrement postdecrement
pre-increment predecrement unary plus
unary minus logical
NOT bitwise NOT

Level
1

Associativity
left to right

right to left

cast object creation

right to left

*/%

multiplicative

left to right

+-+

additive string
concatenation
shift

left to right

left to right

< <=
> >=
instanceof
== !=

relational type
comparison

left to right

equality

left to right

&
^
|
&&
||
?:
= += -=
*= /= %=
&= ^= |=
<<= >>= >>>=

bitwise AND
bitwise XOR
bitwise OR
conditional AND
conditional OR
conditional
assignment

<< >> >>>

9
10
11
12
13
14
15

left to right
left to right
left to right
left to right
left to right
right to left
right to left

Relational operators:
We can compare two quantities depending upon their relation, using the relational operator. We can take
decisions. An expression containing relational operators is called relational expression. The value of this
expression will be either zero or one. i.e the relation is true the value will be one. If it is false the value will be
zero.
Ex:
10<20 true

20<10 false
Relational operator

Meaning

<

Is less than

<=

Is less than or equal to

>

Is greater than

>=

Is greater than or equal to

==

Is equal to

!=

Is not equal to

A simple expression taking only one relational operation takes the following form
ae-1 relational operator ae-2
ae-1 and ae-2 are arithmetic expression may be simple constants,variable or the combination of them.
Ex:
4.5<= 10
TRUE
-25>= 0
FALSE
10<7+5
TRUE
a+b==c+d
TRUE only if the sum of values of a and b is equal to the sum of the values c and d.

when the arithmetic expressions are used on either side of relational operators the arithmetic expression will be
evaluated first and then the results compared.
Logical Operator:
Logical operators (&&) and (||) are used when want to test more than one condition and make decisions.
Ex:
a>b && x==10
This expression is which combines 2 or more relational expression is termes=d as a 'logical operator' or a
'compound relational expression'. This also gives the value TRUE or FALSE.
Assignment Operator:
This operator is used to assign the result of an expression to a variable. The usual operator is '=', the
others are 'shorthand' assignment operator of the form
V op=exp;
V is a variable. Exp is expression and O/P is a binary arithmetic operator. The operator op = is known as the
shorthand assignment operator.
The above form is equal to
v = v op (exp); with v is evaluated only once.
Ex.1:
x+=y+1;
is same as
x=x+(y+1);
Ex.2:
x+=3;
The value of x is incremented by 3, statements with shorthand assignmentoperators,
a+=1;
a-=1;
a*=n+1;
a/=n+1;
a%=b;
Advantages:
1. Left hand side is not repeated so it is easier to write
2. The statement is more concise and easier to read.
3. The statement is more efficient.
Ex.3:
Value(6*x-3) = value (6*x-3)+alpha;
using +=,
value(6*x-3)+=alpha;
Increment and decrement operator:
These operators (+ +,- -) are used to add 1 to the operand and subtracts 1 from the operand.
The form is
(m+=1)(m=m+1;)++m or m++;
(m-=1)(m=m-1;) - -m or m- - ;
We use these operators in the for, while loops while ++m and m++ mean the same thing when they form
statements independently. They behave differently in expressions as follows,
Ex.1:

m=5;
y=++m;
The values of y and m is 6.
but
Ex.2:
m=5;
y=m++;
y would be 5 and m would be 6.
The prefix operator first adds 1 to the operand and then the result is assigned to the variable on left. On
the other hand a postfix operator first assigns the value to the variable on left and and then increments the
operand.
Ex.3:
a[i++]=10;
a[i]=10;
i=i+1;
The increment and decrement operators can be used in complex statements
Ex.4:
m=n++ -j+10;
old value of n is incremented after the evaluation. Some compilers require a space on eithe side of n++ and ++n
Conditional Operator:
A ternary operator pair ?: is available to construct conditional expressions of the form,
exp1?exp2:exp3;
where exp1,exp2,exp3 are expressions
The operator ?: works as follows. Exp1 is evaluated first. If it is non-zero(true) then the expression exp2
is evaluated and becomes the value of the expression. If exp1 is false, exp3 is evaluated. So only one of the
expressions exp1 or exp2 are evaluated.
Ex:
a=10;
b=15;
x=(a>b)?a:b;
x will be assigned the values of b. using if...else,
if(a>b)
x=a;
else
x=b;
The comma operator:
This is used to link the related expressions together. This expressions using this operator are evaluated
left to right and the value of the right-most expression is the value of the combined expression.
Ex: value=value(x=10,y=5,x+y);
first assigns the value 10 to , then assigns 5 to y and finally assigns 15 (i.e 10+5) to value since comma operator
has the lowest precedence of all operators, the parenthesis are necessary.

Ex:- for loops;


for(n=1,m=10;n<=m;n++,m++)
while loops;
while(c=getchar(),c!='10')
Exchanging Values:
5=x,x=y,y=f;
The sizeof operator:
This is the compile time operator and when used with operand, it returns the number of bytes the
operand occupies. The operand may be a variable , a constant or a datatype qualifier.
Ex:
m=sizeof(sum);
n=sizeof(long int);
k=sizeof(235L);
sizeof is used to determine lengths of arrays structures when their sizes are not known to the
programmer. It is also used to allocate memory space dynamically to variables during execution of the program.
Arithmetic Expression:
This is the combination of variables,constants and operators arranged as per the system of the language.
Expression using the assignment statements is of the form:
Variable=expression;
Type conversion expressions:
Automatic:
This computer considers one operator ata time, involving two operands. If the operands are of two
different types, the lower type is automatically converted to the higher type before the operation proceeds. The
result is of higher type.
Ex:
Int i,x;
float f;
double d;
long int l;
x =l / i + i * f - d

long float

long
float

double
int
float

floatdouble

Sequence of rules are applied while evaluating expressions. [z=x operator y]


1. All 'short ' and 'char' are automatically converted to int.
2. if x is 'long double' y is converted to 'long double' and is 'long double'.
3. Else if x is 'double', y is converted to 'double' and result is 'double'.
4. Else if x is 'float', y will be converted to 'float' and result will be 'float'
5. else if x is 'unsigned long int' the y will be converted to 'unsigned long int' and result will be 'unsigned

long int'
6. if x is 'long int' and y is 'unsigned int'
a. if y is converted to 'long int', result is 'long int'
b. else both x and y are converted to 'long int', then the result is 'long int'
7. if x is 'long int', y is converted to 'long int' result will be 'long int'
8. if x is 'unsigned int' y is converted to 'unsigned int' and result will be 'unsigned int'
changes during final assignment,
1. float to int- truncation of fractional part.
2. double to float- rounding off digits.
3. long int to int- dropping of excess higher order bits.
Casting a Variable:
Usually 'casting a value' we can force the type conversion locally.
Ex:
ratio=female-number / male-number;
Numbers are integers. The ratio will represent wrong figure (while dividing we can't get the remainder )
solution,
ratio=(float)female-number/male-number;
The operation float converts the floating the female number to floating point and operation done in that
mode, so it retains the fractional part.
In other parts of the program female-number remains as int. This is known as 'casting a value'.
(type name)expression;
X=int(y+0.5);
Managing Input and output operations:
Unlike other higher level languages C does not have any built in input/output statements as a part of its
syntax. There exists several functions that have more or less become standard input and output operations on C.
These functions are collectively known as 'Standard I/O library'.
For input/output function must contain the statement
#include<stdio.h>
For mathematical functions we should include
#include<math.h>
Formatted Input:
Formatted input refers to an inpur data that has been arranged in a particular format.
General Format:
Scanf(control string, arg1,arg2,arg3...argn);
The 'Control String' specifies the field format in which the data is to be entered and the arguments
arg1,arg2,arg3...argn specify the address of the locations where the data is stored. Arguments are separated by
commas.
Control strings include,
(i) field specifications (format) consisting of the conversion character % a datatype character (type
specifier) and an optional number, specifying field width.
(ii) Blanks,tabs,new lines (optional)

Inputting input numbers


The field specification for spreading an integer number is
%wd
The percent (%) sign indicates that a conversion specification follows. W specifies the 'field width', 'd'
the datatype character indicates that the read is in integer mode.
Ex:
scanf(%2d,%5d,&num1,&num2);
I/P data,
50
31426
num1 takes the value 50 and num2 takes the value 31426
suppose if the input data is,
31426
50
num1 will be assigned 31. num2 will be assigned 426. The unread value 50 will be assigned to the next scanf
call. This can be eliminated by specifying
scanf(%d%d,&num1,&num2);
now num1 will be assigned 31426 and num2 will be assigned 50.
Input Data must be separated by spaces, tabs or new lines. If we enter a following point number instead of
integer, the fractional part is stripped away and scanf may skip further reading.
Scanf reads a particular value until the number specified by the field width is reached or until a character
that is not valid for the value being is read is encountered.
An input field may be skipped by specifying * in the place of field width.
Ex:
scanf(%d%*d%d%d,&a,&b);
I/P data 123
456
assign as follows,
123 to a
456 skipped
789 to b.

789

Inputting Real numbers:


Unlike integer numbers, the field width of real numbers is not to be specified and therefore scanf reads
real numbers using the simple specification %f for both the notations namely decimal point notation and
exponential notation.
Ex:
scanf(%f%f%f,&x,&y,&z);
with input data,
475.89
43.21E-1
678
will assign the values 475.89 to x; 4.321 to y and 678.0 to z. A number can be skipped using %f specification.
Input Character String:
scanf function can input strings containing more than one character using the following specification,
%ws of %wc.
When we specify width of the string it takes the input upto that width. But when we simply specify %s
it takes the string upto the blank space.
We can use the following specification,
%[character] and
%[^characters]

The first specification %[character] means that inly the character specified within the brackets are
permissible in the input sting. If the input string contains any other character. The string will be terminated at the
first encounter of such a character.
The second specification %[^characters] does exactly the reverse. The character specified after the
circumflex(^) are not permitted in the input string.
%s cannot be used for reading blank spaces. But this can be done with the help of %[] specification.
Blank spaces may be included within the brackets, thus enabling the scanf to read the strings with spaces.
Ex: %[a...z] scanf(%[a...z],&name);
%[^\n]
scanf(%['^\n'],&set);
Reading Mixed Datatype:
For mixed mode data type data care should be exercised to ensure that the input data items match the
control specifications in order and type. When an attempt is made to read an item that does not match the type
expected. The scanf() function does not read any further and immediately returns the value read.
Ex:
scanf(%d%c%f%s,&count,&code,&ratio,name); will read the data
15
P
1.5755 coffee
correctly assign the values to the variable in the order in which they appear. Some systems accept integers in
place of real numbers and vice versa.
Scanf format codes
CODE

MEANING

%c

Reads a single character

%d

Reads a decimal integer

%e

Reads a floating point value

%f

Reads a floating point value

%g

Reads a floating point value

%h

Reads a short integer

%i

Reads a decimal,hexadecimal or octal integer

%o

Reads an octal integer

%s

Reads a string

%u

Reads a unsigned decimal integer

%x

Reads a hexadecimal integer

%[...]

Reads a string of word(s)

The following letters may be used as prefix for certain conversion characters.
h
for short integer
l
for long integers or double
L
for long double
Points while using scanf
Given below are some of the general points to keep in mind while writing a scanf characters
1. All functions arguments,except the control string must be pointers to variables.
2. Format specifications contained in the control string should match the arguments in order.

3. Input data items must be separated by spaces and must match the variables receiving the input in
the same order
4. The reading will be terminated,when scanf encounters an invalid mismatch of the data or a
character that is not valid for the value being read.
5. Any unread data items in a line will be considered as a part of the data input line to the next
scanf call.
6. When the field width specifier 'w' is used. It should be large enough to contain the input data
size.
Formatted Output:
The printf statement provides certain features that can be effectively exploited to control the alignment
and spacing of printouts on the terminals.
General Format:
printf(control string,arg1,arg2,arg3...argn);
The control string consists of 3 items,
1. characters that will be printed on the screen as they appear.
2. Format specifications that define the output format for display of each item.
3. Escape sequences characters such as \n,\t,\v,\b,\a etc
The arguments arg1,arg2,arg3...argn are the variables whose values are formatted and printed according to the
specifications of the control string.
General Format:
%w.p type-specifier;
Where w is an integer number that specifies the total number of columns for the output value and p is another
integer number that specifies the number of digits to the right of the decimal point. W and p are optional.
Ex:
printf(programming in c);
printf( );
printf(\n);
printf(%d,x);
printf(a=%f\nb=%f,a,b);
printf(sum=%d,1234);
Output of integer numbers:
Format specification for printing integers is %wd.
W specifies the minimum foeld width for the output. However if a number is greater than the specified field
width, it will be printed in fall, over riding the minimum specification. d specifies that the value to be printed is
integer. The number is written right-justified in the given field width.
FORMAT
Printf(%d,9876);

OUTPUT
9

Printf(%6d,9876);

Printf(%2d,9876);

Printf(%-6d,9876);

Printf(%06d,9876);

Output of real numbers:


The output of real numbers may be displayed in the decimal notation using the following format %w.pf.
The integer w indicates the minimum number of positions that are to be used for the display of the
values and the integer p indicates the number of digits to be displayed after the decimal point. The value when
displayed is rounded to p decimal places and printed right-justified in the field of w columns. The default

precision is 6 decimal places. If it is -ve number it is of the form -mmm.nnn


In exponent notation we use %w.pe.
i.e [-]m.nnnn e [+-]xx. N's length is specified by p. w specifies the condition, w>=p+7
FORMAT
Printf(%7.4f,y);

OUTPUT
9

Printf(%7.2f,y);

Printf(%-7.2f,y);

Printf(%f,y);

Printf(%10.2e,y);
Printf(%11.4e,-y);

Printf(%-10.2e,y);

Printf(%e,y);
9 .
8
7
6
5
4
0
e
+ 0
The special specification os of the form
printf(%*.*f,7,2,number);
is equivalent to
printf(%7.2f,number);
we can also supply the values at runtime thus making the format a 'dynamic' one.
Ex:
int w=?;
int precision=2;
printf(%*.*fw,p,no);
Printing a single character:
General Format:
%wc will be displayed right-justified in the field of w columns. We can make the display lefi-justified by
placing minus sign before the integer w. default for w is 1.
Printing of Strings:
The Form is %w.ps. W specifies the field width for display and p instructs only the first p characters of
the string are to be displayed. The display is right-justified.
SPECIFICATION
%s

OUTPUT
N

%10s

D
W

%10.3s
%0.5s

%-10.3s

%5s

D
D

Mixed data output:


It is permitted to mix data types in one printf statement.
Ex:
printf(%d%f%s%c,a,b,c,d);
The format specification should match the variables in number, order and type. If there are not enough variables
or if they are of the wrong type, incorrect results will be ouput.

CODES

Printf format codes


MEANING

%c

Print a single character

%d

Print a decimal integer

%e

Print a floating point value in exponent form

%f

Print a floating point value without exponent

%g

Print a floating point value either in e-type or in f-type


depending upon value

%i

Print a signed decimal integer

%o

Print an octal number without leading 0

%s

Print a string

%u

Print an unsigned decimal integer

%x

Print a hexadecimal integer without leading 0x

The following letters may be used as prefix for certain characters,


h for short integers
l for long integers or double
L for long double
Enhancing the readability of output:
Following are some of the steps we can take to improve the clarity and hence the readability and
understandability of outputs:
1.provide enough blank spaces between two numbers
2. introduce appropriate headings and variable names in the output
3. print special messages whenever a peculiar condition occurs in the output
4. introduce blank lines between the important sections of the output.
5.DECISION MAKING AND BRANCHING:In practice we have a number of situations where we may have to change the order of execution of statements
based on certain condition 'c' language possesses such decision making capabilities and supports the following
statements known as 'control' or 'decision making' statements.
1.if statements
2.switch statements
3.conditional operator statements
4.goto statements
5.1.Decision Making With If Statements:The if statement is a powerful decision making statement and is used to control the flow of execution
statements.
General Format
If (test condition)
It allows the computer to evaluate first and the depending on whether the value of the expression (relation or
condition) is true(non zero) or false(zero),it transfers the control to the particular statements.
Thus the two way path is,
Two way branching

The if statements may be implemented depending on the complexity of conditions to be tested in different
forms.
1.Simple if statements
2.If .....else statements
3.Nested if ....else statements
4.else if ladder.
5.2 Simple if statements
General format

If (test expression)
{
statement-block;
}
statement-x;
The 'statement-block' may be a single statement or a group of statements. If the Test expression' is
true the 'statement-block' will be executed otherwise the execution jumps to the statement x. When the condition
is true both the block and statement -x will be executed sequentially.

Ex:
if(category==SPORTS)
{
marks==marks+bonus-marks;
}
printf(%f,marks);
The program test the type of category of the student. If the student belongs to the SPORTS category the
additional marks added to his marks before they are printed. For others bonus-marks are not added.
Ex:2
if(weight<50 && weight>170)
is equivalent to
if(weight<50)
if(weight>170)
The If...Else statement:
This is the extention of simple if statement.
General Format:
If(test-expression)
{
True-block statement(s);
}
else
{
flase-statement(s);
}
statement-x;
If the text expression is true then the block statements are executed. Otherwise false block statements are
executed. In either case either one will be executed not both. In both cases the control is transferred to statementx.

Ex:
Counting the number of boys and girls in class. We can use the code 1 for for boy and 2 girls.
if(code= =1)
boy=boy+1;

if(code= = 2)
girl=girl+1;
if the code equal to no. of boys increased by 1 and the program goto next test, if it is true girl's no is
incremented by 1.
But this is unnecessary i.e once a student is identified as boy there is no need check for code = = 2
student can be either boy or girl not both. So we can check if as,
if(code= =1)
boy=boy+1;
else
girl=girl+1;
Nesting of if...else statements:
When a series of decision are involved, we may have to use more than one if...else statement is nested
form as follows:
General Format:
If(test condition-1)
{
if(text condition-2)
{
statement-1;
}
else
{
statement-2;
}
}
else
{
statement-3;
}
statement-x;
If condition-1 is false, the statement-3 will be executes; otherwise it continues to preform the second
test. If the condition-2 is true, the statement will be evaluated; otherwise statement-2 will be evaluated and then
the control is transferred to the statement-x.
The logic of execution is illustrated in the following figure:

Flow for nested if...else statement.


Ex:
Part of the largest of 3 numbers program uses this nested if...else.
If(a>b) && (a>c)
printf(largest is a);
else
{
if(b>c)
printf(largest is b);
else
printf(c is largest);
}
When nesting, care should be exercised to match every if with an else. In the above example else part will not be
calculated, if a is the largest number otherwise the second is statement i.e the inner loop of it will be executed.
Else if ladder
Another way of putting ifs together when multi-path decisions are involved. A multi-path decision is a
chain of if's in which the statements associated with each else is an if.
General Format:

If(condition-1)
statement-1;
else if(conditon-2)
statement-2;
else if(condition-3)
statement-3;
...
else if(condition-n)
statement-n;
else
default statement;
statement-x;
This construct is known as the else-if ladder. The conditions are evaluated from the top downwards. As
soon as a condition is found, the statement associated with it is executed and the control is transferred to the
statement-x (skipping rest of the ladder). When all n conditions become false then the final else containing
default-statement is executed.

Ex:
Grading the students:
AVERAGE MARKS

GRADE

80 to 100

Honours

60 to 99

First Class

AVERAGE MARKS

GRADE

50 to 59

Second Class

40 to 49

Third Class

0 to 39

Fail

Using the else...if ladder this can be as follows,


if(marks>79)
grade=Honours;
else if(marks>59)
grade=First Class;
else if(marks>49)
grade=Second Class;
else if(marks>39)
grade=Third Class;
else
grade=Fail;
printf(%s\n,grade);
The Switch statement:
We have seen that when one of the many alternatives is to be selected we can design a program using if
statements to control the selection. But if many alternatives arise it will be a complex one. There will be a
difficulty to read and follow. To remove this 'c' provides the 'switch' statement.
The statements tests the value of a given variable against a list of care values and when a match is found,
a block statements associated with that 'case' is executed.
General Format:
Switch(expression)
{
case value-1:
block-1
break;
case value-2:
block-2
break;
default:
default-block
break;
}
statement-x;
The expression is an integer expression or characters 'value-1','value-2'...'value-n' are constants or
constant expression and are known as 'case labels'. Each of these values should be unique within a switch
statement. Block-1,block-2...block-n are statements lists and may contain zero or more statements. There is no
need to put braces around these blocks. Case labels and with a colon(:)
When the statement is executed, the value of the expression is successfully compared against the values,
value-1,value-2,..value-n if a case is found whose value matches with the value of the expression, then the block
of statements that follows the case are executed.
The break statement at the end of each block signals the end of a particular case and causes an exit from
the switch statement, transferring the control to the statement-x following the switch.
The default is optional. When present it will be executed if the value of the 'expression' does not match
with any of the case values. If not present, no action takes place if all matches fail and the control goes to

statement-x.
Ex:
The switch statement can be used to grade the students.
Index=marks/10;
switch(index)
{
case 10:
case 9:
case 8:
grade=Honours;
break;
case 7:
case 6:
grade= First Class;
break;
case 5:
grade=Second Class;
break;
case 4:
grade=Third Class;
break;
default:
grade=Fail;
break;
}
printf(%s\n,grade);
We have used a conversion statement.
Index=marks/10;
index is defined as an integer.
MARKS

INDEX

100

10

90-99

80-89

70-79

60-69

50-59

40-49

30-39

20-29

10-19

This segment of the program first uses empty cases. The first three cases will execute the same
statements,
grade=honours;
break;
same is the case with 7 and case 6. second default condition is used for all other cases where marks is less than
40.

selection process of the switch statement


The Goto Statement:
'C' supports the goto statement to branch unconditionally from one point to another point in a program.
The goto statement requires a label in order to identify the place where the branch is to be made. A 'label' is any
variable name, and must be followed by a colon. The 'label' is placed immediately before the statement where
the control is to be transferred.
General Form at:
Forward Jump
Backward Jump
Goto label;
Label:
...

statements;
...

...

...

...

label:
...

statement;
goto label;
The label: can be anywhere in the program either before or after the goto label, statement.
During running of a program when a statement like goto begin;

is met, the flow of control will jump to the statement immediately following the label begin: Note that a goto
breaks the normal sequential execution of the program. If the label: is before the statement goto label; a loop will
be formed and source statements will be executed repeatedly. Such a jump is known as 'backward jump'. If the
label: is placed after the goto label; some statements will be skipped and the jump is known as 'forward jump'.
A goto is often used at the end of a program to direct the control to go to the input statement, to read
further data.
Ex:
The following program is written to evaluate the square root of series numbers read from the terminal.
Main()
{
double x,y;
read:
scanf(%f,&x);
if(x>0) goto read;
y=sqrt(x);
printf(%f%f\nx,y);
goto read;
}
The program was uses two way goto statement one at the end, after printing the results to transfer the
control back to input statement and the other to skip any further computation when the number is -ve.
The program puts the computer in a permanent loop id known as infinite loop. Another use of goto
statement is to transfer the control out of a loop (or nested loop) which certain peculiar conditions are
encountered.
Ex:

Decision Making and Looping:


In looping, a sequence of statements are executed until some conditions for termination of the loop are
satisfied. The test conditions should be carefully stated inorder to program the described number of loop
executions.
In general looping includes:
1. Setting and initialization of a counter.
2. Execution of the statement in the loop.
3. Test for a specified condition for execution.
4. Incrementing the counter.
'C' provides 3 loop constructs,
1. The while statement
2. The Do statement
3. The For statement

The while statement:


General Format:
While(test-condition)
{
body of the loop;
}
The while is an 'entry-controlled' loop statement the control condition is tested before the state of the loop
execution. If it is not satisfied the body of the loop will not be executed. The following flowchart explains this,

(a) Entry Control


The 'Test condition' is evaluated and if the condition is true, then the body of the loop is executed. After this the
loop is once again evaluated if the condition is true in 2 nd test. This process is repeated until the test-condition
finally becomes false and the control is transferred out of the loop.
The body of the loop may have one or more statement. More than one statement need opening and
closing process.
Ex:
sum=0;
n=1;
while(n<=10)
{
sum=sum+n*n;
n=n+1;
}
printf(sum=%d\n,sum);
The body of the loop is executed for n=1,2,3...10 each time adding the square of the value of n, which is
incremented inside the loop. Condition may ne n<11, the result would be the same.
The Do statement:
On some occasions it might be necessary to execute the body of the loop before the test is performed.
The Do statement is used for this purpose
General Format:
Do
{
body of the loop;
}
while(test-condition);

On reaching the do statement the program proceeds to evaluate the body of the loop first. At the end of
the loop, the test condition in the while statement is evaluated. If the condition is true the program continues to
evaluate the body of the loop once again. This process continues as long as the condition is true.
When the condition is false, the loop will be terminated and control goes to the statement that appears
immediately after the while statement.
Since the test condition is evaluated at the bottom of the loop, the do...while construct provides an 'exitcontrol loop' i.e the body of the loop is always executed atleast once.
Ex:
do
{
printf(Input a number\n);
number=getnum();
}
while(number>0);
This segment of a program reads a number from the keyboard until a zero or a negative number in keyed in.
The FOR statement:
Simple'for' loop
The for loop is another is another entry-controlled loop that provides a more concise control structure.
General Format:
For(initialization;test-condition;increment)
{
body of the loop
}

1. 'Initialization' of the control variable is done first, using assignment statements such as i=1 and count=0.
The variable i and count are known as loop-control variables
2. The value of the control variable is tested using the test condition. The test condition is a relational
expression, such as i<10 that determines when the loop will exist. If the condition is true, the body of
the loop is executed. Otherwise the loop is terminated and the execution continues with the statement
that immediately follows the loop.
3. After the evaluation of the body of the loop, control variable is incremented using assignment statements
such as i=i+1 and this is again tested to see whether it satisfies till value of the control variable fails to
satisfy the test-condition.
Ex:1
for(x=0;x<=9;x=x+1)
{
printf(%d,x);
}
printf(\n);
This for loop is executed 10 times and prints the digits 0 to 9 is one line. The 3 sections enclosed within the
parenthesis must be separated by semicolon. No semicolon at the end od the increment section, x=x+1.
Ex:2
The for statement allows negative increments.
For(x=9;x>=0;x=x-1)
{
printf(%d,x);
prinf(\n);

This is also executed 10 times. But the output will be from 9 to 0 instead if 0 to 9.
Note: Braces is optional.
Ex 3:
Since the conditional test is always performed at the beginning of the loop, the body of the loop may not
be executed at all, if the condition fails at the start.
For(x=9;x<9;x=x-1)
printf(%d,x);
will never be executed because the test condition fails at the very beginning itself.
One of the important point in for is that all the 3 actions viz, initialization, testing and incrementing are
placed in the statement itself, thus making them visible to the programmers and users in one place.
Ex:4
More than one variable can be initialized at a time in the for statement.
P=1;
for(n=0;n<17;n++)
can be written as for(p=1,n=0;n<17,n++)
Two initializations are separates by commas. We can use this facility in the increment section also.
Ex:5
for(n=1,m=50;n<=m;n=n+1,m=m-1)
{
p=m/n;
printf(%d%d%d\n,n,m,p);
}
Ex.6:
Test condition may have compound relations and testing need not be limited only to the loop control
variable.
Sum=0;
for(i=1;i<20 && sum<100;i++)
{
sum=sum+i;
printf(%d%d,i,sum);
}
The loop uses a compound test condition with a control variable i and external variable sum. The loop us
executed as long as both conditions i<20 and sum<100 are true. The sum is evaluated inside the loop.
Ex.7:
For initialization and increment we can also use expressions.
For(x=(m+n)/2;x>0;x=x/2)
Ex.8:
We can also one or more sections,
m=5;
for(;m!=100;)
{
printf(%d\n,m);
m=m+5;
}
Here initialization is omitted in for but used before for statement. Increment section is omitted but incremented

inside the loop. But the semicolons separating the sections must remain.
If the test-condition is not present, the for statement sets up an infinite loop such loop can be broken
using the break goto statements in the loop.
Ex 9
for(j=1000;j>0;j=j-1)
The loop is executed 1000 times without producing any output; it simply causes a time delay. Body of the loop
contains only semicolon known as 'null statement'. We can also write this as
for(j=1000;j>0;j=j--);
No error message will come, but it may produce some non-sense.
Nesting of For loops:
Nesting of loops, i.e one for statement nested within another for statement is allowed in C. the nesting
may contain upto 15 levels in ANSI C. The loops should be properly indented so as to enable the reader to easily
determine with statements that are contained within each For statement.

Jumping in the loops:


Sometimes when executing a loop it becomes desirable to skip a part of the loop or to leave the loop as
soon as a certain condition occurs.
Ex:
Consider the case of searching for a particular name in a list containing 100 names. The program loop
written for reading must be terminated as soon as the desires name is found. C allows a jump form one
statement to another within a loop as well as a jump out of a loop.
Jumping out of a loop:
Exit from the loop can be done by using break or goto statement. When break occurs in a loop the
control is transferred out of the loop. The program continues with the statement immediately following the loop.
In the nested loop, break will change the control only out of that particular block (where it is used). So break will
exit only from a single loop.

Usage of break and Goto Statements:

Exit a loop with break:

Jumping within and exiting from loop

goto statement can be used to change the control anywhere in the program. So we can use goto for branching.
Important use of goto is to exit from deeply tested loops when an error occurs, simple break would not work
here.
Skipping a part of the loop:
During the loop operations, it may be necessary to skip a part of the body of the loop under certain
conditions. For example, in processing of applications for some job, we might like to exclude the processing of

data belonging to a certain category. On reading the category code of an applicant, check whether we can
consider it or not. If it is not to be considered, the part of the program loop that program loop that processes the
application details is skips and the execution continues with next loop operation.
Unlike break which causes the loop to be terminated, the another concept continue causes the loop to be
continued with the next iteration after skipping any statement in between.
The continue statement tells the compiler, SKIP THE FOLLOWING STATEMENTS AND
CONTINUE WITH THE NEXT ITERATION
General Format:
Continue;
The use of continue statement in loops is illustrated as follows

In while and Do loops, 'continue' causes the control to go directly to the test-conditions and then continue the
iteration process. In case of for loop, the 'increment section' of the loop is executed before the test-condition is
evaluated.
Avoiding Goto:
Usage of goto produce lack of efficiency, complicated logic and lack of readability. So we should avoid
the following goto jumps.

Arrays:
Introduction:
An ARRAY is a group of related data items that share a common name.
Ex:
Salary[10];
The array name states to represent a set of salaries of a group of employees. Here 10 is called 'index
number'. Or 'subscript'(with in brackets). The complete set of values is referred to as an array and the individual
values are called 'elements'.
One Dimensional Array:
When only one subscript is used for a list of items, it is called 'single subscripted variable' or a 'one

dimensional array'.
Ex:
x[1],x[2],x[3],x[4]...x[n]
The subscript can also begin with 0 i.e x[0] is allowed. When we want to represent by array variable
'number', then the declaration will be int number[5];
The storage will be,

we can use these in programs like number[4]=number[0]+5;


a=number[0]+20;
Declaration of arrays:
Arrays should be declared before usage.
General Format:
Type variable-name[size];
Type specifies the type of element that will be contained in an array. Size indicates maximum number if
elements stored in an array.
Ex:
float height[20];
char name[50];
That 'size' in a character string represents the maximum number of characters that the string can hold.
WELL DONE is stored in an array as follows,
'W' 'E' 'L' 'L' ' ' 'D' 'O' 'N' 'E' '\0'
Compiler terminates the character with a null character. So extra element space should be allowed to character
type.
Initialization of arrays:
General Format:
Static type array-name[size]={list of variables};
Ex.1:
static int no[3]={0,0,0};
Here the array of size 3 will assign 0 to each element.
Ex.2:
static float total[5]={0.0,5.5,-3};
Here, the first three elements will get the values of 0.0,5.5 and -3 respectively. Remaining 2 elements are
initialized to 0 automatically.
Note: In ANSI 'static' can be omitted.
The size may be omitted.
Ex:
static char name[]={'R' 'A' 'M'};
Therefore the string RAM is initialized.

Drawbacks of initialization of arrays:


1. There is no convenient way to initialize only selected elements.
2. We can't initialize a large number of array elements.
Two dimensional arrays:
This is used for table of values. For matrix we elements we use these two dimensional arrays.
General Format:
Type array-name[row-size][column-size];
In memory,

Initialization of two dimensional arrays:


Ex:
static int table[2][3]={{0,0,0},{1,1,1}};
with braces for each row.
We can also initialize in matrix form,
static int x[2][3]={
{0,0,0},
{1,1,1}
};
for each braces comma is required except the last one.
Ex:
static int x[2][3]={
{1,1},
{2}
};
First two elements of the 1st row get 1. The 1st element if the 2nd row get 2. All others are 0. When all the
elements are to be 0, we can write
static int m[3][5]={{0},{0},{0}};
The first element of the first row is 0 while all others are automatically initialized to 0.

Multidimensional arrays:
General Format:
type array-name[s1,][s2],[s3],...,[sn];
Ex:
int survey [3][5][12];
This is an example of 3 dimensional array declared to contain 180[3*5*12] integer type elements.
Handling of Character Strings:
A string is an array of characters. A group of characters defined between double quotation is a constant
string.
MAN IS A SOCIAL ANIMAL
If we want double quote in the string, we can use back slash.
\MAN IS A SOCIAL ANIMAL\
The following string operations increase program's readability.

Reading and writing strings

Combining strings together

Copying one string to another

Comparing one string with another

Extracting a portion of the string


Declaring and initializing string variables:
String variable is always declared as an array.
Char string-name[size];
'size' determines the number of characters in the 'string-name'.
Ex:
char college[30];
1.When one char string is assigned to char array, it automatically supplies 'null'('\0') at the end of the string. Size
should be equal to number of characters + 1.
Ex:
We can combine declaration and initialization as in following forms:
1. static char college[8]= THANJAVUR;
2. static char college[8]= 'T','H','A','N','J','A','V','U','R','\0' ;
2. Here we should give the null ('\0') char because we give the listings of array elements
3.When we are not specifying the total number of elements, the compiler automatically determines it based on
the number of initialized values.
Ex:
static char string[]={'T','O','W','N'.'\0'};
The above example defines the array 'string' as a five element array.
Reading Strings form the terminal:
We can use %s for reading string of characters in scanf.
Char address[20];
Scanf(%s,address);
if we give NEW YORK as input to this it will take only NEW as its input because of the blank space left in
between.
Note that there is no need for &(ambersand) symbol. To read NEW YORK, we can use
scanf(%s%s,address1,address2);

Reading a line of tent:


Using 'scanf' we can't read a line (more than one word). This is because of space between words.
For this we can use 'getchar' function to read successive single character and stored in an array with last
char /.. as well. Input is stored when ('\n') enter is encountered.
Ex:
#include<stdio.h>
main()
{
char time[81], ct;
int c=0;
printf(Enter a text <Return> at end\n);
do
{
ch=getchar();
line(ct)=ch;
c++;
}
while(ch!='\n')
c=c-1;
line(c)='\0';
printf(\n%s\n,line);
}
2. We can't assign a string to another string datatype directly.
String= ABC
Srting 1= string 2;
The above are not valid. We can do this only on a character-by-character basis.
Ex:
#include<stdio.h>
main()
{
char st1[80],st2[80];
int i;
scanf(%s,st2);
for(i=0,st2[i]='\0';i++)
st1[i]=st2[i];
st1[i]='\0';
printf(String %s\n,st1);
prinf(no of characters=%d,i);
}
Writing strings to screen
We can use the printf statement for writing.
Ex:
printf(%s,name);
This can display the entire content of the array name.
Precision can also be used.
Ex:
%10.4s indicates that 4 characters are to be printed with the field width of columns.

Printf(%15s\n,ct);
Printf(%15s\n,ct);

I
T

T
E

I
K

Printf(%15.6s\n,ct);
Printf(-15.6s\nct);

Printf(%.3s\n,ct);

Printf(%s\n,ct);

O M

Printf(%15.0s\n,ct);

1.
2.
3.
4.

K I

When the field is width is less than string length, the entire string is printed.
The integer on the right sideof decimal point indicates the character to be printed.
When the characters to be printed is specified as 0, then nothing is printed
-ve sign make the string right justified

Arithmetic operations on characters:


When we use character variable in an expression, the system converts it to integer value.
Ex.1:
To write a character we may use integer. In ASCII,
x='a';
printf(%d\n,x);
will display 97.
Ex.2:
Arithmetic operations is also possible,
x='z-1';
is a valid statement. The ASCII value of 'z' is 122. Therefore 121 is assigned to x.
Ex.3:
using relational operations,
ch>= 'A' && ch <= 'Z';
would test whether the character contained in the variable ch is an upper-case letter.
Ex.4:
x=char-'o';
x=ASCII of '7'- ASCII of 'O';
x=55-48;
x=7;
Ex.5:
Library function ato i converts string of digits into their integer value.
General Format:
x=ato i (string);
X is an integer variable and the string is a character array containing string of digits.
Number= 2000;
year=atoi(number);
atoi converts 2000 into its numeric equivalent 1988 and associated to year.
User Defined Functions:
'C' has two functions viz
library function-printf,scanf,sqrt(),pow()

user defined functions- main()


The main difference between the two is that library functions are not required to be returned by us. Whereas the
user-defined functions have to be developed by the user.
Need for user-defined functions:
Utilizing only main() function for coding results in too large and complex program. So the task of
debugging,testing and manupulating turns out to be difficult. If we divide the program into functional part, they
can be coded separately and combined into a single unit.These sub-programs are called functions which are
much easier to understand, debug and test.
If some particular set of statements are to be repeated at many points, then the entire statements should
be repeated again. We can use a function for this purpose which holds the repeating statement. Whenever the
statements are to be repeated, the functions can be called. This saves a lot of time and space.
Advantages of functions are,
1. It provides top-down modular programming. In a problem high level logic is preformed first and
then the low level is executed.
2. Length of the source program can be reduced by using functions.
3. Easy to locate faulty function.
4. A function can be used in many programs.
General Form of C functions:
Function-name(argument list)
argument declaration;
{
local variable declarations;
executable statements 1;
executable statements 2;
.
.
.
executable statements n;
return(expression);
}
Here argument list and declaration part are optional. Also local variable declaration is optional, it is used only
when we use local variables. A function may have any number of statements and also it can contain any number
of executable statements.
Ex
do-nothing()
{...
...
}
We can use the 'return' statement to return the value to the calling function. The absence tells that no value is
returned.
For function name we should use rules of variable names. We should never use library function names or
operating system commands.
The Argument list contains variable names separated by commas and closed by parenthesis. Values of
argument variables are passed form calling function to the called function.
Ex:
quad(a,b,c);
int a ,b, c;
Returns values and their types:

The 'return' takes the following forms,


return;
or
return(expression);
plain 'return' does not return any value, expression or valid variable or value. The return statement transfer the
control to the calling function.
Ex:
1. return(p);
2. return(m*n);
3. return(x<=0);
4. return(0);
else
5. return(1);[based on the condition]
We can force a function to return a particular type od data using 'type specifier' in header.
Double product(x,y);
float square-root(p);
Calling a function:
main()
{
int p;
p=mul(10,5);
printf(%d\n,p);
}
When the compiler encounters mul(10,5) the control is transferred to mul(10,5) function. Then after
executing function the 'return' statement returns the vlaue to the main() and p gets the value.
But mul(a,b)=15; is invalid.
The function which returns a value can be used in expression while the others can't.
Category of functions:
A function, depending on whether the argument is present or not whether the value is returned or may
not belong to one of the following category.
1. Functions with no arguments and no return values
2. Functions with arguments and no return values
3. Functions with arguments and return values
No arguments and No return Values:
When a function has no arguments it doen not receive any data from the calling function. When it does
not return a value the calling function doen not return receive any data from the called function. Therefore, no
data between calling and called function.

No data communications

Arguments with no return type:


Here the calling function reads the data from the terminal and pass it on to the called function.

One-way data Communication

Ex:
The calling function has the statement value(500,0.5,5)
Here the argument are called actual arguments and the statement value(p,r,n) are called formal arguments. This
actual and formal should match in number type and order on one-to-one basis.

Arguments matching between the function call and called function


If the actual arguments are more than formals, the extra actual arguments are discarded. If the actual arguments
are less than the formal arguments, the unmatched formal arguments are initialized to some garbage values.
Mismatch also produces garbage, but no error messages.
Formals must be valid variables. The actual arguments may be variable names, expressions or constants.
The actual arguments must be assigned values before function call.

When a call is made, only one copy of the values of actual arguments is passed into the called
function.
Arguments with return values:
Some functions receives data from the calling function through arguments. It doesn't send back any
value but it prints the results at the terminal.
But an independent function(black box) that receives input will contain the output. This process is called
two way communication.

Two way data communication between functions


Ex:
return(sum);
The 'sum' is returned to the calling function and assigned to the 'amount' by the function call,
amount=value(principal,rate,time_period);
for this above call, the following events occur,
1. Values of actual arguments are transferred to the function 'value' and assigned to the formal
arguments, p,r,n respectively.
2. 'Value' is executed until return(sum); statement. This point passes the value 'sum' to the calling
function. The following indirect argument occurs.
Value(principal,rate,time_period)=sum;
3. On executing the calling statement, the returned values is assigned to the 'amount'.
Recursion:
The special process of recursion occurs when a function calls itself.
Ex:
main()
{
printf(This is an example of recursion);
main();
}
The output will be
This is an example of recursion
This is an example of recursion
This is an example of recursion
This is an example of recursion
This is an example of recursion
.....
.....
.....
The execution has to be terminated abruptly, otherwise it will continue infinite number of times.
Ex.2:
The factorial of a number n is expressed as a series of repetitive multiplication,
factorial of n = n.(n-1).(n-2)....1
The function is
factorial(n)
int n;
{

int fact;
if(n==1)
return(1);
else
fact=n*factorial(n-1);
return(fact);
}
In recursive functions we should have, if statement to force the function to return without recursive call,
otherwise the function will never end.
Functions with Arrays:
While calling of a function using arrays, the calling statement will have the array name and the size of
the array as its arguments.
Ex:
largest(a,n)
means array 'a' of size 'n'
The 'largest' function header might look like;
float largest(array,size);
float array[];
int size;
When array elements are passed to a function, the changes are copied to the original array. When we
pass arguments, only the address of arguments are passed. But the changes in the original array in the calling
function.
Scope and lifetime of variables in functions:
The 'scope' and 'longevity' of each of the following storage class are as follows,
1. Automatic Variables
2. Static Variables
Scope- area of activeness of variables.
Longevity- How far the variables are alive.
Automatic Variables:
These are declared inside the function in which they are utilized. During function call it is created and
destroyed during function exit(Auto). These are local or private variables and are also referred to as local or
internal variables.
When a variable is declared in a function without storage class specification(by default) it is automatic
variable.
Ex:
main()
{
int number;
...
...
}
We may also use 'auto' explicitly.
Ex:
main()
{
auto int number;

...
...
}

Feature of automatic variable is that its value cannot be accidentally changed by some other function
statements. So we can declare and use the same variable name in different function in a program without
compiler confusion.

Working:
main()
{
int m=1000;
function2();
printf(%d\n,m);
}
function1()
{
int m=10;
printf(%d\n,m);
}
function2()
{
int m=100;
function1();
printf(%d\n,m);
}
Output:
10
100
1000
Static Variables:
The value of the static variable remains until the end of the program.
Ex:
static int x;
static float y;
Depending on place of declaration this may be internal or external type. Internal Static variables are declared
inside a function. The scope(validity) of the variables extend upto the end of that function. At this point the
difference between static and auto variables is that, internal static variables can be used to return values between
function calls.
External static variables are declared outside the functions and available to all functions in the program.
Static External Variables are available only within the file where it id defined while the simple external variable
can be accessed by other files.
Ex:
main()
start()
{
{
int i;
static int x;
for(i=1;i<=3;i++)
x=x+1;
start();
printf(x=%d\nx);
}
}
When the program is compiled, static variable is initialized only once. It is never initialized again. So in the first

call x is 1. second time x is 2. But when x is an auto variable, each time x will be printed as 1. Because the auto
initialize x each time.

Storage Class

Scope and lifetime of Declarations


When declared

Visibility(Active)

Lifetime(Alive)

None

Before all functions in a


file (May be initialized)

Entire File+Other files


Entire program(Global)
where variable is declared
with extern

Static

Before all functions in a


file

Only in that file

Global

None or Auto

Inside a function

Only in that function or


block

Until end of the function


or block

Static

Inside a function

Only in that function

Global

Declaration and Return statements:


By default 'C' function returns int datatype. The following return statement returns the following
datatype
return(sum);
When we don't specify the type of data it returns only integer part of 'sum'. This is because of the absence of
type specifier in function header. So to receive a nun-integer datatype we must,
1. use explicit type-specifier
type-specifier function name(argument list)
argument declaration;
{
function statement;
}
Type specifier tells the complier, the type data it returns.
2. The called function must be declared at the starting in the calling function.
Ex:
main()
float mul(x,y)
float div(p,q)
{
{
{
float a,b,mul();
...
....
double div();
... ;
....;
...;
}
}
}
Function returning nothing:
When the function returns nothing we should declare it as 'void'.
Ex:
main()
{
int a,b;
void print ();
void value(a,b);
}
void print()
{
printf(Enter a and b\n);
printf(%d%d,&a,&b);

}
void value(int a,int b)
{
printf(Before swapping=%d%d\n,a,b);
printf(After Swapping=%d%d\nb,a);
}
Here the function returns nothing. They do simply the housekeeping work. So we should indicate that the return
type of the function is 'void' . We need to declare it in the calling functions.
Structures and Unions:
Structure is a method for packing data of different types (constructed datatype). So structure is a
convenient tool for handling group of logically related data items.
General Format:
Struct tag-name
{
data-type member1;
data-type member2;
...
};
Structure definition:
Ex:
Struct book-bank
{
char title[20];
char author[15];
int page;
float price;
};
The structure named 'book-bank'(as its tag-name) holds four fields 'title' 'author' 'page' and 'price' called structure
elements or members. Each member is of different type.
There is no declaration mentioned above but for the description of the template(format).
Using tag-name structure variables are declared anywhere in the program.
Ex:
struct book-bank
The complete declaration will be,
struct book-bank
{
char title[20];
char author[15];
int page;
float price;
};
struct book-bank1,book-bank2,book-bank3;
Members are not variables individually. It can occupy no memory space until used with structure variablename(ex-book1)
System rules:
1. Template should be always terminated by a semicolon.
2. The entire declaration is a single statement but inside each member is defined its datatype in
separate statement.

3. 'book-bank(tag-name)' is used to declare structure variables of its type, later in the program.
We can also declare the structure as follows,
struct book-bank
{
char title[20];
char author[15];
int page;
float price;
};
struct book1,book2,book3;
Structure definition should always be in global declaration part i.e after header files and before main() function.
Giving values to the members:
The members should be linked with variables to make them meaningful.
Ex:
Here 'title' alone has no meaning but 'title.book' has a meaning.
The link is established using member operator i.e '.' or 'dot operator' or 'period operator'.
Like this the member with variable name can be used like an ordinary variable name.
Ex:
scanf(%s\nbook1.title);
Structure Initialization:
This is similar to array initialization,
Ex:
main()
{
static struct
{
int weight;
float height;
}
student={60,185.75};
}
Here 60 is assigned to student.weight and 180.75 is assigned to stident.height.(one-to-one concordance). Here
ANSI C allows structures as an auto declaration. i.e after main().
Ex-2:
When we initialize two variables tag-name is essential,
main()
{
struct st-rec
int weight;
float height;
};
static struct st-rec student1={60,180.75};
static struct st-rec student2={53,120.50};
}
Ex-3(without static)
struct st-rec
{
int weight;
int height;

}student1={160,180.75};
main()
{
static struct st-rec student2={53,120.50};
....
....
}
We cant initialize members within the template, but only in actual variable declaration.
Comparison os structure variables:
Operation

Meaning

Person1=person2

Assign person2 to person1

Person1==person2

Compare members of person1 and person2. If


equal return 1 otherwise return 0

Person1!=person2

Return1 if all members are not equal, otherwise


Return 0.

Arrays of structures:
This describes the format of a number if related variables. Each of the elements represent one structure.
Ex:
struct class student[100];
Array name, student containing 100 elements each element of struct calss.
Declaration,
struct marks
{
int sub1;
int sub2;
int sub3;
}
main()
{
static struct marks student[3]={{45,68,81},{75,53,69},{57,36,71}};
}
Here the array contains 3 elements student[0],student[1],student[2];
Initialization:
student[0].sub1=45;
student[0].sub2=68;
student[0].sub3=81;
student[1].sub1=75;
student[1].sub2=53;
student[1].sub3=69;
student[2].sub1=57;
student[2].sub2=36;
student[2].sub3=71;
Arrays within structures:
We can use both single and multidimensional arrays as members of structures.

Ex:
struct marks
{
int number;
float sub[3];
}student[2];
The member sub[3] which has 3 elements can be accessed as,
student[1].sub[2];
This indicates the marks the second student in all 3 subjects.
Structures within structures:
Structures within a structure means nesting of structures.
Ex:
Struct salary
{
char name[20];
char depart[20];
int basic;
int DA;
int HRA;
int CA;
}employee;
Structures Vs Union:
1. Memory allocation (storage)
In case if structure, each member has its own storage location.
In unions all the members, use the same location.
2. Member Access:
In case of structure, we can access all the members at a time.
In unions, we can use only one member at a time.
3. Values assigned to members:
In Structures all members can be assigned different values
In unions one member can be assigned a value at a time and this value is shared by other members.
4. Declaration:
struct tag-name
{
datatype member1;
datatype member2;
};
5. Example:
struct code
union code
{
{
int x;
int x;
float y;
float y;
char z;
char z;
} item;
}:item:

Initialization of members:
In structures there is only one to one correspondence between the members and their initializing values.
In case of union, most of the compilers will accept an initial value for only one union member and they
will assign this value to the first member within the union.
Strings:
Putting Strings together:
We cannot join two strings as follows,
string3=stting1+string2;
The characters in string1 and string2. Should be copied into string3 one after the other. String3 should be large to
hold the characters.
Ex:
Process of combining two strings together is called concatenation.
#include<stdio.h>
main()
{
int i,j,k;
static char fname[10]={RAM};
static char sname[10]={SEETHA};
static char lase-name[10]={SRI};
char name[30];
for(i=0;f-name[i]!='\0';i++)
name[i]=f-name[i];
name[i]=' ';
for(j=0;s-name[j]!='\0';j++)
name[i+j+1]=s-name[j];
name[i+j+1]=' ';
for(k=0;last-name[k]!='\0';k++)
name[i+j+k+2]=last-name[k];
name[i+j+k+2]='\0';
printf(\n\n%s\n,name);
}
Comparison of two strings:
We can't compare two strings directly. The Example is invalid,
Ex:
if(name1= =name2)
if(name=ABC)

We should test character-by-character. The comparison is done until mismatch or one of the string terminates
with null
i=0;
while(st1[i]= = st2[i] && st1[i]!='\0' && st2[i]!='\0')
i++;
if(st1[i]= = '\0' && st2[i]= ='\0' )
printf(Strings are equal\n);
else
printf(Strings are not equal\n);
String Handling functions:
These functions carry out many of string manipulates. The functions are
FUNCTION
MEANING
Strcat()

Concatenates two strings

Strcmp()

Compares two strings

Strcpy()

Copies one string over the other

Strlen()

Finds the length of the string

Strcat Function:
This function joins two strings.
General Format:
strcat(string1,string2);
string2 is appended to string1. The null character at the end of the string1 is removed and string2 is placed there.
String2 remains unchanged.
Ex:

when we use strcat(p1,p2), result will be


0 1 2 3 4 5 6 7 8 9 10 11 12

p1 should be large enough to hold the final result.


Nesting of string is also possible
The statement strcat(strcat(st1,st2),st3); concatenates all 3 strings together and result is stored in string1.
User defined program for concatinating two strings:
void main()
{
int i,j,l,ls;
char a[80],b[80];
printf("\nEnter main string:-\n");
gets(a);
printf("enter the string to be concatinated\n");

gets(b);
l=strlen(a);
ls=strlen(b);
for(i=l,j=0;j<=ls;i++,j++)
a[i]=b[j];
printf("\n\nconcatinated string is ");
puts(a);
}
Strcmp() function:
This compares two strings and if the two strings are equal the value is zero. Otherwise it has a numeric
difference between the non-matching characters.
General Format:
strcmp(string1,string2);
string 1 or 2 may be string variable or string constant.
Ex:
x=strcmp(name1,name2);
y=strcmp(name1,RAM);
z=strcmp(there,their);
we should determine whether the strings are equal or not. If not which is alphabetically. The last example will
retuen the value of 9, difference between ASCII 'i' and 'r'. i.e 'i' to 'r'. If the value is negative the string1 is
alphabetically above string2.
User defined program for comparing two strings:
void main()
{
int i,j,k=0,l,k1;
char a[80],b[80];
printf("\nEnter main string:-\n");
gets(a);
printf("\nEnter sub-string:-\n");
gets(b);
l=strlen(b);
k1=strlen(a);
for(i=0,j=0;(i<l-1)||(j<k1-1);i++,j++)
{
if(a[i]==b[j])
k=1;
if(a[i]!=b[j])
{k=0;
break;
}
}
if (k==1)
printf("strings are equal\n");
else
{if(k==0)
printf("\n\nstrings are not equal.");}
}
Strcpy() function:

This is like string assignment operator.


General Format:
strcpy(string1,string2);
The contents of string2 are assigned to string1. String2 may be character, variable or string constant.
Ex:
strcpy(city, DELHI);
strcpy(city1,city2);
Here the size of city and city1 must be large.
User defined program for copying one string into another:
void main()
{
int i,j,l,ls;
char a[80],b[80];
printf("\nEnter main string:-\n");
gets(b);
ls=strlen(b);
for(i=0,j=0;j<=ls-1;i++,j++)
a[i]=b[j];
printf("\n\ncopied string is %s ",a);
}
Strlen() function:
This function counts the number of characters in the string
General Format:
n=strlen(string);
n is an integer variable which receives the value of the length string. String may be a string constant. The
counting of the string ends with the first null.
User defined program for calculating string length:
#include<stdio.h>
#include<conio.h>
void main()
{
int i=1;
char a[25];;
printf("any number\n");
while((a[i]=getchar())!='\n')
i++;
printf("lenght is %d",i-1);
}
Table of Strings:
When we use a list of names, we treat it as a table of string and stored in two dimensional array.
Ex.1:
student[30][15];
The above statement is used to store 30 names in the length of 15[each name's length].
Ex.2:
String assignment and declaration:
static char city[][]
{
chandigarh;
Madras;
Bombay;

}
Here city[0] denoted chandigarh. Therefore when we declare two dimensional array, we can use it as one
dimensional array. The table can be treated as a column of strings.

Pointers:
Reasons for using pointers:
1. A Pointer enables us to access a variable that is defined outside the function.
2. Pointers are more efficient in handling the data tables.
3. Pointers reduce the length and complexity of the program.
4. Increases the execution speed.
5. The use of pointer array to char strings results in saving of data storage space in memory.
Introduction
Each storage byte in the memory is numbered with an address. Addresses are numbered from 0. the last
address is 65,535 for 64k memory.
Whenever we declare a variable, the system allocates an appropriate location to hold the values of the
variable.
Ex:
int x=10;

\
Memory Organization

Representation of a variable

In the above example, value of x is allocated at the location 5000.Since memory addresses are simply
numbers they can be assigned to some variables which can be stored in the memory. The variable that hold
'memory addresses' are called 'pointers'.
Definition:
A pointer is a variable that contains an address which is a location of another variable in memory. Since
pointer is a variable, its value is also stored in memory an another location. Let the address of x be assigned to a
variable p.

P points the address of the variable X.


Accessing the address of a variable:
The actual location of a variable in the memory is system independent. Therefore the address of a
variable is not known immediately.
The address of a variable can be determined with the help address operator. The operator ambersand '&'
immediately preceding a variable, returns the address of the variables associated with it,
p=&quantity;
The above statement would assign the address of the variable 'quantity' to p.
Invalid use of '&' operator:
1. pointing at constants. Ex &125
2. pointing at array name or expressions
Ex:
int x[10];
&x;
&(x+y);
3. If x is an array,
&x pointing at the first element of the array- valid.
&(i+3) pointing at the (i+3)th element of array x- valid.
Declaration and initialization of pointers:
The declaration of pointer variable will be,
datatype*pointer-name;
From this the compiler understands the following.
1. The asterisk(*) tells that pointer-name is a pointer variable.
2. Pointer-name needs a memory location
3. pointer-name points to a variable of type 'datatype'
Ex:
int *p;
This declares the pointer variable p. Hence p points the integer variable.
Initialization
Process of making the pointer to point to a variable using an assignment statement is called initialization.
Ex:
int *p;
This declares the variable p as a pointer variable that points to an integer datatype. 'int' refers to the
datatype of variable being pointed to by 'p'. and not the type of the value of the pointer.
Ex
float*x;
X as a pointer variable pointing to a float, we can use it in assignment as
p=&qunatity;
which points p to quantity. Therefore p contains address of quantity. pointer initialization.

Ex 2:
Invalid pointer declarations
1. float a,b;
int x, *p;
p=&a;
b=*p;
The above data assignment is
invalid vecause we should not
assign a float value to an int
pointer.

2. int *pt;
pt=5000;
The above statement is invalid because, the
pointer is assigned to absolute address .

Ex 3:
Pointer Variables can be initialized in its declaration itself.
Ex:
int x, *p =&x is equivalent to int x, *p; p=&x;
This declares x as an integer variable and 'p' to the pointer variable and then initialized p to the address
of x. Address will be assigned only to p and not *p.
Accessing a variable through its pointer
After a pointer has been assigned the address of the address of the variable, the value of the variable can
be accessed by unary operator. '*' is known as indirection operator.
Ex:
int q,*p,n;
q=10;
p=&q;
n=*p;
The first statement declares q and n of the integer data, p as a pointer variable pointing to an integer value. In
Second statement the value 10 is assigned to q. In the third statement the address of the variable 'q' is assigned
to p. In fourth statement the contents of p are assigned to n.
Pointer Expression
Like other variables, pointer variables can be used in expressions. If p1 and p2 are pointers, then the
following statements are valid.
Y=*p1 * *p2 ; is equivalent to y=(*p1)*(*p2);
sum=sum+*p1;
z=5*-*p2/*p1; is equivalent to (5*(-(*p2)))/*p1;
*p2=*p2+10;
z=5*-p2/*p1 is invalid because /* is considered to be the beginning of a comment. There should be a blank space
between / and *
The following arithmetic operators are allowed in C
1. Subtract one-pointer from another.
2. If p1 and p2 are arrays, p1-p2 gives the number of elements between p1 and p2.
Pointers can be compared using relational operators.
3. If p1 and p2 are both pointers to the same array,
p1>p2
p1==p2
p1!=p2
comparisons can be meaningfully in handling arrays and strings.
4. Invalid Operators
1. Pointers in division or multiplication

p1/p2 or p1*p2 or p1/3


5. Two pointers cannot be added. P1+p2 is invalid.
Pointer increments and scalar factor
When a pointer is incremented, its value is increased by the length of the datatype that it points to. This
length is called scalar factor.
Ex: p1++;
If p1 is an integer pointer with initial value 2000 then,
p1++ p1+1;
2000+1*length of int
2000+1*2
= 2002
Ex:
p2=p2+2
If p2 is a float pointer with initial value 200, then
p2+2
200+2*length of float
200+2*4
208
Pointers and arrays
When an array is declared the compiler allocates a base address(location of first element index 0) and
sufficient amount of storage for all the elements of the array in continuous memory locations.
Compiler also defines the array name as a constant pointer to the first element
Ex:
int x[5]={10,20,30,40,50};
Elements

A[0]

A[1]

A[2]

A[3]

A[4]

value

10

20

30

40

50

address

1000

1002

1004

1006

1008

P+1

P+2

P+3

P+4

Now the base address 1000 is stored in the array name x.


Pointer to an array,
int *p;
int x[5];
p=x; or p=&x[0];
Note: By assigning starting address of an array to a pointer variable, we can make the pointer to an array.
In the above example relationship between x and p is
p=&x[20] (1000)
p+1=&x[1] (1002)
p+4=&x[4] (1008)
and *(p+4) gives the value of x[4] is 50.
Pointers and character strings
A string is an array of characters terminated with a null character. Like one dimensional array, we can
use a pointer to access the individual characters in a string. Constant character string always represents a pointer
to that string.
Char=*name;

name=DELHI; Valid
But
char name[20];
name= DELHI; Invalid
Handling of table of strings
char name[3][3];
This declaration, totally allocates 75 bytes. But all the strings will not be of equal lengths. Instead of
making each row a fixed length, we can make it to a pointer to a string of varying length.
Ex:
char *name[3]={ DELHI INDIA AUSTRALIA};
The above statement declares the name to be an array of 3 pointers to character, each pointer pointing to a
particular name as shown below.
Name[0]DELHI

\0

Name[1]INDIA

\0

Name[2]AUSTRALIA
This allocates 22 bytes.

To print 3 strings,
for(i=0;i<3;i++)
printf(%s\nname[i]);
To access the first character in the first name, *(name[i]+j) statement is used.
Ragged Arrays
The character arrays with rows of varying length are called ragged arrays
Pointers and Functions
There are two methods for calling a function.
1. Call by reference
The process of passing sctual value of the variables is known as call by value.
Ex:
main()
{
int x,y;
scanf(%d%d&x,&y);
printf(\n%dmull(&x,&y));
/*The function mul() is referenced by passing the address of the variables*/
}
mul(int*a,int*b)
/*To receive the address,formal parameters as declared as pointer variables */
{
return((*a)*(*b));
}
Points
1. Function parameters are declared as pointers.
2. The referenced pointers are used in the function body.
3. When the function is called, the addresses are passed as actual arguments.
Note

\0

Call by reference provides a mechanism by which a function can change the stored values in the calling
function.
Pointers to functions
Like variables, a function has an address location in the memory. A pointer to a function is declared as
follows,
type(*fptr)();
fptr is a pointer to a function which returms the type. The parenthesis around *fptr are necessary. If we omit
parenthesis then,
type *fptr();
This would be declared as a fptr function returning a pointer to type.
Ex:
for function pointer,
double(*p1)(), mul();
p1=mul();
The above example declares p1 pointer to a functional
mul() a function that returns a double value
p1=mul assigns the starting address of the function mul() to the pointer variable p1.
Function reference
(*p1)(x,y); This function is equivalent to mul(x,y);
Pointers and structures
Like arrays, starting address os structure array is stored in structure array name.
Ex:
struct student
{
char name[20];
int rno;
}s1[10],*ptr;
Now ptr=s1;
This statement assigns the starting address s1[0] to ptr.
Individual member access
Using pointers, structure members can be accessed by using 'arrow operation'.
Ptr name
ptr rno
When ptr is incremented by 1,(ptr+1) it points to s1[1]. Alternatively, instead of arrow operation, the following
statement can also be used.
*ptr.member name
Ex.1
*ptr.name
Ex.2
struct
{
int count;
float *p;
}*ptr;
1) ++ptr = count;
Both the ++ and have the same priority and the associativity is from Right left. The above
increments count.

2) (++ptr) count;
The above statement first increments ptr and then links count.
3) Ptr++ count;
The above statement increments ptr after accessing count.
4) *ptr p; (Right Left)
fetches whatever p points to
5) *ptr p++;
Increments p after accessing whatever p is pointing to.
6) (*ptr p)++;
increments whatever p points to.
7) *ptr++ p;
Increments ptr after accessing whatever it points to.
Note:
A pointer contains a garbage value until it is initialized.
Bitwise operator:
To manipulate the data at the bit level bitwise operators are used.
The operators are
1. logical bitwise operator
2. shift operators
3. complement operators
These operators are used in settling a particular bit or a group of bits to 1 or 0. they are also used to
perform certain numerical computation faster.
1. Bitwise AND (&)
2. Bitwise OR (|)
3. Bitwise exclusive OR (^)
These requires two binary operators. These operators work on their operands bit by bit starting from the
least significant bit, setting each bit in the result as shown below,

op1

Result of the LOGICAL BITWISE OPERATORS


op2
Op1&op2
Op1|op2

Op1^op2

Ex 1:
#define TEST 8
main()
{
int flag;
if((flag & TEST)!=0)
{
printf(\n Fourth bit is set\n);
}
}
Bitwise shift operator:

a) Left shift: op<<n


b) Right Shift op>>n
These operators used to move bit patterns either to the left or to the right. The operator symbols are <<
and >>.
In the above form op is the integer expression that is to be shifted and n is the number of bit positions to
be shifted.
The left shift(right shift) operation causes the op bits to be shifted left(right) by n positions. The
leftmost(rightmost) n bits is the original bit pattern will be lost and the rightmost(leftmost) n bit positions that
are vacated will be with os.
There are two restrictions on the value of n. It may not be negative and it may not exceed the number of
bits used to represent the last operand 'op'.
Ex:
x=0100 1001 1100 1011
x<<3=0100 1110 0101 1000 vacated positions
x>>3=0000 1001 0011 1001
Ex.2:
x=y<<1;
Shift operators are often used for multiplication and division by powers of two. The often statement shifts one bit
to the left in y and then the results is assigned to x. The decimal value of x will be the value of y multiplied by
2.
x=y>>1;
Bitwise complement operator:
The complement operator ~ is an unary operator and inverts all the bits representes by its operand. That
is 0's become 1s and 1s become 0.
Ex:
x=1001 0110 1100 1011
~x=0110 1001 0011 0100
This operator is often combined with the bitwise AND operator to the turn off a particular bit.
Ex:
x=8;
flag=flag8~x;
would turn off the fourth bit in the variable flag.
Dynamic memory allocation
The process of allocating the memory during the runtime is known as dynamic memory allocation.
Memory allocation function:
Function

Task

malloc

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

calloc

Allocates space for an array of elements, initializes them to 0 and then


returns a pointer to the memory

free

Frees the previously allocated space

realloc

Modifies the size of previous allocated space.

Files:
A file is a place on disc where a group of related data is stored. The basic operations are,
1.naming the file- opening the file
2.reading data from the file
3. writing data to a file and
4. closing a file
High level I/O function for handling files:
S.NO

Function name

Operation

1.

f open ( )

1.Creates a new file


2. Opens an existing file

2.

f close()

Closes a file which has been opened for use

3.

getc()

Reads a character from a file

4.

putc()

Write a character to a file

5.

f prinf

Writes a set of data values to a file

6.

f scanf

Reads a set of data values from a file

7.

getw

Reads an integer from a file

8.

putw

Writes an integer to a file

9.

f seek()

Sets the position to a desired point in the file

10.

f tell()

Gives the current position in the file

11.

rewind

Sets the position to the beginning of the file

Defining and opening a file:


To store data in a file in the secondary memory,we have to include
1. File name
2. Data structure
3. Purpose
Filename (string of characters)
Ex: 1. test.c
2.output
To define data structure, a defined datatype file is used.
When we open a file, we have to specify what we want to do with the file, i.e either write data to the file
or read the already data from the file.
The general format for declaring and opening a file is
FILE *fp;
fp=fopen(filename, mode);
The first statement declares the variable fp as a pointer to the datatype FILE.

The second statement opens the file named filename and assigns an identifier to the FILE pointer fp.
Mode can be one of any of the following:
r-open a file for reading only
w-open a file for writing only
a- open a file for appending data to it.
Ex:
FILE *p1,*p2;
p1=fopen(data, r);
p2=fopen(results w);
In this, file data- opened for reading
results- opened fpr writing
While opening a file, the following things may happen,
Writing mode:
The file with the specified name is created if the file doesn't exist. If the file already exists, the contents
are deleted.
Reading mode:
If the file already exists, file is opened with the current contents safe. Otherwise an error occurs.
Appending mode:
If the file already exists, the file is opened with the current contents safe. Otherwise a file with specified
name is created.
NOTE:
1. Any number of files can be opened and used at a time(number depends on the system)
2. Recent compilers include additional modes of operations.
r+- Existing file is opened to the beginning for both reading and writing.
w+- Both for reading and writing.
a+- Same as a except for both reading and writing.
Closing a file:
A file must be closed as soon as all operations on it have been completed.
Closing of a file,
1.ensures that all outstanding information associated with the file is flushed out from the buffers and all
links to the file are broken.
2.it also prevents any accidental misuse of file.
3.helps to reopen the same file in a different mode.
I/O library function for closing a file is
fclose(file-pointer);
Ex:
FILE p1,p2;
p1=f open(test, w);
p2=f open(output, v);
fclose(p1);
fclose(p2);
NOTE:

1. Once a file is closed its file pointer can be reused for another file.
2. Whenever a program terminates,all files are closed automatically
I/O operations on a files:
getc() and putc() functions:
The simplest file I/O functions are getc() and putc()
General Format:
putc(c,fp1);
fp1-file pointer.
c-character variable.
This statement writes the character contained in the character variable C.
Similarly getc()- to read a character from a file.
C=getc(fp2);
For arrray operation of getc or putc moves the file pointer by one character position. The getc will return an endof-file marker EOF when the end of a file has been reached.
getw and putw functions:
The getw and putw are integer oriented function. They are similar to the getc and putc functions and are
used to read and write integer values. The general forms of getw and putw are
putw(integer,fp);
fp-file pointer
getw(fp);
integer-integer-variable
Ex:
1. Program to read the number from integer data file and write all odd numbers to a file ODD and
all even numbers to a file EVEN.
#include<stdio.h>
main()
{
FILE f1,f2,*f3;
int n,i;
/* Create a data file */
f1=fopen(data, w);
for(i=1;i<=20;i++)
{
scanf(%d,&n);
putw(n,f1);
}

fclose(f1);
f1=fopen(DATA, v);
f2=fopen(ODD, w);
f3= fopen(EVEN, w);
while((n!=getw(f1))!=EOF)
{
if(n%2==0)
/*Write to even file*/
putw(n,f3);
else
/*Write to odd file*/
putw(n,f2);
}
fclose(f1);
fclose(f2);
fclose(f3);
/*To display the content of ODD and EVEN files*/
f2=fopen(ODD, v);
f3=fopen(EVEN, v);
while((n=getw(f3))!=EOF)
printf(\n%d,n);
fclose(f2);
fclose(f3);
}
fprintf and fscanf functions:
To handle a group of mixed data simultaneously,we use two function fscanf and fprintf.
Similar to printf and scanf except that they work on files.
General Format of fprintf:
fprintf(fp, control string,list);
fp-file pointer
control string-O/P specifications for items in the list
list-list of variables.
Ex.1:
fprintf(f1%s%d%f,name,age,7.5);
General Format of fscanf:
fscanf(fpcontrol string,list of address of variables);
Ex 2:
fscanf(f2 %s%d,&name,&quantity);
Error handling I/O operations:
These are two functions feof and f errorf to detect I/O errors in the files. The 'feof' function can be

used to test for an end of file condition.


General Format:
feof(file pointer);
This function returns non-zero integer i.e if all the data from the specified file has been read, zero otherwise.
ferror:
This ferror function reports the status of the file indicated. It takes a file pointer as its arguments.
General Format:
ferror(fp);
returns non-zero integer, if an error occurs zero-otherwise.
Ex:
if(ferror(fp)!=0)
printf(\n Error has occurred);
Whenever a file is opened using fopen function, a file pointer is returned. If the file can't be opened, then
the function returns a null pointer.
Ex:
if(fp=NULL)
printf(\n file could not be opened);
Random Access to File:
To access only a particular part of a file and not in reading other parts, we can use the following
functions.
(i)fseek (ii)ftell and

(iii)rewind

ftell:
ftell takes a file pointer and returns a number of type long, that corresponds to the current position.
n=ftell(fp);
rewind:
rewind takes a file pointer and resets the position to the start of the file.
Ex:
rewind(fp); /* position of the file*/
a=ftell(fp); /* pointer to the beginning of the file ('0')*/
Now 'n' is assigned a value of ZERO
NOTE:
1. The first byte in the file is membered as 0, Second as 1 and so on.
2. rewind function is used to read a file more than once, without having to close and open the file.
fseek:
This function is used to move the file position to a desired location within the file.
General Format:
fseek(file ptr, offset, position);

fileptr
offset

pointer to the file concerned


specifies the number of positions (bytes) to be moved
from the location specified by position

position can take one of the following three values:


value

meaning

beginning of file

current position

end of the file

statement

meaning

fseek(fp,ol,0)

go to beginning similar to rewind

fseek(fp,ol,1)

stay at current

fseek(fp,ol,2)

go to end of the file

fseek(fp,m,0)

move to (m+1)th byte in file

fseek(fp,m,1)

go forward by m bytes

fseek(fp,-m,1)

go backward by m bytes from the current position

fseek(fp,-m,2)

go backward by m bytes from the end

When the operation is successful, fseek returns a zero. Returns 1 when an error occurs.
PREPROCESSOR:
The preprocessor is a program that processes the source code before it passes through the compiler. It
operate under the control of preprocessor command lines or directives. Preprocessor directives are placed in the
source program before the main line. They all begin with the symbol # in column 1 and do not require a
semicolon at the end.
The directives can be divided into
1. Macro substitution directives
2. File inclusion
3. Compiler control directives
Macro Substitution:
It is a process where an identifier in a program is replaced by a predefined string composed of one or
more tokens. The preprocessor accomplishes this task under the direction of #define statements.
This statement, usually known as macro definition or macro.
#define identifier string
Identifier-valid c name
string-may be any text
In this statement is included in the program at the beginning, the preprocessor replaces every occurrence
of the identifier in the source code by the string.
There are three forms of Macro substitution
1. Simple Macro Substitution

2. Arguments Macro Substitution


3. Nested Macro Substitution
Simple Macro Substitution:
Simple string replacement is commonly used to define constants.
Ex:
#define COUNT 100
#define FALSE 0
#define CAPITAL DELHI
A Macro definition can include expressions.
Ex 2: #define TEST if(X>Y)
#define AND
#define PRINT printf(VERY GOOD);
If the source program contains, TEST AND PRINT
The preprocesor translates in the following way

if(X>Y) printf(VERY GOOD);


other examples,
#define AND &&
#define OR ||
In place of && symbol we can use AND. Similarly in the place of the symbol || we can use OR
Macros with Argument:
General Format:
#define identifier(f1,f2...,fn) string;
NOTE:
No space between Macro identifier and the left parenthesis.
f1,f2...fn are called formal macro arguments.
Macro call:
Occurrence of macro with actual arguments is known as macro call. When a macro is called the the
preprocessor substitutes the string, replacing the formal parameters with actual parameters.
Ex:
#define CUBE(X) (X*X*X)
If in the program, we refer the macro volume = CUBE(SIDE);
preprocessor would expand this to volume=(SIDE*SIDE*SIDE);
Suppose if the macro call is as follows,
volume=CUDE(a+b);
preprocessor would expand this as follows,
volume=(a+b*a+b*a+b);
This will not produce correct results, because preprocessor performs a blind text substitution of the
argument a+b in place of X.
This can be corrected by enclosing individual formal parameters with parenthesis as follows,
#define CUBE(X) ((X)*(X)*(X));
Nesting of Macros:
Use of one Macro in a definition of another macro is referred to as nesting of macros.

#define M 5
#define N M+1
#define SQUARE(X) ((X)*(X))
#define CUBE (SQUARE (X)*(X))
For macro call,
volume=CUBE(side);
It is first expanded by preprocessor as follows,
SQUARE(X)*(X)
ie SQUARE (side)*(side)
Then (side)*(side)*(side)
Undefining a Macro:
A defined macro can be undefined using the statement,
#undef identifier
File Inclusion:
An external file containing functions or macro definitions can be included as a part of program by the
following preprocessor directive.
#include filename

#include (filename)

Where the filename-name of the file containing the required definitions or functions.
Now the preprocessor inserts the entire contents of filename into the source code of the program
Ex:
#include TEST.C- This command would look for the file TEST.C in the current directory as well as in the
specified list of directories.
(STANDARD DIRECTORIES)
#include<TEST.C>- This command would look for the file TEST.C in the specified list of directories only.
Compiler Control Directives:
while developing large programs the following situation may arise:
1. We want to know whether a particular macro has been defined in the included file.
2. Try to use the same program that will run on two different types of computers, although certain
lines of code must be different for each system and so on.
Solutions to these problems is to develop a single comprehensive program that includes optional codes and then
directs the compiler to skip over certain parts of the source code when they are not required.
'C'-preprocessor offers a feature known as conditional compilation which can be used to switch ON or OFF a
particular line or group of lines in a program.
Ex 1:

#include DEFINE.H
#include TEST
#include TEST 1
This with check whether the macro TEST is defined in the header file and not to define that macro.
#ifdef TEST-searches for the definition if the TEST in the headerfile and if not defined all the lines between
#ifdef and #endef are left active in the program.
Additionals :
Mathematical functions:

One of the standard I/O library math.h should be included for using these functions.
FUNCTIONS

MEANING

TRIGONOMETRIC
Acos(x)

Arc cosine of x

Atan(x)

Arc tangent of x

Asin(x)

Arc sine of x

Atan2(x)

Arc tangent of (x/y)

Cos(x)

Cosine of x

Sin(x)

Sine of x

Tan(x)

Tangent of x
HYPERBOLIC

Cosh(x)

Hyperbolic cosine of x

Sinh(x)

Hyperbolic sine of x

Tanh(x)

Hyperbolic tangent of x

OTHER FUNCTIONS
Ceil(x)

X rounded up to the nearest integer

Exp(x)

E to the power of x (^x)

Fabs(x)

Absolute value of x

Floor(x)

X rounded down to the nearest integer

Fmod(x,y)

Remainder of x/y

Log10(x)

Base of log of x x>0

Pow(x,y)

X to the power y

Sqrt(x)

Square root of x x>=0

Reading a character:
The simplest of all the I/O operations in reading a character from the standard input unit and writing it to
the standard output unit. Reading a single character can be done by using the function getchar.
General Format:
Variable-name=getchar();
Variable-name is a valid C name declared as char. The computer waits until a key is pressed and assigns this
value to getchar function.
Char name;
name= getchar();
Since getchar is a function, it requires a lot of parameters as shown,
The getchar function may be called successively to read the characters contained in a line of text.
The following program segment reads the characters from the keyboard one after another until
RETURN key is pressed.
Char character;
character='';
while (character!='\n')

{
character=getchar();
}
using getchar() we can also check the input as in the following table. For using these functions we should
include #include<ctype.h>
FUNCTION

TEST

Isalnum(c)

Is c an alpha numeric character?

Isalpha(c)

Is c an alphabetic character?

Isdigit(c)

Is c a digit?

Islower(c)

Is c a lower case letter?

Isupper(c)

Is c an uppercase letter?

Isprint(c)

Is c a printable charcater?

Ispunct(c)

Is c a punctuation mark?

Isspace(c)

Is c a white space character?

Writing a character:
Like getchar() there is a function putchar() for writing characters one at a time to the terminal.
General Format:
Putchar(variable-name);
Variable-name is of the type char. This statement displays the character contained in the variable name at the
terminal.
Ex-1:
answer='y';
putchar(answer);
will display the character y in the screen. The statement putchar('\n'); would cause the cursor on the screen to
move to the beginning os the next line.
Ex-2:
using putchar we can convert the input character to lower case or uppercase with the functions
toupper(c) and tolower(c).
External Variables:
Variables that are alive and active throughout the program are known as External variables. They are
also known as Global Variables. These variables can be accessed using any function. They must be declared
outside the function.
Ex:
int x;
main()
{
x=10;
printf(x=%d\n,x);
printf(x=%d\n,func1());
printf(x=%d\n,func2());
printf(x=%d\n,func3());
}

func1()
{
x=x+10;
return(x);
}
func2()
{
int x;
x=1;
return(x);
}
func3()
{
x=x+10;
return(x);
}
Output:
x=10
x=20
x=1
x=30
Here x is declared above all the functions. So it is not needed to pass it as arguments. Any function can
use it and change the value. Function2 has the definition x=1. So here local variable has the precedence over the
global.
Ex 2:
main()
{
y=5;
...
...
}
int y;
func1()
{
y=y+1;
}
In the main() function y is not declared. So an error message will be displayed. Global variables will be
initialized to 0 by default. Therefore the output if the above program is 1(y=0+1).
Register Variables:
Normal variables are stored in memory. Register is a temporary storage and faster accessing capacity
than memory. So the registers lead to faster execution of programs.
Ex:
register int count;
Only a few variables can be placed in registers. Once the limit is reached 'c' automatically convert the register
variables into non register variables. So we can have to select the variables carefully.
The following table summarizes the information on the visibility and lifetime of variables in functions
and files

A ceiling is the smallest integral value greater than or equal to a number.


ceil(3.001)=4
Floor function:
floor(1.2) returns 1.0
Truncate function:
The truncate functions return the integral in the direction of 0. They are the same as the floor function for
positive numbers and the same as ceiling function for negative numbers.
trunc(-1.1) returns -1.0
trunc(1.9) returns 1.0
Round function:
The round functions return the nearest integral value.
round(1.9)=2.0
Power function:
The power (pow) function returns the value of the raised to the power y.
pow(3.0,4.0) return 81.0
Square root function:
The square root functions return the non negative square root of a number. An error occurs if the number is
negative.
sqrt(25) returns 5.0
Shorthand structure with typedef keyword
To make the source code more concise, we can use typedef keyword to create a synonym for a structure. This is
an example of using typedef keyword to define address structure, so when we want to create an instance of it we
can omit the keyword struct
typedef struct
{
unsigned int house_number;
UNIONS
Union is user defined data type used to stored data under unique variable name at single memory location. Union
is similar to that of structure. Syntax of union is similar to structure.
But the major difference between structure and union is 'storage.' In structures, each member has its own
storage location, whereas all the members of union use the same location. Union contains many members of
different types, it can handle only one member at a time.
To declare union data type, 'union' keyword is used.
Union holds value for one data type which requires larger storage among their members.

Syntax:
union union_name
{
<data-type> element 1;
<data-type> element 2;
<data-type> element 3;
}union_variable;
Example:
union techno
{
int comp_id;
char nm;
float sal;
}tch;
In above example, it declares tch variable of type union. The union contains three members as data type of int,
char, float. We can use only one of them at a time.
MEMORY ALLOCATION :
To access union members, we can use the following syntax.
tch.comp_id
tch.nm
tch.sal
Program:
#include <stdio.h>
#include <conio.h>
union techno
{
int id;
char nm[50];
}tch;
void main()
{
clrscr();
printf("\n\t Enter developer id : ");
scanf("%d", &tch.id);
printf("\n\n\t Enter developer name : ");
scanf("%s", tch.nm);
printf("\n\n Developer ID : %d", tch.id);//Garbage
printf("\n\n Developed By : %s", tch.nm);
getch();
}
Output :
Enter developer id : 101
Enter developer name : technowell
Developer ID : 25972
Developed By : technowell_
Difference between Structure and Union:
Structure
Union
i. Access Members
We can access all the members of structure at anytime.
Only one member of union can be accessed at anytime.
ii. Memory Allocation
Memory is allocated for all variables.

Allocates memory for variable which variable require


more memory.

iii. Initialization
All members of structure can be initialized
iv. Keyword
'struct' keyword is used to declare structure.
v. Syntax
struct struct_name
{
structure element 1;
structure element 2;
------------------structure element n;
}struct_var_nm;
vi. Example
struct item_mst
{
int rno;
char nm[50];
}it;

Only the first member of a union can be initialized.


'union' keyword is used to declare union.
union union_name
{
union element 1;
union element 2;
------------------union element n;
}union_var_nm;
union item_mst
{
int rno;
char nm[50];
}it;

Enumerations
An enumeration is a data type consisting of a set of named values that represent integral constants, known as
enumeration constants.
An enumeration also referred to as an enumerated type because we must list (enumerate) each of the values in
creating a name for each of them. In addition to providing a way of defining and grouping sets of integral
constants, enumerations are useful for variables that have a small number of possible values.
ENUM is closely related to the #define preprocessor.
It allows you to define a list of aliases which represent integer numbers. For example if you find yourself coding
something like:
#define MON 1
#define TUE 2
#define WED 3
You could use enum as below.
enum week { Mon=1, Tue, Wed, Thu, Fri Sat, Sun} days;
or
enum escapes { BELL = '\a', BACKSPACE = '\b', HTAB = '\t',
RETURN = '\r', NEWLINE = '\n', VTAB = '\v' };
or
enum boolean { FALSE = 0, TRUE };
An advantage of enum over #define is that it has scope This means that the variable (just like any other) is only
visable within the block it was declared within.
We can declare an enumeration type separately from the definition of variables of that type.We can define an
enumeration data type and all variables that have that type in one statement
Enumeration type definition
An enumeration type definition contains the enum keyword followed by an optional identifier (the enumeration
tag) and a brace-enclosed list of enumerators. A comma separates each enumerator in the enumerator list. C99
allows a trailing comma between the last enumerator and the closing brace.
Enumeration definition syntax
enum tag_identifier{enumerators list};
The tag_identifier gives a name to the enumeration type. If we do not provide a tag name, we must put all
variable definitions that refer to the enumeration type within the declaration of the type. Similarly, we cannot use

a type qualifier with an enumeration definition; type qualifiers placed in front of the enum keyword can only
apply to variables that are declared within the type definition.
Enumeration members
The list of enumeration members, or enumerators, provides the data type with a set of values.
Enumeration member declaration syntax
Identifier= enumeration constant
In C, an enumeration constant is of type int. If a constant expression is used as an initializer, the value of the
expression cannot exceed the range of int (that is, INT_MIN to INT_MAX as defined in the header limits.h).
Enumeration type and variable definitions in a single statement
We can define a type and a variable in one statement by using a declarator and an optional initializer after the
type definition. To specify a storage class specifier for the variable, we must put the storage class specifier at the
beginning of the declaration. For example:
register enum score { poor=1, average, good } rating = good;
Either of these examples is equivalent to the following two declarations:
enum score { poor=1, average, good };
register enum score rating = good;
Both examples define the enumeration data type score and the variable rating. rating has the storage class
specifier register, the data type enum score, and the initial value good.
Combining a data type definition with the definitions of all variables having that data type lets you leave the data
type unnamed. For example:
enum { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday } weekday;
This defines the variable weekday, which can be assigned any of the specified enumeration constants. However,
we can not declare any additional enumeration variables using this set of enumeration constants.
Example:
#include <stdio.h>
int main()
{
enum Days{Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday};
Days TheDay;
int j = 0;
printf("Please enter the day of the week (0 to 6)\n");
scanf("%d",&j);
TheDay = Days(j);
if(TheDay == Sunday || TheDay == Saturday)
printf("Hurray it is the weekend\n");
else
printf("Curses still at work\n");
return 0;
}
Bit Fields
In addition to declarators for members of a structure or union, a structure declarator can also be a specified
number of bits, called a "bit field." Its length is set off from the declarator for the field name by a colon. A bit
field is interpreted as an integral type.
Bit Fields allow the packing of data in a structure. This is especially useful when memory or data storage is at a
premium. Typical examples:
Packing several objects into a machine word. e.g. 1 bit flags can be compacted -- Symbol tables in compilers.
Reading external file formats -- non-standard file formats could be read in. E.g. 9 bit integers.
C lets us do this in a structure definition by putting :bit length after the variable. i.e.
struct packed_struct {

unsigned int f1:1;


unsigned int f2:1;
unsigned int f3:1;
unsigned int f4:1;
unsigned int type:4;
unsigned int funny_int:9;
} pack;
Here the packed_struct contains 6 members: Four 1 bit flags f1..f3, a 4 bit type and a 9 bit funny_int.
C automatically packs the above bit fields as compactly as possible, provided that the maximum length of the
field is less than or equal to the integer word length of the computer. If this is not the case then some compilers
may allow memory overlap for the fields whilst other would store the next field in the next word (see comments
on bit fiels portability below).
Access members as usual via:
pack.type = 7;
12 Preprocessor Commands
Making programming versatile.
C is unusual in that it has a pre-processor. This comes from its Unix origins. As its name might suggest, the
preprocessor is a phase which occurs prior to compilation of a program. The preprocessor has two main uses: it
allows external files, such as header files, to be included and it allows macros to be defined. This useful feature
traditionally allowed constant values to be
defined in Kernighan and Ritchie C, which had no constants in the language. Pre-processor commands are
distinguished by the hash (number) symbol #. One example of this has already been encountered for the
standard header file stdio.h.
#include <stdio.h>
is a command which tells the preprocessor to treat the file stdio.h as if it were the actually part of the program
text, in other words to include it as part of the program to be compiled. Macros are words which can be defined
to stand in place of something complicated: they are a way of reducing the amount of typing in a program and a
way of making long ungainly pieces of code into short words. For
example, the simplest use of macros is to give constant values meaningful names: e.g.
#define TELEPHNUM 720663
This allows us to use the word TELEPHNUM in the program to mean the number 720663. In this particular
case, the word is clearly not any shorter than the number it will replace, but it is more meaningful and would
make a program read more naturally than if the raw number were used. For
instance, a program which deals with several different fixed numbers like a telephone number, a postcode and a
street number could write:
printf("%d %d %d",TELEPHNUM,postcode,streetnum);
instead of
printf("%d %d %d",720663,345,14);
Using the macros instead makes the actions much clearer and allows the programmer to forget about what the
numbers actually are. It also means that a program is easy to alter because to change a telephone number, or
whatever, it is only necessary to change the definition, not to retype the
number in every single instance.
The important feature of macros is that they are not merely numerical constants which are referenced at compile
time, but are strings which are physically replaced before compilation by the preprocessor! This means that
almost anything can be defined:
#define SUM 1 + 2 + 3 + 4
would allow SUM to be used instead of 1+2+3+4. Or
#define STRING "Mary had a little lamb..."
would allow a commonly used string to be called by the identifier "string"
instead of typing it out afresh each time. The idea of a define statement
then is:
#define macroname definition on rest of line

Macros cannot define more than a single line to be substituted into a program but they can be used anywhere,
except inside strings. (Anything enclosed in string quotes is assumed to be complete and untouchable by the
compiler.) Some macros are defined already in the file stdio.h such as:
EOF The end of file character (= -1 for instance) NULL The null character (zero) = 0
12.1 Macro Functions
A more advanced use of macros is also permitted by the preprocessor. This involves macros which accept
parameters and hand back values. This works by defining a macro with some dummy parameter, say x. For
example: a macro which is usually defined in one of the standard libraries is abs() which means the absolute or
unsigned value of a number. It is defined below:
#define ABS(x) ((x) < 0) ? -(x) : (x)
The result of this is to give the positive (or unsigned) part of any number or variable. This would be no problem
for a function which could accept parameters, and it is, in fact, no problem for macros. Macros can also be made
to take parameters. Consider the ABS() example. If a programmer
were to write ABS(4) then the preprocessor would substitute 4 for x. If a program read ABS(i) then the
preprocessor would substitute i for x and so on. (There is no reason why macros cant take more than one
parameter too. The programmer just includes two dummy parameters with different names. See the example
listing below.) Notice that this definition uses a curious operator which belongs to C:
<test> ? <true result> : <false result>
This is like a compact way of writing an if..then..else statement, ideal for macros. But it is also slightly
different: it is an expression which returns a value, where as an if..then..else is a statement with no value.
Firstly the test is made. If the test is true then the first statement is carried out, otherwise the second is carried
out. As a memory aid, it could be read as:
if <test> then <true result> else <false result>
(Do not be confused by the above statement which is meant to show what a programmer might think. It is not a
valid C statement.) C can usually pro-duce much more efficient code for this construction than for a
corresponding if-else statement.
12.2 When and when not to use macros with parameters
It is tempting to forget about the distinction between macros and functions, thinking that it can be ignored. To
some extent this is true for absolute beginners, but it is not a good idea to hold on to. It should always be
remembered that macros are substituted whole at every place where they are used in a program: this is
potentially a very large amount of repetition of code. The advantage of a macro, however, is speed. No time is
taken up in passing control over to a new function, because control never leaves the home function when a
macro is used: it just makes the function a bit longer.
There is a limitation with macros though. Function calls cannot be used as their parameters, such as:
ABS(function())
has no meaning. Only variables or number constants will be substituted. Macros are also severely restricted in
complexity by the limitations of the preprocessor. It is simply not viable to copy complicated sequences of code
all over programs.
Choosing between functions and macros is a matter of personal judgement. No simple rules can be given. In the
end (as with all programming choices) it is experience which counts towards the final ends. Functions are easier
to debug than macros, since they allow us to single step through the
code. Errors in macros are very hard to find, and can be very confusing.
12.3 Example Listing
#include <stdio.h>
#define STRING1 "A macro definition\n"
#define STRING2 "must be all on one line!!\n"
#define EXPRESSION 1 + 2 + 3 + 4
#define EXPR2 EXPRESSION + 10
#define ABS(x) ((x) < 0) ? -(x) : (x)
#define MAX(a,b) (a < b) ? (b) : (a)
#define BIGGEST(a,b,c) (MAX(a,b) < c) ? (c) : (MAX(a,b))
/************************************************************/
main () /* No #definitions inside functions! */

{
printf (STRING1);
printf (STRING2);
printf ("%d\n",EXPRESSION);
printf ("%d\n",EXPR2);
printf ("%d\n",ABS(-5));
printf ("Biggest of 1 2 and 3 is %d",BIGGEST(1,2,3));
}
12.4 Note about #include
When an include statement is written into a program, it is a sign that a compiler should merge another file of C
programming with the current one.However, the #include statement is itself valid C, so this means that a file
which is included may contain #includes itself. The includes are then said to be "nested". This often makes
includes simpler.
12.5 Other Preprocessor commands
This section lies somewhat outside the main development of the book. You might wish to omit it on a first
reading. There are a handful more preprocessor commands which can largely be ignored by the beginner. They
are commonly used in "include" files to make sure that things are not defined twice.
NOTE : true has any non zero value in C. false is zero.
#undef This undefines a macro, leaving the name free.
#if This is followed by some expression on the same line. It allows conditional compilation. It is an advanced
feature which can be used to say: only compile the code between #if and #endif
if the value following #if is true, else leave out that code altogether. This is different from not executing code
the code will not even be compiled.
#ifdef This is followed by a macro name. If that macro is defined then this is true.
#ifndef This is followed by a macro name. If that name is not defined then this is true.
#else This is part of an #if, #ifdef, #ifndef preprocessor statement.
#endif This marks the end of a preprocessor statement.
#line Has the form:
#line constant filename
This is for debugging mainly. This statement causes the compiler to believe that the next line is line number
(constant) and is part of the file (filename).
#error This is a part of the proposed ANSI standard. It is intended for debugging. It forces the compiler to abort
compilation.
12.6 Example
/***********************************************************/
/* To compile or not to compile */
/***********************************************************/
#define SOMEDEFINITION 6546
#define CHOICE 1 /* Choose this before compiling */
/***********************************************************/
#if (CHOICE == 1)
#define OPTIONSTRING "The programmer selected this"
#define DITTO "instead of .... "
#else
#define OPTIONSTRING "The alternative"
#define DITTO "i.e. This! "
#endif
/***********************************************************/
#ifdef SOMEDEFINITION
#define WHATEVER "Something was defined!"
#else
#define WHATEVER "Nothing was defined"
#endif

/************************************************************/
main ()
{
printf (OPTIONSTRING);
printf (DITTO);
}

You might also like