Computer Programming Notes
Computer Programming Notes
COMPUTER
PROGRAMMING
System languages: These are designed for low-level tasks, like memory and process
management
Scripting languages: These tend to be high-level and very powerful
Domain-specific languages: These are only used in very specific contexts
Visual languages: Languages that are not text-based
Esoteric languages: Languages that are jokes or are not intended for serious use
These languages are not mutually exclusive, and some languages can belong to multiple
categories. The terms low-level and high-level are also open to interpretation, and some
languages that were once considered high-level are now considered low-level as languages have
continued to develop.
Low-Level Languages
Low-level computer languages are either machine codes or are very close them. A computer
cannot understand instructions given to it in high-level languages or in English. It can only
understand and execute instructions given in the form of machine language i.e. binary. There are
two types of low-level languages:
Machine Language
Machine language is the lowest and most elementary level of programming language and was the
first type of programming language to be developed. Machine language is basically the only
language that a computer can understand and it is usually written in hex.
In fact, a manufacturer designs a computer to obey just one language, its machine code, which is
represented inside the computer by a string of binary digits (bits) 0 and 1. The symbol 0 stands
for the absence of an electric pulse and the 1 stands for the presence of an electric pulse. Since a
computer is capable of recognizing electric signals, it understands machine language.
Advantages Disadvantages
Machine language makes fast and efficient use
All operation codes have to be remembered
of the computer.
It requires no translator to translate the code. It All memory addresses have to be
is directly understood by the computer. remembered.
It is hard to amend or find errors in a program
written in the machine language.
Assembly Language
Assembly language was developed to overcome some of the many inconveniences of machine
language. This is another low-level but very important language in which operation codes and
operands are given in the form of alphanumeric symbols instead of 0’s and l’s.
These alphanumeric symbols are known as mnemonic codes and can combine in a maximum of
five-letter combinations e.g. ADD for addition, SUB for subtraction, START, LABEL etc.
Because of this feature, assembly language is also known as ‘Symbolic Programming Language.'
This language is also very difficult and needs a lot of practice to master it because there is only a
little English support in this language. Mostly assembly language is used to help in compiler
orientations. The instructions of the assembly language are converted to machine codes by a
language translator and then they are executed by the computer.
Advantages Disadvantages
Assembly language is easier to understand Like machine language, it is also machine
and use as compared to machine language. dependent/specific.
Since it is machine dependent, the programmer
It is easy to locate and correct errors.
also needs to understand the hardware.
It is easily modified.
High-Level Languages
High-level computer languages use formats that are similar to English. The purpose of
developing high-level languages was to enable people to write programs easily, in their own
native language environment (English).
High-level languages are basically symbolic languages that use English words and/or
mathematical symbols rather than mnemonic codes. Each instruction in the high-level language
is translated into many machine language instructions that the computer can understand.
Advantages Disadvantages
A high-level language has to be
High-level languages are user-friendly translated into the machine language by a
translator, which takes up time
The object code generated by a translator
They are similar to English and use English
might be inefficient compared to an
vocabulary and well-known symbols
equivalent assembly language program
They are easier to learn
They are easier to maintain
They are problem-oriented rather than 'machine'-
based
A program written in a high-level language can be
translated into many machine languages and can run
on any computer for which there exists an
appropriate translator
The language is independent of the machine on
which it is used i.e. programs developed in a high-
level language can be run on any computer text
Many languages have been developed for achieving a variety of different tasks. Some are fairly
specialized, and others are quite general.
These languages are oriented towards the computational procedures for solving mathematical
and statistical problems.
Examples include:
These languages are best able to maintain data processing procedures and problems involved in
handling files. Some examples include:
COBOL (Common Business Oriented Language)
RPG (Report Program Generator)
These are used for string manipulation, including search patterns and inserting and deleting
characters. Examples are:
C++
Java
Visual Basic
Visual Java
Visual C
Compilers
Compiler is a computer program that reads a program written in one language, which is called the
source language, and translates it in to another language, which is called the target language. Most
often, the source language is a high level language and the target language is a low level language.
So, in general compilers can be seen as translators that translate from one language to another. In
addition, compilers perform some optimizations to the code. A typical compiler is made up of
several main components. The first component is the scanner (also known as the lexical analyzer).
Scanner reads the program and converts it to a string of tokens. The second component is the
parser. It converts the string of tokens in to a parse tree (or an abstract syntax tree), which captures
the syntactic structure of the program. Next component is the semantic routines that interpret the
semantics of the syntactic structure. The code optimizations and final code generation follow this.
Assemblers
Assembler is a software or a tool that translates Assembly language to machine code. So, an
assembler is a type of a compiler and the source code is written in Assembly language. Assembly
is a human readable language but it typically has a one to one relationship with the corresponding
machine code. Therefore an assembler is said to perform isomorphic (one to one mapping)
translation. Advanced assemblers provide additional features that support program development
and debugging processes. For example, the type of assemblers called macro assemblers provides
a macro facility.
Compiler is a computer program that reads a program written in one language and translates it in
to another language, while an assembler can be considered a special type of compiler which
translates only Assembly language to machine code. Compilers usually produce the machine
executable code directly from a high level language, but assemblers produce an object code which
might have to be linked using linker programs in order to run on a machine. Because Assembly
language has a one to one mapping with machine code, an assembler may be used for producing
code that runs very efficiently for occasions in which performance is very important (for e.g.
graphics engines, embedded systems with limited hardware resources compared to a personal
computer like microwaves, washing machines, etc.).
FLOWCHARTS
Before you start coding a program it is necessary to plan the step by step solution to the task your
program will carry out. Such a plan can be symbolically developed using a diagram. This
diagram is then called a flowchart. Hence a flowchart is a symbolic representation of a solution
to a given task. A flowchart can be developed for practically any job. Flowcharting is a tool that
can help us to develop and represent graphically program logic sequence. It also enables us to
trace and detect any logical or other errors before the programs are written.
TYPES OF FLOWCHARTS
Computer professionals use two types of flowcharts viz :
- Program Flowcharts.
- System Flowcharts
Program Flowcharts :
These are used by programmers. A program flowchart shows the program structure, logic flow
and operations performed. It also forms an important part of the documentation of the system. It
broadly includes the following:
- Program Structure.
- Program Logic.
- Data Inputs at various stages.
- Data Processing
- Computations and Calculations.
- Conditions on which decisions are based.
- Branching & Looping Sequences.
- Results.
- Various Outputs.
The emphasis in a program flowchart is on the logic.
System Flowcharts :
System flowcharts are used by system analyst to show various processes, sub systems, outputs
and operations on data in a system
FLOWCHART SYMBOLS
Normally, an algorithm is expressed as a flowchart and then the flowchart is converted into a
program with the programming language. Flowcharts are independent of the programming
language being used. Hence one can fully concentrate on the logic of the problem solving at this
stage. A large number of programmers use flowcharts to assist them in the development of
computer programs. Once the flowchart is fully ready, the programmer then write it in the
programming language. At this stage he need not concentrate on the logic but can give more
attention to coding each instruction in the box of the flowchart in terms of the statements of the
programming language selected.
A flowchart can thus be described as the picture of the logic to be included in the computer
program. It is always recommended for a beginner, to draw flowcharts prior to writing programs
in the selected language. Flowcharts are very helpful during the testing of the program as well as
incorporating further modifications.
Flowcharting has many standard symbols. Flowcharts use boxes of different shapes to denote
different types of instructions. The actual instruction is written in the box. These boxes are
connected with solid lines which have arrowheads to indicate the direction of flow of the flowchart.
The boxes which are used in flowcharts are standardised to have specific meanings. These
flowchart symbols have been standardised by the American National Standards Institute. (ANSI).
While using the flowchart symbols following points have to be kept in
mind:
- The shape of the symbol is important and must not be changed.
- The size can be changed as required.
- The symbol must be immediately recognizable.
- The details inside the symbol must be clearly legible.
- The flow lines, as far as possible, must not cross.
Terminal Symbol:
Every flowchart has a unique starting point and an ending point. The flowchart begins at the start
terminator and ends at the stop terminator. The Starting Point is indicated with the word START
inside the terminator symbol. The Ending Point is indicated with the word STOP inside the
terminator symbol. There can be only one
START and one STOP terminator in you entire flowchart. In case a program logic involves a
pause, it is also indicated with the terminal symbol.
Input/Output Symbol :
This symbol is used to denote any input/output function in the program. Thus if there is any input
to the program via an input device, like a keyboard, tape, card reader etc. it will be indicated in
the flowchart with the help of the Input/Output symbol. Similarly, all output instructions, for
output to devices like printers, plotters, magnetic tapes, disk, monitors etc. are indicated in the
Input/Output symbol.
Process Symbol :
A process symbol is used to represent arithmetic and data movement instructions in the
flowchart. All arithmetic processes of addition, subtraction, multiplication and division are
indicated in the process symbol. The logical process of data movement form one memory
location to another is also represented in the process box. If there are more than one process
instructions to be executed sequentially, they can be placed in the same process box, one below
the other in the sequence in which they are to be executed.
Decision Symbol :
The decision symbol is used in a flowchart to indicate the point where a decision is to be made
and branching done upon the result of the decision to one or more alternative paths. The criteria
for decision making is written in the decision box. All the possible paths should be accounted
for. During execution, the appropriate path will be followed depending upon the result of the
decision.
Flowlines :
Flowlines are solid lines with arrowheads which indicate the flow of operation. They show the
exact sequence in which the instructions are to be executed. The normal flow of the flowchart is
depicted from top to bottom and left to right.
Connectors :
In situations, where the flowcharts becomes big, it may so happen that the flowlines start
crossing each other at many places causing confusion. This will also result in making the
flowchart difficult to understand. Also, the flowchart may not fit in a single page for big
programs. Thus whenever the flowchart becomes complex and spreads over a number of pages
connectors are used. The connector represents entry from or exit to another part of the flowchart.
A connector symbol is indicated by a circle and a letter or a digit is placed in the circle. This
letter or digit indicates a link. A pair of such identically labelled connectors are used to indicate a
continued flow in situations where flowcharts are complex or spread over more than one page.
Thus a connector indicates an exit from some section in the flowchart and an entry into another
section of the flowchart. If an arrow enters a flowchart but does not leave it, it means that it is an
exit point in the flowchart and program control is transferred to an identically labelled connector
which has an outlet. This connector will be connected to the further program flow from the point
where it has exited. Connectors do not represent any operation in the flowchart. Their use is only
for the purpose of increased convenience and clarity.
ADVANTAGES OF FLOWCHARTS
There are a number of advantages when using flowcharts in problem solving. They provide a
very powerful tool to programmers to first represent their program logic graphically and
independent of the programming language.
- Developing the program logic and sequence. A macro flowchart can first be designed to depict
the main line of logic of the software. This model can then be broken down into smaller detailed
parts for further study and analysis.
- A flowchart being a pictorial representation of a program, makes it easier for the programmer
to explain the logic of the program to others rather than a program
- It shows the execution of logical steps without the syntax and language complexities of a
program.
- In real life programming situations a number of programmers are associated with the
development of a system and each programmer is assigned a specific task of the entire system.
Hence, each programmer can develop his own flowchart and later on all the flowcharts can be
combined for depicting the overall system. Any problems related to linking of different modules
can be detected at this stage itself and suitable modifications carried out. Flowcharts can thus be
used as working models in design of new software systems.
- Flowcharts provide a strong documentation in the overall documentation of the software
system.
- Once the flowchart is complete, it becomes very easy for programmers to write the program
from the starting point to the ending point. Since the flowchart is a detailed representation of the
program logic no step is missed during the actual program writing resulting in error free
programs. Such programs can also be developed faster.
- A flowchart is very helpful in the process of debugging a program. The bugs can be detected
and corrected with the help of a flowchart in a systematic manner.- A flowchart proves to be a
very effective tool for testing. Different sets of data are fed as input to program for the purpose
Programming Considerations :
Most programming languages have commands for performing test and branching. The exact
commands and syntax depends on the language used. Some of the conditional constructs
available in programming languages for implementing decision making in programs are as
follows:
- If
- If - else - endif
- If - elseif - endif
- Do case - endcase. - Switch. All languages do not support all of the above constructs. The
operators available for implementing the decision test are as follows: - Relational Operators
(which determine equality or inequality) - Logical Operators, (useful for combining expressions)
The branching to another set of commands can be implemented by using functions, procedures
etc.
Example: Flowchart to get marks for 3 subjects and declare the result. If the marks >= 35 in all
the subjects the student passes else fails.
The steps involved in this process are :
1. Start.
2. Create memvars m1, m2, m3.
3. Read marks of three subjects m1, m2, m3.
4. If m1 >= 35 goto step 5 else goto step 7
5. If m2 >= 35 goto step 6 else goto step 7
6. If m3 >= 35 print Pass. Goto step 8
7. Print fail
8. Stop
Basic elements of C
Structure of C program
STRUCTURE OF A C PROGRAM
While writing a C program, a programmer has to follow some rules. Structure of a C program is a
protocol (rules) to the programmer.
The general format of a C program is
Documentation Section
Link Section Preprocessor
DefinitionSection Statements
Global Declaration Section
main( )
{
Local declaration section
Body of
Programming statements
main()
Calling user defined function
function (optional to user)
}
Sub program section
Function 1
Option to user
Function 2
Documentation Section:-
This section consists of a set of comment lines giving the name of the program and any other
details about the program which may be required by the programmer likes.
Comment lines:-
The lines which begins with /* and ends with */ are known as comment lines. These are not
executable statements. Therefore we can use them anywhere in our program. They also do not
affect the execution speed and size of a program. They help the programmers and other users in
understanding what is happening in the program.
Preprocessor Statements:
The preprocessor statement begins with # symbol and are also called the preprocessor directives.
They provide instructions to the compiler to link functions from the system library.
Definition section defines all symbolic constants.
# define instructions:
Defines value to a symbolic constant for use in the program.
Eg: # define PI 3.14. Here this value remains constant through out the execution of the program.
A # define is a compiler directive and not a statement. Therefore # define lines should not end with
a semicolon.
# include <stdio.h> :
stdio.h refers to the standard I/O header file containing standard input and output functions.
main( ):
Every program must have only one main( ) function . This section mainly consists of two parts
a. Declaration part
b. Executable part
All the variables used in the executable part are declared in the declaration part. These two parts
are enclosed between an opening brace and . The program execution begins at the opening brace
and ends at the closing brace.
Keywords
KEYWORDS
Keywords are reserved words that have standard, predefined meanings in C. These keywords can
be used only for their intended purpose. So, a programmer cannot use them to name variables,
functions or constants. C keywords are in lowercase only. There are 32 keywords available in C.
Table 1.2 shows the standard keywords used in C.
Table 1.2: Standard Keywords
auto double int struct
break else long switch
case enum register typedef
char extern return union
const float short unsigned
continue for signed void
default go to sizeof volatile
do if static while
Identifiers
IDENTIFIERS
Identifiers are names given to various program elements such as variables, functions and arrays.
An identifier is a combination of alphanumeric characters , the first being a letter of the
alphabet or an underline, and the remaining being any letter of the alphabet, any numeric
digit or the underline.
Both upper case and lower case letters are permitted, however they are not interchangeable
( i.e., an upper case letter is not equivalent to the corresponding lowercase letter.)
Must contain atleast one character of the alphabet.
Keywords cannot be used as an identifier.
Identifier should contain enough characters so that it is meaningful.
Eg: i , a12, total_56, DATA etc
data types,
DATA TYPES
Variables should be defined before it is used. C has the concept of ‘data types’ for the same. There
are mainly four classes of data types. They are
a. Primary (or Fundamental ) Data type
b. User defined data type - typedef
- enum
c. Derived data type - Array
- Function
- Pointer
- Structure
- Union
d. Empty data set
Primary data types are discussed in this chapter.
short int represents small integer values. They require only half the amount of storage as a regular
int number uses. Unsigned int uses all the bits for the magnitude of the number and they are
always positive. So range of unsigned integer numbers will be from 0 to 65,535. It is not
compulsory to use the qualifier signed on integers, because by default declaration assumes a signed
number. A signed integer uses one bit for sign and 15 bits for the magnitude of the number. Table
1.4 shows the integer data type, its size and range on a 16 bit machine.
Table 1.4: Integer Data Types, Size and Range
Integer Data Size
Range of Values
type (bytes)
int or signed -32,768 to
2
int 32,767
unsigned int 2 0 to 65,535
short int or
1 -128 to 127
signed short int
unsigned short
1 0 to 255
int
long int or -2,147,483,648
4
signed long int to 2,147,483,647
unsigned long 0 to
4
int 4,294,967,295
Operators are symbols which operate on value or a variable. C programming language has wide
range of operators to perform various operations. Operators are classified as follows:
1. Arithmetic Operator
2. Assignment Operator
3. Relational Operators
4. Logical Operators
5. Increment or Decrement Operators
6. Conditional Operators
7. Bitwise Operators
8. Special Operators
2.2 EXPRESSIONS:
An expression is any computation that yields a value. Or, an expression is a combination of
operators and operands. The operands can be constants, variables or a combination of the two.
2.2.1 Precedence And Order Of Evaluation
The precedence and associativity of C operators affect the grouping and evaluation of operands
in expressions. An operator’s precedence comes into play only if other operators with higher or
lower precedence are present. Expressions with higher precedence operators are evaluated first.
Precedence can also be described by the word ‘binding’. Operators with a higher precedence are
said to have tighter binding. The following table 2.2 shows the precedence and associativity (the
order in which the operands are evaluated) of C operators, in the order of highest precedence to
lowest precedence. If several operators with equal precedence are present, then they are evaluated
according to their associativity.
Table 2.2: Precedence and Associativity of Operators
Symbol Description Associativity
Parenthesis L to R
()
(Function call)
Brackets (Array
[]
Subscript )
- > Member selection
. via pointer
++ -- Postfix increment /
decrement
* / L to R
% Multiplication/ Division/ Modulus
+ - Addition/ Subtraction L to R
>> << Bitwise shift right, bitwise shift left L to R
< < = Relational less than / less than or equal to L to R
> >= Relational greater than / greater than or equal to L to R
&arg1 & arg2 are the addresses of the variables where the input datas are stored.
Eg: scanf(“%d %d”. &a, &b);
%d is the format specifier. &a and &b provides the address of variable a and b. The value entered
is stored in the variable a and b.
2.3.1.2 printf ( ) --- print formatted:
This function is a formatted output function which is used to get printed output on screen. This
function can be used for printing captions as well as the numerical results. When the results are
printed on the screen, it should be printed in such a way that they are understandable to the user.
The general format of printf( ) function is
printf(“Control/format string”,arg1,arg2);
Control string can be any one of the following
Characters that will be printed on the screen as they appear.
Format specifications that define the output format for display of each item.
Escape sequence characters such as \n, \t, \b etc.
The control string also indicates the number of arguments required to be printed along with their
types. arg1 , arg2 are the variables whose values are formatted and printed according to the
specifications of the control string.
Eg: printf(“Sum is %d”,c);
Optional format specifiers
%8d prints the value in 8 column and is right justified. That is, it inserts blanks at the left.
%8.3f prints 8 column output , 3 digit after decimal point, 4 digit before decimal point and
one digit for decimal.
%-8d prints 8 column output and is left justification. That is, blanks are inserted on the
right side.
2.3.2.1 getch ( ):
getch( ) function is an unformatted console input function which is used to enter one character at
a time. If the user doesn’t want to show the input, then this function can be used.
Eg: a = getch( );
Here, when the user press any character key on the keyboard, it will be immediately accepted and
stored in the variable a.
2.3.2.2 getche ( ):
This function is also an unformatted console input function which is used to enter one character at
a time. In this, the character which is entered by the user will be echoed/ displayed on the screen
but the user need not press the Enter key to submit the character. When the key is pressed, it will
be accepted from the program.
Eg: a = getche( );
2.3.2.3 getchar ( ):
This function is also an unformatted console input function which is used to enter one character at
a time from a standard input device such as keyboard. Here also, the entered character will be
echoed/ displayed on the screen but the user need to press Enter key.
Eg: a = getchar( );
2.3.2.4 putch ( ):
putch( ) function is an unformatted console character output function which is used to print one
character at a time on the screen.
Eg: putch ( a);
2.3.2.5 putchar ( ):
This function is also an unformatted console character output function which is used to print one
character at a time on the screen.
Eg: putchar (a);
2.3.2.6 gets ( ):
gets( ) function is an unformatted string input function which is used to enter a string (array of
characters) from the keyboard. This function accepts a single argument. The argument must be a
data item that represents a string. The string may include white space characters. The string will
be entered from the keyboard and will terminate with a newline character. (Pressing Enter key
allows the user to end a string).
Eg: gets (name);
Here, name must be an array of characters
2.3.2.7 puts ( ):
This function is an unformatted string output function which is used to print the string on the
monitor. This function also accepts a single argument. The argument must be a data item that
represents a string.
Eg: puts(name);
MODULE II
Control statements in C
Control statements are the statements which determine the flow of control in the program. They
specify the order in which the various instructions are to be executed.
4.2 DECISION MAKING AND BRANCHING STATEMENTS:
A program is a set of statements. These statements are executed sequentially in the order in which
it is written. In some cases, we may need to change the order of execution of the statements
depending on certain conditions. C supports the following decision making or control statements
to enable branching of statements based on conditions.
a. if statement
b. switch statement
c. conditional operator statement
Test true
expressio
n
Statement block
False
Statement x
Next statement
Fig 4.1 Flowchart of Simple if statement
In the above example, if the password entered by the user is 1000, “WELCOME” will be printed
otherwise no output will be displayed.
4.2.1.2 if……….else statement:
The if ……… else statement is an expansion of the simple if statement. The general format of
if….. else statement is
if (expression)
{
statement block 1;
}
else
{
statement block 2;
}
statement x;
If the condition is true, the true block statements are executed first and then the control is
transferred to statement x. If the condition is false, the statement block 2 is executed first and then
the control is transferred to statement x. Figure 4.2 shows the flow chart of if ……. else statement.
entry
Statement
Statement
block 1
block 2
Statement x
Fig 4.2 Flowchart of if……else statement
P17. A program to print “WELCOME” on the screen ,if the password entered by the user
matches with 1000 and if it doesn’t match, print “The entered password is wrong” on screen.
#include<stdio.h>
#include<conio.h>
void main()
{
int password, check=1000;
clrscr();
printf("Enter the password: ");
scanf("%d",&password);
if(password == check)
{
printf("Welcome");
}
else
{
printf("The entered password is wrong");
}
getch();
}
In this program, if the user enter the password as 1000, then “Welcome” will be printed. Otherwise,
the message “ The entered password is wrong “ will be displayed.
4.2.1.3 Nested if……….else statement:
When a series of decisions are involved, we may have to use more than one if………else statement
in nested form. That means, we may have to use one if……. else statement inside another if or
else statement. The general format of nested if……. else statement is
if (expression)
{
if (expression 1)
{
statement block 1;
}
else
{ entry
statement block 2;
False expr
} True
essio
} n
else
{
Statement
statement block 3;
block 3
}
False expr True
statement x; essi
Statement
Figblock
4.3 Flowchart
2 of Nested if……else
Statement statement
block 1
Here, if the expression is true, then expression 1 will be checked and if expression 1 is true,
statement block 1 will be executed. If expression 1 is false, then statement block 2 will be executed.
But, if the expression is false, it jumps to else part and execute the statement 3. Then statement x
will be executed. Figure 4.3 shows the flow chart of nestedStatement x statement.
if ……. else
P18. A program to relate the two integers entered by the user using ‘=’ or ‘>’ or ‘<’ sign.
#include<stdio.h>
#include<conio.h>
void main()
{
int firstno, secondno;
clrscr();
printf("Enter the first number: ");
scanf("%d",&firstno);
printf("Enter the second number: ");
scanf("%d",&secondno);
if(firstno == secondno)
{
printf("Result ---> %d = %d \n",
firstno,secondno);
}
else
{
if(firstno > secondno)
{
printf("Result ---> %d > %d \n",
firstno,secondno);
}
else
{
printf("Result ---> %d < %d \n",
firstno,secondno);
}
}
getch();
}
Entry
Statement
block 1
Statement
block 2
switch
(expression)
False
False
Default
Statement
Fig 4.5 Flowchart of switch – case statement
P20. A program which accepts an integer between 0 and 9 from the user and display it in
words.
#include<stdio.h>
#include<conio.h>
void main()
{
int number;
clrscr();
printf("Enter an integer between 0 and 9: ");
scanf("%d",&number);
switch(number)
{
case 0: printf("ZERO"); break;
case 1: printf("ONE"); break;
case 2: printf("TWO"); break;
case 3: printf("THREE"); break;
case 4: printf("FOUR"); break;
case 5: printf("FIVE"); break;
case 6: printf("SIX"); break;
case 7: printf("SEVEN"); break;
case 8: printf("EIGHT"); break;
case 9: printf("NINE"); break;
default : printf("You have entered a wrong
integer ");
}
getch();
}
P22. A program to check whether the number entered by the user is odd or even.
#include<stdio.h>
#include<conio.h>
void main()
{
int num;
clrscr();
printf("Enter the number: ");
scanf("%d",&num);
if (num%2 == 0)
{
printf("The entered number %d is
even",num);
}
else
{
printf("The entered number %d is
odd",num);
}
getch();
}
P28. A program to check whether the entered year in four digits is a leap year or not.
Note: The years that are divisible by 100 and also divisible by 400 are leap years. Those years that
are not divisible by 100 but divisible by 4 are also leap years.
#include<stdio.h>
#include<conio.h>
void main()
{
int year;
clrscr();
printf("Enter a year in four digits: ");
scanf("%d",&year);
if(year%4 ==0 && year %100!=0 || year %
400 ==0)
{
printf("The entered year %d is a leap
year",year);
}
else
{
printf("The entered year %d is not a leap
year",year);
}
getch();
}
EXERCISES
A17. Write a program to check whether the entered number is odd or even only if it is a three digit
number. Otherwise, display the message that the entered number is not a three digit number.
A18. Write a program to check whether the number is positive or negative or zero.
A19. Write a program which accepts an integer from the user and display its cube if it is a non
zero number.
A20. Write a program to find the smallest of two numbers.
While
Do-while
For statement
Break
Continue
Go to
Labels
5.2 TYPES OF LOOPS
Loops are mainly classified into three. They are
i) for loop
ii) while loop
iii) do …… while loop
Entry
Initialisation Expression
True
Increment/Decrement
Figure 5.3: Flowchart of for Loop
The for loop is also known as determinate or definite loop because the programmer knows exactly
how many times the loop will be repeated.
P29. A program to print 0 to 9 using for loop.
#include<stdio.h>
#include<conio.h>
void main()
{
int i;
clrscr();
for (i =0; i<10; i++)
{
printf("%d ",i);
}
getch();
}
Output:
0 1 2 3 4 5 6 7 8 9
In the above program,
i. The first step is the initialization of the control variable. That is, ‘i’ is set to 0. The variable
‘i’ is known as loop control variable.
ii. After initialization, the value of the control variable is tested using the test condition. If the
condition is true, the printf statement will be executed.
iii. After the execution of the loop, the control is transferred back to the for statement and the
variable is incremented. That is, i = i + 1.
iv. Again the value is tested and if it is true, again the body is executed and the process continues.
v. When the value of ‘i’ becomes 10, the test condition becomes false and the for loop is
terminated.
5.2.1.2 Nesting of for loop:
Nesting of loops, that is one for statement within another for statement, is allowed in C
programming language. The general format of nested for loop is
for ( i = 1; i<10; i++)
{
body of outer loop
for (j = 1; j<10; j++)
{
Body of inner loop
}
}
Entry
True
#include<stdio.h>
#include<conio.h>
void main()
{
int i=0;
clrscr();
while (i<10)
{
printf("%d ",i);
i = i + 1;
}
getch();
}
Output:
0 1 2 3 4 5 6 7 8 9
Entry
While loop
#include<stdio.h>
#include<conio.h>
void main()
{
int i=15;
clrscr();
while (i<11)
{
printf("%d ",i);
i = i + 1;
}
getch();
}
Output:
No output
P33. A program to print “Hello” on the screen 10 times using for loop.
#include<stdio.h>
#include<conio.h>
void main()
{
int i;
clrscr();
for(i=1;i<=10;i++)
{
printf("%d. Hello \n",i);
}
getch();
}
P34. A program to print the alphabets on the screen using for loop.
#include<stdio.h>
#include<conio.h>
void main()
{
char ch;
clrscr();
for(ch='A';ch<='Z';ch++)
{
printf("%c\t",ch);
}
getch();
}
P35. A program to print “Hello” on the Screen, n times using while loop. Accept the value
of n from the user.
#include<stdio.h>
#include<conio.h>
void main()
{
int n,i=1;
clrscr();
printf("Enter how many times: ");
scanf("%d",&n);
while(i<=n)
{
printf("%d. Hello\n",i);
i++;
}
getch();
}
P36. A program to print all the even numbers less than n using for loop. Accept the value of
n from the user.
#include<stdio.h>
#include<conio.h>
void main()
{
int n,i;
clrscr();
printf("Enter the value of n:");
scanf("%d",&n);
for(i =1;i<=n;i++)
{
if(i%2 == 0)
{
printf("%d \t",i);
}
}
getch();
}
P37. A program to print all the odd numbers less than n using do-while loop. Accept the
value of n from the user.
#include<stdio.h>
#include<conio.h>
void main()
{
int n,i=1;
clrscr();
printf("Enter the value of n:");
scanf("%d",&n);
do
{
if(i%2 != 0)
{
printf("%d \t",i);
}
i++;
}while(i<=n);
getch();
}
P38. A program to display perfect squares less than 100. [ i.e., 1,4,9,16,……..81]
#include<stdio.h>
#include<conio.h>
void main()
{
int i;
clrscr();
for(i=1;i*i<100;i++)
{
printf("%d \t",i*i);
}
getch();
}
P39. A program to display the first 10 English alphabets using do-while loop
#include<stdio.h>
#include<conio.h>
void main()
{
int i=1;
char ch='A';
clrscr();
do
{
printf("%c \t",ch);
ch++;
i++;
}while(i<=10);
getch();
}
P40. A program to print the sum of first 10 natural numbers using for loop.
#include<stdio.h>
#include<conio.h>
void main()
{
int i,sum=0;
clrscr();
for(i=1;i<=10;i++)
{
sum = sum + i;
}
printf("The sum of first 10 natural numbers
is %d",sum);
getch();
}
P41. A program to print the sum of even numbers less than 100 using while loop.
#include<stdio.h>
#include<conio.h>
void main()
{
int i=1,sum=0;
clrscr();
while (i<100)
{
if(i%2 ==0)
{
sum = sum + i;
}
i++;
}
printf("The sum of even numbers less than
100 is %d",sum);
getch();
}
P42. A program to print the sum of first 100 even numbers using for loop.
#include<stdio.h>
#include<conio.h>
void main()
{
int i,sum=0,check=1;
clrscr();
for(i=1;check<=100;i++)
{
if(i%2 ==0)
{
sum = sum + i;
check++;
}
};
printf("The sum of first %d even numbers is
%d",check-1,sum);
getch();
}
P43. A program to print the sum of 10 different numbers entered by the user using for loop.
#include<stdio.h>
#include<conio.h>
void main()
{
int i,sum=0,num;
clrscr();
for(i=1;i<=10;i++)
{
printf("\nEnter number %d: ",i);
scanf("%d",&num); sum = sum + num;
}
printf("The sum of 10 different numbers is
%d",sum);
getch();
}
P44. A program to print the multiplication table of an integer entered by the user having 10
rows.
#include<stdio.h>
#include<conio.h>
void main()
{
int i,num;
clrscr();
printf("Enter an integer");
scanf("%d",&num);
printf("\nMULTIPLICATION TABLE OF
%d",num);
printf("\n--------------------------\n");
for(i=1;i<=10;i++)
{
printf("\n %d * %d = %d
",i,num,i*num);
}
getch();
}
P45. A program to display all the factors of an integer number entered by the user.
#include<stdio.h>
#include<conio.h>
void main()
{
int i=1,num;
clrscr();
printf("Enter an integer: ");
scanf(" %d",&num);
printf("\n The factors of %d are : ",num);
while(i<=num)
{
if(num%i == 0)
printf(" %d\t",i);
i++;
}
getch();
}
P46. A program to find the HCF (highest common factor of two numbers entered by the
user.
#include<stdio.h>
#include<conio.h>
void main()
{
int n1,n2,i=1,hcf;
clrscr();
printf("Enter two integer numbers : ");
scanf("%d%d",&n1,&n2);
while (i<=n1 || i<=n2)
{
if(n1%i ==0 && n2%i == 0)
{
hcf = i ;
}
i++;
}
printf("The HCF of %d and %d is
%d",n1,n2,hcf);
getch();
}
P47. A program to find the factorial of a number entered by the user. Also, if the user enters
a negative number, the following message should be displayed. “The factorial of a negative
number doesn’t exist”.
#include<stdio.h>
#include<conio.h>
void main()
{
int num,fact=1,i;
clrscr();
printf("Enter a number : ");
scanf("%d",&num);
if(num<0)
{
printf("The factorial of a negative number
doesn't exist");
}
else
{
for(i=1;i<=num;i++)
{
fact = fact * i;
}
printf("The factorial of %d is
%d",num,fact);
}
getch();
}
P48. A program to find the sum of digits of a number entered by the user using while loop.
#include<stdio.h>
#include<conio.h>
void main()
{
int num,dup,sum=0,i,rem;
clrscr();
printf("Enter a number : ");
scanf("%d",&num);
dup = num;
while(num!=0)
{
rem = num % 10;
sum = sum + rem;
num = num/10;
}
printf("Sum of digits of %d is %d",dup,sum);
getch();
}
Test
conditi True
break
on
within
False
Figure 5.6: Flowchart of break statement
Figure 5.7 explains the working of break statement in while, do-while and for loop
Test
Normal return of loop
False
5.3.3 GO TO Statement:
This is another statement used to alter the normal sequence of program execution by
unconditionally transferring control to some other part of the program. The general format of the
goto statement is
goto label;
Label is an identifier used to label the statement where the control is to be transferred. Control can
be transferred to anywhere within the current function. The general format is
label: statement;
Figure 5.10 shows the working of goto statement.
Note: Use of goto statement should be reduced as much as possible in a program. The goto
statement makes the logic of the program complex and tangled. The goto statement can be replaced
with the use of break and continue statements.
P54. A program to check whether a
number is Armstrong or not.
Note: A number is said to be an Armstrong number if it is equal to the sum of the cubes of the
digits of that number. Eg. 153 = 13+53+33
#include<stdio.h>
#include<conio.h>
void main()
{
int num, sum=0,i=1,dup,rem;
clrscr();
printf("Enter a number: ");
scanf("%d",&num);
dup = num;
while(num>0)
{
rem = num%10;
sum = sum + rem *rem * rem;
num = num/10;
}
if (dup == sum)
{
printf("The number %d is an Armstrong
number",dup);
}
else
{
printf("The number %d is not an Armstrong
number",dup);
}
getch();
}
#include<stdio.h>
#include<conio.h>
void main()
{
int i,num,flag = 0;
clrscr();
printf("Enter an integer: ");
scanf("%d",&num);
for(i=2;i<=num/2;i++)
{
if (num%i == 0)
{
printf("The number %d is not
prime",num);
flag = 1;
break;
}
}
if(flag == 0)
{
printf("The number %d is prime",num);
}
getch();
}
#include<stdio.h>
#include<conio.h>
void main()
{
float sum=0, term,acc,nr,x,a;
int dr = 1, f=1;
const float pi=22.0/7.0;
clrscr();
printf("Enter angle in degrees: ");
scanf(" %f",&a);
x = a * pi/180;
term = acc = nr = x;
while (acc>0.0001)
{
sum = sum + term;
nr = nr * x * x;
dr = dr * (f+1) * (f+2);
f=f+2;
acc = nr/dr;
term = (-1)*acc;
}
printf("sin(%f) = %f",a,sum);
getch();
}
#include<stdio.h>
#include<conio.h>
#include<math.h>
void main()
{
float sum=1, term,acc,nr,x,a;
int dr = 2, f=2;
const float pi=22.0/7.0;
clrscr();
printf("Enter angle in degrees: ");
scanf(" %f",&a);
x = a * pi/180;
nr = x * x;
acc = nr/dr;
term = (-1) * acc;
while (acc>0.0001)
{
sum = sum + term;
nr = nr * x * x;
dr = dr * (f+1) * (f+2);
f=f+2;
acc = nr/dr;
term = (-1)*acc;
}
printf("cos(%f) = %f",a,sum);
getch();
}
#include<stdio.h>
#include<conio.h>
void main()
{
float sum = 1, nr, term, x;
int dr =1, i = 1;
clrscr();
printf("Enter the value of x: ");
scanf(" %f",&x);
nr=x;
do
{
term = nr/dr;
sum = sum + term;
i = i +1;
dr = dr * i;
nr = nr * x;
}while( term > 0.0001);
printf("The value is %f",sum);
getch();
}
#include<stdio.h>
#include<conio.h>
void main()
{
float sum =0 , term, x;
int i = 1 ;
clrscr();
printf("Enter the value of x");
scanf("%f",&x);
term = x ;
sum = sum + term;
while(abs(term) > 0.0001)
{
i++;
term = term * (x/i) * (-1);
sum = sum + term;
}
printf(" The value is %f",sum);
getch();
}
*******************
Module III
Arrays and Strings:
C programming language provides a data structure called the array, which can store a fixed-size
sequential collection of elements of the same type. An array is used to store a collection of data,
but it is often more useful to think of an array as a collection of variables of the same type.
Instead of declaring individual variables, such as number0, number1, ..., and number99, you
declare one array variable such as numbers and use numbers[0], numbers[1], and ..., numbers[99]
to represent individual variables. A specific element in an array is accessed by an index.
All arrays consist of continuous memory locations. The lowest address corresponds to the first
element and the highest address to the last element.
Declaration
DECLARING ARRAYS
To declare an array in C, a programmer specifies the type of the elements and the number of
elements required by an array as follows:
This is called a single-dimensional array. The arraySize must be an integer constant greater than
zero and type can be any valid C data type. For example, to declare a 10-element array
called balance of type double, use this statement:
double balance[10];
Now balance is a variable array which is sufficient to hold upto 10 double numbers.
Initialisation
INITIALIZING ARRAYS
You can initialize array in C either one by one or using a single statement as follows:
If you omit the size of the array, an array just big enough to hold the initialization is created.
Therefore, if you write:
You will create exactly the same array as you did in the previous example.
balance[4] = 50.0;
The above statement assigns element number 5th in the array a value of 50.0. Array with 4th index
will be 5th ie. last element because all arrays have 0 as the index of their first element which is
also called base index. Following is the pictorial representation of the same array we discussed
above:
The above statement will take 10th element from the array and assign the value to salary variable.
Following is an example which will use all the above mentioned three concepts viz. declaration,
assignment and accessing arrays:
#include <stdio.h>
int main ()
{
int n[ 10 ]; /* n is an array of 10 integers */
int i,j;
return 0;
}
When the above code is compiled and executed, it produces following result:
Element[0] = 100
Element[1] = 101
Element[2] = 102
Element[3] = 103
Element[4] = 104
Element[5] = 105
Element[6] = 106
Element[7] = 107
Element[8] = 108
Element[9] = 109
type name[size1][size2]...[sizeN];
For example, the following declaration creates a three dimensional 5 . 10 . 4 integer array:
int threedim[5][10][4];
Two dimensional
Multidimensional Arrays
Application of arrays
Example programs.
TWO-DIMENSIONAL ARRAYS:
The simplest form of the multidimensional array is the two-dimensional array. A two-dimensional
array is, in essence, a list of one-dimensional arrays. To declare a two-dimensional integer array
of size x,y you would write something as follows:
type arrayName [ x ][ y ];
Where type can be any valid C data type and arrayName will be a valid C identifier. A two
dimensional array can be think as a table which will have x number of rows and y number of
columns. A 2-dimentional array a which contains three rows and four columns can be shown as
below:
Thus, every element in array a is identified by an element name of the form a[ i ][ j ], where a is
the name of the array, and i and j are the subscripts that uniquely identify each element in a.
int a[3][4] = {
{0, 1, 2, 3} , /* initializers for row indexed by 0 */
{4, 5, 6, 7} , /* initializers for row indexed by 1 */
{8, 9, 10, 11} /* initializers for row indexed by 2 */
};
The nested braces, which indicate the intended row, are optional. The following initialization is
equivalent to previous example:
The above statement will take 4th element from the 3rd row of the array. You can verify it in the
above diagram. Let us check below program where we have used nested loop to handle a two
dimensional array:
#include <stdio.h>
int main ()
{
/* an array with 5 rows and 2 columns*/
int a[5][2] = { {0,0}, {1,2}, {2,4}, {3,6},{4,8}};
int i, j;
When the above code is compiled and executed, it produces following result:
a[0][0]: 0
a[0][1]: 0
a[1][0]: 1
a[1][1]: 2
a[2][0]: 2
a[2][1]: 4
a[3][0]: 3
a[3][1]: 6
a[4][0]: 4
a[4][1]: 8
As explained above, you can have arrays with any number of dimensions, although it is likely that
most of the arrays you create will be of one or two dimensions.
Way-1
Formal parameters as a pointer as follows. You will study what is pointer in next chapter.
Way-2
Formal parameters as a sized array as follows:
Way-3
Formal parameters as an unsized array as follows:
Example
Now consider the following function which will take an array as an argument along with another
argument and based on the passed arguments, it will return average of the numbers passed through
the array as follows:
return avg;
}
#include <stdio.h>
/* function declaration */
double getAverage(int arr[], int size);
int main ()
{
/* an int array with 5 elements */
int balance[5] = {1000, 2, 3, 17, 50};
double avg;
return 0;
}
When the above code is compiled together and executed, it produces following result:
As you can see, the length of the array doesn't matter as far as the function is concerned because
C performs no bounds checking for the formal parameters.
RETURN ARRAY FROM FUNCTION IN C
C programming language does not allow to return an entire array as an argument to a function.
However, You can return a pointer to an array by specifying the array's name without an index.
You will study pointer in next chapter so you can skip this chapter until you understand the concept
of Pointers in C.
If you want to return a single-dimension array from a function, you would have to declare a
function returning a pointer as in the following example:
int * myFunction()
{
.
.
.
}
Second point to remember is that C does not advocate to return the address of a local variable to
outside of the function so you would have to define the local variable as static variable.
Now consider the following function which will generate 10 random numbers and return them
using an array and call this function as follows:
#include <stdio.h>
return r;
}
p = getRandom();
for ( i = 0; i < 10; i++ )
{
printf( "*(p + %d) : %d\n", i, *(p + i));
}
return 0;
}
When the above code is compiled together and executed, it produces result something as follows:
r[0] = 313959809
r[1] = 1759055877
r[2] = 1113101911
r[3] = 2133832223
r[4] = 2073354073
r[5] = 167288147
r[6] = 1827471542
r[7] = 834791014
r[8] = 1901409888
r[9] = 1990469526
*(p + 0) : 313959809
*(p + 1) : 1759055877
*(p + 2) : 1113101911
*(p + 3) : 2133832223
*(p + 4) : 2073354073
*(p + 5) : 167288147
*(p + 6) : 1827471542
*(p + 7) : 834791014
*(p + 8) : 1901409888
*(p + 9) : 1990469526
POINTER TO AN ARRAY IN C
It is most likely that you would not understand this chapter until you through the chapter related
Pointers in C.
So assuming you have bit understanding on pointers in C programming language, let us start: An
array name is a constant pointer to the first element of the array. Therefore, in the declaration:
double balance[50];
balance is a pointer to &balance[0], which is the address of the first element of the array balance.
Thus, the following program fragment assigns p the address of the first element of balance:
double *p;
double balance[10];
p = balance;
It is legal to use array names as constant pointers, and vice versa. Therefore, *(balance + 4) is a
legitimate way of accessing the data at balance[4].
Once you store the address of first element in p, you can access array elements using *p, *(p+1),
*(p+2) and so on. Below is the example to show all the concepts discussed above:
#include <stdio.h>
int main ()
{
/* an array with 5 elements */
double balance[5] = {1000.0, 2.0, 3.4, 17.0, 50.0};
double *p;
int i;
p = balance;
return 0;
}
When the above code is compiled and executed, it produces following result:
STRINGS
7.1 INTRODUCTION
A string is a one dimensional array of characters terminated by a null character ‘\0’. The null
character is an escape sequence which is used to denote the end of a string.
The general format of declaring a string variable is
datatype stringname [size];
The datatype must be always char. The size determines the number of characters that can be stored
in the array. The compiler automatically inserts a null character ‘\0’ at the end of the string.
Therefore the size should be equal to the maximum number of characters in the string plus one.
Eg. char name [20];
7.2 INITIALIZATION OF A STRING VARIABLE
7.2.1 Compile Time Initialization:
Character arrays may be initialized while declaring. There are different ways of initializing an
array of characters.
Eg. char strg[12] = {‘H’,’O’,’W’,
’ ‘,’A’,’R’,’E’, ’Y’,’O’,’U’,’\0’}
or
char string[12] = “HOW ARE YOU”;
or
char strg[ ] = “HOW ARE YOU”;
Whenever a string is enclosed in double quotes, C language automatically inserts a null character
‘\0’ at the end of the string.
7.3 READING STRINGS
There are different methods available in C for reading string.
7.3.1 Using scanf( ) function
The scanf( ) function can be used for reading words. The scanf ( ) function reads a string until a
white space it finds. The white space includes blank, tab, newline etc. The general format is scanf
(“ %ws”, string name);
String name is the name of the character array which is not preceded by ampersand ( & ) symbol.
‘w’ specifies the number of characters accepted in the input string.
Eg. char name[10];
scanf ( “%5s”, name);
Input Output
SAM S A M \0 ? ? ? ? ? ?
KRISHNA K R I S H \0 ? ? ? ?
? represents garbage value.
7.3.2 Using getchar( ) and gets( ) function
Refer chapter 2
7.4 PRINTING STRINGS
There are different methods available in C for printing strings.
7.4.1 Using printf ( ) function
The printf ( ) can be used for printing strings to the screen, with %s format. The format %s can be
used to display an array of characters that is terminated by the null character. The general format
is
Module IV
Functions
Functions
INTRODUCTION
A function can be defined as a set of statements that perform some specific, well defined task.
Every C program consists of one or more functions. One of the functions used in any C program
must be a main ( ) function. Execution of any C program begins by carrying out the instructions in
main.
Function in C can be classified into two categories, namely library functions and user defined
functions. Library functions are already built in and we need not write its code. But user defined
functions has to be written by the programmer at the time of writing a program. This is the main
difference between the two functions.
8.2 NEED FOR THE USE OF USERDEFINED FUNCTIONS
There may be instances where we may need to repeat certain operations or calculations during the
development of a program. In C language, a user defined function may be created which includes
these set of statements. And the function can be called anywhere in the program any number of
times. So functions save us from repetitious programming. We can write a function ones and call
it many times from different places
Declaring
FUNCTION PROTOTYPE (DECLARATION)
Before using any user defined function in a C program, it should be declared. This type of
declaration are also called function prototype.
Function prototype tells the compiler about the function name, type of arguments to be passed and
the return type. The syntax of function prototype is
return_type function_name(datatypes);
eg. int sum (int, int);
In the above example, int describes the return type, sum denotes the function name , and (int, int)
denotes the type of two arguments passed to the function.
Function prototype is not compulsory, if we write user defined function before main( ) function.
Defining
Function definition Syntax
Just like in the example above, the general syntax of function definition is,
Note: While defining a function, there is no semicolon(;) after the parenthesis in the
function header, unlike while declaring the function or calling the function.
Accessing
Calling a function
When a function is called, control of the program gets transferred to the function.
functionName(argument1, argument2,...);
In the example above, the statement multiply(i, j); inside the main() function is function
call.
Passing Arguments to a function
Arguments are the values specified during the function call, for which the formal parameters
are declared while defining the function.
It is possible to have a function with parameters but no return type. It is not necessary, that
if a function accepts parameter(s), it must return a result too.
While declaring the function, we have declared two parameters a and b of type int.
Therefore, while calling that function, we need to pass two arguments, else we will get
compilation error. And the two arguments passed should be received in the function
definition, which means that the function header in the function definition should have the
two parameters to hold the argument values. These received arguments are also known as
formal parameters. The name of the variables while declaring, calling and defining a
function can be different.
A function may or may not return a result. But if it does, we must use the return statement
to output the result. return statement also ends the function execution, hence it must be the
last statement of any function. If you write any statement after the return statement, it won't
be executed.
The datatype of the value returned using the return statement should be same as the
return type mentioned at function declaration and definition. If any of it mismatches, you will
get compilation error.
In the next tutorial, we will learn about the different types of user defined functions in C
language and the concept of Nesting of functions which is used in recursion.
Below, we will discuss about all these types, along with program examples.
Such functions can either be used to display information or they are completely dependent
on user inputs.
Below is an example of a function, which takes 2 numbers as input from user, and display
which is the greater number.
#include<stdio.h> void greatNum(); // function declaration int main() { greatNum(); // function call
return 0; } void greatNum() // function definition { int i, j; printf("Enter 2 numbers that you want to
compare..."); scanf("%d%d", &i, &j); if(i > j) { printf("The greater number is: %d", i); } else {
printf("The greater number is: %d", j); } }
We have modified the above example to make the function greatNum() return the number
which is greater amongst the 2 input numbers.
#include<stdio.h> int greatNum(); // function declaration int main() { int result; result = greatNum();
// function call printf("The greater number is: %d", result); return 0; } int greatNum() // function
definition { int i, j, greaterNum; printf("Enter 2 numbers that you want to compare..."); scanf("%d%d",
&i, &j); if(i > j) { greaterNum = i; } else { greaterNum = j; } // returning the result return
greaterNum; }
We are using the same function as example again and again, to demonstrate that to solve a
problem there can be many different ways.
This time, we have modified the above example to make the function greatNum() take two
int values as arguments, but it will not be returning anything.
#include<stdio.h> void greatNum(int a, int b); // function declaration int main() { int i, j;
printf("Enter 2 numbers that you want to compare..."); scanf("%d%d", &i, &j); greatNum(i, j); //
function call return 0; } void greatNum(int x, int y) // function definition { if(x > y) { printf("The
greater number is: %d", x); } else { printf("The greater number is: %d", y); } }
This is the best type, as this makes the function completely independent of inputs and
outputs, and only the logic is defined inside the function body.
#include<stdio.h> int greatNum(int a, int b); // function declaration int main() { int i, j, result;
printf("Enter 2 numbers that you want to compare..."); scanf("%d%d", &i, &j); result = greatNum(i, j);
// function call printf("The greater number is: %d", result); return 0; } int greatNum(int x, int y) //
function definition { if(x > y) { return x; } else { return y; } }
Nesting of Functions
C language also allows nesting of functions i.e to use/call one function inside another
function's body. We must be careful while using nested functions, because it may lead to
infinite nesting.
function1() { // function1 body here function2(); // function1 body here }
If function2() also has a call for function1() inside it, then in that case, it will lead to an
infinite nesting. They will keep calling each other and the program will never terminate.
Not able to understand? Lets consider that inside the main() function, function1() is called
and its execution starts, then inside function1(), we have a call for function2(), so the control
of program will go to the function2(). But as function2() also has a call to function1() in its
body, it will call function1(), which will again call function2(), and this will go on for infinite
times, until you forcefully exit from program execution.
What is Recursion?
Recursion is a special way of nesting functions, where a function calls itself inside it. We
must have certain conditions in the function to break out of the recursion, otherwise
recursion will occur infinite times.
function1() { // function1 body function1(); // function1 body }
1. Call by Value
2. Call by Reference
Call by Value
Calling a function by value means, we pass the values of the arguments which are stored or
copied into the formal parameters of the function. Hence, the original values are unchanged
only the parameters inside the function changes.
#include<stdio.h> void calc(int x); int main() { int x = 10; calc(x); // this will print the value of
'x' printf("\nvalue of x in main is %d", x); return 0; } void calc(int x) { // changing the value of
'x' x = x + 10 ; printf("value of x in calc function is %d ", x); }
value of x in main is 10
In this case, the actual variable x is not changed. This is because we are passing the
argument by value, hence a copy of x is passed to the function, which is updated during
function execution, and that copied value in the function is destroyed when the function
ends(goes out of scope). So the variable x inside the main() function is never changed and
hence, still holds a value of 10.
But we can change this program to let the function modify the original x variable, by making
the function calc() return a value, and storing that value in x.
#include<stdio.h> int calc(int x); int main() { int x = 10; x = calc(x); printf("value of x is %d", x);
return 0; } int calc(int x) { x = x + 10 ; return x; }
value of x is 20
Call by Reference
In this case the formal parameter can be taken as a reference or a pointer(don't worry
about pointers, we will soon learn about them), in both the cases they will change the
values of the original variable.
#include<stdio.h> void calc(int *p); // functin taking pointer as argument int main() { int x = 10;
calc(&x); // passing address of 'x' as argument printf("value of x is %d", x); return(0); } void
calc(int *p) //receiving the address in a reference pointer variable { /* changing the value directly
that is stored at the address passed */ *p = *p + 10; }
value of x is 20
There are two possible ways to do so, one by using call by value and other by using call by
reference.
2. Or, we can have a pointer in the parameter list, to hold the base address of our array.
int sum (int* ptr);
We will study the second way in details later when we will study pointers.
We don't return an array from functions, rather we return a pointer holding the base address
of the array to be returned. But we must, make sure that the array exists after the function
ends i.e. the array is not local to the function.
int* sum (int x[]) { // statements return x ; }
We will discuss about this when we will study pointers with arrays.
Now let's see a few examples where we will pass a single array element as argument to a
function, a one dimensional array to a function and a multidimensional array to a function.
Passing a single array element to a function
Let's write a very simple program, where we will declare and define an array of integers in
our main() function and pass one of the array element to a function, which will just print the
value of the element.
#include<stdio.h> void giveMeArray(int a); int main() { int myArray[] = { 2, 3, 4 };
giveMeArray(myArray[2]); //Passing array element myArray[2] only. return 0; } void giveMeArray(int a) {
printf("%d", a); }
To understand how this is done, let's write a function to find out average of all the elements
of the array and print it.
We will only send in the name of the array as argument, which is nothing but the address of
the starting element of the array, or we can say the starting memory address.
#include<stdio.h> float findAverage(int marks[]); int main() { float avg; int marks[] = {99, 90, 96,
93, 95}; avg = findAverage(marks); // name of the array is passed as argument. printf("Average marks =
%.1f", avg); return 0; } float findAverage(int marks[]) { int i, sum = 0; float avg; for (i = 0; i <=
4; i++) { sum += age[i]; } avg = (sum / 5); return avg; }
94.6
Here again, we will only pass the name of the array as argument.
#include<stdio.h> void displayArray(int arr[3][3]); int main() { int arr[3][3], i, j; printf("Please
enter 9 numbers for the array: \n"); for (i = 0; i < 3; ++i) { for (j = 0; j < 3; ++j) { scanf("%d",
&arr[i][j]); } } // passing the array as argument displayArray(arr); return 0; } void displayArray(int
arr[3][3]) { int i, j; printf("The complete array is: \n"); for (i = 0; i < 3; ++i) { // getting cursor
to new line printf("\n"); for (j = 0; j < 3; ++j) { // \t is used to provide tab space printf("%d\t",
arr[i][j]); } } }
1 2 3
4 5 6
7 8 9
Storage classes
Storage classes in C
In C language, each variable has a storage class which decides the following things:
scope i.e where the value of the variable would be available inside a program.
default initial value i.e if we do not explicitly initialize that variable, what will be its
default initial value.
lifetime of that variable i.e for how long will that variable exist.
1. Automatic variables
2. External variables
3. Static variables
4. Register variables
Scope: Variable defined with auto storage class are local to the function block inside which
they are defined.
Lifetime: Till the end of the function/method block where the variable is defined.
A variable declared inside a function without any storage class specification, is by default an
automatic variable. They are created when a function is called and are destroyed
automatically when the function's execution is completed. Automatic variables can also be
called local variables because they are local to a function. By default they are assigned
garbage value by the compiler.
#include<stdio.h> void main() { int detail; // or auto int details; //Both are same }
Scope: Global i.e everywhere in the program. These variables are not bound by any
function, they are available everywhere.
Lifetime: Till the program doesn't finish its execution, you can access global variables.
A variable that is declared outside any function is a Global Variable. Global variables
remain available throughout the program execution. By default, initial value of the Global
variable is 0(zero). One important thing to remember about global variable is that their
values can be changed by any function in the program.
#include<stdio.h> int number; // global variable void main() { number = 10; printf("I am in main
function. My value is %d\n", number); fun1(); //function calling, discussed in next topic fun2();
//function calling, discussed in next topic } /* This is function 1 */ fun1() { number = 20; printf("I
am in function fun1. My value is %d", number); } /* This is function 1 */ fun2() { printf("\nI am in
function fun2. My value is %d", number); }
Here the global variable number is available to all three functions and thus, if one function
changes the value of the variable, it gets changed in every function.
Note: Declaring the storage class as global or external for all the variables in a program can
waste a lot of memory space because these variables have a lifetime till the end of the
program. Thus, variables, which are not needed till the end of the program, will still occupy
the memory and thus, memory will be wasted.
extern keyword
The extern keyword is used with a variable to inform the compiler that this variable is
declared somewhere else. The extern declaration does not allocate storage for variables.
Problem when extern is not used
int main() { a = 10; //Error: cannot find definition of variable 'a' printf("%d", a); }
Static variables
A static variable tells the compiler to persist/save the variable until the end of program.
Instead of creating and destroying a variable every time when it comes into and goes out of
scope, static variable is initialized only once and remains into existence till the end of the
program. A static variable can either be internal or external depending upon the place of
declaration. Scope of internal static variable remains inside the function in which it is
defined. External static variables remain restricted to scope of file in which they are
declared.
1 2 3
Register variable
Lifetime: Till the end of function/method block, in which the variable is defined.
Register variables inform the compiler to store the variable in CPU register instead of
memory. Register variables have faster accessibility than a normal variable. Generally, the
frequently used variables are kept in registers. But only a few variables can be placed inside
registers. One application of register storage class can be in using loops, where the variable
gets used a number of times in the program, in a very short span of time.
Syntax :
register int number;
Note: Even though we have declared the storage class of our variable number as register,
we cannot surely say that the value of the variable would be stored in a register. This is
because the number of registers in a CPU are limited. Also, CPU registers are meant to do
a lot of important work. Thus, sometimes they may not be free. In such scenario, the
variable works as if its storage class is auto.
To improve the speed of execution of the program and to carefully use the memory space
occupied by the variables, following points should be kept in mind while using storage
classes:
We should use static storage class only when we want the value of the variable to
remain same every time we call it using different function calls.
We should use register storage class only for those variables that are used in our
program very oftenly. CPU registers are limited and thus should be used carefully.
We should use external or global storage class only for those variables that are being
used by almost all the functions in the program.
If we do not have the purpose of any of the above mentioned storage classes, then we
should use the automatic storage class.
Extern
Auto
Register
Static
Example programs
Module V
Structures
Declaration
Introduction to Structure
Structure is a user-defined datatype in C language which allows us to combine data of
different types together. Structure helps to construct a complex data type which is more
meaningful. It is somewhat similar to an Array, but an array holds data of similar type only.
But structure on the other hand, can store data of any type, which is practical more useful.
For example: If I have to write a program to store Student information, which will have
Student's name, age, branch, permanent address, father's name etc, which included string
values, integer values etc, how can I use arrays for this problem, I will require something
which can hold data of different types together.
Defining a structure
struct keyword is used to define a structure. struct defines a new data type which is a
collection of primary and derived datatypes.
Syntax:
struct [structure_tag] { //member variable 1 //member variable 2 //member variable 3 ...
}[structure_variables];
As you can see in the syntax above, we start with the struct keyword, then it's optional to
provide your structure a name, we suggest you to give it a name, then inside the curly
braces, we have to mention all the member variables, which are nothing but normal C
language variables of different types like int, float, array etc.
After the closing curly brace, we can specify one or more structure variables, again this is
optional.
Note: The closing curly brace in the structure type declaration must be followed by a
semicolon(;).
Example of Structure
struct Student { char name[25]; int age; char branch[10]; // F for female and M for male char gender;
};
Here struct Student declares a structure to hold the details of a student which consists of
4 data fields, namely name, age, branch and gender. These fields are called structure
elements or members.
Each member can have different datatype, like in this case, name is an array of char type
and age is of int type etc. Student is the name of the structure and is called as the
structure tag.
Here S1 and S2 are variables of structure Student. However this approach is not much
recommended.
Structure members can be accessed and assigned values in a number of ways. Structure
members have no meaning individually without the structure. In order to assign a value to
any structure member, the member name must be linked with the structure variable using
a dot . operator also called period or member access operator.
For example:
#include<stdio.h> #include<string.h> struct Student { char name[25]; int age; char branch[10]; //F for
female and M for male char gender; }; int main() { struct Student s1; /* s1 is a variable of Student
type and age is a member of Student */ s1.age = 18; /* using string function to add name */
strcpy(s1.name, "Viraaj"); /* displaying the stored values */ printf("Name of Student 1: %s\n",
s1.name); printf("Age of Student 1: %d\n", s1.age); return 0; }
Age of Student 1: 18
We can also use scanf() to give values to structure members through terminal.
scanf(" %s ", s1.name); scanf(" %d ", &s1.age);
Structure Initialization
Like a variable of any other datatype, structure variable can also be initialized at compile
time.
struct Patient { float height; int weight; int age; }; struct Patient p1 = { 180.75 , 73, 23 };
//initialization
or,
struct Patient p1; p1.height = 180.75; //initialization of each member separately p1.weight = 73;
p1.age = 23;
Array of Structure
We can also declare an array of structure variables. in which each element of the array will
represent a structure variable. Example : struct employee emp[5];
The below program defines an array emp of size 5. Each element of the array emp is of type
Employee.
#include<stdio.h> struct Employee { char ename[10]; int sal; }; struct Employee emp[5]; int i, j; void
ask() { for(i = 0; i < 3; i++) { printf("\nEnter %dst Employee record:\n", i+1); printf("\nEmployee
name:\t"); scanf("%s", emp[i].ename); printf("\nEnter Salary:\t"); scanf("%d", &emp[i].sal); }
printf("\nDisplaying Employee record:\n"); for(i = 0; i < 3; i++) { printf("\nEmployee name is %s",
emp[i].ename); printf("\nSlary is %d", emp[i].sal); } } void main() { ask(); }
Nested Structures
Nesting of structures, is also permitted in C language. Nested structures means, that one
structure has another stucture as member variable.
Example:
struct Student { char[30] name; int age; /* here Address is a structure */ struct Address { char[50]
locality; char[50] city; int pincode; }addr; };
We can pass a structure as a function argument just like we pass any other variable or an
array as a function argument.
Example:
#include<stdio.h> struct Student { char name[10]; int roll; }; void show(struct Student st); void
main() { struct Student std; printf("\nEnter Student record:\n"); printf("\nStudent name:\t");
scanf("%s", std.name); printf("\nEnter Student rollno.:\t"); scanf("%d", &std.roll); show(std); } void
show(struct Student st) { printf("\nstudent name is %s", st.name); printf("\nroll is %d", st.roll); }
typedef in C
The above statement define a term ulong for an unsigned long datatype. Now this ulong
identifier can be used to define unsigned long type variables.
ulong i, j;
Application of typedef
typedef can be used to give a name to user defined data type as well. Lets see its use with
structures.
typedef struct { type member1; type member2; type member3; } type_name;
Here type_name represents the stucture definition associated with it. Now this type_name
can be used to declare a variable of this stucture type.
type_name t1, t2;
typedef can be used to give an alias name to pointers also. Here we have a case in which
use of typedef is beneficial during pointer declaration.
By this declaration statement, we are actually declaring x as a pointer of type int, whereas
y will be declared as a plain int variable.
But if we use typedef like we have used in the example above, we can declare any number
of pointers in a single statement
Unions in C Language
Unions are conceptually similar to structures. The syntax to declare/define a union is also
similar to that of a structure. The only differences is in terms of storage. In structure each
member has its own storage location, whereas all members of union uses a single shared
memory location which is equal to the size of its largest data member.
This implies that although a union may contain many members of different types, it cannot
handle all the members at the same time. A union is declared using the union keyword.
union item { int m; float x; char c; }It1;
This declares a variable It1 of type union item. This union contains three members each
with a different data type. However only one of them can be used at a time. This is due to
the fact that only one location is allocated for all the union variables, irrespective of their
size. The compiler allocates the storage that is large enough to hold the largest variable
type in the union.
In the union declared above the member x requires 4 bytes which is largest amongst the
members for a 16-bit machine. Other members of union will share the same memory
address.
Accessing a Union Member
Syntax for accessing any union member is similar to accessing structure members,
union test { int a; float b; char c; }t; t.a; //to access members of union t t.b; t.c;
-26426
20.1999
As you can see here, the values of a and b get corrupted and only variable c prints the
expected result. This is because in union, the memory is shared among different data types.
Hence, the only member whose value is currently stored will have the memory.
In the above example, value of the variable c was stored at last, hence the value of other
variables is lost.
Definition
Initialization
Unions
Pointers
Introduction to Pointers
A Pointer in C language is a variable which holds the address of another variable of same
data type.
Before we start understanding what pointers are and what they can do, let's start by
understanding what does "Address of a memory location" means?
Address in C
Whenever a variable is defined in C language, a memory location is assigned for it, in which
it's value will be stored. We can easily check this memory address, using the & symbol.
If var is the name of the variable, then &var will give it's address.
Let's write a small program to see memory address of any variable that we define in our
program.
#include<stdio.h> void main() { int var = 7; printf("Value of the variable var is: %d\n", var);
printf("Memory address of the variable var is: %x\n", &var); }
You must have also seen in the function scanf(), we mention &var to take user input for
any variable var.
scanf("%d", &var);
This is used to store the user inputted value to the address of the variable var.
Concept of Pointers
Let us assume that system has allocated memory location 80F for a variable a.
int a = 10;
We can access the value 10 either by using the variable name a or by using its address 80F.
The question is how we can access a variable using it's address? Since the memory
addresses are also just numbers, they can also be assigned to some other variable. The
variables which are used to hold memory addresses are called Pointer variables.
A pointer variable is therefore nothing but a variable which holds an address of some other
variable. And the value of a pointer variable gets stored in another memory location.
Benefits of using pointers
Pointer variablea always point to variables of same datatype. Let's have an example to
showcase this:
#include<stdio.h> void main() { float a; int *ptr; ptr = &a; // ERROR, type mismatch }
If you are not sure about which variable's address to assign to a pointer variable while
declaration, it is recommended to assign a NULL value to your pointer variable. A pointer
which is assigned a NULL value is called a NULL pointer.
#include <stdio.h> int main() { int *ptr = NULL; return 0; }
Once a pointer has been assigned the address of a variable, to access the value of the
variable, pointer is dereferenced, using the indirection operator or dereferencing
operator *.
#include <stdio.h> int main() { int a, *p; // declaring the variable and pointer a = 10; p = &a; //
initializing the pointer printf("%d", *p); //this will print the value of 'a' printf("%d", *&a); //this
will also print the value of 'a' printf("%u", &a); //this will print the address of 'a' printf("%u",
p); //this will also print the address of 'a' printf("%u", &p); //this will print the address of 'p'
return 0; }
1. While declaring/initializing the pointer variable, * indicates that the variable is a pointer.
2. The address of any variable is given by preceding the variable name with Ampersand &.
3. The pointer variable stores the address of a variable. The declaration int *a doesn't
mean that a is going to contain an integer value. It means that a is going to contain the
address of a variable storing integer value.
4. To access the value of a certain address stored by a pointer variable, * is used. Here,
the * can be read as 'value at'.
Syntax:
int **p1;
Here, we have used two indirection operator(*) which stores and points to the address of a
pointer variable i.e, int *. If we want to store the address of this (double pointer) variable
p1, then the syntax would become:
int ***p2
Address of a = 2686724
Address of p1 = 2686728
Address of p2 = 2686732
Value of **p2 = 10
p1 pointer variable can only hold the address of the variable a (i.e Number of indirection
operator(*)-1 variable). Similarly, p2 variable can only hold the address of variable p1. It
cannot hold the address of variable a.
*p2 gives us the value at an address stored by the p2 pointer. p2 stores the address of
p1 pointer and value at the address of p1 is the address of variable a. Thus, *p2 prints
address of a.
**p2 can be read as *(*p2). Hence, it gives us the value stored at the address *p2.
From above statement, you know *p2 means the address of variable a. Hence, the
value at the address *p2 is 10. Thus, **p2 prints 10.
When an array is declared, compiler allocates sufficient amount of memory to contain all the
elements of the array. Base address i.e address of the first element of the array is also
allocated by the compiler.
Assuming that the base address of arr is 1000 and each integer requires two bytes, the five
elements will be stored as follows:
Here variable arr will give the base address, which is a constant pointer pointing to the first
element of the array, arr[0]. Hence arr contains the address of arr[0] i.e 1000. In short,
arr has two purpose - it is the name of the array and it acts as a pointer pointing towards
the first element in the array.
We can also declare a pointer of type int to point to the array arr.
int *p; p = arr; // or, p = &arr[0]; //both the statements are equivalent.
Now we can access every element of the array arr using p++ to move from one element to
another.
NOTE: You cannot decrement a pointer once incremented. p-- won't work.
Pointer to Array
As studied above, we can use a pointer to point to an array, and then we can use that
pointer to access the array elements. Lets have an example,
#include <stdio.h> int main() { int i; int a[5] = {1, 2, 3, 4, 5}; int *p = a; // same as int*p = &a[0]
for (i = 0; i < 5; i++) { printf("%d", *p); p++; } return 0; }
In the above program, the pointer *p will print all the values stored in the array one by one.
We can also use the Base address (a in above case) to act as a pointer and print all the
values.
is same as:
a[i]
A multidimensional array is of form, a[i][j]. Lets see how we can make a pointer point to
such an array. As we know now, name of the array gives its base address. In a[i][j], a will
give the base address of this array, even a + 0 + 0 will also give the base address, that is
the address of a[0][0] element.
Here is the generalized form for using pointer with multidimensional arrays.
*(*(a + i) + j)
Pointer can also be used to create strings. Pointer variables of char type are treated as
string.
char *str = "Hello";
The above code creates a string and stores its address in the pointer variable str. The
pointer str now points to the first character of the string "Hello". Another important thing to
note here is that the string created using char pointer can be assigned a value at runtime.
char *str; str = "hello"; //this is Legal
The content of the string can be printed using printf() and puts().
printf("%s", str); puts(str);
Notice that str is pointer to the string, it is also name of the string. Therefore we do not
need to use indirection operator *.
Array of Pointers
We can also have array of pointers. Pointers are very helpful in handling character array
with rows of varying length.
char *name[3] = { "Adam", "chris", "Deniel" }; //Now lets see same array without using pointer char
name[3][20] = { "Adam", "chris", "Deniel" };
In the second approach memory wastage is more, hence it is prefered to use pointer in
such cases.
When we say memory wastage, it doesn't means that the strings will start occupying less
space, no, characters will take the same space, but when we define array of characters, a
contiguos memory space is located equal to the maximum size of the array, which is a
wastage, which can be avoided if we use pointers instead.
Pointer to Structure Array
Like we have array of integers, array of pointers etc, we can also have array of structure
variables. And to use the array of structure variables efficiently, we use pointers of
structure type. We can also have pointer to a single structure variable, but it is mostly used
when we are dealing with array of structure variables.
#include <stdio.h> struct Book { char name[10]; int price; } int main() { struct Book a; //Single
structure variable struct Book* ptr; //Pointer of Structure type ptr = &a; struct Book b[10]; //Array
of structure variables struct Book* p; //Pointer of Structure type p = &b; return 0; }
To access members of structure using the structure variable, we used the dot . operator.
But when we have a pointer of structure type, we use arrow -> to access structure
members.
#include <stdio.h> struct my_structure { char name[20]; int number; int rank; }; int main() { struct
my_structure variable = {"StudyTonight", 35, 1}; struct my_structure *ptr; ptr = &variable;
printf("NAME: %s\n", ptr->name); printf("NUMBER: %d\n", ptr->number); printf("RANK: %d", ptr->rank);
return 0; }
NAME: StudyTonight
NUMBER: 35
RANK: 1
Pointer Arithmetic
If you want to have complete knowledge of pointers, pointer arithmetic is very important to
understand. In this topic we will study how the memory addresses change when you
increment a pointer.
In a 16 bit machine, size of all types of pointer, be it int*, float*, char* or double* is
always 2 bytes. But when we perform any arithmetic function like increment on a pointer,
changes occur as per the size of their primitive data type.
char 1
long 4
float 4
double 8
long double 10
Now lets take a few examples and understand this more clearly.
int* i; i++;
In the above case, pointer will be of 2 bytes. And when we increment it, it will increment by
2 bytes because int is also of 2 bytes.
float* i; i++;
In this case, size of pointer is still 2 bytes initially. But now, when we increment it, it will
increment by 4 bytes because float datatype is of 4 bytes.
double* i; i++;
Similarly, in this case, size of pointer is still 2 bytes. But now, when we increment it, it will
increment by 8 bytes because its data type is double.
The concept of pointer arithmetic remains exact same, but the size of pointer and various
datatypes is different in a 32 bit machine. Pointer in 32 bit machine is of 4 bytes.
char 2
long 8
float 8
double 16
Note: We cannot add two pointers. This is because pointers contain addresses, adding two
addresses makes no sense, because you have no idea what it would point to.
But we can subtract two pointers. This is because difference between two pointers gives the
number of elements of its data type that can be stored between the two pointers.
p1 = 2680016
p2 = 2680012
*p1+*p2 = 15
p1-p2 = 1
p1++ = 2680020
p2-- = 2680008
1. Point 1: Here, * means 'value at the given address'. Thus, it adds the value of m and n
which is 15.
2. Point 2: It subtracts the addresses of the two variables and then divides it by the size of
the pointer datatype (here integer, which has size of 4 bytes) which gives us the number
of elements of integer data type that can be stored within it.
3. Point 3: It increments the address stored by the pointer by the size of its datatype(here
4).
4. Point 4: It decrements the address stored by the pointer by the size of its datatype(here
4).
5. Point 5: Addition of two pointers is not allowed.
m = 10
n = 20
After Swapping:
m = 20
n = 10
A function can also return a pointer to the calling function. In this case you must be careful,
because local variables of function doesn't live outside the function. They have scope only
inside the function. Hence if you return a pointer connected to a local variable, that pointer
will be pointing to nothing when the function ends.
#include <stdio.h> int* larger(int*, int*); void main() { int a = 15; int b = 92; int *p; p =
larger(&a, &b); printf("%d is larger",*p); } int* larger(int *x, int *y) { if(*x > *y) return x; else
return y; }
92 is larger
1. Either use argument with functions. Because argument passed to the functions are
declared inside the calling function, hence they will live outside the function as well.
2. Or, use static local variables inside the function and return them. As static variables
have a lifetime until the main() function exits, therefore they will be available througout
the program.
Pointer to functions
Here is an example :
int (*sum)(); //legal declaration of pointer to function int *sum(); //This is not a declaration of
pointer to function
A function pointer can point to a specific function when it is assigned the name of that
function.
int sum(int, int); int (*s)(int, int); s = sum;
Here s is a pointer to a function sum. Now sum can be called using function pointer s along
with providing the required argument values.
s (10, 20);
25
You will find a lot of complex function pointer examples around, lets see one such example
and try to understand it.
void *(*foo) (int*);
It appears complex but it is very simple. In this case (*foo) is a pointer to the function,
whose argument is of int* type and return type is void*.
Module VI
File Management
File Input/Output in C
A file represents a sequence of bytes on the disk where a group of related data is stored.
File is created for permanent storage of data. It is a ready made structure.
C provides a number of functions that helps to perform basic file operations. Following are
the functions,
Function description
The fopen() function is used to create a new file or to open an existing file.
General Syntax:
*fp = FILE *fopen(const char *filename, const char *mode);
Here, *fp is the FILE pointer (FILE *fp), which will hold the reference to the opened(or
created) file.
filename is the name of the file to be opened and mode specifies the purpose of opening
the file. Mode can be of following types,
mode description
Closing a File
General Syntax :
int fclose( FILE *fp);
Here fclose() function closes the file and returns zero on success, or EOF if there is an
error in closing the file. This EOF is a constant defined in the header file stdio.h.
In the above table we have discussed about various file I/O functions to perform reading
and writing on file. getc() and putc() are the simplest functions which can be used to read
and write individual characters to a file.
#include<stdio.h> int main() { FILE *fp; char ch; fp = fopen("one.txt", "w"); printf("Enter data...");
while( (ch = getchar()) != EOF) { putc(ch, fp); } fclose(fp); fp = fopen("one.txt", "r"); while( (ch =
getc(fp)! = EOF) printf("%c",ch); // closing the file pointer fclose(fp); return 0; }
In this program, we have created two FILE pointers and both are refering to the same file
but in different modes.
fprintf() function directly writes into the file, while fscanf() reads from the file, which can
then be printed on the console using standard printf() function.
Write (w) mode and Append (a) mode, while opening a file are almost the same. Both are
used to write in a file. In both the modes, new file is created if it doesn't exists already.
The only difference they have is, when you open a file in the write mode, the file is reset,
resulting in deletion of any data already present in the file. While in append mode this will
not happen. Append mode is used to append or add data to the existing data of file(if any).
Hence, when you open a file in Append(a) mode, the cursor is positioned at the end of the
present data in the file.
A Binary file is similar to a text file, but it contains only large numerical data. The Opening
modes are mentioned in the table for opening modes above.
fread() and fwrite() functions are used to read and write is a binary file.
fread() is also used in the same way, with the same arguments like fwrite() function.
Below mentioned is a simple example of writing into a binary file
const char *mytext = "The quick brown fox jumps over the lazy dog"; FILE *bfp= fopen("test.txt", "wb");
if (bfp) { fwrite(mytext, sizeof(char), strlen(mytext), bfp); fclose(bfp); }
File operations
File pointer
Introduction to Python
It has simple easy-to-use syntax, making it the perfect language for someone trying to learn
computer programming for the first time.
The syntax of the language is clean and length of the code is relatively short. It's fun to work
in Python because it allows you to think about the problem rather than focusing on the syntax
Comments are used in programming to describe the purpose of the code. This helps you as
well as other programmers to understand the intent of the code. Comments are completely
ignored by compilers and interpreters.
Line 2: num1 = 3
Here, num1 is a variable. You can store a value in a variable. Here, 3 is stored in this variable.
Line 3: num2 = 5
The variables num1 and num2 are added using + operator. The result of addition is then stored
in another variable sum.
Line 5: print(sum)
The print() function prints the output to the screen. In our case, it prints 8 on the screen.
Basic Syntax
Operators
For example:
>>> 2+3
5
Here, + is the operator that performs addition. 2 and 3 are the operands and 5 is the output of the
operation.
Arithmetic operators
Arithmetic operators are used to perform mathematical operations like addition, subtraction,
multiplication etc.
x+y
+ Add two operands or unary plus
+2
x-y
- Subtract right operand from the left or unary minus
-2
/ Divide left operand by the right one (always results into float) x/y
x % y (remainder of
% Modulus - remainder of the division of left operand by the right
x/y)
x**y (x to the
** Exponent - left operand raised to the power of right
power y)
# Output: x + y = 19
print('x + y =',x+y)
# Output: x - y = 11
print('x - y =',x-y)
# Output: x * y = 60
print('x * y =',x*y)
# Output: x / y = 3.75
print('x / y =',x/y)
# Output: x // y = 3
print('x // y =',x//y)
# Output: x ** y = 50625
print('x ** y =',x**y)
x + y = 19
x - y = 11
x * y = 60
x / y = 3.75
x // y = 3
x ** y = 50625
Comparison operators are used to compare values. It either returns True or False according to
the condition.
> Greater that - True if left operand is greater than the right x>y
< Less that - True if left operand is less than the right x<y
Greater than or equal to - True if left operand is greater than or equal to the
>= x >= y
right
<= Less than or equal to - True if left operand is less than or equal to the right x <= y
# Output: x == y is False
print('x == y is',x==y)
# Output: x != y is True
print('x != y is',x!=y)
Logical operators
Logical operators are the and, or, not operators.
# Output: x or y is True
print('x or y is',x or y)
Bitwise operators
Bitwise operators act on operands as if they were string of binary digits. It operates bit by bit,
hence the name.
In the table below: Let x = 10 (0000 1010 in binary) and y = 4 (0000 0100 in binary)
Assignment operators
Assignment operators are used in Python to assign values to variables.
a = 5 is a simple assignment operator that assigns the value 5 on the right to the variable a on
the left.
There are various compound operators in Python like a += 5 that adds to the variable and later
assigns the same. It is equivalent to a = a + 5.
= x=5 x=5
+= x += 5 x=x+5
-= x -= 5 x=x-5
*= x *= 5 x=x*5
/= x /= 5 x=x/5
%= x %= 5 x=x%5
//= x //= 5 x = x // 5
**= x **= 5 x = x ** 5
|= x |= 5 x=x|5
^= x ^= 5 x=x^5
Special operators
Python language offers some special type of operators like the identity operator or the
membership operator. They are described below with examples.
Identity operators
is and is not are the identity operators in Python. They are used to check if two values (or
variables) are located on the same part of the memory. Two variables that are equal does not
imply that they are identical.
is not True if the operands are not identical (do not refer to the same object) x is not True
# Output: False
print(x1 is not y1)
# Output: True
print(x2 is y2)
# Output: False
print(x3 is y3)
Here, we see that x1 and y1 are integers of same values, so they are equal as well as identical.
Same is the case with x2 and y2 (strings).
But x3 and y3 are list. They are equal but not identical. Since list are mutable (can be changed),
interpreter locates them separately in memory although they are equal.
Membership operators
in and not in are the membership operators in Python. They are used to test whether a value or
variable is found in a sequence (string, list, tuple, set and dictionary).
In a dictionary we can only test for presence of key, not the value.
# Output: True
print('H' in x)
# Output: True
print('hello' not in x)
# Output: True
print(1 in y)
# Output: False
print('a' in y)
Here, 'H' is in x but 'hello' is not present in x (remember, Python is case sensitive). Similary, 1 is key
and 'a' is the value in dictionary y. Hence, 'a' in y returns False.
Control statements
In Python, the body of the if statement is indicated by the indentation. Body starts with an
indentation and the first unindented line marks the end.
Python interprets non-zero values as True. None and 0 are interpreted as False.
script.py
solution.py
IPython Shell
Plots
6
7
10
11
num = 3
if num > 0:
num = -1
if num > 0:
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
In [1]:
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1/0 0/0
IPython Shell
Plots
When variable num is equal to 3, test expression is true and body inside body of if is executed.
If variable num is equal to -1, test expression is false and body inside body of if is skipped.
The print() statement falls outside of the if block (unindented). Hence, it is executed
regardless of the test expression.
The if..else statement evaluates test expression and will execute body of if only when test
condition is True.
If the condition is False, body of else is executed. Indentation is used to separate the blocks.
num = 3
if num >= 0:
print("Positive or Zero")
else:
print("Negative number")
In the above example, when num is equal to 3, the test expression is true and body of if is
executed and body of else is skipped.
If num is equal to -5, the test expression is false and body of else is executed and body of if is
skipped.
If num is equal to 0, the test expression is true and body of if is executed and body of else is
skipped.
The elif is short for else if. It allows us to check for multiple expressions.
If the condition for if is False, it checks the condition of the next elif block and so on.
Only one block among the several if...elif...else blocks is executed according to the
condition.
The if block can have only one else block. But it can have multiple elif blocks.
Flowchart of if...elif...else
Example of if...elif...else
# In this program,
# we check if the number is positive or
# negative or zero and
# display an appropriate message
num = 3.4
if num > 0:
print("Positive number")
elif num == 0:
print("Zero")
else:
print("Negative number")
# In this program,
# we check if the number is positive or
# negative or zero and
# display an appropriate message
num = 3.4
if num > 0:
print("Positive number")
elif num == 0:
print("Zero")
else:
print("Negative number")
Here, val is the variable that takes the value of the item inside the sequence on each iteration.
Loop continues until we reach the last item in the sequence. The body of for loop is separated
from the rest of the code using indentation.
Flowchart of for Loop
# List of numbers
numbers = [6, 5, 3, 8, 4, 2, 5, 4, 11]
This function does not store all the values in memory, it would be inefficient. So it remembers
the start, stop, step size and generates the next number on the go.
To force this function to output all the items, we can use the function list().
# Output: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(list(range(10)))
# Output: [2, 3, 4, 5, 6, 7]
print(list(range(2, 8)))
We can use the range() function in for loops to iterate through a sequence of numbers. It can be
combined with the len() function to iterate though a sequence using indexing. Here is an
example.
for i in range(len(genre)):
I like pop
I like rock
I like jazz
for loop with else
A for loop can have an optional else block as well. The else part is executed if the items in the
sequence used in for loop exhausts.
break statement can be used to stop a for loop. In such case, the else part is ignored.
digits = [0, 1, 5]
for i in digits:
print(i)
else:
No items left.
Here, the for loop prints items of the list until the loop exhausts. When the for loop exhausts, it
executes the block of code in the else and prints
No items left.
We generally use this loop when we don't know beforehand, the number of times to iterate.
In while loop, test expression is checked first. The body of the loop is entered only if the
test_expression evaluates to True. After one iteration, the test expression is checked again.
This process continues until the test_expression evaluates to False.
Body starts with indentation and the first unindented line marks the end.
Python interprets any non-zero value as True. None and 0 are interpreted as False.
# numbers upto
# sum = 1+2+3+...+n
# n = int(input("Enter n: "))
n = 10
sum = 0
i=1
while i <= n:
sum = sum + i
Enter n: 10
The sum is 55
In the above program, the test expression will be True as long as our counter variable i is less
than or equal to n (10 in our program).
We need to increase the value of counter variable in the body of the loop. This is very important
(and mostly forgotten). Failing to do so will result in an infinite loop (never ending loop).
The else part is executed if the condition in the while loop evaluates to False.
The while loop can be terminated with a break statement. In such case, the else part is ignored.
Hence, a while loop's else part runs if no break occurs and the condition is false.
# Example to illustrate
counter = 0
print("Inside loop")
counter = counter + 1
else:
print("Inside else")
Output
Inside loop
Inside loop
Inside loop
Inside else
Here, we use a counter variable to print the string Inside loop three times.
On the forth iteration, the condition in while becomes False. Hence, the else part is executed.
Loops iterate over a block of code until test expression is false, but sometimes we wish to
terminate the current iteration or even the whole loop without checking test expression.
If break statement is inside a nested loop (loop inside another loop), break will terminate the
innermost loop.
Syntax of break
break
Flowchart of break
The working of break statement in for loop and while loop is shown below.
Example: Python break
if val == "i":
break
print(val)
print("The end")
Output
t
r
The end
In this program, we iterate through the "string" sequence. We check if the letter is "i", upon
which we break from the loop. Hence, we see in our output that all the letters up till "i" gets
printed. After that, the loop terminates.
Syntax of Continue
continue
Flowchart of continue
The working of continue statement in for and while loop is shown below.
if val == "i":
continue
print(val)
print("The end")
Output
The end
This program is same as the above example except the break statement has been replaced with
continue.
We continue with the loop, if the string is "i", not executing the rest of the block. Hence, we see
in our output that all the letters except "i" gets printed.
However, nothing happens when pass is executed. It results into no operation (NOP).
Syntax of pass
pass
pass
def function(args):
pass
class example:
pass
Python programming offers two kinds of loop, the for loop and the while loop. Using these loops
along with loop control statements like break and continue, we can create various forms of loop.
while True:
num = int(input("Enter an integer: "))
print("The double of",num,"is",2 * num)
Output
Enter an integer: 3
The double of 3 is 6
Enter an integer: 5
The double of 5 is 10
Enter an integer: 6
The double of 6 is 12
Enter an integer:
Traceback (most recent call last):
while i <= n:
sum = sum + i
i = i+1 # update counter
The sum is 55
vowels = "aeiouAEIOU"
# infinite loop
while True:
v = input("Enter a vowel: ")
# condition in the middle
if v in vowels:
break
print("That is not a vowel. Try again!")
print("Thank you!")
Output
Enter a vowel: r
That is not a vowel. Try again!
Enter a vowel: 6
That is not a vowel. Try again!
Enter a vowel: ,
That is not a vowel. Try again!
Enter a vowel: u
Thank you!
# condition
if option == 'n':
break
Output
The sum is 55
vowels = "aeiouAEIOU"
# infinite loop
while True:
v = input("Enter a vowel: ")
# condition in the middle
if v in vowels:
break
print("That is not a vowel. Try again!")
print("Thank you!")
Output
Enter a vowel: r
That is not a vowel. Try again!
Enter a vowel: 6
That is not a vowel. Try again!
Enter a vowel: ,
That is not a vowel. Try again!
Enter a vowel: u
Thank you!
# condition
if option == 'n':
break
Output
Python Functions
What is a function in Python?
In Python, function is a group of related statements that perform a specific task.
Functions help break our program into smaller and modular chunks. As our program grows
larger and larger, functions make it more organized and manageable.
Syntax of Function
def function_name(parameters):
"""docstring"""
statement(s)
Example of a function
def greet(name):
parameter"""
Once we have defined a function, we can call it from another function, program or even the
Python prompt. To call a function we simply type the function name with appropriate
parameters.
>>> greet('Paul')
Hello, Paul. Good morning!
Docstring
The first string after the function header is called the docstring and is short for documentation
string. It is used to explain in brief, what a function does.
Although optional, documentation is a good programming practice. Unless you can remember
what you had for dinner last week, always document your code.
In the above example, we have a docstring immediately below the function header. We generally
use triple quotes so that docstring can extend up to multiple lines. This string is available to us as
__doc__ attribute of the function.
For example:
Try running the following into the Python shell to see the output.
>>> print(greet.__doc__)
This function greets to
the person passed into the
name parameter
Syntax of return
return [expression_list]
This statement can contain expression which gets evaluated and the value is returned. If there is
no expression in the statement or the return statement itself is not present inside a function, then
the function will return the None object.
For example:
>>> print(greet("May"))
Hello, May. Good morning!
None
Example of return
def absolute_value(num):
if num >= 0:
return num
else:
return -num
# Output: 2
print(absolute_value(2))
# Output: 4
print(absolute_value(-4))
Lifetime of a variable is the period throughout which the variable exits in the memory. The
lifetime of variables inside a function is as long as the function executes.
They are destroyed once we return from the function. Hence, a function does not remember the
value of a variable from its previous calls.
def my_func():
x = 10
print("Value inside function:",x)
x = 20
my_func()
Output
Here, we can see that the value of x is 20 initially. Even though the function my_func() changed
the value of x to 10, it did not effect the value outside the function.
This is because the variable x inside the function is different (local to the function) from the one
outside. Although they have same names, they are two different variables with different scope.
On the other hand, variables outside of the function are visible from inside. They have a global
scope.
We can read these values from inside the function but cannot change (write) them. In order to
modify the value of variables outside the function, they must be declared as global variables
using the keyword global.
Types of Functions
Basically, we can divide functions into the following two types:
Arguments
In user-defined function topic, we learned about defining a function and calling it. Otherwise, the
function call will result into an error. Here is an example.
def greet(name,msg):
"""This function greets to
the person with the provided message"""
print("Hello",name + ', ' + msg)
greet("Monica","Good morning!")
Output
Since, we have called this function with two arguments, it runs smoothly and we do not get any
error.
If we call it with different number of arguments, the interpreter will complain. Below is a call to
this function with one and no arguments along with their respective error messages.
We can provide a default value to an argument by using the assignment operator (=). Here is an
example.
greet("Kate")
greet("Bruce","How do you do?")
In this function, the parameter name does not have a default value and is required (mandatory)
during a call.
On the other hand, the parameter msg has a default value of "Good morning!". So, it is optional
during a call. If a value is provided, it will overwrite the default value.
Any number of arguments in a function can have a default value. But once we have a default
argument, all the arguments to its right must also have default values.
This means to say, non-default arguments cannot follow default arguments. For example, if we
had defined the function header above as:
When we call a function with some values, these values get assigned to the arguments according
to their position.
For example, in the above function greet(), when we called it as greet("Bruce","How do you
do?"), the value "Bruce" gets assigned to the argument name and similarly "How do you do?" to
msg.
Python allows functions to be called using keyword arguments. When we call functions in this
way, the order (position) of the arguments can be changed. Following calls to the above function
are all valid and produce the same result.
As we can see, we can mix positional arguments with keyword arguments during a function call.
But we must keep in mind that keyword arguments must follow positional arguments.
Having a positional argument after keyword arguments will result into errors. For example the
function call as follows:
Sometimes, we do not know in advance the number of arguments that will be passed into a
function.Python allows us to handle this kind of situation through function calls with arbitrary
number of arguments.
In the function definition we use an asterisk (*) before the parameter name to denote this kind of
argument. Here is an example.
def greet(*names):
"""This function greets all
the person in the names tuple."""
greet("Monica","Luke","Steve","John")
Output
Hello Monica
Hello Luke
Hello Steve
Hello John
Here, we have called the function with multiple arguments. These arguments get wrapped up into
a tuple before being passed into the function. Inside the function, we use a for loop to retrieve all
the arguments back.
Python Recursion
A physical world example would be to place two parallel mirrors facing each other. Any object
in between them would be reflected recursively.
Factorial of a number is the product of all the integers from 1 to that number. For example, the
factorial of 6 (denoted as 6!) is 1*2*3*4*5*6 = 720.
def calc_factorial(x):
"""This is a recursive function
to find the factorial of an integer"""
if x == 1:
return 1
else:
return (x * calc_factorial(x-1))
num = 4
print("The factorial of", num, "is", calc_factorial(num))
When we call this function with a positive integer, it will recursively call itself by decreasing the
number.
Each function call multiples the number with the factorial of number 1 until the number is equal
to one. This recursive call can be explained in the following steps.
Our recursion ends when the number reduces to 1. This is called the base condition.
Every recursive function must have a base condition that stops the recursion or else the function
calls itself infinitely.
Advantages of Recursion
1. Recursive functions make the code look clean and elegant.
2. A complex task can be broken down into simpler sub-problems using recursion.
3. Sequence generation is easier with recursion than using some nested iteration.
Disadvantages of Recursion
1. Sometimes the logic behind recursion is hard to follow through.
2. Recursive calls are expensive (inefficient) as they take up a lot of memory and time.
3. Recursive functions are hard to debug.
Functions
examples.