Notesf
Notesf
on
PROGRAMMING for Problem Solving
Any programming language is implemented on a computer. Right form its inception, to the present
day, all computer system (irrespective of their shape & size) perform the following 5 basic
operations. It converts the raw input data into information, which is useful to the users.
Inputting: It is the process of entering data & instructions to the computer system.
Storing: The data & instructions are stored for either initial or additional processing,
as & when required.
Processing: It requires performing arithmetic or logical operation on the saved data to
convert it into useful information.
Outputting: It is the process of producing the output data to the end user.
Controlling: The above operations have to be directed in a particular sequence to be
completed.
Primary Storage: The primary storage, also called as the main memory, holds the data
when the computer is currently on. As soon as the system is switched off or restarted,
the information held in primary storage disappears (i.e. it is volatile in nature).
Moreover, the primary storage normally has a limited storage capacity, because it is
very expensive as it is made up of semiconductor devices.
Secondary Storage: The secondary storage, also called as the auxiliary storage,
handles the storage limitation & the volatile nature of the primary memory. It can
retain information even when the system is off. It is basically used for holding the
program instructions & data on which the computer is not working on currently, but
needs to process them later.
Central Processing Unit: Together the Control Unit & the Arithmetic Logic Unit are
called as the Central Processing Unit (CPU). The CPU is the brain of the computer.
Like in humans, the major decisions are taken by the brain itself & other body parts
function as directed by the brain. Similarly in a computer system, all the major
calculations & comparisons are made inside the CPU. The CPU is responsible for
activating & controlling the operation of other units of the computer system.
Arithmetic Logic Unit: The actual execution of the instructions (arithmetic or logical
operations) takes place over here. The data & instructions stored in the primary storage
are transferred as & when required. No processing is done in the primary storage.
Intermediate results that are generated in ALU are temporarily transferred back to the
primary storage, until needed later. Hence, data may move from the primary storage
to ALU & back again to storage, many times, before the processing is done.
Control Unit: This unit controls the operations of all parts of the computer but does
not carry out any actual data processing.It is responsible for the transfer of data and
instructions among other units of the computer.It manages and coordinates all the units
of the system.It also communicates with Input/Output devices for transfer of data or
results from the storage units.
Output Unit: The job of an output unit is just the opposite of an input unit. It accepts
the results produced by the computer in coded form. It converts these coded results to
human readable form. Finally, it displays the converted results to the outside world
with the help of output devices ( Eg :monitors, printers, projectors etc..).
System Software- System software are a set of programs, responsible for running the
computer, controlling various operations of computer systems and management of
computer resources. They act as an interface between the hardware of the computer &
the application software. E.g.: Operating System
Before moving on to any programming language, it is important to know about the various types of
languages used by the computer. Let us first know what the basic requirements of the programmers
were & what difficulties they faced while programming in that language.
COMPUTER LANGUAGES
Languages are a means of communication. Normally people interact with each other through a
language. On the same pattern, communication with computers is carried out through a language.
This language is understood both by the user and the machine. Just as every language like English,
Hindi has its own grammatical rules; every computer language is also bounded by rules known as
syntax of that language. The user is bound by that syntax while communicating with the computer
system.
Computer languages are broadly classified as:
Low Level Language: The term low level highlights the fact that it is closer to a language
which the machine understands.
The low level languages are classified as:
o Machine Language: This is the language (in the form of 0’s and 1’s, called binary
numbers) understood directly by the computer. It is machine dependent. It is difficult
to learn and even more difficult to write programs.
o Assembly Language: This is the language where the machine codes comprising of
0’sand 1’s are substituted by symbolic codes (called mnemonics) to improve their
understanding. It is the first step to improve programming structure. Assembly
language programming is simpler and less time consuming than machine level
programming, it is easier to locate and correct errors in assembly language than in
machine language programs. It is also machine dependent. Programmers must have
knowledge of the machine on which the program will run.
High Level Language: Low level language requires extensive knowledge of the hardware
since it is machine dependent. To overcome this limitation, high level language has been
evolved which uses normal English, which is easy to understand to solve any problem. High
level languages are computer independent and programming becomes quite easy and
simple. Various high level languages are given below:
o BASIC (Beginners All Purpose Symbolic Instruction Code): It is widely used, easy
to learn general purpose language. Mainly used in microcomputers in earlier days.
o COBOL (Common Business Oriented language): A standardized language used for
commercial applications.
o FORTRAN (Formula Translation): Developed for solving mathematical and
scientific problems. One of the most popular languages among scientific
community.
o C: Structured Programming Language used for all purpose such as scientific
application, commercial application, developing games etc.
o C++: Popular object oriented programming language, used for general purpose.
As you know that high level language is machine independent and assembly language
though it is machine dependent yet mnemonics that are being used to represent instructions are not
directly understandable by the machine. Hence to make the machine understand the instructions
provided by both the languages, programming language instructors are used. They transform the
instruction prepared by programmers into a form which can be interpreted & executed by the computer.
Flowing are the various tools to achieve this purpose:
Compiler: The software that reads a program written in high level language and translates
it into an equivalent program in machine language is called as compiler. The program
written by the programmer in high level language is called source program and the program
generated by the compiler after translation is called as object program.
Interpreter: it also executes instructions written in a high level language. Both complier &
interpreter have the same goal i.e. to convert high level language into binary instructions,
but their method of execution is different. The complier converts the entire source code into
machine level program, while the interpreter takes 1 statement, translates it, executes it &
then again takes the next statement.
Assembler: The software that reads a program written in assembly language and translates
it into an equivalent program in machine language is called as assembler.
Linker: A linker or link editor is a computer program that takes one or more object files
generated by a compiler and combines them into a single executable file, library file, or
another object file.
Brief History of C
Many of C’s ideas & principles were derived from the earlier language B, thereby naming
this new language “C”.
Taxonomy of C Language
WHY IS C POPULAR
WHY TO STUDY C
By the early 1980s, C was already a dominant language in the minicomputer world of Unix
systems. Since then, it has spread to personal computers (microcomputers) and to
mainframes.
Many software houses use C as the preferred language for producing word processing
programs, spreadsheets, compilers, and other products.
C is an extremely flexible language—particularly if it is to be used to write operating
systems.
Unlike most other languages that have only four or five levels of precedence, C has 15.
CHARECTERESTICS OF A C PROGRAM
USES
The C programming language is used for developing system applications that forms a major portion
of operating systems such as Windows, UNIX and Linux. Below are some examples of C being
used:
Database systems
Graphics packages
Word processors
Spreadsheets
Operating system development
Compilers and Assemblers
Network drivers
Interpreters
STRUCTURE OF A C PROGRAM
The structure of a C program is a protocol (rules) to the programmer, which he has to follow while
writing a C program. The general basic structure of C program is shown in the figure below.
Example:
#include <stdio.h>
void main(void) {
int number;
printf( "Please enter a number: " ); scanf(
"%d", &number );
printf( "You entered %d", number ); return
0;}
Stepwise explanation:
#include
The part of the compiler which actually gets your program from the source file is called the
preprocessor.
▪ #include <stdio.h>
#include is a pre-processor directive. It is not really part of our program, but instead it is an
instruction to the compiler to make it do something. It tells the C compiler to include the
contents of a file (in this case the system file called stdio.h).
The compiler knows it is a system file, and therefore must be looked for in a special place,
by the fact that the filename is enclosed in <> characters
<stdio.h>
stdio.h is the name of the standard library definition file for all STanDard Input and Output
functions.
Your program will almost certainly want to send information to the screen and read things
from the keyboard, and stdio.h is the name of the file in which the functions that we want
to use are defined.
The function we want to use is called printf. The actual code of printf will be tied in later
by the linker.
The ".h" portion of the filename is the language extension, which denotes an include file.
void
This literally means that this means nothing. In this case, it is referring to the function whose
name follows.
Void tells to C compiler that a given entity has no meaning, and produces no error.
main
In this particular example, the only function in the program is called main.
A C program is typically made up of large number of functions. Each of these is given a
name by the programmer and they refer to each other as the program runs.
C regards the name main as a special case and will run this function first i.e. the program
execution starts from main.
(void)
This is a pair of brackets enclosing the keyword void.
It tells the compiler that the function main has no parameters.
A parameter to a function gives the function something to work on.
{ (Brace)
This is a brace (or curly bracket). As the name implies, braces come in packs of two - for
every open brace there must be a matching close one.
Braces allow us to group pieces of program together, often called a block.
A block can contain the declaration of variable used within it, followed by a sequence of
program statements.
In this case the braces enclose the working parts of the function main.
; (semicolon)
The semicolon marks the end of the list of variable names, and also the end of that
declaration statement.
All statements in C programs are separated by ";" (semicolon) characters.
The ";" character is actually very important. It tells the compiler where a given statement
ends.
If the compiler does not find one of these characters where it expects to see one, then it will
produce an error.
scanf
In other programming languages, the printing and reading functions are a part of the
language.
In C this is not the case; instead they are defined as standard functions which are part of the
language specification, but are not a part of the language itself.
The standard input/output library contains a number of functions for formatted data transfer;
the two we are going to use are scanf (scan formatted) and printf (print formatted).
printf
Source File- This file contains the source code of the program. The file extension of any c
file is .c. The file contains C source code that defines the main function & maybe other
functions.
Header File- A header file is a file with extension .h which contains the C function
declarations and macro definitions and to be shared between several source files.
Object File- An object file is a file containing object code, with an extension .o, meaning
relocatable format machine code that is usually not directly executable. Object files are
produced by an assembler, compiler, or other language translator, and used as input to the
linker, which in turn typically generates an executable or library by combining parts of
object files.
Executable File- The binary executable file is generated by the linker. The linker links the
various object files to produce a binary file that can be directly executed.
LECTURE NOTE -4
ELEMENTS OF C
Every language has some basic elements & grammatical rules. Before starting with programming,
we should be acquainted with the basic elements that build the language.
Character Set
Communicating with a computer involves speaking the language the computer understands. In C,
various characters have been given to communicate.
Keywords
Keywords are the words whose meaning has already been explained to the C compiler. The
keywords cannot be used as variable names because if we do so we are trying to assign a new
meaning to the keyword, which is not allowed by the computer.
There are only 32 keywords available in C. Below figure gives a list of these keywords for your
ready reference.
Identifier
Data Type
In the C programming language, data types refer to a domain of allowed values & the operations
that can be performed on those values. The type of a variable determines how much space it
occupies in storage and how the bit pattern stored is interpreted. There are 4 fundamental data types
in C, which are- char, int, float &, double. Char is used to store any single character; int is used to
store any integer value, float is used to store any single precision floating point number & double
is used to store any double precision floating point number. We can use 2 qualifiers with these basic
types to get more types.
Constants
A constant is an entity that doesn’t change whereas a variable is an entity that may change.
Here our only focus is on primary constant. For constructing these different types of constants
certain rules have been laid down.
Real constants are often called Floating Point constants. The real constants could be written in two
forms—Fractional form and Exponential form.
a) The mantissa part and the exponential part should be separated by a letter e.
b) The mantissa part may have a positive or negative sign.
c) Default sign of mantissa part is positive.
d) The exponent must have at least one digit, which must be a positive or negative integer.
Default sign is positive.
e) Range of real constants expressed in exponential form is -3.4e38 to 3.4e38. Ex. +3.2e-5,
4.1e8, -0.2e+3, -3.2e-5
a) A character constant is a single alphabet, a single digit or a single special symbol enclosed
within single inverted commas.
Eg:
int page_no;
salary;
long y;
Declaring Variables:
There are two places where you can declare a variable:
• After the opening brace of a block of code (usually at the top of a function)
• Before a function name (such as before main() in the program) Consider various
examples:
Suppose you had to keep track of a person's first, middle, and last initials. Because an
initial is obviously a character, it would be prudent to declare three character variables
to hold the three initials. In C, you could do that with the following statement:
1. main()
{
char first, middle, last;
}
2. main()
middle;
char last;
Initialization of Variables
When a variable is declared, it contains undefined value commonly known as garbage value.
If we want we can assign some initial value to the variables during the declaration itself.
This is called initialization of the variable.
char grade=’A’;
Expressions
== b - logical operation
4+21
a*(b + c/d)/20
q = 5*2 x =
++q % 3
q>3
As you can see, the operands can be constants, variables, or combinations of the two. Some
expressions are combinations of smaller expressions, called subexpressions. For example, c/d is a
subexpression of the sixth example.
An important property of C is that every C expression has a value. To find the value, you perform
the operations in the order dictated by operator precedence.
Statements
Statements are the primary building blocks of a program. A program is a series of statements with
some necessary punctuation. A statement is a complete instruction to the computer. In C, statements
are indicated by a semicolon at the end. Therefore
legs = 4
legs = 4;
is a statement.
What makes a complete instruction? First, C considers any expression to be a statement if you
append a semicolon. (These are called expression statements.) Therefore, C won't object to lines
such as the following:
8;
3 + 4;
However, these statements do nothing for your program and can't really be considered sensible
statements. More typically, statements change values and call functions:
x = 25;
++x;
y = sqrt(x);
Although a statement (or, at least, a sensible statement) is a complete instruction, not all complete
instructions are statements. Consider the following statement:
x = 6 + (y = 5);
In it, the subexpression y = 5 is a complete instruction, but it is only part of the statement.
Because a complete instruction is not necessarily a statement, a semicolon is needed to identify
instructions that truly are statements.
Compound Statements (Blocks)
A compound statement is two or more statements grouped together by enclosing them in braces; it
is also called a block. The following while statement contains an example:
= years + 1;
If any variable is declared inside the block then it can be declared only at the beginning of the
block. The variables that are declared inside a block can be used only within the block.
INPUT-OUTPUT IN C
When we are saying Input that means we feed some data into program. This can be given in the
form of file or from command line. C programming language provides a set of built-in functions to
read given input and feed it to the program as per requirement.
When we are saying Output that means to display some data on screen, printer or in any file. C
programming language provides a set of built-in functions to output the data on the computer screen.
Functions printf() and scanf() are the most commonly used to display out and take input
respectively. Let us consider an example:
Explanation:
#include<stdio.h>
int main()
{ int
c=5;
printf("
Number
=%d",c
);
return
0;
}
Output Number=5
Inside quotation of printf() there, is a conversion format string "%d" (for integer). If this conversion
format string matches with remaining argument, i.e, c in this case, value of c is displayed.
#include<stdio.h>
int main()
{ int c; printf("Enter a
number\n");
scanf("%d",&c);
printf("Number=%d",c);
return 0; }
Output
Enter a number
4
Number=4
The scanf() function is used to take input from user. In this program, the user is asked an input and
value is stored in variable c. Note the '&' sign before c. &c denotes the address of c and value is
stored in that address.
Conversion format string "%f" is used for floats to take input and to display floating value of a
variable.
Input - Output of characters and ASCII code
#include <stdio.h>
int main()
{
char var1;
printf("Enter character: ");
scanf("%c",&var1); printf("You
entered %c.",var1);
return 0;
}
Output
Enter character: g You
entered g.
ASCII code
When character is typed in the above program, the character itself is not recorded a numeric value
(ASCII value) is stored. And when we displayed that value by using "%c", that character is
displayed.
#include <stdio.h>
int main()
{
char var1;
printf("Enter character: ");
scanf("%c",&var1);
printf("You entered %c.\n",var1);
/* \n prints the next line(performs work of enter). */
printf("ASCII value of %d",var1);
return 0;
}
Output:
Enter character:
g
103
When, 'g' is entered, ASCII value 103 is stored instead of g.
You can display character if you know ASCII code only. This is shown by following example.
Output
Character of ASCII value 69: E
The ASCII value of 'A' is 65, 'B' is 66 and so on to 'Z' is 90. Similarly ASCII value of 'a' is 97, 'b' is
98 and so on to 'z' is 122.
FORMATTED INPUT-OUTPUT
Data can be entered & displayed in a particular format. Through format specifications, better
presentation of results can be obtained.
EXERCISE:
1. To print out a and b given below, which of the following printf() statement will you use?
#include<stdio.h>
float a=3.14;
double b=3.14;
A. printf("%f %lf", a, b);
B. printf("%Lf %f", a, b);
C. printf("%Lf %Lf", a, b);
D. printf("%f %Lf", a, b);
2. To scan a and b given below, which of the following scanf() statement will you use?
#include<stdio.h> float
a;
double b;
A. scanf("%f %f", &a, &b);
B. scanf("%Lf %Lf", &a, &b);
C. scanf("%f %Lf", &a, &b);
D. scanf("%f %lf", &a, &b);
#include <stdio.h>
int main()
{
int i = 10, j = 3; printf("%d %d
%d", i, j);
}
#include <stdio.h>
int main()
{ int n; scanf("%d",
n); printf("%d\n",
n); return 0;
}
A. Compilation error
B. Undefined behavior
C. Whatever user types
D. Depends on the standard
#include <stdio.h>
int main()
{ short int i;
scanf("%hd", &i);
printf("%hd", i);
return 0;
}
A. Compilation error
B. Undefined behavior
C. Whatever user types
D. None of the mentioned
10. In a call to printf() function the format specifier %b can be used to print binary equivalent of an
integer.
A. True
B. False
11. Point out the error in the program?
#include<stdio.h>
int main()
{ char ch;
int i;
scanf("%c", &i);
scanf("%d", &ch); printf("%c
%d", ch, i);
return 0;
}
A. Error: suspicious char to in conversion in scanf()
B. Error: we may not get input for second scanf() statement
C. No error
D. None of above
An operator is a symbol that tells the compiler to perform specific mathematical or logical
manipulations. C language is rich in built-in operators and provides the following types of
operators:
• Arithmetic Operators
• Relational Operators
• Logical Operators
• Bitwise Operators
• Assignment Operators
• Conditional operators
• Misc Operators
Arithmetic operator:
These are used to perform mathematical calculations like addition, subtraction, multiplication,
division and modulus.
Following table shows all the arithmetic operators supported by C language. Assume variable A
holds 10 and variable B holds 20 then:
Relational Operators:
These operators are used to compare the value of two variables.
Following table shows all the relational operators supported by C language. Assume variable A
holds 10 and variable B holds 20, then:
== Checks if the values of two operands are equal or not, if yes (A == B) is not
then condition becomes true. true.
!= Checks if the values of two operands are equal or not, if values (A != B) is true.
are not equal then condition becomes true.
> Checks if the value of left operand is greater than the value of (A > B) is not
right operand, if yes then condition becomes true. true.
< Checks if the value of left operand is less than the value of right (A < B) is true.
operand, if yes then condition becomes true.
>= Checks if the value of left operand is greater than or equal to (A >= B) is not
the value of right operand, if yes then condition becomes true.
true.
<= Checks if the value of left operand is less than or equal to the (A <= B) is true.
value of right operand, if yes then condition becomes true.
Logical Operators:
These operators are used to perform logical operations on the given two variables.
Following table shows all the logical operators supported by C language. Assume variable A holds
1 and variable B holds 0, then:
Operator Description Example
Bitwise Operators
Bitwise operator works on bits and performs bit-by-bit operation. Bitwise operators are used in bit
level programming. These operators can operate upon int and char but not on float and double.
Showbits( ) function can be used to display the binary representation of any integer or character
value.
Bit wise operators in C language are; & (bitwise AND), | (bitwise OR), ~ (bitwise OR), ^ (XOR),
<< (left shift) and >> (right shift).
0 0 0 0 0
0 1 0 1 1
1 1 1 1 0
1 0 0 1 1
The Bitwise operators supported by C language are explained in the following table. Assume
variable A holds 60 (00111100) and variable B holds 13 (00001101), then:
& Binary AND Operator copies a bit to the result if it (A & B) will give 12,
exists in both operands. which is 0000 1100
| Binary OR Operator copies a bit if it exists in either (A | B) will give 61, which
operand. is 0011 1101
^ Binary XOR Operator copies the bit if it is set in one (A ^ B) will give 49,
operand but not both. which is 0011 0001
~ Binary Ones Complement Operator is unary and has (~A ) will give -61, which
the effect of ‘flipping’ bits. is 1100 0011 in 2’s
complement form.
<< Binary Left Shift Operator. The left operands value A << 2 will give 240
is moved left by the number of bits specified by the which is 1111 0000
right operand.
>> Binary Right Shift Operator. The left operands value A >> 2 will give 15 which
is moved right by the number of bits specified by the is 0000 1111
right operand.
Assignment Operators:
In C programs, values for the variables are assigned using assignment operators.
In C, ++ and – are called increment and decrement operators respectively. Both of these operators
are unary operators, i.e, used on single operand. ++ adds 1 to operand and – subtracts 1 to operand
respectively. For example:
When i++ is used as prefix(like: ++var), ++var will increment the value of var and then return it
but, if ++ is used as postfix(like: var++), operator will return the value of operand first and then
only increment it. This can be demonstrated by an example:
#include <stdio.h> int
main()
int c=2,d=2;
Return 0;
Output
4
Conditional Operators (? :)
Conditional operators are used in decision making in C programming, i.e, executes different
statements according to test condition whether it is either true or false.
If the test condition is true (that is, if its value is non-zero), expression1 is returned and if false
expression2 is returned.
y = ( x> 5 ? 3 : 4 ) ;
This statement will store 3 in y if x is greater than 5, otherwise it will store 4 in y. The
if ( x > 5 )
y=3;
else
y=4;
Misc Operators:
& Returns the address of a variable. &a; will give actual address of the
variable.
Operators Precedence in C
Operator precedence determines the grouping of terms in an expression. This affects how an
expression is evaluated. Certain operators have higher precedence than others; for example, the
multiplication operator has higher precedence than the addition operator.
For example x = 7 + 3 * 2; here, x is assigned 13, not 20 because operator * has higher precedence
than +, so it first gets multiplied with 3*2 and then adds into 7.
Here, operators with the highest precedence appear at the top of the table, those with the lowest
appear at the bottom. Within an expression, higher precedence operators will be evaluated first.
The selection statements are also known as Branching or Decision Control Statements.
Decision making structures require that the programmer specify one or more conditions to
be evaluated or tested by the program, along with a statement or statements to be executed
if the condition is determined to be true, and optionally, other statements to be executed if
the condition is determined to be false.
if Statement
The keyword if tells the compiler that what follows is a decision control instruction. The if
statement allows us to put some decision -making into our programs. The general form of
the if statement is shown Fig 2:
Multiple statements may be grouped by putting them inside curly braces {}. For example:
if (total_purchase>=1000)
{
gift_count++;
printf("You are gifted a pen drive.\n");
For readability, the statements enclosed in {} are usually indented. This allows the
programmer to quickly tell which statements are to be conditionally executed. As we will
see later, mistakes in indentation can result in programs that are misleading and hard to read.
Programs:
#include<stdio.h>
int main()
{ int no;
printf("Enter a no : ");
scanf("%d", &no);
if(no<0)
{
printf("no entered is negative");
no = -no;
} printf("value of no is %d
\n",no); return 0;
}
Output: Enter a
no: 6 value of
no is 6
Output:
Output:
Enter 2 nos: 6 0
Division is not possible
if-else Statement
The if statement by itself will execute a single statement, or a group of statements, when the
expression following if evaluates to true. By using else we execute another group of
statements if the expression evaluates to false.
if (a > b)
{ z = a; printf(“value of z is
:%d”,z);
} else
{ z = b; printf(“value of z is
:%d”,z);
}
The group of statements after the if is called an ‘if block’. Similarly, the statements after
Output:
Enter an integer 3 Odd
Output:
Enter an integer 4
Even
return 0;
}
Output:
Enter a year to check if it is a leap year 1996
1996 is a leap year
Output:
Enter a year to check if it is a leap year 2015
2015 is not a leap year
Nested if-else
An entire if-else construct can be written within either the body of the if statement or the
body of an else statement. This is called ‘nesting’ of ifs. This is shown in the following
structure.
if (n > 0)
{
if (a > b)
z = a;
} else z =
b;
The second if construct is nested in the first if statement. If the condition in the first if
statement is true, then the condition in the second if statement is checked. If it is false, then
the else statement is executed.
Program:
40 is greater than 20
else-if Statement:
This sequence of if statements is the most general way of writing a multi−way decision. The
expressions are evaluated in order; if an expression is true, the statement associated with it
is executed, and this terminates the whole chain. As always, the code for each statement is
either a single statement, or a group of them in braces.
If (expression) statement
else if (expression) statement
else if (expression) statement
else if (expression) statement
else statement
The last else part handles the ``none of the above'' or default case where none of the other
conditions is satisfied. Sometimes there is no explicit action for the default; in that case the
trailing can be omitted, or it may be used for error checking to catch an “impossible”
condition.
Program:
6. The above program can be used as an eg here.
Output:
m is greater than n
switch case:
This structure helps to make a decision from the number of choices. The switch statement
is a multi−way decision that tests whether an expression matches one of a number of
constant integer values, and branches accordingly [3].
main( )
{ int i = 2; switch
(i)
{
case 1: printf ( "I am in case 1
\n" ) ;
case 2: printf ( "I am in case 2
\n" ) ;
case 3: printf ( "I am in case 3
\n" ) ;
default :
printf ( "I am in default \n" ) ; }
}
The output of this program would be:
I am in case 2
I am in case 3
I am in default
Here the program prints case 2 and 3 and the default case. If you want that only case 2
should get executed, it is up to you to get out of the switch then and there by using a break
statement. main( )
{ int i = 2 ;
switch ( i )
{
case 1:
printf ( "I am in case 1 \n" ) ;
break ;
case 2:
printf ( "I am in case 2 \n" ) ; break
;
case 3:
printf ( "I am in case 3 \n" ) ; break
;
default: printf ( "I am in default
\n" ) ;
}
}
Program
while statement
The while statement is used when the program needs to perform repetitive tasks. The general
form of a while statement is:
The program will repeatedly execute the statement inside the while until the condition
becomes false(0). (If the condition is initially false, the statement will not be executed.)
Consider the following program: main( )
{ int p, n, count; float
r, si; count = 1; while
( count <= 3 )
{ printf ( "\nEnter values of p, n and r " ) ;
scanf(“%d %d %f", &p, &n, &r ) ;
si=p * n * r / 100 ; printf ( "Simple interest
= Rs. %f", si ) ;
count = count+1;
}
}
#include <stdio.h>
int main()
{
int n, reverse = 0, temp;
printf("Enter a number to check if it is a palindrome or not\n");
scanf("%d",&n); temp = n;
while( temp != 0 )
{
reverse = reverse * 10;
reverse = reverse +temp%10; temp
= temp/10;
}
if ( n == reverse )
printf("%d is a palindrome number.\n", n);
else printf("%d is not a palindrome number.\n", n);
return 0;
}
Output:
do
{ block of one or more C statements; } while
(test expression)
The test expression must be enclosed within parentheses, just as it does with a while
statement.
// C program to add all the numbers entered by a user until user enters 0.
Output:
Enter a number
3
Enter a number
-2
Enter a number
0
sum=1
#include <stdio.h>
main()
{ int i = 10;
do
{ printf("Hello %d\n", i );
i = i -1;
}while ( i > 0 );
}
Output
Hello 10
Hello 9
Hello 8
Hello 7
Hello 6
Hello 5
Hello 4
Hello 3
Hello 2
Hello 1
Program
Output
Enter an integer: 34523
Number of digits: 5
for Loop
The for is the most popular looping instruction. The general form of for statement is as
under:
The for allows us to specify three things about a loop in a single line:
(a) Setting a loop counter to an initial value.
(b) Testing the loop counter to determine whether its value has reached the number of
repetitions desired. (c) Updating the value of loop counter either increment or
decrement.
int main(void)
{
int num;
printf(" n n cubed\n"); for (num =
1; num <= 6; num++)
printf("%5d %5d\n", num,
num*num*num);
return 0;
}
The program prints the integers 1 through 6 and their cubes.
n n cubed
1 19
2 19
3 28
4 36
5 36
6 216
The first line of the for loop tells us immediately all the information about the loop
parameters: the starting value of num, the final value of num, and the amount that num
increases on each looping [5].
Grammatically, the three components of a for loop are expressions. Any of the three parts
can be omitted, although the semicolons must remain.
main( )
{
int i ;
for ( i = 1 ; i <= 10 ; )
{ printf ( "%d\n", i )
;i=i+1;
}
}
Here, the increment is done within the body of the for loop and not in the for statement.
Note that in spite of this the semicolon after the condition is necessary.
Output
Enter the limit: 5
Sum of N natural numbers is 15.
10. Program to find the reverse of a number
#include<stdio.h>
int main()
{
int num,r,reverse=0;
printf("Enter any number: ");
scanf("%d",&num);
for(;num!=0;num=num/10)
{
r=num%10;
reverse=reverse*10+r;
}
printf("Reversed of number: %d",reverse);
return 0;
}
Output:
C programming language allows using one loop inside another loop. Following section shows few
examples to illustrate the concept.
Syntax:
{ statement(s);
} statement(s); } The syntax for a nested while loop statement in C
programming language is as follows:
while(condition)
{
while(condition)
{ statement(s);
}
statement(s);
}
The syntax for a nested do...while loop statement in C programming language is as follows:
do
{ statement(s);
do
{ statement(s);
}while( condition );
}while( condition );
A final note on loop nesting is that you can put any type of loop inside of any other type of loop.
For example, a for loop can be inside a while loop or vice versa.
Programs: 11. program using a nested for loop to find the prime numbers from 2
to 20:
return 0;
}
Output
2 is prime
3 is prime
5 is prime
7 is prime
11 is prime
13 is prime
17 is prime
19 is prime
12. *
***
*****
******* *********
#include<stdio.h>
void main ()
{ int a;
a=10;
for (k=1;k=10;k++)
{
while (a>=1)
{ printf ("%d",a); a--; }
printf("\n");
a= 10;
}
}
Output:
10 9 8 7 5 4 3 2 1
10 9 8 7 5 4 3 2 1
10 9 8 7 5 4 3 2 1
10 9 8 7 5 4 3 2 1
10 9 8 7 5 4 3 2 1
10 9 8 7 5 4 3 2 1
10 9 8 7 5 4 3 2 1
10 9 8 7 5 4 3 2 1
10 9 8 7 5 4 3 2 1
10 9 8 7 5 4 3 2 1
main( )
{
int i = 1 , j = 1 ;
while ( i++ <= 100 )
{
while ( j++ <= 200 )
{
if ( j == 150 )
break ;
else
printf ( "%d %d\n", i, j );
}
}
}
In this program when j equals 150, break takes the control outside the inner while only, since
it is placed inside the inner while.
The continue Statement
The continue statement is related to break, but less often used; it causes the next iteration of
the enclosing for, while, or do loop to begin. In the while and do, this means that the test
part is executed immediately; in the for, control passes to the increment step. The continue
statement applies only to loops, not to switch.
main( )
{
int i, j ;
for ( i = 1 ; i <= 2 ; i++ )
{ for ( j = 1 ; j <= 2 ; j++ )
{ if ( i == j) continue ;
printf ( "\n%d %d\n", i, j ) ; }
}
}
12
21
Note that when the value of I equals that of j, the continue statement takes the control to the
for loop (inner) by passing rest of the statements pending execution in the for loop (inner).
Kernighan and Ritchie refer to the goto statement as "infinitely abusable" and suggest that
it "be used sparingly, if at all.
The goto statement causes your program to jump to a different location, rather than execute
the next statement in sequence. The format of the goto statement is;
Here, if the if conditions satisfies the program jumps to block labelled as a: if not then it
jumps to block labelled as b:.
Exercise questions:
1. WAP to input the 3 sides of a triangle & print its corresponding type.
2. WAP to input the name of salesman & total sales made by him. Calculate & print the
commission earned.
1-1000 3%
1001-4000 8%
6001-6000 12 %
6001 and above 15 %
3. WAP to calculate the wages of a labor.
TIME WAGE
First 10 hrs. Rs 60
Next 6 hrs. Rs 15
Next 4 hrs. Rs 18
Above 10 hrs. Rs 25
4. WAP to calculate the area of a triangle, circle, square or rectangle based on the user’s choice.
5. WAP that will print various formulae & do calculations:
i. Vol of a cube
ii. Vol of a
cuboid iii. Vol of
a cyclinder iv. Vol of
sphere
6. WAP to print the following series
i. S = 1 + 1/2 + 1/3 .......... 1/10
ii. P= (1*2) + (2 *3) + (3* 4)+ ........ (8 *9) +(9 *10)
iii. Q= ½ + ¾ +5/6 +.....13/14
iv. S = 2/5 + 5/9 + 8/13….n
.....
v. S = x + x2 + x3 + x4 + x9 + x10
vi. P= x + x3/3 + x5/5 + x7/7 ................... n terms vii. S= (13 *1) + (12 * 2)……(1
*13) viii. S = 1 + 1/(2 2) + 1/ (3 3) + 1/(44) + 1/(55)
ix. S = 1/1! + 1/2! + 1/3! .................... +1/n!
x. S = 1 + 1/3! + 1/5!+ ......... n terms
xi. S = 1 + (1+2) +(1+2+3) + (1+2+3+4)……………+(1+2+3… .....20) xii. S=
x + x2/2! + x3/3! + x4/4!.... +x10/10! xiii. P = x/2! + x2/3! + ........ x9/10! xiv. S =
1 – 2 + 3 - 4… ......... + 9 – 10
xv. S = 1 -22 + 32 - 42 ............. +92 - 102
xvi. S = 1/(1 + 2) + 3/(3 + 5)……15/(15 + 16)
xvii. S = 1 +x2/2! – x4/4! + x6/6! ... n
xviii. S = 1 + ( 1 + 2) + (1+2+3)……..(1+2+3+4… . 20)
xix. S = 1 + x + x2/2 + x3/3… .... +xn/n
xx. S = 1 * 3/ 2 * 4 * 5 + 2 * 4 / 3 * 5 * 6 + 3 * 5/ 4 * 6 * 7… ..... n * (n+2)/ (n+1) *
(n+3) * (n+4)
7. WAP to input a no & print its corresponding table.
8. WAP to print the table from 1 to 10 till 10 terms.
9. WAP to input a no & print its factorial.
10. WAP to input a no & check whether it is prime or not.
11. WAP to input a no & print all the prime nos upto it.
12. WAP to input a no & print if the no is perfect or not.
13. WAP to find the HCF of 2 nos.
14. WAP to print the Pythagoras triplets within 100. (A Pythagorean triplet consists of three
positive integers a, b, and c, such that a2 + b2 = c2).
15. WAP to input a no & check whether its automorphic or not. (An automorphic number is a
number whose square "ends" in the same digits as the number itself. For example, 52 = 25,
62 = 36, 762 = 5776, and 8906252 = 793212890625, so 5, 6, 76 and 890625 are all
automorphic numbers).
16. WAP to convert a given no of days into years, weeks & days.
17. WAP to input a no & check whether it’s an Armstrong no or not. (An Armstrong no is an
integer such that the sum of the cubes of its digits is equal to the number itself. For example,
371 is an Armstrong number since 33 + 73 + 13 = 371).
18. A cricket kit supplier in Jalandhar sells bats, wickets & balls. WAP to generate sales bill.
Input form the console the date of purchase, name of the buyer, price of each item & quantity
of each item. Calculate the total sale amount & add 17.5 % sales tax if the total sales amount
>300000 & add 12.5 % if the total sales amount is >150000 & 7 % otherwise. Display the
total sales amount, the sales tax & the grand total.
19. WAP to check whether a given number is magic number or not.
(What is a magic number? Example: 1729
20. Write a C program to calculate generic root of the given number. (To find the generic root
of a no we first find the sum of digits of the no until we get a single digit output. That
resultant no is called the generic no. Eg: 456791: 4+5+6+7+9+1=32. 3 +2 =5. So, 5 becomes
the generic root of the given no)
FUNCTION
1. Monolithic Programming indicates the program which contains a single function for the large
program.
2. Modular programming help the programmer to divide the whole program into different modules
and each module is separately developed and tested. Then the linker will link all these modules
to form the complete program.
3. On the other hand monolithic programming will not divide the program and it is a single thread
of execution. When the program size increases it leads inconvenience and difficult to maintain.
Disadvantages of monolithic programming: 1. Difficult to check error on large programs. 2.
Difficult to maintain. 3. Code can be specific to a particular problem. i.e. it can not be reused.
Advantage of modular programming: 1. Modular program are easier to code and debug. 2.
Reduces the programming size. 3. Code can be reused in other programs. 4. Problem can be isolated
to specific module so easier to find the error and correct it.
FUNCTION:
A function is a group of statements that together perform a task. Every C program has at least one
function, which is main(), and all the most trivial programs can define additional functions.
OR
a) Function header
b) Function coding
Function definition tells what are the I/O function and what is going to do.
arg2)
{ local variable;
statements ; return
(expression);
2. Function definition can be placed any where in the program but generally placed after the main
function .
3. Local variable declared inside the function is local to that function. It cannot be used anywhere
in the program and its existence is only within the function.
5. Return type denote the type of value that function will return and return type is optional if
omitted it is assumed to be integer by default.
A function that is declare, calling and define by the user is called user define function. Every
user define function has three parts as:
1. Prototype or Declaration
2. Calling
3. Definition
Standard Function:
The C standard library is a standardized collection of header files and library routines used to
implement common operations, such as input/output and character string handling. Unlike other
languages (such as COBOL, FORTRAN, and PL/I) C does not include built in keywords for these
tasks, so nearly all C programs rely on the standard library to function.
FUNCTION CATAGORIES
There are four main categories of the functions these are as follows:
syntax:
void funct (void);
main ( ) { funct (
);
}
void funct ( void );
{
}
NOTE: There is no communication between calling and called function. Functions are
executed independently, they read data & print result in same block.
Example:
void link (void) ; int
main ()
{ link
(); }
void link ( void );
{ printf (“ link the file
“)
}
Function with no arguments and a return value: This type of functions has no arguments but a
return value
example: int msg (void) ;
int main ( )
{ int s = msg (
);
printf( “summation = %d” , s);
} int msg ( void
)
{ int a, b, sum
; sum = a+b ;
return (sum) ;
}
NOTE: Here called function is independent, it read the value from the keyboard, initialize and
return a value .Both calling and called function are partly communicated with each other.
int main ( ) {
int a,b;
a= 2; b=3;
msg( a, b);
}
sum = a+b;
Here calling function of arguments that passed to the called function and called function
example:
int main ( ) {
int a, b; a=
2; b=3; int
s = msg (a,
b);
}
ACTUAL ARGUMENTS AND FORMAL ARGUMENTS
Actual Arguments:
1. Arguments which are mentioned in the function in the function call are known as calling
function.
2. These are the values which are actual arguments called to the function.
It can be written as constant , function expression on any function call which return a value .
Formal Arguments:
1. Arguments which are mentioned in function definition are called dummy or formal argument.
2. These arguments are used to just hold the value that is sent by calling function.
3. Formal arguments are like other local variables of the function which are created when
function call starts and destroyed when end function.
a) Formal arguments are declared within the ( ) where as local variables are declared
at beginning.
c) Where other local variables are assigned variable through the statement inside the
function body.
Note: Order, number and type of actual argument in the function call should be matched with the
order , number and type of formal arguments in the function definition .
Since formal arguments are photo copy of actual argument, any change of the formal arguments
does not affect the actual arguments
Changes made to the formal argument t are local to block of called function, so when control back
to calling function changes made vanish.
Example:
void swap (int a , int b) /* called function */
{ int
t; t =
a;
a=b;
b = t;
main( )
Explanation:
When this function is calling the control goes to the called function.
void swap (int a , int b),
k and m values are assigned to the ‘a’ and ‘b’.
then a= 50 and b= 25 ,
After that control enters into the function a temporary memory space ‘t’ is created when int t is
executed.
after this control again enters into the main function and execute the print function print (k,m). it
returns the value 50 , 25.
NOTE:
Whatever change made in called function not affects the values in calling function.
Call by reference:
Here instead of passing value address or reference are passed. Function operators or address rather
than values .Here formal arguments are the pointers to the actual arguments.
Example:
#include<stdio.h>
void add(int *n); int
main()
{
int num=2; printf(“\n The value of num before calling the
function=%d”, num); add(&num); printf(“\n The value of num after
calling the function = %d”, num);
return 0;
} void add(int
*n)
{
*n=*n+10;
printf(“\n The value of num in the called function = %d”, n);
}
Output:
NOTE:
In call by address mechanism whatever change made in called function affect the values in calling
function.
EXAMPLES:
return (p);
}
void main()
{ int a, result; printf ("Enter an integer
number: ");
scanf ("%d", &a); result
= factorial (a);
printf ("The factorial of %d is %d.\n", a, result); }
EXERCISE:
Recursion is a process in which a problem is defined in terms of itself. In ‘C’ it is possible to call a
function from itself. Functions that call themselves are known as recursive functions, i.e. a
statement within the body of a function calls the same function. Recursion is often termed as
‘Circular Definition’. Thus recursion is the process of defining something in terms of itself. To
implement recursion technique in programming, a function should be capable of calling itself.
void main()
{
………………………
fun1();
/* Some statements*/
/* Some statements */
………………………
} void fun1()
/*RECURSIVE CALL*/
/* Some statements */
………………………
}
Example:
Here the function fun1() is calling itself inside its own function body, so fun1() is a recursive
function. When main() calls fun1(), the code of fun1() will be executed and since there is a call to
fun1() insidefun1(), again fun1() will be executed. It looks like the above program will run up to
infinite times but generally a terminating condition is written inside the recursive functions which
end this recursion. The following program (which is used to print all the numbers starting from the
given number to 1 with successive decrement by 1) illustrates this:
How to write a Recursive Function?
Before writing a recursive function for a problem its necessary to define the solution of the problem
in terms of a similar type of a smaller problem.
(i). Identify the Non-Recursive part(base case) of the problem and its solution(Part of the
problem whose solution can be achieved without recursion).
(ii). Identify the Recursive part(general case) of the problem(Part of the problem where
recursive call will be made).
Identification of Non-Recursive part of the problem is mandatory because without it the function
will keep on calling itself resulting in infinite recursion.
How control flows in successive recursive calls?
Consider the following program which uses recursive function to compute the factorial of a number.
In the above program if the value entered by the user is 1 i.e.n=1, then the value of n is copied into
m. Since the value of m is 1 the condition ‘if(m==1)’ is satisfied and hence 1 is returned through
return statement i.e. factorial of 1 is 1.
When the number entered is 2 i.e. n=2, the value of n is copied into m. Then in function fact(), the
condition ‘if(m==1)’ fails so we encounter the statement a=m*fact(m-1); and here we meet
recursion. Since the value of m is 2 the expression (m*fact(m-1)) is evaluated to (2*fact(1)) and
the result is stored in a(factorial of a). Since value returned by fact(1) is 1 so the above expression
reduced to (2*1) or simply 2. Thus the expression m*fact(m-1) is evaluated to 2 and stored in a and
returned to main(). Where it will print ‘Factorial of 2 is 2’.
In the above program if n=4 then main() will call fact(4) and fact(4) will send back the computed
value i.e. f to main(). But before sending back to main() fact(4) will call fact(4-1) i.e. fact(3) and
wait for a value to be returned by fact(3). Similarly fact(3) will call fact(2) and so on. This series
of calls continues until m becomes 1 and fact(1) is called, which returns a value which is so called
as termination condition. So we can now say what happened for n=4 is as follows
All recursive functions work in two phases- winding phase and unwinding phase.
Winding phase starts when the recursive function is called for the first time, and ends when the
termination condition becomes true in a call i.e. no more recursive call is required. In this phase a
function calls itself and no return statements are executed.
After winding phase unwinding phase starts and all the recursive function calls start returning in
reverse order till the first instance of function returns. In this phase the control returns through each
instance of the function.
Implementation of Recursion
We came to know that recursive calls execute like normal function calls, so there is no extra
technique to implement recursion. All function calls(Whether Recursive or Non-Recursive) are
implemented through run time stack. Stack is a Last In First Out(LIFO) data structure. This means
that the last item to be stored on the stack(PUSH Operation) is the first one which will be
deleted(POP Operation) from the stack. Stack stores Activation Record(AR) of function during run
time. Here we will take the example of function fact() in the previous recursive program to find
factorial of a number.
Now will see how the run time stack changes during the evaluation of factorial of 3.
The following steps will reveal how the above stack contents were expressed:
First main() is called, so PUSH AR of main() into the stack. Then main() calls fact(3) so PUSH AR
of fact(3). Now fact(3) calls fact(2) so PUSH AR of fact(2) into the stack. Likewise PUSH AR of
fact(1). After the above when fact(1) is completed, POP AR of fact(1), Similarly after completion
of a specific function POP its corresponding AR. So when main() is completed POP AR of main().
Now stack is empty.
In the winding phase the stack content increases as new Activation Records(AR) are created and
pushed into the stack for each invocation of the function. In the unwinding phase the Activation
Records are popped from the stack in LIFO order till the original call returns.
Examples of Recursion
Q1. Write a program using recursion to find the summation of numbers from 1 to n.
Ans: We can say ‘sum of numbers from 1 to n can be represented as sum of numbers from 1 to n-
1 plus n’ i.e.
#include<stdio.h> void
main()
int n,s;
printf(“Enter a number”); scanf(“%d”,&n);
%d”,n,s);
}
int sum(int m) int r; if(m==1)
return (1);
else
r=m+sum(m-1);/*Recursive Call*/ return
r;
}
Output:
Enter a number 5
15
Q2. Write a program using recursion to find power of a number i.e. nm. Ans:
We can write,
nm = n*nm-1
=n*n*nm-2
#include<stdio.h>
int power(int,int);
void main()
%d”,n,m,k);
if(y==0)
return 1;
else
return(x*power(x,y-1));
Output:
Enter the value of n and m
3
5
The value of nm for n=3 and m=5 is 243
Ans: The GCD or HCF (Highest Common Factor) of two integers is the greatest integer that divides
both the integers with remainder equals to zero. This can be illustrated by Euclid’s remainder
Algorithm which states that GCD of two numbers say x and y i.e.
GCD(x, y) = x if y is 0
Output:
Enter two numbers 21
35
GCD of 21 and 35 is 7
Ans: Fibonacci series is a sequence of integers in which the first two integers are 1 and from third
integer onwards each integer is the sum of previous two integers of the sequence i.e.
Output:
Enter the number of terms of Fibonacci Series which is going to be printed 6
1 1 2 3 5 8 13
RECURSION VERSES ITERATION
Every repetitive problem can be implemented recursively or iteratively
Recursion should be used when the problem is recursive in nature. Iteration should be used when
the problem is not inherently recursive
Recursive solutions incur more execution overhead than their iterative counterparts, but its
advantage is that recursive code is very simple.
Recursive version of a problem is slower than iterative version since it requires PUSH and POP
operations.
In both recursion and iteration, the same block of code is executed repeatedly, but in recursion
repetition occurs when a function calls itself and in iteration repetition occurs when the block of
code is finished or a continue statement is encountered.
For complex problems iterative algorithms are difficult to implement but it is easier to solve
recursively. Recursion can be removed by using iterative version.
Tail Recursion
A recursive call is said to be tail recursive if the corresponding recursive call is the last statement
to be executed inside the function.
if(a==1) return;
printf(“%d”,a);
show(a-1);
In the above example since the recursive call is the last statement in the function so the above
recursive call is Tail recursive call.
In non void functions(return type of the function is other than void) , if the recursive call appears in
return statement and the call is not a part of an expression then the call is said to be Tail recursive,
otherwise Non Tail recursive. Now look at the following example
if(q==0)
return p; else return(hcf(q,p%q)); /*Tail
recursive call*/
int factorial(int a)
if(a==0)
return 1; else return(a*factorial(a-1)); /*Not a Tail
recursive call*/ }
In the above example in hcf() the recursive call is not a part of expression (i.e. the call is the
expression in the return statement) in the call so the recursive call is Tail recursive. But in factorial()
the recursive call is part of expression in the return statement(a*recursive call) , so the recursive
call in factorial() is not a Tail excursive call.
A function is said to be Tail recursive if all the recursive calls in the function are tail recursive.
In tail recursive functions, the last work that a function does is a recursive call, so no operation is
left pending after the recursive call returns. Therefore in tail recursive functions , there is nothing
to be done in unwinding phase, so we can jump directly from the last recursive call to the place
where recursive function was first called.
Tail recursion can be efficiently implemented by compilers so we always will try to make our
recursive functions tail recursive whenever possible.
Functions which are not tail recursive are called augmentive recursive functions and these types of
functions have to finish the pending work after the recursive call finishes.
If a function fun1() calls another function fun2() and the function fun2() in turn calls function
fun1(), then this type of recursion is said to be indirect recursion, because the function fun1() is
calling itself indirectly.
fun1( ) {
………………………
fun2();
……………………… /* Some statements*/
} fun2(
){ /* Some statements*/
………………………
fun1();
………………………
} /* Some statements*/
/* Some statements*/
The chain of functions in indirect recursion may involve any number of functions.For example
suppose n number of functions are present starting from f1() to fn() and they are involved as
following: f1() calls f2(), f2() calls f3(), f3() calls f4() and so on with fn() calls f1().
If a function calls itself directly i.e. function fun1() is called inside its own function body, then that
recursion is called as direct recursion. For example look at the following
fun1()
{
… /* Some statements*/
fun2();
… /* Some statements*/
}
Indirect recursion is complex, so it is rarely used.
Exercise:
Find the output of programs from 1 to 5.
1. void main()
{
printf(“%d\n”,count(17243));
} int count(int
x)
{
if(x==0) return
0;
else
return 1+count(x/10)
2. void main()
{
printf(“%d\n”,fun(4,8)); printf(“%d\n”,fun(3,8));
} int fun(int x. int
y)
{
if(x==y)
return x; else return
(x+y+fun(x+1,y-1));
}
3. void main()
printf(“%d\n”,fun(4,9));
printf(“%d\n”,fun(4,0));
printf(“%d\n”,fun(0,4));
if(y==0)
return 0; if(y==1)
return x;
return x+fun(x,y-1);
4. void main()
printf(“%d\n”,fun1(14837));
}
int fun1(int m)
5. void main()
{
printf(“%d\n”,fun(3,8));
} int fun(int x, int
y) { if(x>y)
return 1000;
return x+fun(x+1,y);
}
ARRAYS
Introduction
A data structure is the way data is stored in the machine and the functions used to access that data.
An easy way to think of a data structure is a collection of related data items. An array is a data
structure that is a collection of variables of one type that are accessed through a common name.
Each element of an array is given a number by which we can access that element which is called
an index. It solves the problem of storing a large number of values and manipulating them.
Arrays
Previously we use variables to store the values. To use the variables we have to declare the variable
and initialize the variable i.e, assign the value to the variable. Suppose there are 1000 variables are
present, so it is a tedious process to declare and initialize each and every variable and also to handle
1000 variables. To overcome this situation we use the concept of array .In an Array values of same
type are stored. An array is a group of memory locations related by the fact that they all have the
same name and same type. To refer to a particular location or element in the array we specify the
name to the array and position number of particular element in the array.
Declaration:
Syntax:
data_type array_name[size];
Size represents the number of elements that can be stored in the array.
Example:
int age[100];
float sal[15]; char
grade[20]; Here
age is an integer
elements of
values. Grade is a
character type
20 characters.
Initialization:
Syntax:
data_type array_name[size]={value1, value2,… .... valueN};
Value1, value2, valueN are the constant values known as initializers, which are assigned to the array
elements one after another.
Example:
int marks[5]={10,2,0,23,4};
NOTE:
1. In 1-D arrays it is optional to specify the size of the array. If size is omitted during
initialization then the compiler assumes the size of array equal to the number of
initializers.
Example:
int marks[]={10,2,0,23,4};
2. We can’t copy the elements of one array to another array by simply assigning it.
Example:
int a[5]={9,8,7,6,5};
int b[5]; b=a;
//not valid
Processing:
For processing arrays we mostly use for loop. The total no. of passes is equal to the no.
of elements present in the array and in each pass one element is processed.
Example:
#include<stdio.h> main()
int a[3],i;
}
for(i=0;i<=2;i++) //display the array values
printf(“%d”,a[i]); printf(“\n”);
main()
{
int i;
(i = 0; i < 4; i++)
arr[i]++;
array[i]);
Example: 2
Arrays that we have considered up to now are one dimensional array, a single line of elements.
Often data come naturally in the form of a table, e.g. spreadsheet, which need a two-dimensional
array.
Declaration:
The syntax is same as for 1-D array but here 2 subscripts are used.
Syntax:
data_type array_name[rowsize][columnsize];
Example:
int a[4][5];
This is a 2-D array of 4 rows and 5 columns. Here the first element of the array is a[0][0] and last
element of the array is a[3][4] and total no.of elements is 4*5=20.
Initialization:
int m[4][3]={1,2,3,4,5,6,7,8,9,10,11,12};
The values are assigned as follows:
int m[4][3]={{11},{12,13},{14,15,16},{17}};
m[3][2]:0
Note:
In 2-D arrays it is optional to specify the first dimension but the second dimension should always
be present.
{1,10},
{2,20,200},
{3},
{4,40,400} };
Here the first dimension is taken 4 since there are 4 roes in the initialization list. A 2-D array is
known as matrix.
Processing:
For processing of 2-D arrays we need two nested for loops. The outer loop indicates the rows and
the inner loop indicates the columns.
Example:
int a[4][5];
a) Reading values in a
for(i=0;i<4;i++) for(j=0;j<5;j++)
scanf(“%d”,&a[i][j]);
b) Displaying values of a
for(i=0;i<4;i++) for(j=0;j<5;j++)
printf(“%d”,a[i][j]);
Example 1:
Example 3:
Program to find transpose of a matrix.
#include <stdio.h> int
main()
{ int a[10][10], trans[10][10], r, c, i, j;
printf("Enter rows and column of matrix: ");
scanf("%d %d", &r, &c); printf("\nEnter
elements of matrix:\n"); for(i=0; i<r; i++)
for(j=0; j<c; j++)
{
printf("Enter elements a%d%d: ",i+1,j+1); scanf("%d",
&a[i][j]);
}
/* Displaying the matrix a[][] */
printf("\n Entered Matrix: \n");
for(i=0; i<r; i++)
for(j=0; j<c; j++)
{ printf("%d ",a[i][j]);
if(j==c-1)
printf("\n\n");
}
Output
Multidimensional Array
Example:
int a[2][3][4];
Here a represents two 2-dimensional arrays and each of these 2-d arrays contains 3 rows and 4
columns.
The individual elements are:
a[1][0][0],a[1][0][1],a[1][0][2],a[1][1][0] ................a[1][3][2]
Initialization:
int a[2][4][3]={
{
{1,2,3},
{4,5},
{6,7,8},
{9}
},
{10,11},
{12,13,14},
{15,16},
{17,18,19}
Note:
The rule of initialization of multidimensional arrays is that last subscript varies most frequently and
the first subscript varies least rapidly.
Example:
#include<stdio.h> main()
{ int
d[5];
int i;
for(i=0;i<5;i++)
{ d[i]=i;
}
for(i=0;i<5;i++)
{
printf(“value in array %d\n”,a[i]);
}
} pictorial representation of d will look like
d[0] d[1] d[2] d[3] d[4]
0 1 2 3 4
Output:
enter the array elements:
1 2 3 4 5 6 7 8 9 10
1 is odd
2 is even
3 is odd
4 is even
5 is odd
6 is even
7 is odd
8 is even
9 is odd
10 is even
Example:
234
We can pass whole array as an actual argument to a function the corresponding formal arguments
should be declared as an array variable of the same type.
Example:
#include<stdio.h> main()
{ int i,
a[6]={1,2,3,4,5,6};
func(a);
printf(“contents of array:”);
for(i=0;i<6;i++) printf(“%d”,a[i]);
printf(”\n”);
} func(int
val[])
{ int
sum=0,i;
for(i=0;i<6;i++)
{ val[i]=val[i]*val[i];
sum+=val[i];
}
printf(“the sum of squares:%d”, sum);
}
Output
Output
Solved Example:
1. Write a program to find the largest of n numbers and its location in an array.
#include <stdio.h>
#include<conio.h> void
main()
{ int array[100], maximum, size, c, location =
1;
clrscr();
printf("Enter the number of elements in array\n");
scanf("%d", &size);
printf("Enter %d integers\n", size);
2. Write a program to enter n number of digits. Form a number using these digits.
# include<stdio.h>
#include<conio.h>
#include<math.h>
void main()
{
int number=0,digit[10], numofdigits,i; clrscr();
printf(“\n Enter the number of digits:”);
scanf(“%d”, &numofdigits); for(i=0;i<numofdigits;i++)
{
printf(“\n Enter the %d th digit:”, i);
scanf(“%d”,&digit[i]);
} i=0;
while(i<numofdigits)
{
number= number + digit[i]* pow(10,i) i++;
}
printf(“\n The number is : %d”,number); getch();
}
Output:
Enter the number of digits: 3
Enter the 0th digit: 5
Enter the 1th digit: 4
Enter the 2th digit: 3 The
number is: 543
3. Matrix addition:
printf("\n");
}
getch();
}
Output:
Enter the number of rows and columns of matrix
2
2
Enter the elements of first matrix
12
34
Enter the elements of second matrix
56
21
Sum of entered matrices:- 6 8
55
STRUCTURE
Definition
A Structure is a user defined data type that can store related information together. The variable
within a structure are of different data types and each has a name that is used to select it from the
structure. C arrays allow you to define type of variables that can hold several data items of the same
kind but structure is another user defined data type available in C programming, which allows you
to combine data items of different kinds.
Structures are used to represent a record, Suppose you want to keep track of your books in a library.
You might want to track the following attributes about each book:
• Title
• Author
• Subject
• Book ID
Structure Declaration
It is declared using a keyword struct followed by the name of the structure. The variables of the
structure are declared within the structure.
Example:
Struct struct-name
var-name;
};
Structure Initialization
Assigning constants to the members of the structure is called initializing of structure. Syntax:
struct struct_name
_type member_name2;
} struct_var={constant1,constant2};
Syntax: strcut_var.
member_name;
The dot operator is used to select a particular member of the structure. To assign value to the
individual
stud.roll=01; stud.name=”Rahul”;
To input values for data members of the structure variable stud, can be written as,
scanf(“%d”,&stud.roll);
scanf(‘’%s”,&stud.name);
printf(“%s”,stud.roll); printf(“%f”,stud.name);
QUESTIONS
1. Write a program using structures to read and display the information about an employee.
2. Write a program to read, display, add and subtract two complex numbers.
3. Write a program to enter two points and then calculate the distance between them.
LECTURE NOTE 25
NESTED STRUCTURES
The structure that contains another structure as its members is called a nested structure or a structure
within a structure is called nested structure. The structure should be declared separately and then
be grouped into high level structure.
1. Write a program to read and display the information of all the students in the class using
nested structure.
Pointer to a structure is a variable that holds the address of a structure. The syntax to declare pointer
to a structure can be given as:
To assign address of stud to the pointer using address operator(&) we would write
ptr_stud=&stud;
example
Ptr_stud->name=Raj;
Self –referential structures are those structures that contain a reference to data of its same type as
that of structure.
Example
struct node
int val;
struct node*next;
};
Pointers to Structures
You can define pointers to structures in very similar way as you define pointer to any other variable
as follows:
struct_pointer = &book1;
To access the members of a structure using a pointer to that structure, you must use the -> operator
as follows:
struct_pointer->title;
1 .Write a program to display, add and subtract two time defined using hour, minutes and values of
seconds.
2. Write a program, using pointer to structure, to initialize the members in the structure. Use
functions to print the students information.
3. Write a program using an array of pointers to a structure to read and display the data of a student.
POINTERS
A pointer is a variable that contains the address of a variable. Pointers are much used in C, partly
because they are sometimes the only way to express a computation, and partly because they usually
lead to more compact and efficient code than can be obtained in other ways. Pointers and arrays are
closely related; this chapter also explores this relationship and shows how to exploit it. Pointers
have been lumped with the goto statement as a marvelous way to create impossible to understand
programs. This is certainly true when they are used carelessly, and it is easy to create pointers that
point somewhere unexpected. With discipline, however, pointers can alsobe used to achieve clarity
and simplicity. This is the aspect that we will try to illustrate.
The main change in ANSI C is to make explicit the rules about how pointers can be manipulated, in
effect mandating what good programmers already practice and good compilers already enforce. In
addition, the type void * (pointer to void) replaces char * as the proper type for a generic pointer.
p = &c;
assigns the address of c to the variable p, and p is said to ``point to'' c. The &operator only applies
to objects in memory: variables and array elements. It cannot be applied to expressions, constants,
or register variables.
The unary operator * is the indirection or dereferencing operator; when applied to a pointer, it
accesses the object the pointer points to. Suppose that x and y are integers and ipis a pointer to
int. This artificial sequence shows how to declare a pointer and how to use &and *:
int x = 1, y = 2, z[10];
int *ip; ip = &x; y =
*ip;
*ip = 0; ip =
&z[0];
The declaration of x, y, and z are what we've seen all along. The declaration of the pointer ip.
int *ip;
is intended as a mnemonic; it says that the expression *ipis an int. The syntax of the declaration
for a variable mimics the syntax of expressions in which the variable might appear. This reasoning
applies to function declarations as well. For example,
says that in an expression *dpand atof(s) have values of double, and that the argument of
atofis a pointer to char.
You should also note the implication that a pointer is constrained to point to a particular kind of
object: every pointer points to a specific data type. If ippoints to the integer x, then *ipcan occur
in any context where x could, so
y = *ip + 1
takes whatever ippoints at, adds 1, and assigns the result to y, while
*ip += 1
The parentheses are necessary in this last example; without them, the expression would increment
ip instead of what it points to, because unary operators like * and ++ associate right to left. Finally,
since pointers are variables, they can be used without dereferencing. For example, if iq is another
pointer to int,
iq = ip copies the contents of ipinto iq, thus making iqpoint to whatever
ippointed to.
swap(a, b);
Because of call by value, swap can't affect the arguments a and b in the routine that called it. The
function above swaps copies of a and b. The way to obtain the desired effect is for the calling
program to pass pointers to the values to be changed:
swap(&a, &b);
Since the operator & produces the address of a variable, &a is a pointer to a. In swap itself, the
parameters are declared as pointers, and the operands are accessed indirectly through them.
{
int temp; temp = *px;
*px = *py;
*py = temp;
Pointer arguments enable a function to access and change objects in the function that called it. As
an example, consider a function getint that performs free-format input conversion by breaking a
stream of characters into integer values, one integer per call. getint has to return the value it found
and also signal end of file when there is no more input. These values have to be passed back by
separate paths, for no matter what value is used for EOF, that could also be the value of an input
integer.
One solution is to have getint return the end of file status as its function value, while using a
pointer argument to store the converted integer back in the calling function. This is the scheme
used by scanfas well
The following loop fills an array with integers by calls to getint:
int n, array[SIZE], getint(int *); for (n = 0; n <
SIZE &&getint(&array[n]) != EOF; n++) ;
Each call sets array[n] to the next integer found in the input and increments n. Notice that it is
essential to pass the address of array[n] to getint. Otherwise there is no way for getint to
communicate the converted integer back to the caller.
Our version of getintreturns EOF for end of file, zero if the next input is not a number, and a
positive value if the input contains a valid number.
#include <ctype.h>
int getch(void);
void ungetch(int);
int getint(int *pn)
{ int c, sign; while (isspace(c = getch())); if
(!isdigit(c) && c != EOF && c != '+' && c != '-')
{ ungetch(c); return
0;
} sign = (c == '-') ? -1 :
1; if (c == '+' || c == '-
')
c = getch();
for (*pn = 0; isdigit(c), c = getch())
*pn = 10 * *pn + (c - '0');
*pn *= sign; if
(c != EOF)
ungetch(c);
return c;
}
Throughout getint, *pnis used as an ordinary intvariable. We have also used getchand ungetchso
the one extra character that must be read can be pushed back onto the input.
Pointers and Arrays
In C, there is a strong relationship between pointers and arrays, strong enough that pointers and
arrays should be discussed simultaneously. Any operation that can be achieved by array subscripting
can also be done with pointers. The pointer version will in general be faster but, at least to the
uninitiated, somewhat harder to understand. The declaration
int a[10];
defines an array of size 10, that is, a block of 10 consecutive objects named a[0], a[1], .,a[9]. The
notation a[i] refers to the i-th element of the array. If pa is a pointer to an integer, declared as
pa = &a[0];
sets pa to point to element zero of a; that is, pa contains the address of a[0]. Now the
assignment
pa = &a[0];
pa and a have identical values. Since the name of an array is a synonym for the location of the
initial element, the assignment pa=&a[0] can also be written as
pa = a;
Rather more surprising, at first sight, is the fact that a reference to a[i] can also be written as
*(a+i). In evaluating a[i], C converts it to *(a+i) immediately; the two forms are equivalent.
Applying the operator &to both parts of this equivalence, it follows that &a[i] and a+iare also
identical: a+iis the address of the i-th element beyond a. As the other side of this coin, if pa is a
pointer, expressions might use it with a subscript; pa[i] is identical to *(pa+i). In short, an array-
and-index expression is equivalent to one written as a pointer and offset.
There is one difference between an array name and a pointer that must be kept in mind. A pointer is
a variable, so pa=a and pa++ are legal. But an array name is not a variable; constructions like a=pa
and a++ are illegal.
When an array name is passed to a function, what is passed is the location of the initial element.
Within the called function, this argument is a local variable, and so an array name parameter is a
pointer, that is, a variable containing an address. We can use this fact to write another version of
strlen, which computes the length of a string.
Since s is a pointer, incrementing it is perfectly legal; s++ has no effect on the character string in
the function that called strlen, but merely increments strlen's private copy of the pointer. That
means that calls like
strlen("hello, world");
strlen(array);
strlen(ptr);
all work.
As formal parameters in a function definition,
are equivalent; we prefer the latter because it says more explicitly that the variable is a pointer.
When an array name is passed to a function, the function can at its convenience believe that it has
been handed either an array or a pointer, and manipulate it accordingly. It can even use both
notations if it seems appropriate and clear.
It is possible to pass part of an array to a function, by passing a pointer to the beginning of the
subarray. For example, if a is an array,
f(&a[2])and f(a+2)
both pass to the function fthe address of the subarray that starts at a[2]. Within f, the parameter
declaration can read f(intarr[]) { ... } or
f(int *arr) { ... }
So as far as f is concerned, the fact that the parameter refers to part of a larger array is of no
consequence.
If one is sure that the elements exist, it is also possible to index backwards in an array; p[-1], p[-
2], and so on are syntactically legal, and refer to the elements that immediately precede p[0]. Of
course, it is illegal to refer to objects that are not within the array bound
Address Arithmetic
If p is a pointer to some element of an array, then p++ increments p to point to the next element,
and p+=iincrements it to point ielements beyond where it currently does. These and similar
constructions are the simples forms of pointer or address arithmetic. All types of arithmetic
operations are not possible with pointers. The valid operations that can be performed using pointers
are
(i) Addition of an integer to a pointer and increment operation.
(ii) Subtraction of an integer from a ponter and decrement operation.
The expression p+1 yields the correct machine address for the next variable of that type. Other valid
pointer expressions:
C is consistent and regular in its approach to address arithmetic; its integration of pointers, arrays,
and address arithmetic is one of the strengths of the language. Let us illustrate by writing a
rudimentary storage allocator. There are two routines. The first, alloc(n), returns a pointer to n
consecutive character positions, which can be used by the caller of allocfor storing characters. The
second, afree(p), releases the storage thus acquired so it can be reused later. The routines are
``rudimentary'' because the calls to afreemust be made in the opposite order to the calls made on
alloc. That is, the storage managed by allocand afree is a stack, or last-in, first-out. The standard
library provides analogous functions called malloc and free that have no such restrictions.
The easiest implementation is to have allochand out pieces of a large character array that we will
call allocbuf. This array is private to allocand afree. Since they deal in pointers, not array
indices, no other routine need know the name of the array, which can be declared static in the
source file containing allocand afree, and thus be invisible outside it. In practical
implementations, the array may well not even have a name; it might instead be obtained by calling
mallocor by asking the operating system for a pointer to some unnamed block of storage. The other
information needed is how much of allocbufhas been used. We use a pointer, called allocp, that
points to the next free element. When allocis asked for n characters, it checks to see if there is
enough room left in allocbuf. If so, allocreturns the current value of allocp(i.e., the beginning
of the free block), then increments it by n to point to the next free area. If there is no room,
allocreturns zero. afree(p) merely sets allocpto pif p is inside allocbuf.
In general a pointer can be initialized just as any other variable can, though normally the only
meaningful values are zero or an expression involving the address of previously defined data of
appropriate type. The declaration
defines allocpto be a character pointer and initializes it to point to the beginning of allocbuf,
which is the next free position when the program starts. This could also have been written
since the array name is the address of the zeroth element. The test
if (allocbuf + ALLOCSIZE - allocp>= n)
checks if there's enough room to satisfy a request for n characters. If there is, the new value of
allocpwould be at most one beyond the end of allocbuf. If the request can be satisfied,
allocreturns a pointer to the beginning of a block of characters (notice the declaration of the
function itself). If not, allocmust return some signal that there is no space left. C guarantees that
zero is never a valid address for data, so a return value of zero can be used to signal an abnormal
event, in this case no space.
Pointers and integers are not interchangeable. Zero is the sole exception: the constant zero may be
assigned to a pointer, and a pointer may be compared with the constant zero. The symbolic constant
NULL is often used in place of zero, as a mnemonic to indicate more clearly that this is a special
value for a pointer. NULL is defined in <stdio.h>. We will use NULL henceforth. Tests like
show several important facets of pointer arithmetic. First, pointers may be compared under certain
circumstances. If p and q point to members of the same array, then relations like ==, !=,
<, >=, etc., work properly. For example, p
< q
is true if p points to an earlier element of the array than q does. Any pointer can be meaningfully
compared for equality or inequality with zero. But the behavior is undefined for arithmetic or
comparisons with pointers that do not point to members of the same array. (There is one exception:
the address of the first element past the end of an array can be used in pointer arithmetic.) Second,
we have already observed that a pointer and an integer may be added or subtracted. The construction
p + n
means the address of the n-th object beyond the one p currently points to. This is true regardless of
the kind of object p points to; n is scaled according to the size of the objects p points to, which is
determined by the declaration of p. If an intis four bytes, for example, the intwill be scaled by
four.
Pointer subtraction is also valid: if p and q point to elements of the same array, and p<q, then q-
p+1 is the number of elements from p to q inclusive. This fact can be used to write yet another
version of strlen:
char *pmessage;
amessage is an array, just big enough to hold the sequence of characters and '\0' that initializes
it. Individual characters within the array may be changed but amessagewill always refer to the
same storage. On the other hand, pmessageis a pointer, initialized to point to a string constant; the
pointer may subsequently be modified to point elsewhere, but the result is undefined if you try to
modify the string contents.
We will illustrate more aspects of pointers and arrays by studying versions of two useful functions
adapted from the standard library. The first function is strcpy(s,t), which copies the string t to
the string s. It would be nice just to say s=t but this copies the pointer, not the characters. To copy
the characters, we need a loop. The array version first:
Because arguments are passed by value, strcpy can use the parameters s and t in any way it
pleases. Here they are conveniently initialized pointers, which are marched along the arrays a
character at a time, until the '\0' that terminates t has been copied into s. In practice,
strcpywould not be written as we showed it above. Experienced C programmers would prefer
'\0'.
As the final abbreviation, observe that a comparison against '\0' is redundant, since the question
is merely whether the expression is zero. So the function would likely be written as
{
for ( ; *s == *t; s++, t++)
if (*s == '\0') return 0;
return *s - *t;
}
Since ++ and -- are either prefix or postfix operators, other combinations of * and ++ and -- occur,
although less frequently. For example,
*--p decrements p before fetching the character that p points to. In fact, the pair of
expressions
*p++ = val;
val = *--p;
are the standard idiom for pushing and popping a stack;The header <string.h> contains declarations
for the functions mentioned in this section, plus a variety of other string-handling functions from
the standard library.
Pointer Arrays; Pointers to Pointers
Syntax to declare pointer to an array is datatype
(*pointer_variable)[size];
For example
int (*ptr)[10]; ,Here ptr is a pointer that can point to an array of 10 integers, where we can initialize
ptr with the base address of the array then by incre menting the value of ptr we can access different
elements of array a[].
Since pointers are variables themselves, they can be stored in arrays just as other variables can. Let
us illustrate by writing a program that will sort a set of text lines into alphabetic order, a stripped-
down version of the UNIX program sort.
We need a data representation that will cope efficiently and conveniently with variable-length text
lines. This is where the array of pointers enters. If the lines to be sorted are stored end-to-end in one
long character array, then each line can be accessed by a pointer to its first character. Thepointers
themselves can bee stored in an array. Two lines can be compared by passing their pointers to
strcmp. When two out-of-order lines have to be exchanged, the pointers in the pointer array are
exchanged, not the text lines themselves.
This eliminates the twin problems of complicated storage management and high overhead that
would go with moving the lines themselves.
As usual, it's best to divide the program into functions that match this natural division, with the main
routine controlling the other functions. Let us defer the sorting step for a moment, and concentrate
on the data structure and the input and output. The input routine has to collect and save the characters
of each line, and build an array of pointers to the lines. It will also have to count the number of input
lines, since that information is needed for sorting and printing. Since the input function can only
cope with a finite number of input lines, it can return some illegal count like -1 if too much input
is presented. The output routine only has to print the lines in the order in which they appear in the
array of pointers.
#include <stdio.h>
#include <string.h>
#define MAXLINES 5000
char *lineptr[MAXLINES];
intreadlines(char *lineptr[], intnlines);
void writelines(char *lineptr[], intnlines); void
qsort(char *lineptr[], int left, int right);
main()
{ intnlines;
if ((nlines = readlines(lineptr, MAXLINES)) >= 0) {
qsort(lineptr, 0, nlines-1);
writelines(lineptr, nlines); return 0;
} else { printf("error: input too big to
sort\n");
return 1;
}
}
#define MAXLEN 1000
intgetline(char *, int); char
*alloc(int);
intreadlines(char *lineptr[], intmaxlines)
{ intlen, nlines; char
*p, line[MAXLEN];
nlines = 0;
while ((len = getline(line, MAXLEN)) > 0)
if (nlines>= maxlines || p = alloc(len) == NULL)
return -1;
else {
line[len-1] = '\0'; /* delete newline */
strcpy(p, line); lineptr[nlines++] = p;
} return
nlines; }
void writelines(char *lineptr[], intnlines)
{ inti;
for (i = 0; i<nlines; i++)
printf("%s\n", lineptr[i]);
}
The main new thing is the declaration for lineptr:
char *lineptr[MAXLINES]
says that lineptris an array of MAXLINES elements, each element of which is a pointer to a char.
That is, lineptr[i] is a character pointer, and *lineptr[i] is the character it points to, the first
character of the i-th saved text line.
Since lineptris itself the name of an array, it can be treated as a pointer in the same manner as in
our earlier examples, and writelinescan be written instead as
Initially, *lineptr points to the first line; each element advances it to the next line pointer while
Since any individual element of v (alias lineptr) is a character pointer, temp must be also, so one
can be copied to the other.
Multi-dimensional Arrays
C provides rectangular multi-dimensional arrays, although in practice they are much less used than
arrays of pointers. In this section, we will show some of their properties.
Consider the problem of date conversion, from day of the month to day of the year and vice versa.
For example, March 1 is the 60th day of a non-leap year, and the 61st day of a leap year. Let us
define two functions to do the conversions: day_of_yearconverts the month and day into the day
of the year, and month_dayconverts the day of the year into the month and day. Since this latter
function computes two values, the month and day arguments will be pointers:
Other than this notational distinction, a two-dimensional array can be treated in much the same way
as in other languages. Elements are stored by rows, so the rightmost subscript, or column, varies
fastest as elements are accessed in storage order.
An array is initialized by a list of initializers in braces; each row of a two-dimensional array is
initialized by a corresponding sub-list. We started the array daytabwith a column of zero so that
month numbers can run from the natural 1 to 12 instead of 0 to 11. Since space is not at a premium
here, this is clearer than adjusting the indices.
If a two-dimensional array is to be passed to a function, the parameter declaration in the function
must include the number of columns; the number of rows is irrelevant, since what is passed is, as
before, a pointer to an array of rows, where each row is an array of 13 ints. In this particular case,
it is a pointer to objects that are arrays of 13 ints. Thus if the array daytabis to
be passed to a function f, the declaration of f would be: f(intdaytab[2][13]) { ... } It
could also be
f(intdaytab[][13]) { ... }
since the number of rows is irrelevant, or it could be
f(int (*daytab)[13]) { ... }
which says that the parameter is a pointer to an array of 13 integers. The parentheses are
necessary since brackets [] have higher precedence than *. Without parentheses, the declaration
int *daytab[13]
is an array of 13 pointers to integers. More generally, only the first dimension (subscript) of an
array is free; all the others have to be specified.
char *month_name(int n)
{ static char *name[]
= { "Illegal month",
"January", "February", "March",
"April", "May", "June",
"July", "August", "September",
"October", "November", "December"
}; return (n < 1 || n > 12) ? name[0] :
name[n];
}
The declaration of name, which is an array of character pointers, is the same as lineptrin the sorting
example. The initializer is a list of character strings; each is assigned to the corresponding position
in the array. The characters of the i-th string are placed somewhere, and a pointer to them is stored
in name[i]. Since the size of the array name is not specified, the compiler counts the initializers
and fills in the correct number.
then a[3][4] and b[3][4] are both syntactically legal references to a single int. But a is a true
two-dimensional array: 200 int-sized locations have been set aside, and the conventional
rectangular subscript calculation 20 * row +col is used to find the element a[row,col]. For b,
however, the definition only allocates 10 pointers and does not initialize them; initialization must
be done explicitly, either statically or with code. Assuming that each element of b does point to a
twenty-element array, then there will be 200 ints set aside, plus ten cells for the pointers. The
important advantage of the pointer array is that the rows of the array may be of different lengths.
That is, each element of b need not point to a twenty-element vector; some may point to two
elements, some to fifty, and some to none at all. Although we have phrased this discussion in terms
of integers, by far the most frequent use of arrays of pointers is to store character strings of diverse
lengths, as in the function month_name. Compare the declaration and picture for an array of pointers:
We can declare an array that contains pointers as its elements. Syntax to declare array of pointer:
datatype *arrayname[size];
For example to declare an array of size 20 that contains integer pointers we can write int
*a[10];
type *function_name(type1,type2,……);
For Example: void main()
{ int
*p;
p=fun();
} int
*fun() {
int a=5;
int *q=&a;
return q;
}
Pointers to Functions
How to declare a pointer to a function?
Syntax: pointer_variable(ist of
arguments); OR
(*pointer_variable)(List of arguments);
int getc() {
return 10; }
void put(int a)
{
printf(“%d”,a);
}
void main()
{ int
k;
int (*p)(); /*You can write void *p();*/
void (*q)(int); /*You can write void *q(int);*/ p=get; q=put;
k=p(); q(k);
}
NOTE:
(i) In C every function is stored into physical memory location and entry point of that function
address is stored into function name. If you assign a pointer to to the function then the base
address of the function is copied into the pointer. Using this control is shifting from calling
function to called function.
(ii) By default all functions are global, we can access from wherever we want. So there is no
such significance to make a pointer to function.
In C, a function itself is not a variable, but it is possible to define pointers to functions, which can
be assigned, placed in arrays, passed to functions, returned by functions, and so on. We will illustrate
this by modifying the sorting procedure written earlier in this chapter so that if the optional argument
-n is given, it will sort the input lines numerically instead of lexicographically.
A sort often consists of three parts - a comparison that determines the ordering of any pair of objects,
an exchange that reverses their order, and a sorting algorithm that makes comparisons and
exchanges until the objects are in order. The sorting algorithm is independent of the comparison and
exchange operations, so by passing different comparison and exchange functions to it, we can
arrange to sort by different criteria. This is the approach taken in our new sort. Lexicographic
comparison of two lines is done by strcmp, as before; we will also need a routine numcmpthat
compares two lines on the basis of numeric value and returns the same kind of condition indication
as strcmpdoes. These functions are declared ahead of main and a pointer to the appropriate one is
passed to qsort. We have skimped on error processing for arguments, so as to concentrate on the
main issues.
#include <stdio.h>
#include <string.h>
#define MAXLINES 5000 /* max #lines to be sorted */
In the call to qsort, strcmpand numcmpare addresses of functions. Since they are known to be
functions, the & is not necessary, in the same way that it is not needed before an array name. We
have written qsortso it can process any data type, not just character strings. As indicated by the
function prototype, qsortexpects an array of pointers, two integers, and a function with two pointer
arguments. The generic pointer type void * is used for the pointer arguments. Any pointer can be
cast to void * and back again without loss of information, so we can call qsortby casting
arguments to void *. The elaborate cast of the function argument casts the arguments of the
comparison function. These will generally have no effect on actual representation, but assure the
compiler that all is well.
The declarations should be studied with some care. The fourth parameter of qsortis
which says that comp is a pointer to a function that has two void * arguments and returns an
int.
is consistent with the declaration: comp is a pointer to a function, *comp is the function, and
(*comp)(v[i], v[left])
is the call to it. The parentheses are needed so the components are correctly associated; without
them,
says that comp is a function returning a pointer to an int, which is very different. We have already
shown strcmp, which compares two strings. Here is numcmp, which compares two strings on a
leading numeric value, computed by calling atof:
#include <stdlib.h>
/* numcmp: compare s1 and s2 numerically */
intnumcmp(char *s1, char *s2)
{ double v1, v2;
v1 = atof(s1);
v2 = atof(s2);
if (v1 < v2)
return -1; else
if (v1 > v2)
return 1; else
return 0;
}
struct stud {
int roll; char
dept_code[25];
float cgpa;
} class[100], *ptr ;
The name class represents the address of the zero-th element of the structure array. ptr is a
pointer to data objects of the type struct stud. The assignment ptr = class; will assign the
address of class[0] to ptr.
When the pointer ptr is incremented by one (ptr++) :
The value of ptr is actually increased by sizeof(stud).
Once ptr points to a structure variable, the members can be accessed as:
ptr –> roll; ptr –>
dept_code;
ptr –> cgpa;
Linear Search
is a sequential searching algorithm in C that is used to find an element in a list.
• We can implement linear search in C to check if the given element is
present in both random access and sequential access data structures such
as arrays, linked lists, trees, etc.
• Linear Search compares each element of the list with the key till the
element is found or we reach the end of the list.
In this article, we will see the iterative and recursive linear search programs in C
programming language.
Algorithm for Linear Search in C
Let key be the element we are searching for.
1. Check each element in the list by comparing it to the key.
3. If we reach the end of the list without finding the element equal to the key,
return some value to represent that the element is not found.
Linear Seach Program in C (Iterative)
C
// C program to implement linear search using loops
#include <stdio.h>
// Driver code
int main()
{
int arr[10] = { 3, 4, 1, 7, 5, 8, 11, 42, 3, 13 };
int size = sizeof(arr) / sizeof(arr[0]);
int key = 4;
// calling linearSearch
int index = linearSearch(arr, size, key);
Output
The element is present at arr[1].
// Driver code
int main()
{
int arr[5] = { 6, 7, 9, 1, 5, 11, 8, 12, 2, 3 };
int size = sizeof(arr) / sizeof(int);
int key = 4;
// calling linearSearch function
int index = linearSearch(arr, size, key);
if (index == -1) {
printf("The element is not present in the list.");
}
else {
printf("The element is present at arr[%d].", index);
}
return 0;
}
Output
The element is not present in the list.
Bubble Sort
is the simplest sorting algorithm that works by repeatedly swapping the adjacent
elements if they are in the wrong order. This algorithm is not suitable for large data
sets as its average and worst-case time complexity is quite high.
Bubble Sort Algorithm
In this algorithm,
• traverse from left and compare adjacent elements and the higher one is
placed at right side.
• In this way, the largest element is moved to the rightmost end at first.
• This process is then continued to find the second largest and place it and
so on until the data is sorted.
How does Bubble Sort Work?
Let us understand the working of bubble sort with the help of the following illustration:
Input: arr[] = {6, 3, 0, 5}
First Pass:
remaining elements at their correct positions
• C
• Java
• Python3
• C#
• Javascript
• PHP
// Optimized implementation of Bubble sort
#include <bits/stdc++.h>
using namespace std;
Output
Sorted array:
11 12 22 25 34 64 90