C Language
C Language
C Language
1. Arithmetic Operators
Arithmetic operators are used for numeric calculations. They are of two types:-
a) Unary arithmetic operators
b) Binary arithmetic operators
After division operation the decimal part will be truncated and result is only integer
part of quotient. After modulus operation the result will be remainder part of integer
division. The second operand must be nonzero for division and modulus operations.
/* program to understand the integer arithmetic operation /*
#include<stdio.h>
#include<conio.h>
int main()
{
int a=17,b=4;
printf("Sum = %d\n",a+b);
printf("Difference = %d\n",a-b);
printf("Product = %d\n",a*b);
printf("quotient = %d\n",a/b);
printf("Remainder = %d\n",a%b);
getch();
return 0;
}
output:-
Sum = 21
Difference = 13
Product = 68
quotient = 4
Remainder = 1
Result of 10%2 is 0
Result of 10%4 is 2
Result of 4 is: 4
Result of -10%4 is -2
Result of 10%-4 is 2
Result of -10%-4 is -2
b) Floating-Point Arithmetic:- When both operands are of float type then the
arithmetic operation with these operands is called floating point arithmetic. Let us
take two variables a and b. The value of a=12.4 and b=3.1, the results of the
following operations are as-
Expression Result
a+b 15.5
a-b 9.3
A*b 38.44
a/b 4.0
The modulus operator % cannot be used with floating point numbers.
/* program to understand the floating point arithmetic operation */
#include<stdio.h>
#include<conio.h>
int main()
{
float a=12.4, b=3.8;
printf("Sum = %.2f\n",a+b);
printf("Difference = %.2f\n",a-b);
printf("Product = %.2f\n",a*b);
printf("a/b = %.2f\n",a/b);
getch();
return 0;
}
output:-
Sum = 16.20
Difference = 8.60
Product = 47.12
a/b = 3.26
c) Mixed Mode Arithmetic :- When one operand is of integer type and the other is of
floating type then the arithmetic operation with these operands is known as mixed
mode arithmetic and the resulting value is float type.
if a=12, b=2.5
Expression Result
A+b 14.5
a-b 9.5
a*b 30.0
a/b 4.8
Sometimes mixed mode arithmetic can help in getting exact results. For example the
result of expression 5/2 will be 2, since integer arithmetic is applied. If we want exact
result we can make one of the operands float type. For example 5.0 or 5/2.0, both will
give result 2.5.
2.Assignment Operator :-A value can be stored in a variable with the use of
assignment operator. This assignment operator " = " is used in assignment expressions
and assignment statements.
x=8 /* 8 is assigned to x */
y=5 /* 5 is assigned to y */
s=x+y-2 /* value of expression x+y-2 is assigned to s */
y=x /* value of x is assigned to y */
x=y /* value of y is assigned to x */
#include<stdio.h>
#include<conio.h>
int main()
{
int a=10;
printf("a = %d",a);
a+=2;
printf("\nResult of a+=2 is %d",a);
a=10;
a-=2;
printf("\nResult of a-=2 is %d",a);
a=10;
a*=2;
printf("\nResult of a*=2 is %d",a);
a=10;
a/=2;
printf("\nResult of a/=2 is %d",a);
a=10;
a%=4;
printf("\nResult of a%%=4 is %d",a);
getch();
return 0;
}
output :-
a= 10
result of a+=2 is 12
result of a-=2 is 8
result of a*=2 is 20
result of a/=2 is 5
result of a%=2 is 2
4. Relational operators
Relational operators are used to compare values of two expressions depending on
their relations. An expression that contains relational operators is called relational
expression. if the relation is true then the value of relational expression is 1 and if the
relation is false then the value of expression is 0. The relational operators are -
Operator Meaning
< Less than
<= Less than or equal to
== Equal to
!= Not equal to
> Grater than
>= Greater than or equal to
let us take two variables a = 9 and b = 5, and form simple relational expressions with
them-
Expression Relation Value of Expression
a<b False 0
a <= b False 0
a==b False 0
a != b True 1
a>b True 1
a >= b True 1
a==0 False 0
b != 0 True 1
a>8 True 1
2>4 False 0
The relational operators are generally used in if....else construct and loops. In our
next program we'll use the if statement to illustrate the use of relational operators
the if control statement evaluates an expression. and if this expression is true(non
zero )then the next statement is executed, otherwise the next statement is skipped.
Here we have used it to give you an idea of how the relational operators are used.
OR( | | ) Operator This operator gives the net result false, if both the conditions
have the value false, otherwise the result is true.
Boolean Table
Condition1 Condition2 Result
False False False
False True True
True False True
True True True
let us take three variables a = 10 , b=5, c= 0
Consider the logical expression- (a >=b) | | (b > 15)
This gives result true because one condition is true.
b=a>5 || a>10;
printf("\na>5 || a>10 : %d",b);
b=a>5 || a<20;
printf("\na>5 || a<20 : %d",b);
getch();
return 0;
}
output:-
a=10
a<10 || a>10 : 0
a<5 || a>10 : 1
a<5 || a<20 : 1
8. Sizeof Operator :- sizeof is an unary operator. This operator gives the size of its
operand in terms of bytes. The operand can be a variable, constant or any datatype
(int,float,char, etc).for example: sizeof(int) gives the bytes occupied by the int
datatype i.e. 2. Generally sizeof operator is used to make portable programs i.e.
programs that can be run on different machines. For example if we write our program
assuming int to be of 2 bytes, then it won't run correctly on a machine on which int is
of 4 bytes. So to make general code that can run on all machines we can use sizeof
operator.
/*program to understand sizeof operator */
#include<stdio.h>
#include<conio.h>
int main()
{
int a;
printf("Result of sizeof(a) is %d",sizeof(a));
printf("Result of sizeof(int) is %d",sizeof(int));
printf("Result of sizeof(float) is %d",sizeof(float));
printf("Result of sizeof(char) is %d",sizeof(char));
printf("Result of sizeof('p') is %d",sizeof('p'));
printf("Result of sizeof(\"Ajmer"\) is %d",sizeof("Ajmer"));
getch();
return 0
}
output:-
Result of sizeof(a) is 2
Result of sizeof(int ) is 2
Result of sizeof(float) is 4
Result of sizeof(char) is 1
Result of sizeof('p') is 2
Result of sizeof("Ajmer") is 6
9. Bitwise operators :- C has the ability to support the manipulation of data at the bit
level. Bitwise operators are used for operations on individual bits. Bitwise operators
operate on integers only. The bitwise operators are as -
Bitwise operator Meaning
& Bitwise AND
| Bitwise OR
^ Bitwise XOR
<< Lift shift
>> Right shift
~ One's complement
/* program to understand bitwise & operator. */
#include<stdio.h>
#include<conio.h>
int main()
{
int a;
a=45&7;
printf("Result of 45&7 is %d",a);
getch();
return 0;
}
output:-
Result of 45&7 is 5
To better understand this bit pattern consider this example:-
45&7
(00101101) & (00000111)
=00000101
=5
Constants
Constants is a value that cannot be changed during execution of the program. There
are three types of constants-
Numeric constants :- Numeric constants consist of numeric digits, they may or may
not have decimal point(.). These are the rules for defining numeric constants-
1. Numeric constant should have at least one digit.
2. No comma or space is allowed within the numeric constant.
3. Numeric constants can either be positive or negative but default sign is always
positive.
there are two types of numeric constants-
a) Integer Constant :- Integer constants are whole numbers which have no decimal
point (.). There are three types of integer constants based on different number system.
The permissible characters that can be used in these constants are-
Decimal constants - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 (base 10)
Octal constants - 0, 1, 2, 3, 4, 5, 6, 7 (base 8)
Hex Decimal constants - 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,a,b,c,d,e,f (base is 16)
Some valid decimal integer constants are: - 0, 123, 3705, 23759.
Some invalid decimal integer constants are
Invalid Remark
2.5 Illegal character( . )
3#5 Illegal character ( # )
98 5 No blank space allowed
0925 First digit can not be zero
8,354 Comma is not allowed
in octal integer constants, first digit must be 0. For example:- 0, 05, 077, 0324
in hexadecimal integer constants, first two characters should be 0x or 0X. Some
examples are as :- 0x, 0X23, 0x515, 0XA15B, 0xFFF, 0xac.
By default the type of an integer constant is int. But if the value of integer constant
exceeds the range of values represented by int type, the type is taken to be unsigned
int or long int. We can also explicitly mention the type of the constant by suffixing it
with l or L (for long ), u or U(for unsigned), ul or UL(for unsigned long ). For
example:-
6453 integer constant of type int
45238722UL or 45238722ul integer constant of type unsigned long int
6655U or 6655u integer constant of type unsigned int
Real (floating point)Constants:- Floating point constants are numeric constants that
contain decimal point. Some valid floating point constants are-
0.5, 5.3, 4000.0, 0.0073, 5597.0, 39.0807
For expressing vary large or very small real constants, exponential (scientific )form is
used. Here the number is written in the mantissa and exponent form, which are
separated by 'e' or 'E'. The mantissa can be an integer or a real number, while the
exponent can be only an integer(positive or negative).For example the number
1800000 can be written as 1.8e6, here 1.8 is mantissa and 6 is the exponent.
Some more examples are as:-
Number Exponential form
9
250000000 2.5*10 2.5e9
0
0.0000076 7.6*10-6 7.6e-6
5
-670000 -6.7*10 -6.7E5
by default the type of a floating point constant is double. We can explicitly mention
the type of constant by suffixing it with a f of F (for float type), l or L(for long
double). For example:-
2.3e5 floating point constant of type double
2.4e-9l or 2.4e-9L floating point constant of type long double
3.52f or 3.52F floating point constant of type float
Character constants:- A character constant is a single character that is enclosed
within single quotes/ Some valid character constants are- '9', 'D', '$', ' ' , '#'
some invalid character constants are:-
Invalid Remark
'four' There should be only one character within quotes
"d" Double quots are not allowed
'' No character between single quotes
Y Single quotes missing
Every character constant has a unique integer value associated with it. This integer is
the numeric value of the character in the machine's character code. if the machine is
using ASCII (American Standard Code for Information Interchange),then the
character 'G' represents integer value 71 and the character 5 represent value 53. some
ASCII values are:-
A - Z ASCII value (65 - 90)
a - z ASCII value (97 - 122)
0 - 9 ASCII value (48 - 57)
; ASCII value(59)
String Constants:- A string constant has zero, one or more than one character. A
string constant is enclosed within double quotes(" "). At the end of string, \0 is
automatically placed by the compiler.
Some examples of string constants are:-
"Kumar", "593", "8", " ","A".
Note that "A " and 'A' are different, the first one is a string constant which
consist of character A and \0 while the second one is a character constant which
represents integer value 65.
Type conversion
C provides the facility of mixing different types of variables and constants in a
expression . In these types of operations data type of one operand is converted into
data type of another operand . This is known as type conversion. The different types
of type conversion are-
Implicit type conversions are done by the compiler while the explicit type conversion
are user defined conversions.
1)Implicit type conversions :- These conversions are done by the C compiler
according to some predefined rules of C language. The two types of implicit type
conversions are automatic type conversions and type conversion in assignments.
i)Automatic Conversions
a)Automatic unary conversions :- All operands of type char and short will
be converted to int before any operation. Some compilers convert all float operands to
double before any operation.
b) Automatic binary conversion the rules for automatic binary conversions
are as-
1) if one operand is long double, then the other will be converted to long double, and
the result will be long double.
2)Otherwise if one operand is double then the other will be converted to double and
the result will be double,
3)Otherwise if one operand is float the other will be converted to float and the result
will be float,
4)otherwise if one operand is unsigned long int, then other will be converted to
unsigned long int and the result will be unsigned long int.
5)Otherwise if one operand is long int and other is unsigned int
(a) if long int can represent all the values of an unsigned int, then unsigned int
will be converted to long int and the result will be long int,
(b)Else both the operands will be converted to unsigned long int and the result
will be unsigned long int,
6)otherwise if one operand is long int, then the other will be converted to long int and
the result will be long int.
7)Otherwise if one operand is unsigned int , then the other will be converted to
unsigned int and the result will be unsigned int.
2)Explicit type conversion or type casting :- There may be certain situations where
implicit conversions may not solve out purpose. For example
float x;
int x= 20 , y =3;
z=x/y;
the value of z will be 6.0 instead of 6.66.
In these types of case we can specify out own conversions known as type casting or
coercion. this is done with the help of cast operator. the cast operator is a unary
operator that is used for converting an expression to a particular data type temporarily.
the expression can be any constant or variable.
the syntax of cast operator is-
(datatype) expression
here the datatype along with the parentheses is called the cast operator. so if we write
the above statement as-
z=(float)x/y;
Now the value of z will come out be 6.66. This happens because the cast operator
(float) temporarily converted the int variable x into float type and so floating point
arithmetic took place and fractional part was not lost. Note that the cast operator
changes the data type of variable x only temporarily for the evaluation of this
expression, everywhere else in the program it will be an int variable only.
/* program to illustrate the use of cast operator */
#include<stdio.h>
#include<conio.h>
int main()
{
int x=5,y=2;
float p,q;
p=x/y;
printf("p= %f\n",p);
q=(float)x/y;
printf("q= %f\n",q);
}
output:-p=2.000000
q=2.500000
Unit 2
Control Flow
In C programs, statements are executed sequentially in the order in which they appear
in the program. But sometimes we may want to use a condition for execution only a
part of program. Also many situations arise where we may want to execute some
statements several times. Control statements enable us to specify the order in which
the various instructions in the program are to be executed. This determines the flow of
control. Control statements define how the control is transferred to other parts of the
program. C language supports four types of control statements, which are as-
1. if….else
2. goto
3. switch
4. loop
a. while
b. do…..while
c. for
Statements and blocks
A compound statement or a block is a group of statements enclosed within a pair of
curly braces { }.The statements inside the block are executed sequentially. The
general form is –
{
statement1;
statement2;
………….
………….
}
For example:-
{
l=4;
b=2;
area = l * b;
printf(“%d ”,area);
}
1. if………..else
this is a bi-directional conditional control statement. This statement is used to test
a condition and take one of the two possible actions. If the condition is true then a
single statement or a block of statements is executed (one part of the program),
otherwise another single statement or a block of statements is executed (other part
of the program). In C, any nonzero value is regarded as true while zero is regarded
as false.
Syntax 1:
if(condition)
Statement1; if(condition)
{
Statement ;
………….
}
if(condition if(condition)
{
Statement1’ Statement;
else …………
statement 2; }
else
{
Statement ;
}
Here if the condition is true then statement1 is executed and if it is false then
statement2 is executed After this the control transfers to the next statement which is
immediately after the if…..else control statement.
/* program to print whether the number is even or odd */
#include<stdio.h>
#include<conio.h>
void main()
{
int num;
printf(“Enter a number ”);
scanf(“%d”,&num);
if(num % 2 = = 0)
printf(“Number is even\n”);
else
printf(“Number is odd\n”);
getch();
}
Nesting of if…..else
We can have another if ……else statement in the if block or the else block. This is
called nesting of if….else statement. Here is an example of nesting where we have
if…..else inside both if block and else block.
if(condition 1)
{
if (condition 2)
statementA1;
else
statementA2;
}
else
{
if (condition 3)
statementB1;
else
statementB2;
}
else if ladder
This is a type of nesting in which there is an if……else statement in every else part
except the last else part. This type of nesting is frequently used in program and is also
known as else if ladder.
This nested structure is generally written in compact form as in second figure. The
flow chart for this structure is –
Here each condition is checked, and when a condition is found to be true, the
statements corresponding to that are executed, and the control comes out of the nested
structure with checking remaining conditions. If none of the conditions is true then the
last else part is executed.
/* program to find out the grade of a student when the marks of 4 subject are given.
The method of assigning grade is as-
per > 85 grade=A
per < 85 and per>70 grade=B
per < 70 and per>=55 grade=C
per < 55 and per>=40 grade=D
per < 40 grade=E
Here per is percentage.
#include<stdio.h>
#include<conio.h>
void main()
{
float m1, m2, m3, m4, total, per;
char grade;
printf(“Enter marks of 4 subject ”);
scanf(“%f%f%f%f”,&m1,&m2,&m3,&m4);
total = m1+m2+m3+m4;
per= total /4;
if(per > =85)
grade=’A’;
else if(per > = 70)
grade =’B’ ;
else if(per > = 55)
grade =’C’ ;
else if(per > = 40)
grade =’D’ ;
else
grade=’E’;
printf(“Percentage is %f\n Grade is %c\n”, per, grade);
getch();
}
goto
This is an unconditional control statement that transfer the flow of control to another
part of the program. The goto statement can be used as-
goto label;
………
………
label:
statement;
…………
…………
Here label is any valid c identifier and it is followed by a colon.
Whenever the statement goto label; is encountered, the control is transferred to the
statement that is immediately after the label.
/* Program to print whether the number is even or odd */
#include<stdio.h>
#include<conio.h>
void main()
{
int n;
printf(“Enter the number :”);
scanf(“%d”, &n);
if(n % 2 = = 0)
goto even;
else
goto odd;
even :
printf(“Number is even”);
goto end;
odd :
printf(“Number is odd”);
goto end;
end :
printf(“\n”);
getch();
}
The label can be placed anywhere. If the label is after the goto then the control is
transferred forward and it is known as forward jump or forward goto, and if the label
is before the goto then the control is transferred backwards and it is known as
backward jump and backward goto. There should always be a statement after any
label. If label is at the end of program, and no statements are to be written after it, we
can write the null statement (single semicolon) after the label because a program can’t
end with a label.
switch
This is multi-directional conditional control statement. Sometimes there is a need in
program to make choice among number of alternatives. For making this choice, we
use the switch statement. This can be written as-
switch (expression)
{
Case constant 1;
Statement
………….
Case constant 2;
Statement
………….
Case constant N;
Statement
………….
Default :
Statement
………….
}
Here switch, case and default are keywords. The “expression” following the switch
keyword can be any C expression that yields an integer value. It can be value of any
integer or character variable, or a function call returning an integer, or an arithmetic,
logical, relational, bitwise expression yielding an integer. It can be any integer or
character constant also, Since character are converted to their ASCII values, so we
can also use character in this expression. Data types long int and short int are also
allowed. The constants following the case keywords should be of integer or character
type. They can be either constants or constant expressions. These constants must be
different from one another.
/* program to perform arithmetic calculations on integers */
/* this program also demonstrate the switch with break statement */
#include<stdio.h>
#include<conio.h>
void main()
{
char op;
int a,b;
Printf(“Enter number operator and another number :”);
Scanf(“%d%c%d”,&a,&op,&b);
Switch(op)
{
case ‘+’:
printf(“Result = %d\n”,a+b);
break;
case ‘-’:
printf(“Result = %d\n”,a-b);
break;
case ‘*’:
printf(“Result = %d\n”,a*b);
break;
case ‘/’:
printf(“Result = %d\n”,a/b);
break;
case ‘%’:
printf(“Result = %d\n”,a%b);
break;
default :
printf(“Enter valid operator\n”);
}
}
/*program to find whether the alphabet is a vowel or constant */
#include<stdio.h>
#include<conio.h>
void main()
{
char ch;
printf(“Enter an alphabet :”);
scanf(“%c”,&ch);
switch(ch)
{
case ‘a’:
case ‘e’:
case ‘i’:
case ‘o’:
case ‘u’:
printf(“Alphabet is a vowel \n”);
break;
default:
printf(“Alphabet is a consonant\n”);
}
}
LOOPS
Loops are used when we want to execute a part of the program or a block of
statements several times. For example, suppose we want to print "C is best" 10 times.
One way to get the desired output is we write 10 printf statements, which is not
preferable. Other way out is - use loop. Using loop we can write one loop statement
and only one printf statement, and this approach is definitely better than the first one.
With the help of loop we can execute a part of the program repeatedly till some
condition is true. There are three loop statements in C.
while
do while
for
1. while loop:- The while statement can be written as:
while(condition) while(condition)
statement; {
statement;
statement;
...............
}
First the condition is evaluated; if it is true then the statements in the body of loop are
executed . After the execution. again the condition is checked and if it is found to be
true then again the statements in the body of loop are executed. This means that these
statements are executed continuously till the condition is true and when it becomes
false, the loop terminates and the control comes out of the loop. Each execution of the
loop body is known as iteration.
/* program to find the product of digits of any number
#include<stdio.h>
#include<conio.h>
int main()
{
int n,prod=1,rem;
printf("Enter the number ");
scanf("%d",&n);
while(n>0)
{
rem=n%10;
prod=prod*rem;
n=n/10;
}
printf("prod of digits = %d \n",prod);
getch();
return 0;
}
/* program to find the factorial of any number */
#include<stdio.h>
#include<conio.h>
void main()
{
int n,num;
long fact=1;
printf("Enter the number");
scanf("%d", &n);
if(n<0)
printf("No factorial of negative number\n");
else
{
while(n>1)
{
fact=fact *n;
n- -;
}
printf("Factorial of %d = %ld\n",num, fact);
}
}
do......while loop
The 'do......while' statement is also used for looping. The body of this loop may
contain a single statement or a block of statements. The syntax for writing this loop is
do do
statment; {
while(condition); statement;
statement;
...............
}while(condition);
Here firstly the statements inside loop body are executed and then the condition is
evaluated. If the condition is true, then again the loop body is executed and this
process continues until the condition becomes false. Note that unlike while loop, here
a semicolon is placed after the condition.
In a 'while' loop, first the condition is evaluated and then the statements are executed
whereas in a do while loop, First the statements are executed and then the condition is
evaluated. So if initially the condition is false the while loop will not executed at all,
whereas the do while loop will always execute at least once.
/* program to count the digits in any number */
#include<stdio.h>
#include<conio.h>
void main()
{
int n,count=0, rem;
printf("Enter the number : ");
scanf("%d",&n);
do
{
n=n/10;
count++;
}while(n>0);
printf("Number of digits = %d\n ",count);
getch();
}
for loop
The 'for ' statement is very useful while programming in c. It has three expressions
and semicolons are used for separation these expressions. The 'for' statement can be
written as-
for(expression1;expression2;expression3)
statement;
for(expression1;expression2;expression3)
{
statement;
statement;
...............
}
the loop body can be a single statement or block of statements.
expression1 is an initialization expression, expression2 is a test expression or
condition and expression3 is an update expression. expression1 is executed only onc
when the loop starts and is used to initialize the loop variables. This expression is
generally an assignment expression. expression2 is a condition and is tested before
each iteration of the loop. This condition generally uses relational and logical
operators. expression2 is an update expression and is executed each time after the
body of the loop is executed.
Now let us see how this loop works. Firstly the initialization expression is executed
and the loop variables are initialized, and then the condition is checked, if the
condition is true then the body of loop is executed. After executing the loop body,
control transfers to expression3(update expression)and it modifies the loop variables
and then again the condition is checked, and if it is true, the body of loop is executed.
this process continues till the condition is true and when the condition becomes false
the loop is terminated and control is transferred to the statements following the loop.
Nesting of loops:- when a loop is written inside the body of another loop then it is
known as nesting of loops. any type of loop can be nested inside any other type of
loop. For example a for loop may be nested inside another for loop or inside a while
or do while loop. Similarly while and do while loops can be nested.
/* program to understand nesting in for loop. The program prints Armstrong number.
Armstrong number is a three digit number in which the sum of cube of all digits is
equal to the number, for example 371 is an Armstrong number since
371=33+73+13=27+343+1. */
#include<stdio.h>
#include<conio.h>
void main()
{
int num, n, cube, d, sum;
printf("Armstrong numbers are :\n");
for(num=100;num<=999;num++)
{
n=num;
sum=0;
while(n>0) /* inner loop */
{
d=n%10;
n/=10;
cube=d*d*d;
sum=sum + cube;
}/* end of while loop */
if(num= =sum)
printf("%d\n", num);
}/* end of for loop */
getch();
}
Infinite loops:-The loops that go on executing infinitely and never terminate are
called infinite loops. Sometimes we write these loops by mistake while sometimes we
deliberately make use of these loops in our programs. Let us take some examples and
see what type of mistakes lead to infinite loops.
A) for(i=0;i<=5;i--)
printf("%d",i);
this loop will execute till the value of i is less then or equal to 5 i.e the loop will
terminate only when i becomes grater then 5. the initial value of i is 0 and after each
iteration its value is decreasing, hence it will never become greater than 5. So the loop
condition will never become false and the loop will go on executing infinitely. For the
loop to work correctly we should write i++ instead of i-- .
B) There should be a statement inside the loop body that changes the value of loop
variable after each iteration. In for loop this work is done by the update expression but
in while and do while we may forget to change the loop variable and this can lead to
infinite loop.
int k=1;
do
{
printf("%d",k);
sum=sum+k;
}while(k<5);
here we are not changing the value of k inside the loop body and hence the loop
becomes infinite.
C) A common mistake made by beginners is to use the assignment operator(=) where
equality operator(= = ) should have been used. if this mistake is made in the loop
condition then it may cause the loop to execute infinitely. for example consider this
loop: while(n=2)
{
----------
}
here we wanted the loop to executed till the value of n is equal to 2. So we should
have written n==2 but mistakenly we have written n =2. Now n=2 is an assignment
expression and the value of this expression is 2. which is a nonzero (true )value and
hence the loop condition is always true.
break statement
Break statement is used inside loops and switch statements. Sometimes it becomes
necessary to come out of the loop even before the loop condition becomes false. In
such a situation, break statement is used to terminate the loop. this statement exit from
that loop in which this statement appears/ It can be written as-
break;
when break statement is encountered, loop is terminated and the control is transferred
to the statement immediately after the loop. the break statement is generally written
along with a condition. If break is written inside a nested loop structure then it causes
exit from the innermost loop.
Unit - 3
Function
A function is a self-contained subprogram that is meant to do some specific, well-
defined task. A C program consists of one or more functions. If a program has only
one function then it must be the main () function.
C programs have two types of functions-
1 User-defined function
2 Library functions
1.User-defined function:- User can create their own functions for performing any
specific task of the program. These types of functions are called user-defined
functions. To create and use these functions, we should know about these three
things:-
a) function definition
b) function call
c) function declaration
void main()
{
int a, b, s;
printf(“Enter values for a and b : ”);
scanf(“%d %d ”, &a,&b);
s=sum(a,b);
printf(“Sum of %d and %d is %d \n”, a, b, s);
}
Here the definition of sum() is written before main(), so main() knows everything
about the function sum(). But generally the function main() is placed at the top and all
other functions are placed after it . In this case, function declaration is needed. The
function declaration is also known as the function prototype, and it informs the
compiler about the following three things-
1. Name of the function.
2. Number and type of arguments received by the function.
3. Type of value returned by the function.
Function declaration tells the compiler that a function with these features will be
defined and used later in the program. The general syntax of a function declaration
is-
Return_type func_name(type1 arg1 , type2 arg2 ,…..);
This looks just like the header of function definition, except that there is a
semicolon at the end. The name of the arguments while declaration a function is
optional. These are only used for descriptive purposes. Sow we can wrie the
declaration in this why also-
return_type func_name(type1,type2,.,,,,,,,,,,,);
return statement:- The return statement is used in a function to return a value to the
calling function. It may also be used for immediate exit from the called function to the
calling function without returning a value.
This statement can appear anywhere inside the body of the function. There are two
ways in which it can be used-
return;
return(expression);
Here return is a keyword. The first form of return statement is used to terminate the
function without returning any value. In this case only return keyword is written. The
following program uses this form of return statement.
We can use multiple return statements in a function but as soon as first return
statement is encountered the function terminates and all the statements following it
are not executed.
Function arguments;- the calling function sends some values to the called function
for communication; these vales are called arguments or parameters.
Actual arguments: The arguments which are mentioned in the function call are
known as actual arguments, since these are the values which are actually sent to the
called function. Actual arguments can be written it the form of variables. Constants or
expressions or any function call that returns a value. For example –
fun(x)
func(a*b, c*d+k)
func(22, 43)
func(1,2,sum(a,b))
Formal arguments:- The name of the arguments which are mentioned in the function
definition are called formal or dummy arguments since they are used just to hold the
values that are sent by the calling function./
These formal arguments are simply like other local variables of the function which are
created when the function call states and are destroyed when the function ends.
However there are two differences:- First is that formal arguments are declared inside
parentheses while other local variables are declared at the beginning of the function
block. The second difference is that formal arguments are automatically initialized
with the values of the actual arguments passed, while other local variables are
assigned values through the statements written inside the function body.
Types of Function
The functions can be classified into four categories on the basic of the arguments and
return value.
1. Functions with no arguments and no return value.;
2. functions with no arguments and a return value.
3. function with arguments and no return value.
4. function with arguments and a return value.
Output:-
Enter 1st no. : 10
Enter 2nd no. : 20
Sum = 30
Introduction of Pointers
C is very powerful language and the real power of c lies in pointers. The use of
pointers makes the code more efficient and compact. Some of the uses of pointers
are–
1. Accessing array elements.
2. Returning more than one value from a function.
3. Accessing dynamically allocated memory.
4. Implementing data structures like linked list, trees and graphs.
About memory
Before studying about pointers it is important to understand how memory is organized
in a computer. The memory in a computer is made up of bytes arranged in a
sequential manner. Each byte has an index number, which is called the address of that
byte. The address of these bytes start from zero and the address of last byte is one less
than the size of memory. Suppose we have 64 MB of RAM, then memory will consist
of 64 * 220 = 67108864 bytes. The address of these bytes will be from 0 to 67108863.
Now let us see what happens when we declare a variable. Suppose we declare a
variable age of type int –
int age;
The compiler reserves 2 consecutive bytes from memory for this variable and
associates the name age with it. The address of first byte from the two allocated bytes
is known as the address of variable age.
Suppose compiler has reserved bytes numbered 2588 and 2599 for the storage of
variable age, and then the address of variable age will be 2588. let us assign some
value to this variable.
age = 20;
Now this value will be stored in these 2 bytes (of course in binary form). The number
of bytes allocated will depend on the data type of variable. For example 4 bytes would
have been allocated for a float variable, and the address of first byte would be called
the address of the variable. Now we will se how to find out the address of a variable.
Address Operator
C provides an address operator ‘&’, which returns the address of a variable when
placed before it. This operator can be read as “the address of”, so &age means address
of age, similarly &sal means address of sal. The following program prints the address
of variables using address operator.
/* Program to print address of variables using address operator */
#include<stdio.h>
main()
{
int age = 30;
float sal = 1500.50;
printf(“Value of age = %d, Address of age = %u\n”, age, &age);
printf(“Value of sal = %f, Address of sal = %u\n”, sal, &sal):
}
Output:
Pointers Variables
A pointer is a variable that stores memory address. It is called pointer because it
points to a particular location in memory by storing the address of that location.
Like other variables, pointer variables should also be declared before being used. The
general syntax of declaration is –
Data_type *pname;
Here pname is the name of pointer variable, which should be a valid C identifier. The
asterisk ‘*’ preceding this name informs the compiler that the variable is declared as a
pointer. Here data type is known as the base type of pointer. Let us take some pointer
declarations –
int *iptr;
float *fptr;
char *cptr, ch1, ch2;
Pointer To Pointer
We know that pointer is a variable that can contain memory address. This pointer
variable takes some space in memory and hence it also has an address. We can store
the address of a pointer variable in some other variable, which is known as a pointer
to pointer variable. Pointer to pointer is generally used while passing pointer variables
to functions.
data_type **pptr;
Here variable pptr is a pointer to pointer and it can point to a pointer pointing to a
variable of type datat_type. The double asterisk used in the declaration informs the
compiler that a pointer to pointer is being declared. Now let us take an example –
int a = 5;
int *pa = &a;
int **ppa = &pa;
Here type of variable a is int, type of variable pa is (int *) or pointer to int, and type of
variable ppa is (int **) or pointer to pointer to int.
Here pa is a pointer variable, which contains the address of the variable a and ppa is a
pointer to pointer variable, which contains the address of the pointer variable pa.
We know that *pa gives value of a, similarly *ppa will give the value of pa. Now let
us see what value will be given by **pa.
**ppa
*(*ppa)
*pa (Since *ppa gives pa)
a (Since *pa gives a )
Hence we can see that **ppa will give the value of a. So to access the value indirectly
pointed to by a pointer to pointer, we can use double indirection operator. The table
given below will make this concept clear.
#include<stdio.h>
main()
{
int a = 5;
int *pa;
int **ppa;
pa = &a;
ppa = &pa;
printf(“Address of a = %u\n”, &a);
printf(“Value of pa = Address of a = %u\n”, pa);
printf(“Value of *pa = Value of a = %d\n”, *pa);
printf(“Address of pa = %u\n”, &pa);
printf(“Value of ppa = Address of pa = %u\n”, ppa);
printf(“Value of *ppa = Value of pa = %u\n”, *ppa);
printf(“Value of **ppa = Value of a = %d\n”, **ppa);
printf(“Address of ppa = %u\n”, &ppa);
}
Output:
Address of a = 65524
Value of pa = Address of a = 64424
Value of *pa = Value of a = 5
Address of pa = 65522
Value of ppa = Address of pa = 65522
Value of *ppa = Value of pa = 65524
Value of **ppa = Value of a = 5
Address of ppa = 65520
For example
int arr[5] = {5 , 10 , 15 , 20 , 25 }
We can get the address of an element of array by applying & operator in front of
subscripted variable name. Hence &arr[0] gives address of 0th element, &arr[1] gives
the address of first element and so on. Since array subscripts start from 0, so we’ll
refer to the first element of array as 0th element and so on.
The following program shows that the elements of an array we stored in consecutive
memory locations.
#include<stdio.h>
main()
{
int arr[5] = {5,10,15,20,25};
int I;
for(i=0; i<5; i++)
{
printf(“Value of arr[%d] = %d\t”, i, arr[i]);
printf(“Address of arr[%d] = %u\n”,i,&arr[i]);
}
}
Output:
Pointer to an Array
We can also declare a pointer that can point to the whole array instead of only one
element of array. This pointer is useful when talking about multidimensional arrays.
int (*ptr)[10];
Here ptr is pointer that can point to an array of 10 integers. Note that it is necessary to
enclose the pointer name inside parentheses. Here the type of ptr is ‘pointer to an
array of 10 integers’.
Note:- The pointer that points to the 0th elements of array and the pointer that
points to the whole array are totally different. The following program shows
this–
#include<stdio.h>
main()
{
int *p; /* Can point to an integer */
int (*ptr) [5]; /* Can point to an array of 5 integers */
int arr[5];
p=arr; /* Points to 0th element of arr */
ptr=arr; /* Points to the whole array arr */
printrf(“p = %u, ptr = %u\n”, p, ptr);
p++;
ptr++;
printf(“p = %u, ptr = %u\n”, p, ptr);
}
Output:-
Here p is pointer that points to 0th element of array arr, while ptr is a pointer that
points to the whole array arr. The base type of p is ‘int’ while base type of ptr is “an
array of 5 integers’.
#include<stdio.h>
main()
{
int arr[3] [4] = {
{10, 11, 12, 13},
{20, 21, 22, 23},
{30, 31, 32, 33}
};
int i, j;
for (i=0; i<3; i++)
{
printf(“address of %dth array = %u %u\n”, i, arr[i], * (arr+i));
for(j=0; j<4; j++)
printf(“%d %d”, arr[i] [j], *(*(arr+i)+j));
printf(“\n”);
}
}
Output
We can consider a three dimensional array to be an array of 2-D arrays i.e. each
element of a 3-D array is considered to be a 2-D array. The 3-D array arr can be
considered as an array consisting of two elements where each element is a 2-D array.
The name of the array arr is a pointer of the 0th element of the array, so arr points to
the 0th 2-D array.
Now let us see how we can access any element of a 3d array using pointer notation.
#include<stdio.h>
main()
{
int arr [2] [3] [2] = {
{
{5,10},
{6,11},
{7,12},
},
{
{20,30},
{21,31},
{22,32},
}
};
int i, j, k;
for ( i=0; i<2, i++)
for(j=0; j<3; j++)
{
for(k=0; k<2; k++)
printf(“%d\t”,*(*(*(arr+i)+j)+k));
printf(“ \n”);
}
}
Output:-
5 10
6 11
7 12
20 30
21 31
22 31
1. Call by value
2. Call by reference
In call by value, only the values of arguments are sent to the function while in call by
reference, addresses of arguments are sent to the function. In call by value method,
any changes made to the formal arguments do not change the actual arguments. In call
by reference method, any changes made to the formal arguments change the actual
arguments also. C uses only call by value when passing arguments to a function, but
we can simulate call by reference by using pointers.
#include<stdio.h>
main()
{
int a =5, b=8;
printf(“Before calling the function, a and b are %d, %d\n” , a, b);
value(a, b);
printf(“After calling the function, a and b are %d, %d\n” , a, b);
}
value(int x, int y)
{
x++;
y++;
printf(“In function changes are %d, %d\n”, x, y);
}
Output:-
#include<stdio.h>
main()
{
int a = 5;
int b = 8;
printf(“Before calling the function, a and b are %d, %d\n”, a, b);
ref(&a, &b);
printf(“After calling the function, a and b are %d, %d\n” , a, b);
}
ref(int *p, int *q)
{
(*p)++;
(*q)++;
printf(“In function changes are %d, %d\n”, *p, *q);
}
Output:
We have studied that we can return only one value from a function through return
statement. This limitation can be overcome by using call by reference. Let us take a
simple example to understand this concept. Suppose we want a function to return the
sum, difference and product of two numbers passed to it. If we use return statement
then we will have to make three different functions with one return statement in each.
The following program shows how we can return all these values from a single
function.
/* Program to show how to return more than one value from a function using call by
reference */
#include<stdio.h>
main()
{
int a, b, sum, diff, prod;
a=6;
b=4;
func(a,b, &sum, &diff, &prod);
printf(“Sum = %d, Difference = %d, Product = %d\n”, Sum, diff, prod);
}
func(int x, int y, int *ps, int *pd, int *pp)
{
*ps = x+y;
*pd = x-y;
*pp = x*y;
}
Output:
In func() variables a and b are passed by value while variables sum, diff, prod are
passed by reference. The function func() knows the addresses of variables sum, diff
and prod, so it accesses these variables indirectly using pointers and changes their
values.
We can have a function that returns a pointer. The syntax of declaration of such type
of function is –
For example –
While returning a pointer, make sure that the memory address returned by the pointer
will exist even after the termination of function.
/* Program to show the use of a function that returns pointer */
#include<stdio.h>
int *fun(int *p, int n);
main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10},n, *ptr;
n=5;
ptr = fun(arr, n);
printf(“Value of arr = %u, Value of ptr = %u, value of *ptr = %d\n” , arr, ptr,
*ptr);
}
int *fun(int *p, int n)
{
p = p+n;
return p;
}
Output
}
Output:
Inside func() : 5 8 4 9 3
Inside main() : 5 8 4 9 3
Array of Pointers
We can declare an array that contains pointers as its elements. Every element of this
array is a pointer variable that can hold address of any variable of appropriate type.
The syntax of declaring an array of pointers is similar to that of declaring arrays
except that an asterisk is placed before the array name.
Datatype *arrayname[size];
For example to declare an array of size 10 tha contents integer ponters we can write-
int *arrp[10];
main()
{
int * pa[3];
int i,a=5,b=10,c=15;
pa[0]=&a;
pa[1]=&b;
p[2]=&c;
for(i=0;i<3;i++)
{
printf(“pa[%d]=%u\t”,i , pa[i]);
printf(“*pa[%d]=%u\t”, i , *pa[i]);
}
Output:
Pa[0] =2012 *pa[0]=5
Pa[1]=2560 *pa[1]=10
Pa[2]=3020 *pa[2]=15
Here pa is declared as an array of pointers. Every element of this array is a pointer to
an integer. Pa[i] gives the value of the ith element of ‘pa’ which is an address of any int
variable and *pa[i] gives the value of that int variable.
unit 9
Structure
Array is a collection of same type of elements but in many real life applications we
may need to group different types of logically related data. for example if we want to create a
record of a person that contains name, age and height of that person, then we can't use array
because all the three data elements are of different types.
Here value of members of stu1 will be "Mary" for name, 25 for rollno, 98 for marks. the
values of members of stu2 will be "john" for name, 24 for rollno, 67.5 for marks.
we cannot initialize members while defining the structure.
struct student {
char name[20];
int rollno;
float marks =99; /* Invalid */
}stu;
This is invalid because there is no variable called marks, and no memory is allocated for
structure definition. If the number of initializers is less than the number of members then the
remaining members are initialized with zero. for example if we have this initialization-
struct student stu1= {"Mary"};
Here the members rollno and marks of stu1 will be initialized to zero. this is equivalent to the
initialization-
struct student stu1={"Mary",0,0};
some old compilers permit initialization of only global and static structures, but there is no
such restriction in ANSI standard compilers.
output:
stu1 : Oliver 12 98.00
stu2 : Oliver 12 98.00
unary relational, arithmetic, bitwise operators are not allowed with structure variables. We
can use there variables with the members provided the member is not a structure itself.
Size of Structure
we may need to find out the size of structure in some situations like reading or writing to
files. To find out the size of a structure by sizeof operator, we can either use the structure
variable name or the tag name with the struct keyword. For example-
sizeof(struct student)
sizeof(stu1)
sizeof(stu2)
Here if stu1 and stu2 are variables of type struct student, then all the three expressions will
give the same result.
Size of structure may be different on different machines. This is because of certain memory
alignment restrictions on some computers. For example some machines store integers only at
even addresses and long ints only at addresses which are multiple of 4. This is called aligning
of data. Consider this structure-
struct
{
char ch;
int num;
}var;
Now here suppose var.ch is stored at an even address, then the next byte will be left unused
since int can't be stored at an odd address. So instead of occupying 3 bytes this structure
variable will occupy 4 bytes with a hole of unused byte in between. Due to these reasons, size
of whole structure may not be equal to the sum of size of the its members. So it is always
better to find the size of structure variable by using sizeof operator rather than using the sum
of size of its members.
Array of Structures
We know that array is a collection of elements of same datatype. We can declare array of
structures where each element of array is of structure type. Array of structures can be declared
as -
struct student stu[10];
Here stu is an array of 10 elements, each of which is a structure of type struct student, means
each element of stu has 3 members, which are name, rollno and marks. These structures can
be accessed through subscript notation. To access the individual members of these structure
we'll use the dot operator as usual.
stu[0].name stu[0].rollno stu[0].marks
stu[1].name stu[0].rollno stu[0].marks
stu[2].name stu[0].rollno stu[0].marks
------------- ---------------- ----------------
------------- ---------------- ----------------
stu[9].name stu[0].rollno stu[0].marks
All the structure of an array are stored in consecutive memory locations.
/* program to understand array of structures */
#include<stdio.h>
#include<conio.h>
struct student{
char name[20];
int rollno;
float marks;
};
int main()
{
int i;
struct student stuarr[10];
for(i=0;i<10;i++)
{
printf("Enter name, rollno and marks : ");
scanf("%s %d %f",stuarr[i].name,&stuarr[i].rollno,&stuarr[i].marks);
}
for(i=0;i<10;i++)
{
printf("%s %d %f \n",stuarr[i].name,stuarr[i].rollno,stuarr[i].marks);
}
getch();
return 0;
}
Arrays Within Structures
We can have an array as a number of structure. In structure student, we have taken the
member name as an array of characters. Now we'll declare another array inside the structure
student.
struct student{
char name[20];
int rollno;
int submarks[4];
};
the array submarks denotes the marks of students in 4 subjects.
if stu is a variable of type struct student then-
stu.submarks[0] - Denotes the marks of the student in first subject
stu.submarks[1] - Denotes the marks in second subject.
stu.name[0] - Denotes the first character of the name member.
stu.name[4] - Denotes the fifth character of the name member.
Structures may be passed as arguments to function in different ways. We can pas individual
members, whole structure variable or structure pointers to the function. Similarly a function
can return either a structure member or whole structure variable or a pointer to structure.
• Passing Structure Members As Arguments
We can pass individual structure members as arguments to functions like any other
ordinary variable.
/* program to understand how structure members are sent to a function*/
#include<stdio.h>
#include<conio.h>
struct student{
char name[20];
int rollno;
int marks;
};
display(char name[],int rollno, int marks);
int main()
{
struct student stu1={"Jhon",12,87};
struct student stu2;
strcpy(stu2.name,"Mary");
stu2.rollno=18;
stu2.marks=90;
display(stu1.name,stu1.rollno,stu1.marks);
display(stu2.name,stu2.rollno,stu2.marks);
getch();
return 0;
}
display(char name[],int rollno, int marks)
{
printf("Name - %s\t",name);
printf("Rollno - %d\t", rollno);
printf("Marks - %d\n", marks);
}
Output:
printf("Name - %s\t",stu.name);
printf("Rollno - %d\t",stu.rollno);
printf("Marks - %d\n",stu.marks);
}
output:
Name - John Rollno - 12 Marks - 88
Name - Mary Rollno - 18 Marks - 91
Here we have passed members of the variables stu1 and stu2 to the function display().
The names of the formal arguments can be similar to the names of the members. we
can pass the arguments using call by reference also so that the changes made in the
called function will be reflected in the calling function. In that case we'll have to send
the addresses and the members. It is also possible to return a single member from a
function.
• Passing Pointers To Structures As Arguments
If the size of a structure is very large, then it is not efficient to pass the whole
structure to the function since a copy of it has to be made inside the called function. In
this case it is better to send address of the structure, which will improve the execution
speed. we can access the members of the structure variable inside the calling function
using arrow operator. In this case any changes made to the structure variable inside
the called function, will be visible in the calling function since we are actually
working on the original structure variable.
#include<stdio.h>
#include<conio.h>
struct student {
char name[20];
int rollno;
int marks;
};
display(struct student *);
inc_marks(struct student *);
int main()
{
struct student stu1={"John",12,87};
struct student stu2={"Mary",18,90};
inc_marks(&stu1);
inc_marks(&stu2);
display(&stu1);
display(&stu2);
getch();
return 0;
}
inc_marks(struct student *stuptr)
{
(stuptr->marks)++;
}
display(struct student *stuptr)
{
printf("Name - %s\t",stuptr->name);
printf("Rollno - %d\t",stuptr->rollno);
printf("Marks - %d\n",stuptr->marks);
}
output:
Name - John Rollno - 12 Marks - 88
Name - Mary Rollno - 18 Marks - 91
#include<stdio.h>
#include<conio.h>
struct student{
char name [20];
int rollno;
int marks;
};
void display(struct student);
struct student change(struct student stu);
int main()
{
struct student stu1={"Jhon",12,87};
struct student stu2={"Mary",18,90};
stu1=change(stu1);
stu2=change(stu2);
display(stu1);
display(stu2);
getch();
return 0;
}
struct student change(struct student stu)
{
stu.marks=stu.marks+5;
stu.rollno=stu.rollno-10;
return stu;
}
void display(struct student stu)
{
printf("Name - %s\t",stu.name);
printf("Rollno - %d\t",stu.rollno);
printf("Marks - %d\n",stu.marks);
}
output:
Name - John Rollno - 2 Marks - 92
Name - Mary Rollno - 8 Marks - 95
}
struct student *func()
{
struct student *ptr;
ptr=(struct student *)malloc(sizeof(struct student));
strcpy(ptr->name," Joseph");
ptr->rollno=15;
ptr->marks=98;
return ptr;
}
void display(struct student *stuptr)
{
printf("Name - %s\t",stuptr->name);
printf("Rollno - %d\t",stuptr->rollno);
printf("marks - %d\t",stuptr->marks);
}
output:
Name - Joseph Rollno - 15 marks - 98