Block 1 Merged
Block 1 Merged
Block 1 Merged
1.0 INTRODUCTION
In our daily life, we routinely encounter and solve problems. We pose problems that
we need or want to solve. For this, we make use of available resources, and solve
them. Some categories of resources include: the time and efforts of yours and others;
tools; information; and money. Some of the problems that you encounter and solve are
quite simple. But some others may be very complex.
• Problem anticipation
• Careful planning
• Proper thought process
• Logical precision
• Problem analysis
• Persistence and attention.
7
An Introduction to C At the same time it requires personal creativity, analytic ability and expression. The
chances of success are amplified when the problem solving is approached in a
systematic way and satisfaction is achieved once the problem is satisfactorily solved.
The problems should be anticipated in advance as far as possible and properly defined
to help the algorithm definition and development process.
Results
1.1 OBJECTIVES
After going through this unit, you should be able to:
8
Problem Solving
1.2 PROBLEM - SOLVING TECHNIQUES
Problem solving is a creative process which defines systematization and
mechanization. There are a number of steps that can be taken to raise the level of
one’s performance in problem solving.
The computer is a resource - a versatile tool - that can help you solve some of the
problems that you encounter. A computer is a very powerful general-purpose tool.
Computers can solve or help to solve many types of problems. There are also many
ways in which a computer can enhance the effectiveness of the time and effort that
you are willing to devote to solving a problem. Thus, it will prove to be well worth the
time and effort you spend to learn how to make effective use of this tool.
In this section, we discuss the steps involved in developing a program. Program
development is a multi-step process that requires you to understand the problem,
develop a solution, write the program, and then test it. This critical process determines
the overall quality and success of your program. If you carefully design each program
using good structured development techniques, your programs will be efficient, error-
free, and easy to maintain. The following are the steps in detail:
1. Develop an Algorithm and a Flowchart.
2. Write the program in a computer language (for example say C programming
language).
3. Enter the program using some editor.
4. Test and debug the program.
5. Run the program, input data, and get the results.
1.3.1 Definition
An algorithm is a finite set of steps defining the solution of a particular problem. An
algorithm is expressed in pseudocode - something resembling C language or Pascal,
but with some statements in English rather than within the programming language.
Developing an efficient algorithm requires lot of practice and skill. It must be noted
that an efficient algorithm is one which is capable of giving the solution to the
problem by using minimum resources of the system such as memory and processor’s
time. Algorithm is a language independent, well structured and detailed. It will enable
the programmer to translate into a computer program using any high-level language.
10
Use of procedures / functions to emphasize modularity Problem Solving
Example 1.1
Let us try to develop an algorithm to compute and display the sum of two numbers
1. Start
2. Read two numbers a and b
3. Calculate the sum of a and b and store it in sum
4. Display the value of sum
5. Stop
Example 1.2
Let us try to develop an algorithm to compute and print the average of a set of data
values.
1. Start
2. Set the sum of the data values and the count to zero.
11
An Introduction to C 3. As long as the data values exist, add the next data value to the sum and add 1 to
the count.
4. To compute the average, divide the sum by the count.
5. Display the average.
6. Stop
Example 1.3
1. Start
2. Read the number n
3. [Initialize]
i ← 1 , fact ← 1
4. Repeat steps 4 through 6 until i = n
5. fact ← fact * i
6. i ← i + 1
7. Print fact
8. Stop
Example 1.4
Write an algorithm to check that whether the given number is prime or not.
1. Start
2. Read the number num
3. [Initialize]
i ← 2 , flag ← 1
4. Repeat steps 4 through 6 until i < num or flag = 0
5. rem ← num mod i
6. if rem = 0 then
flag ← 0
else
i←i+1
7. if flag = 0 then
Print Number is not prime
Else
Print Number is prime
8. Stop
Top down design provides the way of handling the logical complexity and detail
encountered in computer algorithm. It allows building solutions to problems in step by
step. In this way, specific and complex details of the implementation are encountered
only at the stage when sufficient groundwork on the overall structure and relationships
among the various parts of the problem.
Before the top down design can be applied to any problem, we must at least have the
outlines of a solution. Sometimes this might demand a lengthy and creative
12
investigation into the problem while at another time the problem description may in Problem Solving
itself provide the necessary starting point for the top-down design.
Top-down design suggests taking the general statements about the solution one at a
time, and then breaking them down into a more precise subtask / sub-problem. These
sub-problems should more accurately describe how the final goal can be reached. The
process of repeatedly breaking a task down into a subtask and then each subtask into
smaller subtasks must continue until the sub-problem can be implemented as the
program statement. With each spitting, it is essential to define how sub-problems
interact with each other. In this way, the overall structure of the solution to the
problem can be maintained. Preservation of the overall structure is important for
making the algorithm comprehensible and also for making it possible to prove the
correctness of the solution.
The efficient algorithm in which the inner loop terminates much before is given as:
for i=0 to n
for j=0 to n – 1
if(a[j]>a[j+1])
//swap values a[j], a[j+1]
15
An Introduction to C Two or more algorithms can solve the same problem in different ways. So,
quantitative measures are valuable in that they provide a way of comparing the
performance of two or more algorithms that are intended to solve the same problem.
This is an important step because the use of an algorithm that is more efficient in
terms of time, resources required, can save time and money.
Log2 n n n log2 n n2 n3 2n
1 2 2 4 8 4
3.322 10 33.22 102 103 >103
6.644 102 664.4 104 106 >>1025
9.966 103 9966.0 106 109 >>10250
13.287 104 132877 108 1012 >>102500
The above table shows that only very small problems can be solved with an algorithm
that exhibit exponential behaviour. An exponential problem with n=100 would take
immeasurably longer time. At the other extreme, for an algorithm with logarithmic
dependency would merely take much less time (13 steps in case of log2n in the above
table). These examples emphasize the importance of the way in which algorithms
behave as a function of the problem size. Analysis of an algorithm also provides the
theoretical model of the inherent computational complexity of a particular problem.
O(g(n)) = { f(n) : there exist positive constants c and n0, such that 0 <= f(n) <= cg(n)
for all n >= n0 }
Using O-notation, we can often describe the running time of an algorithm merely by
inspecting the algorithm’s overall structure. For example a double nested loop
structure of the following algorithm immediately yields O(n2) upper bound on the
worst case running time.
for i=0 to n
for j=0 to n
print i,j
next j
next i
What we mean by saying “the running time is O(n2)” is that the worst case running
time ( which is a function of n) is O(n2). Or equivalently, no matter what particular
input of size n is chosen for each value of n, the running time on that set of inputs is
O(n2).
16
Problem Solving
1.5.3 Rules for using the Big-O Notation
Big-O bounds, because they ignore constants, usually allow for very simple
expression for the running time bounds. Below are some properties of big-O that
allow bounds to be simplified. The most important property is that big-O gives an
upper bound only. If an algorithm is O(N2), it doesn’t have to take N2 steps (or a
constant multiple of N2). But it can’t take more than N2. So any algorithm that is
O(N), is also an O(N2) algorithm. If this seems confusing, think of big-O as being like
“<”. Any number that is < N is also <N2.
1. Ignoring constant factors: O(c f(N)) = O(f(N)), where c is a constant; e.g. O(20
N3) = O(N3)
2. Ignoring smaller terms: If a<b then O(a+b) = O(b), for example, O(N2+N) =
O(N2)
3. Upper bound only: If a<b then an O(a) algorithm is also an O(b) algorithm. For
example, an O(N) algorithm is also an O(N2) algorithm (but not vice versa).
4. N and log N are bigger than any constant, from an asymptotic view (that means
for large enough N). So if k is a constant, an O(N + k) algorithm is also O(N), by
ignoring smaller terms. Similarly, an O(log N + k) algorithm is also O(log N).
5. Another consequence of the last item is that an O(N log N + N) algorithm, which
is O(N(log N + 1)), can be simplified to O(N log N).
In the worst case, the algorithm examines all n values in the list before terminating.
In the average case, the probability that x will be found at position 1 is 1/n, at position
2 is 2/n and so on. Therefore,
Let us see how to represent the algorithm in a graphical form using a flowchart in the
following section.
1.6 FLOWCHARTS
The next step after the algorithm development is the flowcharting. Flowcharts are
used in programming to diagram the path in which information is processed through a
computer to obtain the desired results. Flowchart is a graphical representation of an 17
An Introduction to C algorithm. It makes use of symbols which are connected among them to indicate the
flow of information and processing. It will show the general outline of how to solve a
problem or perform a task. It is prepared for better understanding of the algorithm.
Start/Stop
Input/Output
Process, Instruction
Comments, Explanations,
Definitions.
18
Example 1.5 Problem Solving
Start
Read a b
Sum = a + b
Print sum
Stop
Example 1.6
The flowchart for the Example 1.3 (to find factorial of a given number) is shown
below:
Start
Read n
i=1
fact = 1
No
Is i<= n ?
yes
i=i+1
Print fact
fact = fact * i
Stop
19
An Introduction to C
Example 1.7:
Start
Read num
i=2
flag = 1
no
is
i<num?
yes
no
is
flag = 0?
yes
rem =
num mod i
no
is rem
!= 0?
yes
i=i+1 flag = 0
no
Print is flag
“number is = 1?
not prime”
yes
Print
“Number
stop is prime
20
Problem Solving
Check Your Progress
1. Differentiate between flowchart and algorithm.
………………………………………………………………………………………
………………………………………………………………………………………
………………………………………………………………………………………
………………………………………………………………………………………
3. Write the following steps are suggested to facilitate the problem solving process
using computer.
………………………………………………………………………………………
………………………………………………………………………………………
………………………………………………………………………………………
………………………………………………………………………………………
4. Draw an algorithm and flowchart to calculate the roots of quadratic equation
Ax^2 + Bx + C = 0.
………………………………………………………………………………….…
…………………………………………………………………………………….
………………………………………………………………………………………
………………………………………………………………………………………
1.7 SUMMARY
To solve a problem different problem - solving tools are available that help in finding
the solution to problem in an efficient and systematic way. Steps should be followed
to solve the problem that includes writing the algorithm and drawing the flowchart for
the solution to the stated problem. Top down design provides the way of handling the
logical complexity and detail encountered in computer algorithm. It allows building
solutions to problems in a stepwise fashion. In this way, specific and complex details
of the implementation are encountered only at the stage when sufficient groundwork
on the overall structure and relationships among the carious parts of the problem. We
present C language - a standardized, industrial-strength programming language known
for its power and portability as an implementation vehicle for these problem solving
techniques using computer.
3. The following steps are suggested to facilitate the problem solving process:
a) Define the problem
b) Formulate a mathematical model
c) Develop an algorithm
d) Design the flowchart
e) Code the same using some computer language
f) Test the program
22
Basics of C
UNIT 2 BASICS OF C
Structure
2.0 Introduction
2.1 Objectives
2.2 What is a Program and what is a Programming Language?
2.3 C Language
2.3.1 History of C
2.3.2 Salient Features of C
2.4 Structure of a C Program
A simple C Program
2.5 Writing a C Program
2.6 Compiling a C Program
2.6.1 The C Compiler
2.6.2 Syntax and Semantic Errors
2.7 Link and Run the C Program
2.7.1 Run the C Program through the Menu
2.7.2 Run from an Executable File
2.7.3 Linker Errors
2.7.4 Logical and Runtime Errors
2.8 Diagrammatic Representation of Program Execution Process
2.9 Summary
2.10 Solutions / Answers
2.11 Further Readings
2.0 INTRODUCTION
2.1 OBJECTIVES
After going through this unit you will be able to:
23
An Introduction to C
2.2 WHAT IS A PROGRAM AND WHAT IS A
PROGRAMMING LANGUAGE?
We have seen in the previous unit that a computer has to be fed with a detailed set of
instructions and data for solving a problem. Such a procedure which we call an
algorithm is a series of steps arranged in a logical sequence. Also we have seen that a
flowchart is a pictorial representation of a sequence of instructions given to the
computer. It also serves as a document explaining the procedure used to solve a
problem. In practice it is necessary to express an algorithm using a programming
language. A procedure expressed in a programming language is known as a computer
program.
2.3 C LANGUAGE
Prior to writing C programs, it would be interesting to find out what really is C
language, how it came into existence and where does it stand with respect to other
computer languages. We will briefly outline these issues in the following section.
2.3.1 History of C
C is a programming language developed at AT&T’s Bell Laboratory of USA in 1972.
It was designed and written by Dennis Ritchie. As compared to other programming
languages such as Pascal, C allows a precise control of input and output.
24
Now let us see its historical development. The late 1960s were a turbulent era for Basics of C
computer systems research at Bell Telephone Laboratories. By 1960, many
programming languages came into existence, almost each for a specific purpose. For
example COBOL was being used for Commercial or Business Applications,
FORTRAN for Scientific Applications and so on. So, people started thinking why
could not there be a one general purpose language. Therefore, an International
Committee was set up to develop such a language, which came out with the invention
of ALGOL60. But this language never became popular because it was too abstract and
too general. To improve this, a new language called Combined Programming
Language (CPL) was developed at Cambridge University. But this language was very
complex in the sense that it had too many features and it was very difficult to learn.
Martin Richards at Cambridge University reduced the features of CPL and developed
a new language called Basic Combined Programming Language (BCPL). But
unfortunately it turned out to be much less powerful and too specific. Ken Thompson
at AT & T’s Bell Labs, developed a language called B at the same time as a further
simplification of CPL. But like BCPL this was also too specific. Ritchie inherited the
features of B and BCPL and added some features on his own and developed a
language called C. C proved to be quite compact and coherent. Ritchie first
implemented C on a DEC PDP-11 that used the UNIX Operating System.
For many years the de facto standard for C was the version supplied with the UNIX
version 5 operating system. The growing popularity of microcomputers led to the
creation of large number of C implementations. At the source code level most of these
implementations were highly compatible. However, since no standard existed there
were discrepancies. To overcome this situation, ANSI established a committee in
1983 that defined an ANSI standard for the C language.
Preprocessor directives
Global data declarations
main ( ) /* main function*/
{
Declaration part;
Program statements;
}
func2 ( )
{
…………
}
.
.
.
funcn ( )
{
…………
}
A Simple C Program
From the above sections, you have become familiar with, a programming language
and structure of a C program. It’s now time to write a simple C program. This
program will illustrate how to print out the message “This is a C program”.
Every C program contains a function called main(). This is the starting point of the
program. This is the point from where the execution begins. It will usually call other
functions to help perform its job, some that we write and others from the standard
libraries provided.
main() declares the start of the function, while the two curly brackets { } shows the
start and finish of the function. Curly brackets in C are used to group statements
together as a function, or in the body of a loop. Such a grouping is known as a
compound statement or a block. Every statement within a function ends with a
terminator semicolon (;).
Comments may appear anywhere within a program, as long as they are placed within
the delimiters /* and */. Such comments are helpful in identifying the program’s
principal features or in explaining the underlying logic of various program features.
While useful for teaching, such a simple program has few practical uses. Let us
consider something rather more practical. Let us look into the example given below,
the complete program development life cycle.
Example 2.1
Algorithm
1. Start
2. Input the two numbers a and b
3. Calculate the sum as a+b
4. Store the result in sum 27
An Introduction to C 5. Display the result
6. Stop.
Flowchart
START
INPUT
a, b
Sum = a + b
PRINT
Sum
STOP
Program
#include <stdio.h>
main()
{
int a,b,sum; /* variables declaration*/
sum=a+b;
OUTPUT
Enter the values of a and b:
23
The sum is 5
In the above program considers two variables a and b. These variables are declared as
integers (int), it is the data type to indicate integer values. Next statement is the printf
statement meant for prompting the user to input the values of a and b. scanf is the
function to intake the values into the program provided by the user. Next comes the
processing / computing part which computes the sum. Again the printf statement is a
28
bit different from the first program; it includes a format specifier (%d). The format Basics of C
specifier indicates the kind of value to be printed. We will study about other data
types and format specifiers in detail in the following units. In the printf statement
above, sum is not printed in double quotes because we want its value to be printed.
The number of format specifiers and the variable should match in the printf statement.
At this stage, don’t go much in detail. However, in the following units you will be
learning all these details.
If you are using Turbo C, then Turbo C provides its own editor which can be used for
writing the program. Just give the full pathname of the executable file of Turbo C and
you will get the editor in front of you. For example:
C:> turboc\bin\tc
Here, tc.exe is stored in bin subdirectory of turboc directory. After you get the menu
just type the program and store it in a file using the menu provided. The file
automatically gets the extension of .c.
UNIX also stores C program in a file with extension is .c. This identifies it as a C
program. The easiest way to enter your text is using a text editor like vi, emacs or
xedit. To edit a file called testprog.c using vi type
$ vi testprog.c
The editor is also used to make subsequent changes to the program.
Source Object
Code Code
Figure 2.3: Process of Translation
29
An Introduction to C 2.6.1 The C Compiler
If you are working on UNIX platform, then if the name of the program file is
testprog.c, to compile it, the simplest method is to type
cc testprog.c
This will compile testprog.c, and, if successful, will produce a executable file called
a.out. If you want to give the executable file any other, you can type
cc testprog.c -o testprog
If you are working with TurboC on DOS platform then the option for compilation is
provided on the menu. If the program is syntactically correct then this will produce a
file named as testprog.obj. If not, then the syntax errors will be displayed on the
screen and the object file will not be produced. The errors need to be removed before
compiling the program again. This process of removing the errors from the program is
called as the debugging.
#include <stdio.h
main( )
{
printf(“Hello, how are you\n”)
Let the name of the program be test.c .If we compile the above program as it is we
will get the following errors:
Error test.c 1:No file name ending
Error test.c 5: Statement missing ;
Error test.c 6: Compound statement missing }
Edit the program again, correct the errors mentioned and the corrected version appears
as follows:
#include <stdio.h>
main( )
{
printf (“Hello, how are you\n”);
30 }
Apart from syntax errors, another type of errors that are shown while compilation are Basics of C
semantic errors. These errors are displayed as warnings. These errors are shown if a
particular statement has no meaning. The program does compile with these errors, but
it is always advised to correct them also, since they may create problems while
execution. The example of such an error is that say you have declared a variable but
have not used it, and then you get a warning “code has no effect”. These variables are
unnecessarily occupying the memory.
include <stdio.h>
main( )
[
printf(“hello\n”);
]
……………………………………………………………………………………
……………………………………………………………………………………
……………………………………………………………………………………
UNIX also includes a very useful program called make. Make allows very
complicated programs to be compiled quickly, by reference to a configuration file
(usually called makefile). If your C program is a single file, you can usually use make
by simply typing –
make testprog
This will compile testprog.c as well as link your program with the standard library so
that you can use the standard library functions such as printf and put the executable
code in testprog.
In case of DOS environment , the options provided above produce an executable file
and this file can be directly executed from the DOS prompt just by typing its name
without the extension. That is if the name of the program is test.c, after compiling and
linking the new file produced is test.exe only if compilation and linking is successful.
The first case simply means that the program is correct. In the second case, we get
wrong results; it means that there is some logical mistake in our program. This kind of
error is known as logical error. This error is the most difficult to correct. This error is
corrected by debugging. Debugging is the process of removing the errors from the
program. This means manually checking the program step by step and verifying the
results at each step. Debugging can be made easier by a tracer provided in Turbo C
environment. Suppose we have to find the average of three numbers and we write the
following code:
a=10;
b=5;
c=20;
sum = a+b+c;
avg = sum / 3;
printf(“The average is %d\n”, avg);
}
OUTPUT
The average is 8.
The exact value of average is 8.33 and the output we got is 8. So we are not getting
the actual result, but a rounded off result. This is due to the logical error. We have
declared variable avg as an integer but the average calculated is a real number,
therefore only the integer part is stored in avg. Such kinds of errors which are not
detected by the compiler or the linker are known as logical errors.
The third kind of error is only detected during execution. Such errors are known as
run time errors. These errors do not produce the result at all, the program execution
stops in between and the run time error message is flashed on the screen. Let us look
at the following example:
#include <stdio.h>
main( )
{
int a,b;
float c;
a=10;
b=10;
c = (a+b) / (a-b);
printf(“The value of the result is %f\n”,c);
}
The above program will compile and link successfully, it will execute till the first
printf statement and we will get the message in this statement, as soon as the next
statement is executed we get a runtime error of “Divide by zero” and the program
halts. Such kinds of errors are runtime errors.
DEBUG SYNTAX
ERRORS (IF ANY),
SAVE AND RECOMPILE
2.9 SUMMARY
In this unit, you have learnt about a program and a programming language. You can
now differentiate between high level and low level languages. You can now define
what is C, features of C. You have studied the emergence of C. You have seen how C
34
is different, being a middle level Language, than other High Level languages. The Basics of C
advantage of high level language over low level language is discussed.
You have seen how you can convert an algorithm and flowchart into a C program. We
have discussed the process of writing and storing a C program in a file in case of
UNIX as well as DOS environment.
You have learnt about compiling and running a C program in UNIX as well as on
DOS environment. We have also discussed about the different types of errors that are
encountered during the whole process, i.e. syntax errors, semantic errors, logical
errors, linker errors and runtime errors. You have also learnt how to remove these
errors. You can now write simple C programs involving simple arithmetic operators
and the printf( ) statement. With these basics, now we are ready to learn the C
language in detail in the following units.
3. Syntax errors:
a) # not present with include
b) {brackets should be present instead of [ brackets.
35
An Introduction to C
36
Variables and
UNIT 3 VARIABLES AND CONSTANTS Constants
Structure
3.0 Introduction
3.1 Objectives
3.2 Character Set
3.3 Identifiers and Keywords
3.3.1 Rules for Forming Identifiers
3.3.2 Keywords
3.4 Data Types and Storage
3.5 Data Type Qualifiers
3.6 Variables
3.7 Declaring Variables
3.8 Initialising Variables
3.9 Constants
3.9.1 Integer Constants
3.9.2 Floating Point Constants
3.9.3 Character Constants
3.9.4 String Constants
3.10 Symbolic Constants
3.11 Summary
3.12 Solutions / Answers
3.13 Further Readings
3.0 INTRODUCTION
As every natural language has a basic character set, computer languages also have a
character set, rules to define words. Words are used to form statements. These in turn
are used to write the programs.
Computer programs usually work with different types of data and need a way to store
the values being used. These values can be numbers or characters. C language has two
ways of storing number values—variables and constants—with many options for
each. Constants and variables are the fundamental elements of each program. Simply
speaking, a program is nothing else than defining them and manipulating them. A
variable is a data storage location that has a value that can change during program
execution. In contrast, a constant has a fixed value that can’t change.
This unit is concerned with the basic elements used to construct simple C program
statements. These elements include the C character set, identifiers and keywords, data
types, constants, variables and arrays, declaration and naming conventions of
variables.
3.1 OBJECTIVES
After going through this unit, you will be able to:
• define identifiers, data types and keywords in C;
• know name the identifiers as per the conventions;
• describe memory requirements for different types of variables; and
• define constants, symbolic constants and their use in programs.
When you write a program, you express C source files as text lines containing
characters from the character set. When a program executes in the target environment,
37
An Introduction to C it uses characters from the character set. These character sets are related, but need not
have the same encoding or all the same members.
Every character set contains a distinct code value for each character in the basic C
character set. A character set can also contain additional characters with other code
values. The C language character set has alphabets, numbers, and special characters as
shown below:
1. Alphabets including both lowercase and uppercase alphabets - A-Z and a-z.
2. Numbers 0-9
; : { , ‘ “ |
} > < / \ ~ _
[ ] ! $ ? * +
= ( ) - % # ^
@ & .
3.3.2 Keywords
Keywords are reserved words which have standard, predefined meaning in C. They
cannot be used as program-defined identifiers.
38
The lists of C keywords are as follows: Variables and
Constants
char while do typedef auto
int if else switch case
printf double struct break static
long enum register extern return
union const float short unsigned
continue for signed void default
goto sizeof volatile
Note: Generally all keywords are in lower case although uppercase of same names
can be used as identifiers.
C Language provides four basic data types viz. int, char, float and double. Using
these, we can store data in simple ways as single elements or we can group them
together and use different ways (to be discussed later) to store them as per
requirement. The four basic data types are described in the following table 3.1:
Memory requirements or size of data associated with a data type indicates the range of
numbers that can be stored in the data item of that type.
Unsigned bits use all bits for magnitude; therefore, this type of number can be larger.
For example signed int ranges from –32768 to +32767 and unsigned int ranges from
0 to 65,535. Similarly, char data type of data is used to store a character. It requires 1
byte. Signed char values range from –128 to 127 and unsigned char value range from
0 to 255. These can be summarized as follows:
Data type Size (bytes) Range
3.6 VARIABLES
Variable is an identifier whose value changes from time to time during execution. It is
a named data storage location in your computer’s memory. By using a variable’s
name in your program, you are, in effect, referring to the data stored there. A variable
represents a single data item i.e. a numeric quantity or a character constant or a string
constant. Note that a value must be assigned to the variables at some point of time in
the program which is termed as assignment statement. The variable can then be
accessed later in the program. If the variable is accessed before it is assigned a value,
it may give garbage value. The data type of a variable doesn’t change whereas the
value assigned to can change. All variables have three essential attributes:
• the name
• the value
• the memory, where the value is stored.
For example, in the following C program a, b, c, d are the variables but variable e is
not declared and is used before declaration. After compiling the source code and look
what gives?
main( )
{
int a, b, c;
char d;
a = 3;
b = 5;
c = a + b;
d = ‘a’;
e=d;
……….
……….
}
After compiling the code, this will generate the message that variable e not defined.
For example,
int a;
short int a, b;
40
int c, d; Variables and
Constants
long c, f;
float r1, r2;
int a = 10;
float b = 0.4 e –5;
char c = ‘a’;
a = 10;
b = 0.4 e –5;
c = ‘a’;
………………………………………………………………………………………
………………………………………………………………………………………
………………………………………………………………………………………
………………………………………………………………………………………
………………………………………………………………………………………
………………………………………………………………………………………
………………………………………………………………………………………
………………………………………………………………………………………
………………………………………………………………………………………
41
An Introduction to C
3.9 CONSTANTS
A constant is an identifier whose value can not be changed throughout the execution
of a program whereas the variable value keeps on changing. In C there are four basic
types of constants. They are:
1. Integer constants
2. Floating point constants
3. Character constants
4. String constants
Integer and Floating Point constants are numeric constants and represent numbers.
For example,
1 443 32767
are valid decimal integer constants.
Long Integer constants: These are used to exceed the magnitude of ordinary
integers and are appended by L.
For example,
50000U decimal unsigned.
1234567889L decimal long.
0123456L otal long.
0777777U otal unsigned.
A Floating Point number taking the value of 5 x 104 can be represented as:
5000. 5e4
5e+4 5E4
5.0e+4 .5e5
43
An Introduction to C The magnitude of floating point numbers range from 3.4E –38 to a maximum of
3.4E+38, through 0.0. They are taken as double precision numbers. Floating Point
constants occupy 2 words = 8 bytes.
Character constants have integer values associated depending on the character set
adopted for the computer. ASCII character set is in use which uses 7-bit code with 27
= 128 different characters. The digits 0-9 are having ASCII value of 48-56 and ‘A’
have ASCII value from 65 and ‘a’ having value 97 are sequentially ordered. For
example,
ESCAPE SEQUENCE
There are some non-printable characters that can be printed by preceding them with ‘\’
backslash character. Within character constants and string literals, you can write a
variety of escape sequences. Each escape sequence determines the code value for a
single character. You can use escape sequences to represent character codes:
• you cannot otherwise write (such as \n)
• that can be difficult to read properly (such as \t)
• that might change value in different target character sets (such as \a)
• that must not change in value among different target environments (such as \0)
For example,
• Replacement of value has to be done at one place and wherever the name
appears in the text it gets the value by execution of the preprocessor. This
saves time. if the Symbolic Constant appears 20 times in the program; it needs
to be changed at one place only.
3.11 SUMMARY
To summarize we have learnt certain basics, which are required to learn a computer
language and form a basis for all languages. Character set includes alphabets, numeric
characters, special characters and some graphical characters. These are used to form
words in C language or names or identifiers. Variable are the identifiers, which
change their values during execution of the program. Keywords are names with
specific meaning and cannot be used otherwise.
We had discussed four basic data types - int, char, float and double. Some qualifiers
are used as prefixes to data types like signed, unsigned, short, and long.
45
An Introduction to C
The constants are the fixed values and may be either Integer or Floating point or
Character or String type. Symbolic Constants are used to define names used for
constant values. They help in using the name rather bothering with remembering and
writing the values.
2. int rollno;
float total_marks, percentage;
46
Expressions and
UNIT 4 EXPRESSIONS AND OPERATORS Operators
Structure
4.0 Introduction
4.1 Objectives
4.2 Assignment Statements
4.3 Arithmetic Operators
4.4 Relational Operators
4.5 Logical Operators
4.6 Comma and Conditional Operators
4.7 Type Cast Operator
4.8 Size of Operator
4.9 C Shorthand
4.10 Priority of Operators
4.11 Summary
4.12 Solutions / Answers
4.13 Further Readings
4.0 INTRODUCTION
In the previous unit we have learnt variables, constants, datatypes and how to declare
them in C programming. The next step is to use those variables in expressions. For
writing an expression we need operators along with variables. An expression is a
sequence of operators and operands that does one or a combination of the following:
• specifies the computation of a value
• designates an object or function
• generates side effects.
An operator performs an operation (evaluation) on one or more operands. An operand
is a subexpression on which an operator acts.
This unit focuses on different types of operators available in C including the syntax
and use of each operator and how they are used in C.
A computer is different from calculator in a sense that it can solve logical expressions
also. Therefore, apart from arithmetic operators, C also contains logical operators.
Hence, logical expressions are also discussed in this unit.
4.1 OBJECTIVES
After going through this unit you will be able to:
The data type of the variable on left hand side should match the data type of
constant/variable/expression on right hand side with a few exceptions where
automatic type conversions are possible. Some examples of assignment statements are
as follows:
b =a; /* b is assigned the value of a */
b=5; /* b is assigned the value 5*/
b = a+5; /* b is assigned the value of expr a+5 */
The expression on the right hand side of the assignment statement can be:
• an arithmetic expression;
• a relational expression;
• a logical expression;
• a mixed expression.
The above mentioned expressions are different in terms of the type of operators
connecting the variables and constants on the right hand side of the variable.
Arithmetic operators, relational operators and logical operators are discussed in the
following sections.
For example,
int a;
float b,c ,avg, t;
avg = (b+c) / 2; /*arithmetic expression */
a = b && c; /*logical expression*/
a = (b+c) && (b<c); /* mixed expression*/
The basic arithmetic operators in C are the same as in most other computer languages,
and correspond to our usual mathematical/algebraic symbolism. The following
arithmetic operators are present in C:
Operator Meaning
+ Addition
- Subtraction
* Multiplication
/ Division
% Modular Division
Some of the examples of algebraic expressions and their C notation are given below:
Expression C notation
b* g (b *g) / d
d
The operands in arithmetic expressions can be of integer, float, double type. In order
to effectively develop C programs, it will be necessary for you to understand the rules
that are used for implicit conversation of floating point and integer values in C.
If the data type is double instead of float, then we get a result of double data type.
For example,
Operation Result
5/3 1
5.0/3 1.3
5/3.0 1.3
5.0/3.0 1.3
It may so happen that the type of the expression and the type of the variable on the left
hand side of the assignment operator may not be same. In such a case the value for the
expression is promoted or demoted depending on the type of the variable on left hand
side of = (assignment operator). For example, consider the following assignment
statements:
int i;
float b;
i = 4.6;
b = 20;
In the first assignment statement, float (4.6) is demoted to int. Hence i gets the value
4. In the second statement int (20) is promoted to float, b gets 20.0. If we have a
complex expression like:
float a, b, c;
int s;
s = a * b / 5.0 * c;
49
An Introduction to C
Where some operands are integers and some are float, then int will be promoted or
demoted depending on left hand side operator. In this case, demotion will take place
since s is an integer.
For example,
( ((3+4)*5)/6 )
( ( (3+4) * 5) / 6 )
1 2 3
For example,
5*5+6*7
5*5+6*7
1 2
3
For example,
8/5-6+5/2
8/5-6+5/2
1 3 4 2
50
Apart from these binary arithmetic operators, C also contains two unary operators Expressions and
Operators
referred to as increment (++) and decrement (--) operators, which we are going to be
discussed below:
The two-unary arithmetic operators provided by C are:
The increment operator increments the variable by one and decrement operator
decrements the variable by one. These operators can be written in two forms i.e.
before a variable or after a variable. If an increment / decrement operator is written
before a variable, it is referred to as preincrement / predecrement operators and if it is
written after a variable, it is referred to as post increment / postdecrement operator.
For example,
a++ or ++a is equivalent to a = a+1 and
a-- or - -a is equivalent to a = a -1
The importance of pre and post operator occurs while they are used in the expressions.
Preincrementing (Predecrementing) a variable causes the variable to be incremented
(decremented) by 1, then the new value of the variable is used in the expression in
which it appears. Postincrementing (postdecrementing) the variable causes the
current value of the variable is used in the expression in which it appears, then the
variable value is incremented (decrement) by 1.
Expression Explanation
++a Increment a by 1, then use the new value of a
The precedence of these operators is right to left. Let us consider the following
examples:
int a = 2, b=3;
int c;
c = ++a – b- -;
printf (“a=%d, b=%d,c=%d\n”,a,b,c);
OUTPUT
a = 3, b = 2, c = 0.
Since the precedence of the operators is right to left, first b is evaluated, since it is a
post decrement operator, current value of b will be used in the expression i.e. 3 and
then b will be decremented by 1.Then, a preincrement operator is used with a, so first
a is incremented to 3. Therefore, the value of the expression is evaluated to 0.
int a = 1, b = 2, c = 3;
int k; 51
An Introduction to C k = (a++)*(++b) + ++a - --c;
printf(“a=%d,b=%d, c=%d, k=%d”,a,b,c,k);
OUTPUT
a = 3, b = 3, c = 2, k = 6
i) a*4c2 - d
m+n
ii)ab - (e+f)4
c
………………………………………………………………………………………
………………………………………………………………………………………
2. Give the output of the following C code:
main()
{
int a=2,b=3,c=4;
k = ++b + --a*c + a;
printf(“a= %d b=%d c=%d k=%d\n”,a,b,c,k);
}
………………………………………………………………………………………
………………………………………………………………………………………
Relational operators usually appear in statements which are inquiring about the truth
of some particular relationship between variables. Normally, the relational operators
in C are the operators in the expressions that appear between the parentheses.
For example,
Let us see a simple C program containing the If statement (will be introduced in detail
in the next unit). It displays the relationship between two numbers read from the
keyboard.
Example: 4.1
#include <stdio.h>
main ( )
{
int a, b;
printf ( “Please enter two integers: ”);
scanf (“%d%d”, &a, &b);
if (a <= b)
printf (“ %d <= %d\n”,a,b);
else
printf (“%d > %d\n”,a,b);
}
OUTPUT
Please enter two integers: 12 17
12 <= 17
We can change the values assigned to a and b and check the result.
Operator Meaning
|| Logical OR
! Logical NOT
Thus logical operators (AND and OR) combine two conditions and logical NOT is
used to negate the condition i.e. if the condition is true, NOT negates it to false and
vice versa.Let us consider the following examples:
(i) Suppose the grade of the student is ‘B’ only if his marks lie within the range 65 to
75,if the condition would be:
if ((marks >=65) && (marks <= 75))
printf (“Grade is B\n”);
(ii) Suppose we want to check that a student is eligible for admission if his PCM is
greater than 85% or his aggregate is greater than 90%, then,
Logical negation (!) enables the programmer to reverse the meaning of the condition.
Unlike the && and || operators, which combines two conditions (and are therefore
Binary operators), the logical negation operator is a unary operator and has one single
condition as an operand. Let us consider an example:
if !(grade==’A’)
printf (“the next grade is %c\n”, grade);
The parentheses around the condition grade==A are needed because the logical
operator has higher precedence than equality operator. In a condition if all the
operators are present then the order of evaluation and associativity is provided in the
table. The truth table of the logical AND (&&), OR (||) and NOT (!) are given below.
These table show the possible combinations of zero (false) and nonzero (true) values
of x (expression1) and y (expression2) and only one expression in case of NOT
operator. The following table 4.2 is the truth table for && operator.
x y x&&y
zero zero 0
54
The following table 4.3 is the truth table for || operator. Expressions and
Operators
x y x || y
zero zero 0
x !x
zero 1
Non zero 0
The following table 4.5 shows the operator precedence and associativity
|| Left to right
Conditional Operator
C provides an called as the conditional operator (?:) which is closely related to the
if/else structure. The conditional operator is C’s only ternary operator - it takes three
operands. The operands together with the conditional operator form a conditional
expression. The first operand is a condition, the second operand represents the value
of the entire conditional expression it is the condition is true and the third operand is
the value for the entire conditional expression if the condition is false.
55
An Introduction to C Let us see the following examples:
(iii) (a>b) ? printf (“a is greater than b \n”): printf (“b is greater than a \n”);
If a is greater than b, then first printf statement is executed else second printf
statement is executed.
Comma Operator
first assigns y the value 2 and then x the value 1. Parenthesis is necessary since
comma operator has lower precedence than assignment operator.
Generally, comma operator (,) is used in the for loop (will be introduced in the next
unit)
For example,
for (i = 0,j = n;i<j; i++,j--)
{
printf (“A”);
}
In this example for is the looping construct (discussed in the next unit). In this loop,
i = 0 and j = n are separated by comma (,) and i++ and j—are separated by comma (,).
The example will be clear to you once you have learnt for loop (will be introduced in
the next unit).
2. In case of binary operators, if one of the two operands is a long double, the other
operand is converted to long double,
else if one operand is double, the other is converted to double,
else if one operand is long, the other is converted to long,
else if one operand is unsigned, the other is converted to unsigned,
C converts all operands “up” to the type of largest operand (largest in terms of
memory requirement for e.g. float requires 4 bytes of storage and int requires 2 bytes
of storage so if one operand is int and the other is float, int is converted to float).
All the above mentioned conversions are automatic conversions, but what if int is to
be converted to float. It is possible to force an expression to be of specific type by
using operator called a cast. The syntax is as follows:
(type) expression
where type is the standard C data type. For example, if you want to make sure that the
expression a/5 would evaluate to type float you would write it as
( float ) a/5
cast is an unary operator and has the same precedence as any other unary operator.
The use of cast operator is explained in the following example:
main()
{
int num;
printf(“%f %f %f\n”, (float)num/2, (float)num/3, float)num/3);
}
57
An Introduction to C Tha cast operator in this example will ensure that fractional part is also displayed on
the screen.
result in an unsigned integer value equal to the size of the specified object or type in
bytes. Actually the resultant integer is the number of bytes required to store an object
of the type of its operand. An object can be a variable or array or structure. An array
and structure are data structures provided in C, introduced in latter units. A type name
can be the name of any basic type like int or double or a derived type like a structure
or a pointer.
For example,
sizeof(char) = 1bytes
sizeof(int) = 2 bytes
4.9 C SHORTHAND
C has a special shorthand that simplifies coding of certain type of assignment
statements. For example:
a = a+2;
-= a-=2 a=a-2
= a*=2 a = a*2
/= a/=2 a=a/2
%= a%=2 a=a%2
58
Expressions and
4.10 PRIORITY OF OPERATORS Operators
Since all the operators we have studied in this unit can be used together in an
expression, C uses a certain hierarchy to solve such kind of mixed expressions. The
hierarchy and associatively of the operators discussed so far is summarized in Table 6.
The operators written in the same line have the same priority. The higher precedence
operators are written first
Table 4.6: Precedence of the operators
Operators Associativity
() Left to right
! ++ -- (type) sizeof Right to left
/% Left to right
+- Left to right
< <= > >= Left to right
== != Left to right
&& Left to right
|| Left to right
?: Right to left
= += -= *= /= %= &&= ||= Right to left
, Left to right
a=5/2;
f=(float)b/2.0;
(a<f)? b=1:b=0;
printf(“b = %d\n”,b);
}
………………………………………………………………………………………
………………………………………………………………………………………
………………………………………………………………………………………
2. What is the difference between && and &. Explain with an example.
………………………………………………………………………………………
………………………………………………………………………………………
……………………………………………………………………………….
3. Use of Bit Wise operators makes the execution of the program.
………………………………………………………………………………………
………………………………………………………………………………………
………………………………………………………………………………………
59
IGNOU STUDY STORE
We provide the highest quality study materials at
+91 7541886112
the affordable price. Get the best deals on:
Handwritten Solved Assignment Soft Copies:-
If you need Handwritten Solved Assignment Soft Copies in
PDF format that you can directly submit to your study center
via G-Form or email, feel free to contact me on WhatsApp.
These copies are superior to those offered by any other seller,
and I guarantee 90%+ marks. I'll provide you with an
affordable price, and after making the payment online DM us on WhatsApp:
through any UPI method, I'll promptly send you the PDF. +91 7541886112
An Introduction to C
4.11 SUMMARY
In this unit, we discussed about the different types of operators, namely arithmetic,
relational, logical present in C and their use. In the following units, you will study
how these are used in C’s other constructs like control statements, arrays etc.
This unit also focused on type conversions. Type conversions are very important to
understand because sometimes a programmer gets unexpected results (logical error)
which are most often caused by type conversions in case user has used improper types
or if he has not type cast to desired type.
Since Logical operators are used further in all types of looping constructs and if/else
construct (in the next unit), they should be thoroughly understood.
1. C expression would be
i) ((a*4*c*c)-d)/(m+n)
ii) a*b-(e+f)*4/c
60
2. && operator is a logical and operator and & is a bit wise and operator. Expressions and
Operators
Therefore, && operator always evaluates to true or false i.e 1 or 0 respectively
while & operator evaluates bit wise so the result can be any value. For example:
3. Use of Bit Wise operators makes the execution of the program faster.
61
Decision and Loop
UNIT 5 DECISION AND LOOP CONTROL Control
Statements
STATEMENTS
Structure
5.0 Introduction
5.1 Objectives
5.2 Decision Control Statements
5.2.1 The if Statement
5.2.2 The switch Statement
5.3 Loop Control Statements
5.3.1 The while Loop
5.3.2 The do-while Statement
5.3.3 The for Loop
5.3.4 The Nested Loop
5.4 The Goto Statement
5.5 The Break Statement
5.6 The Continue Statement
5.7 Summary
5.8 Solutions / Answers
5.9 Further Readings
5.0 INTRODUCTION
A program consists of a number of statements to be executed by the computer. Not
many of the programs execute all their statements in sequential order from beginning
to end as they appear within the program. A C program may require that a logical test
be carried out at some particular point within the program. One of the several possible
actions will be carried out, depending on the outcome of the logical test. This is called
Branching. In the Selection process, a set of statements will be selected for execution,
among the several sets available. Suppose, if there is a need of a group of statements
to be executed repeatedly until some logical condition is satisfied, then looping is
required in the program. These can be carried out using various control statements.
These Control statements determine the “flow of control” in a program and enable us
to specify the order in which the various instructions in a program are to be executed
by the computer. Normally, high level procedural programming languages require
three basic control statements:
• Sequence instruction
• Selection/decision instruction
• Repetition or Loop instruction
Sequence instruction means executing one instruction after another, in the order in
which they occur in the source file. This is usually built into the language as a default
action, as it is with C. If an instruction is not a control statement, then the next
instruction to be executed will simply be the next one in sequence.
• if
• if…else
• switch
5
Control Statements, Repetition/Looping means executing the same section of code more than once. A
Arrays and
Functions
section of code may either be executed a fixed number of times, or while some
condition is true. C provides three looping statements:
• while
• do…while
• for
This unit introduces you the decision and loop control statements that are available in
C programming language along with some of the example programs.
5.1 OBJECTIVES
After going through this unit you will be able to:
• Simple if statement
• If-else statement
• Nested if-else statement
• Else if statement
Simple if statement
It is used to execute an instruction or block of instructions only if a condition is
fulfilled.
The syntax is as follows:
if (condition)
statement;
If we want more than one statement to be executed, then we can specify a block of
statements within the curly bracets { }. The syntax is as follows:
if (condition)
{
block of statements;
}
Example 5.1
Write a program to calculate the net salary of an employee, if a tax of 15% is levied
on his gross-salary if it exceeds Rs. 10,000/- per month.
#include <stdio.h>
main( )
{
float gross_salary, net_salary;
if (gross_salary <10000)
net_salary= gross_salary;
if (gross_salary >= 10000)
net_salary = gross_salary- 0.15*gross_salary;
OUTPUT
Or
if (condition)
{
Statements_1_Block;
}
else
{
Statements_2_Block;
}
Statements _3_Block;
Example 5.2
Write a program to print whether the given number is even or odd.
8
Decision and Loop
Control
Statements
/* Program to print whether the given number is even or odd*/
#include <stdio.h>
main ( )
{
int x;
printf(“Enter a number:\n”);
scanf("%d",&x);
if (x % 2 == 0)
printf(“\nGiven number is even\n”);
else
printf(“\nGiven number is odd\n”);
}
OUTPUT
Enter a number:
6
Given number is even
Enter a number
7
Given number is odd
else
{
Statements_2_Block;
}
}
else
{
Statements_3_Block;
}
Statement_4_Block;
9
Control Statements,
Arrays and
Functions
Example 5.3
Write a program to calculate an Air ticket fare after discount, given the following
conditions:
• If passenger is below 14 years then there is 50% discount on fare
• If passenger is above 50 years then there is 20% discount on fare
• If passenger is above 14 and below 50 then there is 10% discount on fare.
#include <stdio.h>
main( )
{
int age;
float fare;
printf(“\n Enter the age of passenger:\n”);
scanf(“%d”,&age);
printf(“\n Enter the Air ticket fare\n”);
scanf(“%f”,&fare);
if (age < 14)
fare = fare - 0.5 * fare;
else
if (age <= 50)
{
fare = fare - 0.1 * fare;
}
else
{
fare = fare - 0.2 * fare;
}
printf(“\n Air ticket fare to be charged after discount is %.2f”,fare);
10 }
Decision and Loop
Control
OUTPUT Statements
Enter the age of passenger
12
Enter the Air ticket fare
2000.00
Air ticket fare to be charged after discount is 1000.00
Else if statement
To show a multi-way decision based on several conditions, we use the else if
statement. This works by cascading of several comparisons. As soon as one of the
conditions is true, the statement or block of statements following them is executed and
no further comparisons are performed. The syntax is as follows:
if (condition_1)
{
Statements_1_Block;
}
else if (condition_2)
{
Statements_2_Block;
}
------------
else if (condition_n)
{
Statements_n_Block;
}
else
Statements_x;
Here, the conditions are evaluated in order from top to bottom. As soon as any
condition evaluates to true, then the statement associated with the given condition is
executed and control is transferred to Statements_x skipping the rest of the
conditions following it. But if all conditions evaluate false, then the statement
following final else is executed followed by the execution of Statements_x. This is
shown in the figure 5.4 given below:
OUTPUT
Enter the total marks of a student:
80
Grade A
…………………………………………………………………………………
…………………………………………………………………………………
…………………………………………………………………………………
Finally, if the value of expression has not matched any of the previously specified
constants (you may specify as many case statements as values you want to check), the
program will execute the instructions included in the default: section, if it exists, as it
is an optional statement.
Example 5.5
Write a program that performs the following, depending upon the choice selected by
the user.
i). calculate the square of number if choice is 1
ii). calculate the cube of number if choice is 2 and 4
iii). calculate the cube of the given number if choice is 3
iv). otherwise print the number as it is
main()
{
int choice,n; 13
Control Statements, printf(“\n Enter any number:\n “);
Arrays and
Functions
scanf(“%d”,&n);
printf(“Choice is as follows:\n\n”);
printf(“1. To find square of the number\n”);
printf(“2. To find square-root of the number\n”);
printf(“3. To find cube of a number\n”);
printf(“4. To find the square-root of the number\n\n”);
printf(“Enter your choice:\n”);
scanf(“%d”,&choice);
switch (choice)
{
case 1 : printf(“The square of the number is %d\n”,n*n);
break;
case 2 :
case 4 : printf(“The square-root of the given number is %f”,sqrt(n));
break;
case 3: printf(“ The cube of the given number is %d”,n*n*n);
default : printf(“The number you had given is %d”,n);
break;
}
}
OUTPUT
Choice is as follows:
1. To find square of the number
2. To find square-root of the number\n");
3. To find cube of a number
4. To find the square-root of the number
In this section we had discussed and understood various decision control statements.
Next section explains you the various loop control statements in C.
• The while loop keeps repeating an action until an associated condition returns
false. This is useful where the programmer does not know in advance how
many times the loop will be traversed.
• The do while loop is similar, but the condition is checked after the loop body is
executed. This ensures that the loop body is run at least once.
• The for loop is frequently used, usually where the loop will be traversed a fixed
number of times.
Here, test condition is an expression that controls how long the loop keeps running.
Body of the loop is a statement or group of statements enclosed in braces and are
repeatedly executed till the value of test condition evaluates to true. As soon as the
condition evaluates to false, the control jumps to the first statement following the
while statement. If condition initially itself is false, the body of the loop will never be
executed. While loop is sometimes called as entry-control loop, as it controls the
execution of the body of the loop depending upon the value of the test condition. This
is shown in the figure 5.5 given below:
Example 5.6
Write a program to calculate the factorial of a given input natural number.
#include <stdio.h>
#include <math.h>
#include <stdio.h>
main( )
{
int x;
long int fact = 1;
printf(“Enter any number to find factorial:\n”); /*read the number*/
scanf(“%d”,&x);
while (x > 0)
{
fact = fact * x; /* factorial calculation*/
x=x-1;
}
printf(“Factorial is %ld”,fact); 15
Control Statements, }
Arrays and
Functions
OUTPUT
Here, condition in while loop is evaluated and body of loop is repeated until condition
evaluates to false i.e., when x becomes zero. Then the control is jumped to first
statement following while loop and print the value of factorial.
In do-while loop, the body of loop is executed at least once before the condition is
evaluated. Then the loop repeats body as long as condition is true. However, in while
loop, the statement doesn’t execute the body of the loop even once, if condition is
false. That is why do-while loop is also called exit-control loop. This is shown in the
figure 5.6 given below.
Example 5.7
Write a program to print first ten even natural numbers.
OUTPUT
2 4 6 8 10 12 14 16 18 20
The main purpose is to repeat statement while condition remains true, like the while
loop. But in addition, for provides places to specify an initialization instruction and an
increment or decrement of the control variable instruction. So this loop is specially
designed to perform a repetitive action with a counter.
The for loop as shown in figure 5.7, works in the following manner:
1. initialization is executed. Generally it is an initial value setting for a counter
variable. This is executed only once.
2. condition is checked, if it is true the loop continues, otherwise the loop finishes and
statement is skipped.
3. Statement(s) is/are executed. As usual, it can be either a single instruction or a
block of instructions enclosed within curly brackets { }.
4. Finally, whatever is specified in the increment or decrement of the control variable
field is executed and the loop gets back to step 2.
Example 5.8
Write a program to print first n natural numbers.
#include <stdio.h>
main( )
{
int i,n;
printf(“Enter value of n \n”);
scanf(“%d”,&n);
printf(“\nThe first %d natural numbers are :\n”, n);
for (i=1;i<=n;++i)
{
printf(“%d”,i);
}
}
OUTPUT
Enter value of n
6
The first 6 natural numbers are:
123456
The three statements inside the braces of a for loop usually meant for one activity
each, however any of them can be left blank also. More than one control variables can
be initialized but should be separated by comma.
A blank second conditional statement means no test condition to control the exit
from the loop. So, in the absence of second statement, it is required to test the
condition inside the loop otherwise it results in an infinite loop where the control
never exits from the loop.
Example 5.9
Write a program to generate the following pattern given below:
1
1 2
1 2 3
1 2 3 4
#include <stdio.h>
main( )
{
int i,j;
for (i=1;i<=4;++i)
{
printf("%d\n",i);
for(j=1;j<=i;++j)
printf("%d\t",j);
}
}
Here, an inner for loop is written inside the outer for loop. For every value of i, j
takes the value from 1 to i and then value of i is incremented and next iteration of
outer loop starts ranging j value from 1 to i.
#include <stdio.h>
main( )
{
int i;
for(i=0;i<3;i++)
printf("%d ",i);
}
…………………………………………………………………………………
…………………………………………………………………………………
…………………………………………………………………………………
3. What is the output for the following program?
#include <stdio.h>
main( )
{
int i=1;
do
{
printf(“%d”,i);
}while(i=i-1);
}
…………………………………………………………………………………
…………………………………………………………………………………
…………………………………………………………………………………
4. Give the output of the following:
#include <stdio.h>
main( )
{
int i=3;
while(i)
{
int x=100;
printf(“\n%d..%d”,i,x);
x=x+1;
i=i+1;
}
}
…………………………………………………………………………………
…………………………………………………………………………………
…………………………………………………………………………………
label : statement;
Although goto statement is used to alter the normal sequence of program execution
but its usage in the program should be avoided. The most common applications are:
i). To branch around statements under certain conditions in place of use of if-
else statement,
ii). To jump to the end of the loop under certain conditions bypassing the rest of
statements inside the loop in place of continue statement,
iii). To jump out of the loop avoiding the use of break statement.
goto can never be used to jump into the loop from outside and it should be preferably
used for forward jump.
Situations may arise, however, in which the goto statement can be useful. To the
possible extent, the use of the goto statement should generally be avoided.
Example 5.10
Write a program to print first 10 even numbers
#include <stdio.h>
main()
{
int i=2;
while(1)
{
printf(“%d ”,i);
i=i+2;
if (i>=20)
goto outside;
}
outside : printf(“over”);
}
OUTPUT
2 4 6 8 10 12 14 16 18 20 over
When nested loops are used, then break jumps the control from the loop where it has
been used. Break statement can be used inside any loop i.e., while, do-while, for and
also in switch statement.
#include <stdio.h>
main( )
{
int div,num,i;
printf(“Enter any number:\n”);
scanf(“%d”,&num);
for (i=2;i<=num;++i)
{
if ((num % i) == 0)
{
printf(“Smallest divisor for number %d is %d”,num,i);
break;
}
}
}
OUTPUT
Enter any number:
9
Smallest divisor for number 9 is 3
In the above program, we divide the input number with the integer starting from 2
onwards, and print the smallest divisor as soon as remainder comes out to be zero.
Since we are only interested in first smallest divisor and not all divisors of a given
number, so jump out of the for loop using break statement without further going for
the next iteration of for loop.
Break is different from exit. Former jumps the control out of the loop while exit stops
the execution of the entire program.
Let us see the program given below to know the working of the continue statement.
Example 5.12
Write a program to print first 20 natural numbers skipping the numbers divisible by 5.
#include <stdio.h>
main( )
{
int i;
for (i=1;i<=20;++i)
22 {
if ((i % 5) == 0) Decision and Loop
Control
continue; Statements
printf(“%d ”,i);
}
}
OUTPUT
1 2 3 4 6 7 8 9 11 12 13 14 16 17 18 19
Here, the printf statement is bypassed each time when value stored in i is divisible by
5.
#include <stdio.h>
main( )
{
int i, n = 3; 23
Control Statements, for (i=3;n<=20;++n)
Arrays and
Functions
{
if (n%i == 0)
break;
if (i == n)
printf(“%d\n”,i);
}
}
…………………………………………………………………………………
…………………………………………………………………………………
…………………………………………………………………………………
5.7 SUMMARY
A program is usually not limited to a linear sequence of instructions. During its
process it may require to repeat execution of a part of code more than once depending
upon the requirements or take decisions. For that purpose, C provides control and
looping statements. In this unit, we had seen the different looping statements provided
by C language namely while, do…while and for.
Using break statement, we can leave a loop even if the condition for its end is not
fulfilled. It can be used to end an infinite loop, or to force it to end before its natural
end. The continue statement causes the program to skip the rest of the loop in the
present iteration as if the end of the statement block would have reached, causing it to
jump to the following iteration.
Using the goto statement, we can make an absolute jump to another point in the
program. You should use this feature carefully since its execution ignores any type of
nesting limitation. The destination point is identified by a label, which is then used as
argument for the goto instruction. A label is made of a valid identifier followed by a
colon (:).
2 hello
2 012
3 102
4 3..100
2..100
1..100
…..
…..
…...
till infinity
24
Decision and Loop
Control
Check Your Progress 3 Statements
1 4 times
2 65
3 3
25
Control Statements,
Arrays and UNIT 6 ARRAYS
Functions
Structure
6.0 Introduction
6.1 Objectives
6.2 Array Declaration
6.2.1 Syntax of Array Declaration
6.2.2 Size Specification
6.3 Array Initialization
6.3.1 Initialization of Array Elements in the Declaration
6.3.2 Character Array Initialization
6.4 Subscript
6.5 Processing the Arrays
6.6 Multi-Dimensional Arrays
6.6.1 Multi-Dimensional Array Declaration
6.6.2 Initialization of Two-Dimensional Arrays
6.7 Summary
6.8 Solutions / Answers
6.9 Further Readings
6.0 INTRODUCTION
C language provides four basic data types - int, char, float and double. We have learnt
about them in Unit 3. These basic data types are very useful; but they can handle only
a limited amount of data. As programs become larger and more complicated, it
becomes increasingly difficult to manage the data. Variable names typically become
longer to ensure their uniqueness. And, the number of variable names makes it
difficult for the programmer to concentrate on the more important task of correct
coding. Arrays provide a mechanism for declaring and accessing several data items
with only one identifier, thereby simplifying the task of data management.
Many programs require the processing of multiple, related data items that have
common characteristics like list of numbers, marks in a course, or enrolment numbers.
This could be done by creating several individual variables. But this is a hard and
tedious process. For example, suppose you want to read in five numbers and print
them out in reverse order. You could do it the hard way as:
main()
{
int al,a2,a3,a4,a5;
scanf(“%d %d %d %d %d”,&a1,&a2,&a3,&a4,&a5);
printf(“%d %d %d %d %d”',a5,a4,a3,a2,a1);
}
Does it look good if the problem is to read in 100 or more related data items and print
them in reverse order? Of course, the solution is the use of the regular variable names
a1, a2 and so on. But to remember each and every variable and perform the operations
on the variables is not only tedious a job and disadvantageous too. One common
organizing technique is to use arrays in such situations. An array is a collection of
similar kind of data elements stored in adjacent memory locations and are referred to
by a single array-name. In the case of C, you have to declare and define array before
it can be used. Declaration and definition tell the compiler the name of the array, the
type of each element, and the size or number of elements.To explain it, let us consider
to store marks of five students. They can be stored using five variables as follows:
int ar1, ar2, ar3, ar4, ar5;
26
Now, if we want to do the same thing for 100 students in a class then one will find it Arrays
difficult to handle 100 variables. This can be obtained by using an array. An array
declaration uses its size in [ ] brackets. For above example, we can define an array as:
int ar [100];
where ar is defined as an array of size 100 to store marks of integer data-type. Each
element of this collection is called an array-element and an integer value called the
subscript is used to denote individual elements of the array. An ar array is the
collection of 200 consecutive memory locations referred as below:
In the above figure, as each integer value occupies 2 bytes, 200 bytes were allocated
in the memory.
This unit explains the use of arrays, types of arrays, declaration and initialization with
the help of examples.
6.1 OBJECTIVES
After going through this unit you will be able to:
• Array is a data structure storing a group of elements, all of which are of the same
data type.
• All the elements of an array share the same name, and they are distinguished
from one another with the help of an index.
• Random access to every element using a numeric index (subscript).
• A simple data structure, used for decades, which is extremely useful.
• Abstract Data type (ADT) list is frequently associated with the array data
structure.
The declaration of an array is just like any variable declaration with additional size
part, indicating the number of elements of the array. Like other variables, arrays must
be declared at the beginning of a function.
The declaration specifies the base type of the array, its name, and its size or
dimension. In the following section we will see how an array is declared:
27
Control Statements,
Arrays and
Functions
6.2.1 Syntax of Array Declaration
Syntax of array declaration is as follows:
• The amount of storage for a declared array has to be specified at compile time
before execution. This means that an array has a fixed size.
• The data type of an array applies uniformly to all the elements; for this reason, an
array is called a homogeneous data structure.
The following example shows how to declare and read values in an array to store
marks of the students of a class.
Example 6.1
Write a program to declare and read values in an array and display them.
main ( )
{
int i = 0; /* Loop variable */
int stud_marks[SIZE]; /* array declaration */
OUTPUT:
Arrays can be initialized at the time of declaration. The initial values must appear in
the order in which they will be assigned to the individual array elements, enclosed
within the braces and separated by commas. In the following section, we see how this
can be done.
val 1 is the value for the first array element, val 2 is the value for the second element,
and val n is the value for the n array element. Note that when you are initializing the
values at the time of declaration, then there is no need to specify the size. Let us see
some of the examples given below:
float temperature[10] ={ 31.2, 22.3, 41.4, 33.2, 23.3, 32.3, 41.1, 10.8, 11.3, 42.3};
29
Control Statements, 6.3.2 Character Array Initialisation
Arrays and
Functions
The array of characters is implemented as strings in C. Strings are handled differently
as far as initialization is concerned. A special character called null character ‘ \0 ’,
implicitly suffixes every string. When the external or static string character array is
assigned a string constant, the size specification is usually omitted and is
automatically assigned; it will include the ‘\0’character, added at end. For example,
consider the following two assignment statements:
char thing [ 3 ] = “TIN”;
char thing [ ] = “TIN”;
In the above two statements the assignments are done differently. The first statement
is not a string but simply an array storing three characters ‘T’, ‘I’ and ‘N’ and is same
as writing:
char thing [ 3 ] = {‘T’, ‘I’, ‘N’};
whereas, the second one is a four character string TIN\0. The change in the first
assignment, as given below, can make it a string.
6.4 SUBSCRIPT
To refer to the individual element in an array, a subscript is used. Refer to the
statement we used in the Example 6.1,
Here both arrays are of size 5. This is because the country is a char array and
initialized by a string constant “India” and every string constant is terminated by a
null character ‘\0’. And stud is an integer array. country array occupies 5 bytes of
memory space whereas stud occupies size of 10 bytes of memory space. The
following table: 6.1 shows how individual array elements of country and stud arrays
can be referred:
Example 6.2
Write a program to illustrate how the marks of 10 students are read in an array and
then used to find the maximum marks obtained by a student in the class.
main ( )
{
int i = 0;
int max = 0;
int stud_marks[SIZE]; /* array declaration */
/* find maximum */
for (i=0;i<SIZE;i ++)
{
if (stud_marks[i]>max)
max = stud_marks[ i ];
}
31
IGNOU STUDY STORE
We provide the highest quality study materials at
+91 7541886112
the affordable price. Get the best deals on:
Solved Assignments:-
If you need a PDF of solved assignment questions that you
can easily use to write your handwritten assignment and
submit it to your study center, feel free to contact me
directly on WhatsApp. Just send your subject code and
medium, and I'll provide you with an affordable price. Once
you make the payment through any UPI method, I'll promptly DM us on WhatsApp:
send you the solved assignment PDF. Thank you. +91 7541886112
Control Statements,
Arrays and
Functions
printf(“\n\nThe maximum of the marks obtained among all the 10 students is: %d
”,max);
}
OUTPUT
The maximum of the marks obtained among all the 10 students is: 49
Let us now see in the following example how the marks in two subjects, stored in two
different arrays, can be added to give another array and display the average marks in
the below example.
Example 6.3:
Write a program to display the average marks of each student, given the marks in 2
subjects for 3 students.
for(i=0;i<SIZE;i++)
{
total_marks[i]=stud_marks1[i]+ stud_marks2[i];
avg[i]=total_marks[i]/2;
printf(“Student no.=%d, Average= %f\n”,i+1, avg[i]);
}
}
OUTPUT
Let us now write another program to search an element using the linear search.
Example 6.4
Write a program to search an element in a given list of elements using Linear Search.
/* Linear Search.*/
# include<stdio.h>
# define SIZE 05
main()
{
int i = 0;
int j;
int num_list[SIZE]; /* array declaration */
OUTPUT
Example 6.5
Write a program to sort a list of elements using the selection sort method
#include <stdio.h>
#define SIZE 5
main()
{
int j,min_pos,tmp;
int i; /* Loop variable */
int a[SIZE]; /* array declaration */
for(i=0;i<SIZE;i++)
{
printf(“Element no.=%d”,i+1);
printf(“Value of the element: “);
scanf(“%d”,&a[i]);
}
for (i=0;i<SIZE;i++)
{
min_pos = i;
for (j=i+1;j<SIZE;j++)
if (a[j] < a[min_pos])
min_pos = j;
tmp = a[i];
a[i] = a[min_pos];
a[min_pos] = tmp;
}
34
/* print the result */ Arrays
OUTPUT
In principle, there is no limit to the number of subscripts (or dimensions) an array can
have. Arrays with more than one dimension are called multi- dimensional arrays.
While humans cannot easily visualize objects with more than three dimensions,
representing multi-dimensional arrays presents no problem to computers. In practice,
however, the amount of memory in a computer tends to place limits on the size of an
array . A simple four-dimensional array of double-precision numbers, merely twenty
elements wide in each dimension, takes up 20^4 * 8, or 1,280,000 bytes of memory -
about a megabyte.
For exmaple, you have ten rows and ten columns, for a total of 100 elements. It’s
really no big deal. The first number in brackets is the number of rows, the second
number in brackets is the number of columns. So, the upper left corner of any grid 35
Control Statements, would be element [0][0]. The element to its right would be [0][1], and so on. Here is a
Arrays and
Functions
little illustration to help.
Three-dimensional arrays (and higher) are stored in the same way as the two-
dimensional ones. They are kept in computer memory as a linear sequence of
variables, and the last index is always the one that varies fastest (then the next-to-last,
and so on).
In the above example, variable_type is the name of some type of variable, such as int.
Also, size1 and size2 are the sizes of the array’s first and second dimensions,
respectively. Here is an example of defining an 8-by-8 array of integers, similar to a
chessboard. Remember, because C arrays are zero-based, the indices on each side of
the chessboard array run 0 through 7, rather than 1 through 8. The effect is the same: a
two-dimensional array of 64 elements.
To pinpoint an element in this grid, simply supply the indices in both dimensions.
The neutral order in which the initial values are assigned can be altered by including
the groups in { } inside main enclosing brackets, like the following initialization as
above:
int table [ 2 ] [ 3 ] = { {1,2,3},
{4,5,6} };
36
The value within innermost braces will be assigned to those array elements whose last Arrays
subscript changes most rapidly. If there are few remaining values in the row, they will
be assigned zeros. The number of values cannot exceed the defined row size.
It assigns values as
table [0][0] = 1;
table [0][1] = 2;
table [0][2] = 3;
table [1][0] = 4;
table [1][1] = 0;
table [1][2] = 0
Remember that, C language performs no error checking on array bounds. If you define
an array with 50 elements and you attempt to access element 50 (the 51st element), or
any out of bounds index, the compiler issues no warnings. It is the programmer’s task
to check that all attempts to access or write to arrays are done only at valid array
indexes. Writing or reading past the end of arrays is a common programming bug and
is hard to isolate.
6.7 SUMMARY
Like other languages, C uses arrays as a way of describing a collection of variables
with identical properties. The group has a single name for all its members, with the
individual member being selected by an index. We have learnt in this unit, the basic
purpose of using an array in the program, declaration of array and assigning values to
the arrays. All elements of the arrays are stored in the consecutive memory locations.
Without exception, all arrays in C are indexed from 0 up to one less than the bound
given in the declaration. This is very puzzling for a beginner. Watch out for it in the
examples provided in this unit. One important point about array declarations is that
they don't permit the use of varying subscripts. The numbers given must be constant
expressions which can be evaluated at compile time, not run time. As with other
variables, global and static array elements are initialized to 0 by default, and automatic
array elements are filled with garbage values. In C, an array of type char is used to
represent a character string, the end of which is marked by a byte set to 0 (also known
as a NULL character).
Whenever the arrays are passed to function their starting address is used to access rest
of the elements. This is called – Call by reference. Whatever changes are made to the
37
Control Statements, elements of an array in the function, they are also made available in the calling part.
Arrays and
Functions
The formal argument contains no size specification except for the rightmost
dimension. Arrays and pointers are closely linked in C. Multi-dimensional arrays are
simply arrays of arrays. To use arrays effectively it is a good idea to know how to use
pointers with them. More about the pointers can be learnt from Unit -10 (Block -3).
2.
a) 6
b) 5
c) 5
3. This mistake doesn’t produce a compiler error. If you don’t initialize an array,
there can be any value in the array elements. You might get unpredictable
results. You should always initialize the variables and the arrays so that you
know their content.
4. Each element of an array must be initialized. The safest way for a beginner is to
initialize an array, either with a declaration, as shown in this chapter, or with a
for statement. There are other ways to initialize an array, but they are beyond
the scope of this Unit.
5. Use a for loop to total the contents of an integer array which has five elements.
Store the result in an integer called total.
2. It is possible to pass the whole array to a function. In this case, only the address
of the array will be passed. When this happens, the function can change the
value of the elements in the array.
1. float balances[3][5];
39
Control Statements,
Arrays and UNIT 7 STRINGS
Functions
Structure
7.0 Introduction
7.1 Objectives
7.2 Declaration and Initialization of Strings
7.3 Display of Strings Using Different Formatting Techniques
7.4 Array of Strings
7.5 Built-in String Functions and Applications
7.5.1 Strlen Function
7.5.2 Strcpy Function
7.5.3 Strcmp Function
7.5.4 Strcat Function
7.5.5 Strlwr Function
7.5.6 Strrev Function
7.5.7 Strspn Function
7.6 Other String Functions
7.7 Summary
7.8 Solutions / Answers
7.9 Further Readings
7.0 INTRODUCTION
In the previous unit, we have discussed numeric arrays, a powerful data storage
method that lets you group a number of same-type data items under the same group
name. Individual items, or elements, in an array are identified using a subscript after
the array name. Computer programming tasks that involve repetitive data processing
lend themselves to array storage. Like non-array variables, arrays must be declared
before they can be used. Optionally, array elements can be initialized when the array
is declared. In the earlier unit, we had just known the concept of character arrays
which are also called strings.
7.1 OBJECTIVES
Declaration of strings
A string in C is simply a sequence of characters. To declare a string, specify the data
type as char and place the number of characters in the array in square brackets after
the string name. The syntax is shown as below:
char string-name[size];
For example,
char name[20];
char address[25];
char city[15];
Initialization of strings
The string can be initialized as follows:
char name[ 8] = {‘P’, ‘R’, ‘O’, ‘G’, ‘R’, ‘A’, ‘M’, ‘\0’};
Each character of string occupies 1 byte of memory (on 16 bit computing). The size of
character is machine dependent, and varies from 16 bit computers to 64 bit computers.
The characters of strings are stored in the contiguous (adjacent) memory locations.
The C compiler inserts the NULL (\0) character automatically at the end of the string.
So initialization of the NULL character is not essential.
You can set the initial value of a character array when you declare it by specifying a
string literal. If the array is too small for the literal, the literal will be truncated. If the
literal (including its null terminator) is smaller than the array, then the final characters
in the array will be undefined. If you don’t specify the size of the array, but do specify
a literal, then C will set the array to the size of the literal, including the null
terminator.
All of the above declarations are legal. But which ones don’t work? The first one is a
valid declaration, but will cause major problems because it is not null-terminated. The
second example shows a correct null-terminated string. The special escape character
\0 denotes string termination. The fifth example suffers the size problem, the character
array ‘str’ is of size 4 bytes, but it requires an additional space to store ‘\0’. The
fourth example however does not. This is because the compiler will determine the
length of the string and automatically initialize the last character to a null-terminator.
The strings not terminated by a ‘\0’ are merely a collection of characters and are
called as character arrays.
41
Control Statements, String Constants
Arrays and
Functions
String constants have double quote marks around them, and can be assigned to char
pointers. Alternatively, you can assign a string constant to a char array - either with no
size specified, or you can specify a size, but don’t forget to leave a space for the null
character! Suppose you create the following two code fragments and run them:
/* Fragment 1 */
{
char *s;
s=hello”;
printf(“%s\n”,s);
}
/* Fragment 2 */
{
char s[100];
strcpy(s, “ hello”);
printf(“%s\n”,s);
}
These two fragments produce the same output, but their internal behaviour is quite
different. In fragment 2, you cannot say s = "hello";. To understand the differences,
you have to understand how the string constant table works in C. When your program
is compiled, the compiler forms the object code file, which contains your machine
code and a table of all the string constants declared in the program. In fragment 1, the
statement s = "hello"; causes s to point to the address of the string hello in the string
constant table. Since this string is in the string constant table, and therefore technically
a part of the executable code, you cannot modify it. You can only point to it and use it
in a read-only manner. In fragment 2, the string hello also exists in the constant table,
so you can copy it into the array of characters named s. Since s is not an address, the
statement s="hello"; will not work in fragment 2. It will not even compile.
Example 7.1
Write a program to read a name from the keyboard and display message Hello onto
the monitor
Program 7.1
/*Program that reads the name and display the hello along with your name*/
#include <stdio.h>
main()
{
char name[10];
printf(“\nEnter Your Name : “);
scanf(“%s”, name);
printf(“Hello %s\n”, name);
}
OUTPUT
In the above example declaration char name [10] allocates 10 bytes of memory space
(on 16 bit computing) to array name [ ]. We are passing the base address to scanf
function and scanf() function fills the characters typed at the keyboard into array until
enter is pressed. The scanf() places ‘\0’ into array at the end of the input. The printf()
42
function prints the characters from the array on to monitor, leaving the end of the Strings
string ‘\0’. The %s used in the scanf() and printf() functions is a format specification
for strings.
We can also specify the accuracy with which character array (string) is displayed. For
example, if you want to display first 5 characters from a field width of 15 characters,
you have to write as:
printf(“%15.5s”, name);
If you include minus sign in the format (e.g. % –10.5s), the string will be printed left
justified.
Example 7.2
Write a program to display the string “UNIX” in the following format.
U
UN
UNI
UNIX
UNIX
UNI
UN
U
# include <stdio.h>
main()
{
int x, y;
static char string[ ] = “UNIX”;
printf(“\n”);
for( x=0; x<4; x++)
{
y = x + 1;
/* reserves 4 character of space on to the monitor and minus sign is for left
justified*/
printf(“%-4.*s \n”, y, string);
OUTPUT
U
UN
UNI
UNIX
UNIX
UNI
UN
U
char names[5][10];
where names is the name of the character array and the constant in first square
brackets will gives number of string we are going to store, and the value in second
square bracket will gives the maximum length of the string.
Example 7.3
0 1 2 3 4 5 6 7 8 9
m a r t i n \0
p h i l \0
c o l l i n s \0
Example 7.4
#include <stdio.h>
main()
{
int n;
char names[3][10] = {“Alex”, “Phillip”, “Collins” };
for(n=0; n<3; n++)
printf(“%s \n”,names[n] ); }
44
Strings
OUTPUT
Alex
Phillip
Collins
A. Static String;
B. “Static String”;
C. ‘Static String’;
D. char string[100];
…………………………………………………………………………………
…………………………………………………………………………………
…………………………………………………………………………………
2. Which character ends all strings?
A. ‘.’
B. ‘ ‘
C. ‘0’
D. ‘n’
…………………………………………………………………………………
…………………………………………………………………………………
…………………………………………………………………………………
3. What is the Output of the following programs?
(a) main()
{
char name[10] = “IGNOU”;
printf(“\n %c”, name[0]);
printf(“\n %s”, name);
}
(b) main()
{
char s[ ] = “hello”;
int j = 0;
while ( s[j] != ‘\0’ )
printf(“ %c”,s[j++]);
}
(c) main()
{
char str[ ] = “hello”;
printf(“%10.2s”, str);
printf(“%-10.2s”, str);
}
…………………………………………………………………………………
…………………………………………………………………………………
………………………………………………………………………………… 45
Control Statements,
Arrays and
Functions
4 Write a program to read 'n' number of lines from the keyboard using a two-
dimensional character array (ie., strings).
…………………………………………………………………………………
…………………………………………………………………………………
…………………………………………………………………………………
where str is name of the string and n is the length of the string, returned by strlen
function.
Example 7. 5
Write a program to read a string from the keyboard and to display the length of the
string on to the monitor by using strlen( ) function.
/* Program to illustrate the strlen function to determine the length of a string */
#include <stdio.h>
#include <string.h>
main()
{
char name[80];
int length;
printf(“Enter your name: ”);
gets(name);
length = strlen(name);
printf(“Your name has %d characters\n”, length);
}
OUTPUT
Example 7.6
Write a program to read a string from the keyboard and copy the string onto the
second string and display the strings on to the monitor by using strcpy( ) function.
/* Program to illustrate strcpy function*/
#include <stdio.h>
#include <string.h>
main()
{
char first[80], second[80];
printf(“Enter a string: ”);
gets(first);
strcpy(second, first);
printf(“\n First string is : %s, and second string is: %s\n”, first, second);
}
OUTPUT
Example 7.7
/* The following program uses the strcmp function to compare two strings. */
#include <stdio.h>
#include <string.h>
main()
{
char first[80], second[80];
int value;
printf(“Enter a string: ”);
gets(first);
printf(“Enter another string: ”);
gets(second);
value = strcmp(first,second);
if(value == 0)
puts(“The two strings are equal”);
else if(value < 0)
puts(“The first string is smaller ”);
else if(value > 0)
47
Control Statements, puts(“the first string is bigger”);
Arrays and
Functions
}
OUTPUT
The strcat function is used to join one string to another. It takes two strings as
arguments; the characters of the second string will be appended to the first string. The
syntax is as follows:
strcat(str1, str2);
where str1 and str2 are two string arguments, string str2 is appended to string str1.
Example 7.8
Write a program to read two strings and append the second string to the first string.
#include <stdio.h>
#include <string.h>
main()
{
char first[80], second[80];
printf(“Enter a string:”);
gets(first);
printf(“Enter another string: ”);
gets(second);
strcat(first, second);
printf(“\nThe two strings joined together: %s\n”, first);
}
OUTPUT
Example 7.9
Write a program to convert the string into lower case characters using in-built
function.
/* Program that converts input string to lower case characters */
#include <stdio.h>
48 #include <string.h>
main() Strings
{
char first[80];
printf("Enter a string: ");
gets(first);
printf("Lower case of the string is %s”, strlwr(first));
}
OUTPUT
Example 7.9
Write a program to reverse a given string.
/* Program to reverse a given string */
#include <stdio.h>
#include <string.h>
main()
{
char first[80];
printf(“Enter a string:”);
gets(first);
printf(“\n Reverse of the given string is : %s ”, strrev(first));
}
OUTPUT
Example 7.10
Write a program, which returns the position of the string from where first string does
not match with second string.
/*Program which returns the position of the string from where first string does not
match with second string*/
#include <stdio.h>
#include <string.h>
main()
49
IGNOU STUDY STORE
We provide the highest quality study materials at
+91 7541886112
the affordable price. Get the best deals on:
Handwritten Solved Assignment Soft Copies:-
If you need Handwritten Solved Assignment Soft Copies in
PDF format that you can directly submit to your study center
via G-Form or email, feel free to contact me on WhatsApp.
These copies are superior to those offered by any other seller,
and I guarantee 90%+ marks. I'll provide you with an
affordable price, and after making the payment online DM us on WhatsApp:
through any UPI method, I'll promptly send you the PDF. +91 7541886112
Control Statements, {
Arrays and
Functions
char first[80], second[80];
printf("Enter first string: “);
gets(first);
printf(“\n Enter second string: “);
gets(second);
printf(“\n After %d characters there is no match”,strspn(first, second));
}
OUTPUT
stricmp function
The stricmp function is same as strcmp, except it compares two strings ignoring the
case (lower and upper case). The syntax is as follows:
n = stricmp(str1, str2);
strncmp function
The strncmp function is same as strcmp, except it compares two strings up to a
specified length. The syntax is as follows:
n = strncmp(str1, str2, 10);
where 10 characters of str1 and str2 are compared and n is returned value of differed
characters.
strchr function
The strchr funtion takes two arguments (the string and the character whose address is
to be specified) and returns the address of first occurrence of the character in the given
string. The syntax is as follows:
cp = strchr (str, c);
where str is string and c is character and cp is character pointer.
strset function
The strset funtion replaces the string with the given character. It takes two arguments
the string and the character. The syntax is as follows:
strset (first, ch);
where string first will be replaced by character ch.
strchr function
50
The strchr function takes two arguments (the string and the character whose address Strings
is to be specified) and returns the address of first occurrence of the character in the
given string. The syntax is as follows:
cp = strchr (str, c);
where str is string and c is character and cp is character pointer.
strncat function
The strncat function is the same as strcat, except that it appends upto specified
length. The syntax is as follows:
strncat(str1, str2,10);
where 10 character of the str2 string is added into str1 string.
strupr function
The strupr function converts lower case characters of the string to upper case
characters. The syntax is as follows:
strupr(str1);
where str1 is string to be converted into upper case characters.
strstr function
The strstr function takes two arguments address of the string and second string as
inputs. And returns the address from where the second string starts in the first string.
The syntax is as follows:
cp = strstr (first, second);
where first and second are two strings, cp is character pointer.
7.7 SUMMARY
Strings are sequence of characters. Strings are to be null-terminated if you want to use
them properly. Remember to take into account null-terminators when using dynamic
memory allocation. The string.h library has many useful functions. Losing the ‘ \0’
character can lead to some very considerable bugs. Make sure you copy \0 when you
copy strings. If you create a new string, make sure you put \0 in it. And if you copy
one string to another, make sure the receiving string is big enough to hold the source
string, including \0. Finally, if you point a character pointer to some characters, make
sure they end with \0.
1. B
2. C
3. (a) I
IGNOU
(b) hello
(c) hehe
52
Check Your Progress 2 Strings
1. D
2. C
# include<string.h>
# include <stdio.h>
main()
{
char str1[10];
char str2[10];
char output_str[20];
int i=0, j=0, k=0;
printf(" Input the first string: ");
gets(str1);
printf("\nInput the second string: ");
gets(str2);
while(str1[i] != ‘\0’)
output_str[k++] = str1[i++];
while(str2[j] != '\0')
output_str[k++] = str2[j++];
output_str[k] = ‘\0’;
puts(output_str);
}
4. /* Program to find the string length without using the strlen() funtion */
# include<stdio.h>
# include<string.h>
main()
{
char string[60];
int len=0, i=0;
printf(“ Input the string : ”);
gets(string);
while(string[i++] != ‘\0’)
len ++;
printf(“Length of Input String = %d”, len);
getchar();
}
5. /* Program to convert the lower case letters to upper case in a given string
without using strupp() function*/
#include<stdio.h>
main()
{
int i= 0; char source[10], destination[10];
gets(source);
while( source[i] != ‘\0’)
{
if((source[i]>=97) && (source[i]<=122))
53
Control Statements,
Arrays and
Functions
destination[i]=source[i]-32;
else
destination[i]=source[i];
i++;
}
destination[i]= ‘ \0 ’;
puts(destination);
}
54
Control Statements,
Arrays and UNIT 7 STRINGS
Functions
Structure
7.0 Introduction
7.1 Objectives
7.2 Declaration and Initialization of Strings
7.3 Display of Strings Using Different Formatting Techniques
7.4 Array of Strings
7.5 Built-in String Functions and Applications
7.5.1 Strlen Function
7.5.2 Strcpy Function
7.5.3 Strcmp Function
7.5.4 Strcat Function
7.5.5 Strlwr Function
7.5.6 Strrev Function
7.5.7 Strspn Function
7.6 Other String Functions
7.7 Summary
7.8 Solutions / Answers
7.9 Further Readings
7.0 INTRODUCTION
In the previous unit, we have discussed numeric arrays, a powerful data storage
method that lets you group a number of same-type data items under the same group
name. Individual items, or elements, in an array are identified using a subscript after
the array name. Computer programming tasks that involve repetitive data processing
lend themselves to array storage. Like non-array variables, arrays must be declared
before they can be used. Optionally, array elements can be initialized when the array
is declared. In the earlier unit, we had just known the concept of character arrays
which are also called strings.
7.1 OBJECTIVES
Declaration of strings
A string in C is simply a sequence of characters. To declare a string, specify the data
type as char and place the number of characters in the array in square brackets after
the string name. The syntax is shown as below:
char string-name[size];
For example,
char name[20];
char address[25];
char city[15];
Initialization of strings
The string can be initialized as follows:
char name[ 8] = {‘P’, ‘R’, ‘O’, ‘G’, ‘R’, ‘A’, ‘M’, ‘\0’};
Each character of string occupies 1 byte of memory (on 16 bit computing). The size of
character is machine dependent, and varies from 16 bit computers to 64 bit computers.
The characters of strings are stored in the contiguous (adjacent) memory locations.
The C compiler inserts the NULL (\0) character automatically at the end of the string.
So initialization of the NULL character is not essential.
You can set the initial value of a character array when you declare it by specifying a
string literal. If the array is too small for the literal, the literal will be truncated. If the
literal (including its null terminator) is smaller than the array, then the final characters
in the array will be undefined. If you don’t specify the size of the array, but do specify
a literal, then C will set the array to the size of the literal, including the null
terminator.
All of the above declarations are legal. But which ones don’t work? The first one is a
valid declaration, but will cause major problems because it is not null-terminated. The
second example shows a correct null-terminated string. The special escape character
\0 denotes string termination. The fifth example suffers the size problem, the character
array ‘str’ is of size 4 bytes, but it requires an additional space to store ‘\0’. The
fourth example however does not. This is because the compiler will determine the
length of the string and automatically initialize the last character to a null-terminator.
The strings not terminated by a ‘\0’ are merely a collection of characters and are
called as character arrays.
41
IGNOU STUDY STORE
We provide the highest quality study materials at
+91 7541886112
the affordable price. Get the best deals on:
Handwritten Solved Assignment Soft Copies :-
Yadi aapko Handwritten Solved Assignment Soft Copies PDF
chahiye, jo aap apne study center mein G-Form ya email ke
through directly submit kar sakein, to aap mujhse WhatsApp
par contact kar sakte hain. Yeh copies kisi bhi other seller se
better hain, aur main 90%+ marks ka wada karta hoon. Main
aapko affordable price bataunga, aur online kisi bhi UPI se DM us on WhatsApp:
payment karne ke baad, main turant aapko ye PDF bhej
dunga. +91 7541886112
Control Statements, String Constants
Arrays and
Functions
String constants have double quote marks around them, and can be assigned to char
pointers. Alternatively, you can assign a string constant to a char array - either with no
size specified, or you can specify a size, but don’t forget to leave a space for the null
character! Suppose you create the following two code fragments and run them:
/* Fragment 1 */
{
char *s;
s=hello”;
printf(“%s\n”,s);
}
/* Fragment 2 */
{
char s[100];
strcpy(s, “ hello”);
printf(“%s\n”,s);
}
These two fragments produce the same output, but their internal behaviour is quite
different. In fragment 2, you cannot say s = "hello";. To understand the differences,
you have to understand how the string constant table works in C. When your program
is compiled, the compiler forms the object code file, which contains your machine
code and a table of all the string constants declared in the program. In fragment 1, the
statement s = "hello"; causes s to point to the address of the string hello in the string
constant table. Since this string is in the string constant table, and therefore technically
a part of the executable code, you cannot modify it. You can only point to it and use it
in a read-only manner. In fragment 2, the string hello also exists in the constant table,
so you can copy it into the array of characters named s. Since s is not an address, the
statement s="hello"; will not work in fragment 2. It will not even compile.
Example 7.1
Write a program to read a name from the keyboard and display message Hello onto
the monitor
Program 7.1
/*Program that reads the name and display the hello along with your name*/
#include <stdio.h>
main()
{
char name[10];
printf(“\nEnter Your Name : “);
scanf(“%s”, name);
printf(“Hello %s\n”, name);
}
OUTPUT
In the above example declaration char name [10] allocates 10 bytes of memory space
(on 16 bit computing) to array name [ ]. We are passing the base address to scanf
function and scanf() function fills the characters typed at the keyboard into array until
enter is pressed. The scanf() places ‘\0’ into array at the end of the input. The printf()
42
function prints the characters from the array on to monitor, leaving the end of the Strings
string ‘\0’. The %s used in the scanf() and printf() functions is a format specification
for strings.
We can also specify the accuracy with which character array (string) is displayed. For
example, if you want to display first 5 characters from a field width of 15 characters,
you have to write as:
printf(“%15.5s”, name);
If you include minus sign in the format (e.g. % –10.5s), the string will be printed left
justified.
Example 7.2
Write a program to display the string “UNIX” in the following format.
U
UN
UNI
UNIX
UNIX
UNI
UN
U
# include <stdio.h>
main()
{
int x, y;
static char string[ ] = “UNIX”;
printf(“\n”);
for( x=0; x<4; x++)
{
y = x + 1;
/* reserves 4 character of space on to the monitor and minus sign is for left
justified*/
printf(“%-4.*s \n”, y, string);
OUTPUT
U
UN
UNI
UNIX
UNIX
UNI
UN
U
char names[5][10];
where names is the name of the character array and the constant in first square
brackets will gives number of string we are going to store, and the value in second
square bracket will gives the maximum length of the string.
Example 7.3
0 1 2 3 4 5 6 7 8 9
m a r t i n \0
p h i l \0
c o l l i n s \0
Example 7.4
#include <stdio.h>
main()
{
int n;
char names[3][10] = {“Alex”, “Phillip”, “Collins” };
for(n=0; n<3; n++)
printf(“%s \n”,names[n] ); }
44
Strings
OUTPUT
Alex
Phillip
Collins
A. Static String;
B. “Static String”;
C. ‘Static String’;
D. char string[100];
…………………………………………………………………………………
…………………………………………………………………………………
…………………………………………………………………………………
2. Which character ends all strings?
A. ‘.’
B. ‘ ‘
C. ‘0’
D. ‘n’
…………………………………………………………………………………
…………………………………………………………………………………
…………………………………………………………………………………
3. What is the Output of the following programs?
(a) main()
{
char name[10] = “IGNOU”;
printf(“\n %c”, name[0]);
printf(“\n %s”, name);
}
(b) main()
{
char s[ ] = “hello”;
int j = 0;
while ( s[j] != ‘\0’ )
printf(“ %c”,s[j++]);
}
(c) main()
{
char str[ ] = “hello”;
printf(“%10.2s”, str);
printf(“%-10.2s”, str);
}
…………………………………………………………………………………
…………………………………………………………………………………
………………………………………………………………………………… 45
Control Statements,
Arrays and
Functions
4 Write a program to read 'n' number of lines from the keyboard using a two-
dimensional character array (ie., strings).
…………………………………………………………………………………
…………………………………………………………………………………
…………………………………………………………………………………
where str is name of the string and n is the length of the string, returned by strlen
function.
Example 7. 5
Write a program to read a string from the keyboard and to display the length of the
string on to the monitor by using strlen( ) function.
/* Program to illustrate the strlen function to determine the length of a string */
#include <stdio.h>
#include <string.h>
main()
{
char name[80];
int length;
printf(“Enter your name: ”);
gets(name);
length = strlen(name);
printf(“Your name has %d characters\n”, length);
}
OUTPUT
Example 7.6
Write a program to read a string from the keyboard and copy the string onto the
second string and display the strings on to the monitor by using strcpy( ) function.
/* Program to illustrate strcpy function*/
#include <stdio.h>
#include <string.h>
main()
{
char first[80], second[80];
printf(“Enter a string: ”);
gets(first);
strcpy(second, first);
printf(“\n First string is : %s, and second string is: %s\n”, first, second);
}
OUTPUT
Example 7.7
/* The following program uses the strcmp function to compare two strings. */
#include <stdio.h>
#include <string.h>
main()
{
char first[80], second[80];
int value;
printf(“Enter a string: ”);
gets(first);
printf(“Enter another string: ”);
gets(second);
value = strcmp(first,second);
if(value == 0)
puts(“The two strings are equal”);
else if(value < 0)
puts(“The first string is smaller ”);
else if(value > 0)
47
Control Statements, puts(“the first string is bigger”);
Arrays and
Functions
}
OUTPUT
The strcat function is used to join one string to another. It takes two strings as
arguments; the characters of the second string will be appended to the first string. The
syntax is as follows:
strcat(str1, str2);
where str1 and str2 are two string arguments, string str2 is appended to string str1.
Example 7.8
Write a program to read two strings and append the second string to the first string.
#include <stdio.h>
#include <string.h>
main()
{
char first[80], second[80];
printf(“Enter a string:”);
gets(first);
printf(“Enter another string: ”);
gets(second);
strcat(first, second);
printf(“\nThe two strings joined together: %s\n”, first);
}
OUTPUT
Example 7.9
Write a program to convert the string into lower case characters using in-built
function.
/* Program that converts input string to lower case characters */
#include <stdio.h>
48 #include <string.h>
main() Strings
{
char first[80];
printf("Enter a string: ");
gets(first);
printf("Lower case of the string is %s”, strlwr(first));
}
OUTPUT
Example 7.9
Write a program to reverse a given string.
/* Program to reverse a given string */
#include <stdio.h>
#include <string.h>
main()
{
char first[80];
printf(“Enter a string:”);
gets(first);
printf(“\n Reverse of the given string is : %s ”, strrev(first));
}
OUTPUT
Example 7.10
Write a program, which returns the position of the string from where first string does
not match with second string.
/*Program which returns the position of the string from where first string does not
match with second string*/
#include <stdio.h>
#include <string.h>
main()
49
Control Statements, {
Arrays and
Functions
char first[80], second[80];
printf("Enter first string: “);
gets(first);
printf(“\n Enter second string: “);
gets(second);
printf(“\n After %d characters there is no match”,strspn(first, second));
}
OUTPUT
stricmp function
The stricmp function is same as strcmp, except it compares two strings ignoring the
case (lower and upper case). The syntax is as follows:
n = stricmp(str1, str2);
strncmp function
The strncmp function is same as strcmp, except it compares two strings up to a
specified length. The syntax is as follows:
n = strncmp(str1, str2, 10);
where 10 characters of str1 and str2 are compared and n is returned value of differed
characters.
strchr function
The strchr funtion takes two arguments (the string and the character whose address is
to be specified) and returns the address of first occurrence of the character in the given
string. The syntax is as follows:
cp = strchr (str, c);
where str is string and c is character and cp is character pointer.
strset function
The strset funtion replaces the string with the given character. It takes two arguments
the string and the character. The syntax is as follows:
strset (first, ch);
where string first will be replaced by character ch.
strchr function
50
The strchr function takes two arguments (the string and the character whose address Strings
is to be specified) and returns the address of first occurrence of the character in the
given string. The syntax is as follows:
cp = strchr (str, c);
where str is string and c is character and cp is character pointer.
strncat function
The strncat function is the same as strcat, except that it appends upto specified
length. The syntax is as follows:
strncat(str1, str2,10);
where 10 character of the str2 string is added into str1 string.
strupr function
The strupr function converts lower case characters of the string to upper case
characters. The syntax is as follows:
strupr(str1);
where str1 is string to be converted into upper case characters.
strstr function
The strstr function takes two arguments address of the string and second string as
inputs. And returns the address from where the second string starts in the first string.
The syntax is as follows:
cp = strstr (first, second);
where first and second are two strings, cp is character pointer.
7.7 SUMMARY
Strings are sequence of characters. Strings are to be null-terminated if you want to use
them properly. Remember to take into account null-terminators when using dynamic
memory allocation. The string.h library has many useful functions. Losing the ‘ \0’
character can lead to some very considerable bugs. Make sure you copy \0 when you
copy strings. If you create a new string, make sure you put \0 in it. And if you copy
one string to another, make sure the receiving string is big enough to hold the source
string, including \0. Finally, if you point a character pointer to some characters, make
sure they end with \0.
1. B
2. C
3. (a) I
IGNOU
(b) hello
(c) hehe
52
IGNOU STUDY STORE
We provide the highest quality study materials at
+91 7541886112
the affordable price. Get the best deals on:
Handwritten Solved Assignment Soft Copies :-
Yadi aapko Handwritten Solved Assignment Soft Copies PDF
chahiye, jo aap apne study center mein G-Form ya email ke
through directly submit kar sakein, to aap mujhse WhatsApp
par contact kar sakte hain. Yeh copies kisi bhi other seller se
better hain, aur main 90%+ marks ka wada karta hoon. Main
aapko affordable price bataunga, aur online kisi bhi UPI se DM us on WhatsApp:
payment karne ke baad, main turant aapko ye PDF bhej
dunga. +91 7541886112
Check Your Progress 2 Strings
1. D
2. C
# include<string.h>
# include <stdio.h>
main()
{
char str1[10];
char str2[10];
char output_str[20];
int i=0, j=0, k=0;
printf(" Input the first string: ");
gets(str1);
printf("\nInput the second string: ");
gets(str2);
while(str1[i] != ‘\0’)
output_str[k++] = str1[i++];
while(str2[j] != '\0')
output_str[k++] = str2[j++];
output_str[k] = ‘\0’;
puts(output_str);
}
4. /* Program to find the string length without using the strlen() funtion */
# include<stdio.h>
# include<string.h>
main()
{
char string[60];
int len=0, i=0;
printf(“ Input the string : ”);
gets(string);
while(string[i++] != ‘\0’)
len ++;
printf(“Length of Input String = %d”, len);
getchar();
}
5. /* Program to convert the lower case letters to upper case in a given string
without using strupp() function*/
#include<stdio.h>
main()
{
int i= 0; char source[10], destination[10];
gets(source);
while( source[i] != ‘\0’)
{
if((source[i]>=97) && (source[i]<=122))
53
Control Statements,
Arrays and
Functions
destination[i]=source[i]-32;
else
destination[i]=source[i];
i++;
}
destination[i]= ‘ \0 ’;
puts(destination);
}
54
Functions
UNIT 8 FUNCTIONS
Structure
8.0 Introduction
8.1 Objectives
8.2 Definition of a Function
8.3 Declaration of a Function
8.4 Function Prototypes
8.5 The Return Statement
8.6 Types of Variables and Storage Classes
8.6.1 Automatic Variables
8.6.2 External Variables
8.6.3 Static Variables
8.6.4 Register Variables
8.7 Types of Function Invoking
8.8 Call by Value
8.9 Recursion
8.10 Summary
8.11 Solutions / Answers
8.12 Further Readings
8.0 INTRODUCTION
To make programming simple and easy to debug, we break a larger program into
smaller subprograms which perform ‘well defined tasks’. These subprograms are
called functions. So far we have defined a single function main ( ).
After reading this unit you will be able to define many other functions and the main( )
function can call up these functions from several different places within the program,
to carry out the required processing.
Functions are very important tools for Modular Programming, where we break large
programs into small subprograms or modules (functions in case of C). The use of
functions reduces complexity and makes programming simple and easy to understand.
In this unit, we will discuss how functions are defined and how are they accessed from
the main program? We will also discuss various types of functions and how to invoke
them. And finally you will learn an interesting and important programming technique
known as Recursion, in which a function calls within itself.
8.1 OBJECTIVES
After going through this unit, you will learn:
55
Control Statements,
Arrays and
Functions
Example 8.1
#include <stdio.h>
main ()
{
void sample( );
printf(“\n You are in main”);
}
void sample( )
{
printf(“\n You are in sample”);
}
OUTPUT
Here we are calling a function sample ( ) through main( ) i.e. control of execution
transfers from main( ) to sample( ) , which means main( ) is suspended for some time
and sample( ) is executed. After its execution the control returns back to main( ), at
the statement following function call and the execution of main( ) is resumed.
where,
• return data type is the same as the data type of the variable that is returned by the
function using return statement.
• a function_name is formed in the same way as variable names / identifiers are
formed.
• the list of arguments or parameters are valid variable names as shown below,
separated by commas: (data type1 var1,data type2 var2,…….. data type n var n)
for example (int x, float y, char z).
• arguments give the values which are passed from the calling function.
56
• the body of function contains executable statements. Functions
• the return statement returns a single value to the calling function.
Example 8.2
/* square( ) function */
{
int square (int no) /*passing of argument */
int result ; /* local variable to function square */
result = no*no;
return (result); /* returns an integer value */
}
OUTPUT
As we have mentioned in the previous section, every function has its declaration and
function definition. When we talk of declaration only, it means only the function
name, its argument list and return type are specified and the function body or
definition is not attached to it. The syntax of a function declaration is:
For example,
In Example 8.1 for calculating square of a given number, we have declared function
square( ) before main( ) function; this means before coming to main( ), the compiler
knows about square( ), as the compilation process starts with the first statement of
57
Control Statements, any program. Now suppose, we reverse the sequence of functions in this program i.e.,
Arrays and
Functions
writing the main( ) function and later on writing the square( ) function, what
happens ? The “C” compiler will give an error. Here the introduction of concept of
“function prototypes” solves the above problem.
Example 8.3
/*Program to calculate the square of a given integer using the function prototype*/
#include <stdio.h>
main ( )
{
int n , sq ;
int square (int ) ; /* function prototype */
printf (“Enter a number to calculate square value”);
scanf(“%d”,&n);
sq = square(n); /* function call with parameter passing */
printf (“\nSsquare of the number is : %d”, sq);
}
/* square function */
int square (int no) /*passing of argument */
{
int result ; /* local variable to function square */
result = no*no;
return (result); /* returns an integer value */
}
OUTPUT
Points to remember:
• Function prototype requires that the function declaration must include the return
type of function as well as the type and number of arguments or parameters
passed.
• The variable names of arguments need not be declared in prototype.
• The major reason to use this concept is that they enable the compiler to check if
there is any mismatch between function declaration and function call.
58
Functions
8.5 THE return STATEMENT
If a function has to return a value to the calling function, it is done through the return
statement. It may be possible that a function does not return any value; only the
control is transferred to the calling function. The syntax for the return statement is:
return (expression);
We have seen in the square( ) function, the return statement, which returns an integer
value.
Points to remember:
• You can pass any number of arguments to a function but can return only one
value at a time.
• If a function does not return anything, void specifier is used in the function
declaration.
For example:
void square (int no)
{
int sq;
sq = no*no;
printf (“square is %d”, sq);
}
• All the function’s return type is by default is “int”, i.e. a function returns an
integer value, if no type specifier is used in the function declaration.
• What happens if a function has to return some value other than integer? The
answer is very simple: use the particular type specifier in the function
declaration.
2) Code Fragment - 2
float func_float (……..)
{
float f;
…………..
…………..
…………..
return(f);
}
Thus from the above examples, we see that you can return all the data types
from a function, the only condition being that the value returned using return
statement and the type specifier used in function declaration should match.
• A function can have many return statements. This thing happens when some
condition based returns are required.
For example,
• And finally, with the execution of return statement, the control is transferred to
the calling function with the value associated with it.
a) return (a);
b) return (z,13);
c) return (22.44);
d) return;
e) return (x*x, y*y);
…………………………………………………………………………………………
…………………………………………………………………………………………
…………………………………………………………………………………………
60
Functions
Global vs. Static variables: Global variables are recognized through out the program
whereas local valuables are recognized only within the
function where they are defined.
Static vs. Dynamic variables: Retention of value by a local variable means, that in
static, retention of the variable value is lost once the
function is completely executed whereas in certain
conditions the value of the variable has to be retained
from the earlier execution and the execution retained.
The variables can be characterized by their data type and by their storage class. One
way to classify a variable is according to its data type and the other can be through its
storage class. Data type refers to the type of value represented by a variable whereas
storage class refers to the permanence of a variable and its scope within the program
i.e. portion of the program over which variable is recognized.
Storage Classes
There are four different storage classes specified in C:
1. Auto (matic) 2. Extern (al)
3. Static 4. Register
The storage class associated with a variable can sometimes be established by the
location of the variable declaration within the program or by prefixing keywords to
variables declarations.
Points to remember:
• in declarations
• using assignment expression in a function
61
Control Statements, Example 8.4
Arrays and
Functions /* To print the value of automatic variables */
# include <stdio.h>
main ( int argc, char * argv[ ])
{
int a, b;
double d;
printf(“%d”, argc);
a = 10;
b = 5;
d = (b * b) – (a/2);
printf(“%d, %d, %f”, a, b, d);
}
All the variables a, b, d, argc and argv [ ] have automatic storage class.
Points to remember:
• These are global and can be accessed by any function within its scope.
Therefore value may be assigned in one and can be written in another.
• There is difference in external variable definition and declaration.
• External Definition is the same as any variable declaration:
• Usually lies outside or before the function accessing it.
• It allocates storage space required.
• Initial values can be assigned.
• The external specifier is not required in external variable definition.
• A declaration is required if the external variable definition comes after the
function definition.
• A declaration begins with an external specifier.
• Only when external variable is defined is the storage space allocated.
• External variables can be assigned initial values as a part of variable definitions,
but the values must be constants rather than expressions.
• If initial value is not included then it is automatically assigned a value of zero.
OUTPUT
Points to remember:
• The specifier precedes the declaration. Static and the value cannot be accessed
outside of their defining function.
• The static variables may have same name as that of external variables but the
local variables take precedence in the function. Therefore external variables
maintain their independence with locally defined auto and static variables.
• Initial value is expressed as the constant and not expression.
• Zeros are assigned to all variables whose declarations do not include explicit
initial values. Hence they always have assigned values.
• Initialization is done only is the first execution.
Example 8.6
#include <stdio.h>
main()
{
int call_static();
int i,j;
i=j=0;
j = call_static();
printf(“%d\n”,j);
j = call_static ();
printf(“%d\n”,j);
j = call_static();
printf(“%d\n”,j);
}
int call_static()
{
static int i=1;
int j;
j = i;
i++;
return(j);
}
63
IGNOU STUDY STORE
We provide the highest quality study materials at 50%
+91 7541886112
the affordable price. Get the best deals on:
Handwritten Assignment Hard Copies:-
Yadi aapko Handwritten Hard Copies Solved Assignments
chahiye, jo aapke ghar ya office par 7 din ke andar 50% cash
on delivery ke sath Amazon Courier se deliver ki jati hain, to
WhatsApp par contact karein. Inhe aasani se apne study
center mein submit karke 90%+ marks la sakte hain. Main
aapko affordable price bataunga. Order ya inquiry ke liye, DM us on WhatsApp:
WhatsApp par message bhejiyega. +91 7541886112
Control Statements,
Arrays and
Functions
OUTPUT
1
2
3
This is because i is a static variable and retains its previous value in next execution of
function call_static( ). To remind you j is having auto storage class. Both functions
main and call_static have the same local variable i and j but their values never get
mixed.
For the same program, the execution time can be reduced if certain values can be
stored in registers rather than memory. These programs are smaller in size (as few
instructions are required) and few data transfers are required. The reduction is there in
machine code and not in source code. They are declared by the proceeding declaration
by register reserved word as follows:
register int m;
Points to remember:
• These variables are stored in registers of computers. If the registers are not
available they are put in memory.
• Usually 2 or 3 register variables are there in the program.
• Scope is same as automatic variable, local to a function in which they are
declared.
• Address operator ‘&’ cannot be applied to a register variable.
• If the register is not available the variable is though to be like the automatic
variable.
• Usually associated integer variable but with other types it is allowed having
same size (short or unsigned).
• Can be formal arguments in functions.
• Pointers to register variables are not allowed.
• These variables can be used for loop indices also to increase efficiency.
As the name suggests, any function which has no arguments and does not return any
values to the calling function, falls in this category. These type of functions are
confined to themselves i.e. neither do they receive any data from the calling function
nor do they transfer any data to the calling function. So there is no data
communication between the calling and the called function are only program control
will be transferred.
Example 8.7
/* Program for illustration of the function with no arguments and no return value*/
#include <stdio.h>
main()
{
void message();
printf(“Control is in main\n”);
message(); /* Type 1 Function */
printf(“Control is again in main\n”);
}
void message()
{
printf(“Control is in message function\n”);
} /* does not return anything */
OUTPUT
Control is in main
Control is in message function
Control is again in main
Example 8.8
Write a program to find the sum of the first ten natural numbers.
#include <stdio.h>
int cal_sum()
{
int i, s=0;
for (i=0; i<=10; i++)
s=s + i;
return(s); /* function returning sum of first ten natural numbers */
}
main()
{
int sum;
65
Control Statements, sum = cal_sum();
Arrays and
Functions
printf(“Sum of first ten natural numbers is % d\n”, sum);
}
OUTPUT
Before proceeding further, first we discuss the type of arguments or parameters here.
There are two types of arguments:
• Actual arguments
• Formal arguments
#include <stdio.h>
main()
{
int a1, a2, a3;
void sum(int, int, int);
printf(“Enter three numbers: “);
scanf (“%d%d%d”,&a1,&a2,&a3);
sum (a1,a2,a3); /* Type 3 function */
}
OUTPUT
Here f1, f2, f3 are formal arguments and a1, a2, a3 are actual arguments.
Thus we see in the function declaration, the arguments are formal arguments, but
when values are passed to the function during function call, they are actual arguments.
Note: The actual and formal arguments should match in type, order and number
66
TYPE 4: With arguments function and with return value Functions
In this category two-way communication takes place between the calling and called
function i.e. a function returns a value and also arguments are passed to it. We modify
above Example according to this category.
Example 8.10
Write a program to calculate sum of three numbers.
#include <stdio.h>
main ( )
{
int a1, a2, a3, result;
int sum(int, int, int);
printf(“Please enter any 3 numbers:\n”);
scanf (“%d %d %d”, & a1, &a2, &a3);
result = sum (a1,a2,a3); /* function call */
printf (“Sum of the given numbers is : %d\n”, result);
}
OUTPUT
Please enter any 3 numbers:
345
Sum of the given numbers is: 12
Let us illustrate the above concept in more detail by taking a simple function of
multiplying two numbers:
Example 8.11
Write a program to multiply the two given numbers
#include <stdio.h>
main()
{
int x, y, z;
int mul(int, int);
printf (“Enter two numbers: \n”);
scanf (“%d %d”,&x,&y);
z= mul(x, y); /* function call by value */
printf (“\n The product of the two numbers is : %d”, z);
}
67
Control Statements, /* Function to multiply two numbers */
Arrays and
Functions
int mul(int a, int b)
{
int c;
c =a*b;
return(c); }
OUTPUT
Now let us see what happens to the actual and formal arguments in memory.
main( ) function mul( ) function
x a
2 2
6 6
What are meant by local variables? The answer is local variables are those which can
be used only by that function.
Let us discuss the second disadvantage more clearly using one example:
Example 8.12
Write a program to swap two values.
68
/*Program to swap two values*/ Functions
#include <stdio.h>
main ( )
{
int x = 2, y = 3;
void swap(int, int);
OUTPUT
x a a
2 2 3
t 2
y b b t
3 3 2
Here we observe that the changes which takes place in argument variables are not
reflected in the main() function; as these variables namely a, b and t will be destroyed
with function return.
• All these disadvantages will be removed by using “call by reference”, which will
be discussed with the introduction of pointers in UNIT 11.
Example 8.13
Write a program to find factorial of a number
#include <stdio.h>
main ()
{
int n, factorial;
int fact(int);
printf (“Enter any number:\n” );
scanf ("%d", &n);
factorial = fact ( n); /* function call */
printf (“Factorial is %d\n”, factorial);
}
OUTPUT
How it works?
Iterations:
1. i= 5 res = 1*5 = 5
2. i= 4 res = 5*4 = 20
3. i= 3 res = 20*4 = 60
4. i= 2 res = 60*2 = 120
5. i= 1 res = 120*1 = 120
70
Now let us write this function recursively. Before writing any function recursively, Functions
we first have to examine the problem, that it can be implemented through recursion.
That means this function calls itself but with value of argument decreased by ‘1’.
Example 8.14
Modify the program 8 using recursion.
OUTPUT
Enter any number: 5
Factorial is 120
How it works?
5*fact(4) 5*24
Returning Process
4*fact(3) 4*6(=24)
3*fact(2) 3*2*1(= 6)
2*fact(1) 2* 1(=2)
Note: This mechanism applies only to those problems, which repeats itself. These
types of problems can be implemented either through loops or recursive functions,
which one is better understood to you.
8.10 SUMMARY
In this unit, we learnt about “Functions”: definition, declaration, prototypes, types,
function calls datatypes and storage classes, types function invoking and lastly
Recursion. All these subtopics must have given you a clear idea of how to create and
call functions from other functions, how to send values through arguments, and how
to return values to the called function. We have seen that the functions, which do not
return any value, must be declared as “void”, return type. A function can return only
one value at a time, although it can have many return statements. A function can
return any of the data type specified in ‘C’.
Any variable declared in functions are local to it and are created with function call
and destroyed with function return. The actual and formal arguments should match in
type, order and number. A recursive function should have a terminating condition i.e.
function should return a value instead of a repetitive function call.
2. #include <stdio.h>
main ( )
{
int x, y, z;
int mul (int, int); /* function prototype */
printf (“Enter two numbers”);
scanf (“%d %d”, &x, &y);
z = mul (x, y); /* function call */
printf (“result is %d”, z); }
72
Functions
Check Your Progress 2
1. (a) Valid
(b) In valid
(c) Valid
(d) Valid
(e) Invalid
void fib(int n)
{
int curr_term, int count = 0;
int first = 1;
int second = 1;
print (“%d %d”, curr_term);
count = 2;
while(count < = n)
{ curr_term = first + second;
printf (“%d”, curr_term);
first = second;
second = curr_term;
count++;
}
}
/* Main Function */
main ( )
{
int a, b, p;
printf (“ Enter two numbers”);
scanf ( “%d %d”, &a, &b );
p = pow (a, b); /* Function call */
printf ( “ The result is %d”, p);
}
73
Control Statements,
Arrays and
Functions 8.12 FURTHER READINGS
1. The C programming language, Brain W. Kernighan, Dennis M. Ritchie, PHI
2. C,The Complete Reference, Fourth Edition, Herbert Schildt, Tata McGraw
Hill, 2002.
3. Computer Programming in C, Raja Raman. V, 2002, PHI.
5. C,The Complete Reference, Fourth Edition, Herbert Schildt, TMGH,2002.
74
Structures and
Unions
9.0 Introduction
9.1 Objectives
9.2 Declaration of Structures
9.3 Accessing the Members of a Structure
9.4 Initializing Structures
9.5 Structures as Function Arguments
9.6 Structures and Arrays
9.7 Unions
9.8 Initializing an Union
9.9 Accessing the Members of an Union
9.10 Summary
9.11 Solutions / Answers
9.12 Further Readings
9.0 INTRODUCTION
We have seen so far how to store numbers, characters, strings, and even large sets of
these primitives using arrays, but what if we want to store collections of different
kinds of data that are somehow related. For example, a file about an employee will
probably have his/her name, age, the hours of work, salary, etc. Physically, all of that
is usually stored in someone’s filing cabinet. In programming, if you have lots of
related information, you group it together in an organized fashion. Let’s say you have
a group of employees, and you want to make a database! It just wouldn’t do to have
tons of loose variables hanging all over the place. Then we need to have a single data
entity where we will be able to store all the related information together. But this
can’t be achieved by using the arrays alone, as in the case of arrays, we can group
multiple data elements that are of the same data type, and is stored in consecutive
memory locations, and is individually accessed by a subscript. That is where the user-
defined datatype Structures come in.
Structure is commonly referred to as a user-defined data type. C’s structures allow
you to store multiple variables of any type in one place (the structure). A structure
can contain any of C’s data types, including arrays and other structures. Each variable
within a structure is called a member of the structure. They can hold any number of
variables, and you can make arrays of structures. This flexibility makes structures
ideally useful for creating databases in C. Similar to the structure there is another user
defined data type called Union which allows the programmer to view a single storage
in more than one way i.e., a variable declared as union can store within its storage
space, the data of different types, at different times. In this unit, we will be discussing
the user-defined data type structures and unions.
9.1 OBJECTIVES
After going through this unit you should be able to:
5
Structures, Pointers
and File Handling
To declare a structure you must start with the keyword struct followed by the
structure name or structure tag and within the braces the list of the structure’s
member variables. Note that the structure declaration does not actually create any
variables. The syntax for the structure declaration is as follows:
struct structure-tag {
datatype variable1;
datatype variable2;
dataype variable 3;
...
};
For example, consider the student database in which each student has a roll number,
name and course and the marks obtained. Hence to group this data with a structure-
tag as student, we can have the declaration of structure as:
struct student {
int roll_no;
char name[20];
char course[20];
int marks_obtained ;
};
The point you need to remember is that, till this time no memory is allocated to the
structure. This is only the definition of structure that tells us that there exists a user-
defined data type by the name of student which is composed of the following
members. Using this structure type, we have to create the structure variables:
At this point, we have created two instances or structure variables of the user-defined
data type student. Now memory will be allocated. The amount of memory allocated
will be the sum of all the data members which form part of the structure template.
struct {
int roll_no;
char name[20];
char course[20];
int marks_obtained ;
} stud1, stud2 ;
In this case, a tag name student is missing, but still it happens to be a valid
declaration of structure. In this case the two variables are allocated memory
equivalent to the members of the structure.
The advantage of having a tag name is that we can declare any number of variables of
the tagged named structure later in the program as per requirement.
If you have a small structure that you just want to define in the program, you can do
the definition and declaration together as shown below. This will define a structure of
type struct telephone and declare three instances of it.
Consider the example for declaring and defining a structure for the telephone billing
with three instances:
struct telephone{
int tele_no;
int cust_code;
6
Structures and
Unions
char cust_address[40];
int bill_amt;
} tele1, tele2, tele3;
The structure can also be declared by using the typedefinition or typedef. This can be
done as shown below:
This defines a structure which can be referred to either as struct country or Country,
whichever you prefer. Strictly speaking, you don’t need a tag name both before and
after the braces if you are not going to use one or the other. But it is a standard
practice to put them both in and to give them the same name, but the one after the
braces starts with an uppercase letter.
The typedef statement doesn’t occupy storage: it simply defines a new type. Variables
that are declared with the typedef above will be of type struct country, just like
population is of type integer. The structure variables can be now defined as below:
structurevariable. member-name;
struct coordinate{
int x;
int y;
};
Thus, to have the structure named first refer to a screen location that has coordinates
x=50, y=100, you could write as,
first.x = 50;
first.y = 100;
To display the screen locations stored in the structure second, you could write,
Now let us see the following program to clarify our concepts. For example, let us see,
how will we go about storing and retrieving values of the individual data members of
the student structure.
Example 9.1
/*Program to store and retrieve the values from the student structure*/
7
Structures, Pointers
and File Handling
#include<stdio.h>
struct student {
int roll_no;
char name[20];
char course[20];
int marks_obtained ;
};
main()
{
student s1 ;
printf (“Enter the student roll number:”);
scanf (“%d”,&s1.roll_no);
printf (“\nEnter the student name: “);
scanf (“%s”,s1.name);
printf (“\nEnter the student course”);
scanf (“%s”,s1.course);
printf (“Enter the student percentage\n”);
scanf (“%d”,&s1.marks_obtained);
printf (“\nData entry is complete”);
printf ( “\nThe data entered is as follows:\n”);
printf (“\nThe student roll no is %d”,s1.roll_no);
printf (“\nThe student name is %s”,s1.name);
printf (“\nThe student course is %s”,s1.course);
printf (“\nThe student percentage is %d”,s1.marks_obtained);
}
OUTPUT
Another way of accessing the storing the values in the members of a structure is by
initializing them to some values at the time when we create an instance of the data
type.
Example 9.2
struct sale {
char customer[20];
char item[20];
float amt;
} mysale = { "XYZ Industries",
8
Structures and
Unions
“toolskit",
600.00
};
Example 9.3
struct customer {
char firm[20];
char contact[25];
}
struct sale {
struct customer buyer1;
char item [20];
float amt;
} mysale = {
{ "XYZ Industries", "Tyran Adams"},
"toolskit",
600.00
};
For example let us consider the following program where the data members are
initialized to some value.
Example 9.4
Write a program to access the values of the structure initialized with some initial
values.
/* Program to illustrate to access the values of the structure initialized with some
initial values*/
#include<stdio.h>
struct telephone{
int tele_no;
int cust_code;
char cust_name[20];
char cust_address[40];
int bill_amt;
};
main()
{
struct telephone tele = {2314345,
5463,
"Ram",
"New Delhi",
9
Structures, Pointers
and File Handling
2435 };
OUTPUT
…………………………………………………………………………………………
…………………………………………………………………………………………
…………………………………………………………………………………………
…………………………………………………………………………………………..
3. Why does size of report a larger size than, one expects, for a structure type, as if
there were padding at the end?
…………………………………………………………………………………………
…………………………………………………………………………………………
…………………………………………………………………………………………
…………………………………………………………………………………………
10
Structures and
Unions
Example 9.5
#include <stdio.h>
struct data{
float amt;
char fname [30];
char lname [30];
} per;
main()
{
void print_per (struct data x);
printf(“Enter the donor’s first and last names separated by a space:”);
scanf (“%s %s”, per.fname, per.lname);
printf (“\nEnter the amount donated in rupees:”);
scanf (“%f”, &per.amt);
print_per (per);
return 0;
}
OUTPUT
Enter the donor’s first and last names separated by a space: RAVI KANT
Enter the amount donated in rupees: 1000.00
RAVI KANT gave donation of the amount Rs. 1000.00.
You can also pass a structure to a function by passing the structure’s address (that is,
a pointer to the structure which we will be discussing in the next unit). In fact, in the
older versions of C, this was the only way to pass a structure as an argument. It is not
necessary now, but you might see the older programs that still use this method. If you
pass a pointer to a structure as an argument, remember that you must use the indirect
membership operator (Æ) to access structure members in the function.
Please note the following points with respect to passing the structure as a parameter
to a function.
• The return value of the called function must be declared as the value that is being
returned from the function. If the function is returning the entire structure then
the return value should be declared as struct with appropriate tag name.
• The actual and formal parameters for the structure data type must be the same as
the struct type.
• The return statement is required only when the function is returning some data.
• When the return values of type is struct, then it must be assigned to the structure
of identical type in the calling function.
Let us consider another example as shown in the Example 9.6, where structure salary
has three fields related to an employee, namely - name, no_days_worked and
daily_wage. To accept the values from the user we first call the function get_data that
11
Structures, Pointers
and File Handling
gets the values of the members of the structure. Then using the wages function we
calculate the salary of the person and display it to the user.
Example 9.6
Write a program to accept the data from the user and calculate the salary of the
person using concept of functions.
/* Program to accept the data from the user and calculate the salary of the person*/
#include<stdio.h>
main()
{
struct sal {
char name[30];
int no_days_worked;
int daily_wage; };
struct sal salary;
struct sal get_dat(struct); /* function prototype*/
float wages(struct); /*function prototype*/
float amount_payable; /* variable declaration*/
salary = get_data(salary);
printf(“The name of employee is %s”,salary.name);
printf(“Number of days worked is %d”,salary.no_daya_worked);
printf(“The daily wage of the employees is %d”,salary.daily_wage);
amount_payable = wages(salary);
printf(“The amount payable to %s is %f”,salary.name,amount_payable);
}
float wages(struct)
{
struct sal amt;
int total_salary ;
total_salary = amt.no_days_worked * amt.daily_wages;
return(total_salary); }
…………………………………………………………………………………………
…………………………………………………………………………………………
…………………………………………………………………………………………
2. How can I pass constant values to functions which accept structure arguments?
12
Structures and
Unions
…………………………………………………………………………………………
…………………………………………………………………………………………
…………………………………………………………………………………………
#include<stdio.h>
main( )
{
struct pqr{
int x ;
};
struct pqr pqr ;
pqr.x =10 ;
printf (“%d”, pqr.x);
}
…………………………………………………………………………………………
…………………………………………………………………………………………
…………………………………………………………………………………………
So, revising the array for a few moments we would refresh the fact that an array is
simply a collection of homogeneous data types. Hence, if we make a declaration as:
int temp[20];
It simply means that temp is an array of twenty elements where each element is of
type integer, indicating homogenous data type. Now in the same manner, to extend
the concept a bit further to the structure variables, we would say,
It means that stud is an array of twenty elements where each element is of the type
struct student (which is a user-defined data type we had defined earlier). The various
members of the stud array can be accessed in the similar manner as that of any other
ordinary array.
For example,
struct student stud[20], we can access the roll_no of this array as
stud[0].roll_no;
stud[1].roll_no;
stud[2].roll_no;
stud[3].roll_no;
13
Structures, Pointers
and File Handling
…
…
…
stud[19].roll_no;
Please remember the fact that for an array of twenty elements the subscripts of the
array will be ranging from 0 to 19 (a total of twenty elements). So let us now start by
seeing how we will write a simple program using array of structures.
Example 9.7
#include <stdio.h>
struct student { int roll_no;
char name[20];
char course[20];
int marks_obtained ;
};
main( )
{
struct student stud [20];
int i;
printf (“Enter the student data one by one\n”);
for(i=0; i<=19; i++)
{
printf (“Enter the roll number of %d student”,i+1);
scanf (“%d”,&stud[i].roll_no);
printf (“Enter the name of %d student”,i+1);
scanf (“%s”,stud[i].name);
printf (“Enter the course of %d student”,i+1);
scanf (“%d”,stud[i].course);
printf (“Enter the marks obtained of %d student”,i+1);
scanf (“%d”,&stud[i].marks_obtained);
}
printf (“the data entered is as follows\n”);
for (i=0;i<=19;i++)
{
printf (“The roll number of %d student is %d\n”,i+1,stud[i].roll_no);
printf (“The name of %d student is %s\n”,i+1,stud[i].name);
printf (“The course of %d student is %s\n”,i+1,stud[i].course);
printf (“The marks of %d student is %d\n”,i+1,stud[i].marks_obtained);
}
}
The above program explains to us clearly that the array of structure behaves as any
other normal array of any data type. Just by making use of the subscript we can
access all the elements of the structure individually.
Extending the above concept where we can have arrays as the members of the
structure. For example, let’s see the above example where we have taken a structure
for the student record. Hence in this case it is a real world requirement that each
student will be having marks of more than one subject. Hence one way to declare the
structure, if we consider that each student has 3 subjects, will be as follows:
struct student {
int roll_no;
char name [20];
14
Structures and
Unions
char course [20];
int subject1 ;
int subject2;
int subject3;
};
The above described method is rather a bit cumbersome, so to make it more efficient
we can have an array inside the structure, that is, we have an array as the member of
the structure.
struct student {
int roll_no;
char name [20];
char course [20];
int subject [3] ;
};
Hence to access the various elements of this array we can the program logic as
follows:
Example 9.8
/*Program to read and print data related to five students having marks of three
subjects each using the concept of arrays */
#include<stdio.h>
struct student {
int roll_no;
char name [20];
char course [20];
int subject [3] ;
};
main( )
{
struct student stud[5];
int i,j;
printf (“Enter the data for all the students:\n”);
for (i=0;i<=4;i++)
{
printf (“Enter the roll number of %d student”,i+1);
scanf (“%d”,&stud[i].roll_no);
printf(“Enter the name of %d student”,i+1);
scanf (“%s”,stud[i].name);
printf (“Enter the course of %d student”,i+1);
scanf (“%s”,stud[i].course);
for (j=0;j<=2;j++)
{
printf (“Enter the marks of the %d subject of the student %d:\n”,j+1,i+1);
scanf (“%d”,&stud[i].subject[j]);
}
}
printf (“The data you have entered is as follows:\n”);
for (i=0;i<=4;i++)
{
printf (“The %d th student's roll number is %d\n”,i+1,stud[i].roll_no);
printf (“The %d the student's name is %s\n”,i+1,stud[i].name);
printf (“The %d the student's course is %s\n”,i+1,stud[i].course);
for (j=0;j<=2;j++)
{
printf (“The %d the student's marks of %d I subject are %d\n”,i+1, j+1,
stud[i].subject[j]);
15
Structures, Pointers
and File Handling
}
}
printf (“End of the program\n”);
}
Hence as described in the example above, the array as well as the arrays of structures
can be used with efficiency to resolve the major hurdles faced in the real world
programming environment.
9.7 UNIONS
Structures are a way of grouping homogeneous data together. But it often happens
that at any time we require only one of the member’s data. For example, in case of
the support price of shares you require only the latest quotations. And only the ones
that have changed need to be stored. So if we declare a structure for all the scripts, it
will only lead to crowding of the memory space. Hence it is beneficial if we allocate
space to only one of the members. This is achieved with the concepts of the UNIONS.
UNIONS are similar to STRUCTURES in all respects but differ in the concept of
storage space.
A UNION is declared and used in the same way as the structures. Yet another
difference is that only one of its members can be used at any given time. Since all
members of a Union occupy the same memory and storage space, the space allocated
is equal to the largest data member of the Union. Hence, the member which has been
updated last is available at any given time.
For example a union can be declared using the syntax shown below:
union union-tag {
datatype variable1;
datatype variable2;
...
};
For example,
union temp{
int x;
char y;
float z;
};
In this case a float is the member which requires the largest space to store its value
hence the space required for float (4 bytes) is allocated to the union. All members
share the same space. Let us see how to access the members of the union.
Example 9.9
16
Structures and
Unions
float f;
double d;
} generic;
Example 9.10
union date_tag {
char complete_date [9];
struct part_date_tag {
char month[2];
char break_value1;
char day[2];
char break_value2;
char year[2];
} parrt_date;
}date = {“01/01/05”};
#include<stdio.h>
main()
{
union{
struct{
char x;
char y;
char z;
char w;
}xyz;
struct{
int p;
int q ;
}pq;
long a ;
float b;
double d;
}prq;
printf (“%d”,sizeof(prq));
}
9.10 SUMMARY
17
Structures, Pointers
and File Handling
In this unit, we have learnt how to use structures, a data type that you design to meet
the needs of a program. A structure can contain any of C’s data types, including other
structures, pointers, and arrays. Each data item within a structure, called a member, is
accessed using the structure member operator (.) between the structure name and the
member name. Structures can be used individually, and can also be used in arrays.
Unions were presented as being similar to structures. The main difference between a
union and a structure is that the union stores all its members in the same area. This
means that only one member of a union can be used at a time.
1. The first form declares a structure tag; the second declares a typedef. The main
difference is that the second declaration is of a slightly more abstract type - users
do not necessarily know that it is a structure, and the keyword struct is not used
while declaring an instance.
3. Structures may have this padding (as well as internal padding), to ensure that
alignment properties will be preserved when an array of contiguous structures is
allocated. Even when the structure is not part of an array, the end padding remains,
so that sizeof can always return a consistent size.
4. struct date {
char month[2];
char day[2];
char year[4];
} current_date;
2. C has no way of generating anonymous structure values. You will have to use a
temporary structure variable or a little structure - building function.
3. 10
1. 8
18
Structures and
Unions
19
Structures, Pointers
and File Handling UNIT 10 POINTERS
Structure
10.0 Introduction
10.1 Objectives
10.2 Pointers and their Characteristics
10.3 Address and Indirection Operators
10.4 Pointer Type Declaration and Assignment
10.4.1 Pointer to a Pointer
10.4.2 Null Pointer Assignment
10.5 Pointer Arithmetic
10.6 Passing Pointers to Functions
10.6.1 A Function Returning More than One Value
10.6.2 Function Returning a Pointer
10.7 Arrays and Pointers
10.8 Array of Pointers
10.9 Pointers and Strings
10.10 Summary
10.11 Solutions / Answers
10.12 Further Readings
10.0 INTRODUCTION
C uses pointers in three main ways. First, they are used to create dynamic data
structures: data structures built up from blocks of memory allocated from the heap at
run-time. Second, C uses pointers to handle variable parameters passed to functions.
And third, pointers in C provide an alternative means of accessing information stored
in arrays, which is especially valuable when you work with strings.
A normal variable is a location in memory that can hold a value. For example, when
you declare a variable i as an integer, four bytes of memory is set aside for it. In your
program, you refer to that location in memory by the name i. At the machine level,
that location has a memory address, at which the four bytes can hold one integer value.
A pointer is a variable that points to another variable. This means that it holds the
memory address of another variable. Put another way, the pointer does not hold a
value in the traditional sense; instead, it holds the address of another variable. It points
to that other variable by holding its address.
Because a pointer holds an address rather than a value, it has two parts. The pointer
itself holds the address. That addresses points to a value. There is the pointer and the
value pointed to. As long as you’re careful to ensure that the pointers in your
programs always point to valid memory locations, pointers can be useful, powerful,
and relatively trouble-free tools.
We will start this unit with a basic introduction to pointers and the concepts
surrounding pointers, and then move on to the three techniques described above.
Thorough knowledge of the pointers is very much essential for your future courses
like the datastructures, design and analysis of algorithms etc..
20
IGNOU STUDY STORE
We provide the highest quality study materials at the +91 7541886112
10.1 OBJECTIVES
Example 10.1
Write a program to know the size of the various data types on your system.
# include <stdio.h>
main( )
{
printf (“n Size of a int = %d bytes”, sizeof (int));
printf (“\n Size of a float = %d bytes”, sizeof (float));
printf (“\n Size of a char = %d bytes”, sizeof (char));
}
OUTPUT
An ordinary variable is a location in memory that can hold a value. For example,
when you declare a variable num as an integer, the compiler sets aside 2 bytes of
memory (depends up the PC) to hold the value of the integer. In your program, you
refer to that location in memory by the name num. At the machine level that location
has a memory address.
We can access the value 100 either by the name num or by its memory address. Since
addresses are simply digits, they can be stored in any other variable. Such variables
that hold addresses of other variables are called Pointers. In other words, a pointer is
21
Structures, Pointers simply a variable that contains an address, which is a location of another variable in
and File Handling
memory. A pointer variable “points to” another variable by holding its address.
Since a pointer holds an address rather than a value, it has two parts. The pointer
itself holds the address. That addresses points to a value. There is a pointer and the
value pointed to. This fact can be a little confusing until you get comfortable with it,
but once you get familiar with it, then it is extremely easy and very powerful. One
good way to visualize this concept is to examine the figure 10.1 given below:
num
ch
temp
ptr1
ptr2
i. The program execution time will be faster as the data is manipulated with the
help of addresses directly.
ii. Will save the memory space.
iii. The memory access will be very efficient.
iv. Dynamic memory is allocated.
Now we will consider how to determine the address of a variable. The operator that is
available in C for this purpose is “&” (address of ) operator. The operator & and the
immediately preceding variable returns the address of the variable associated with it.
C’s other unary pointer operator is the “*”, also called as value at address or
indirection operator. It returns a value stored at that address. Let us look into the
illustrative example given below to understand how they are useful.
Example 10.2
Write a program to print the address associated with a variable and value
stored at that address.
/* Program to print the address associated with a variable and value stored at that
22 address*/
Pointers
# include <stdio.h>
main( )
{
int qty = 5;
printf ("Address of qty = %u\n",&qty);
printf ("Value of qty = %d \n",qty);
printf("Value of qty = %d",*(&qty));
}
OUTPUT
Look at the printf statement carefully. The format specifier %u is taken to increase
the range of values the address can possibly cover. The system-generated address of
the variable is not fixed, as this can be different the next time you execute the same
program. Remember unary operator operates on single operands. When & is
preceded by the variable qty, has returned its address. Note that the & operator can
be used only with simple variables or array elements. It cannot be applied to
expressions, constants, or register variables.
Observe the third line of the above program. *(&qty) returns the value stored at
address 65524 i.e. 5 in this case. Therefore, qty and *(&qty) will both evaluate to 5.
We have seen in the previous section that &qty returns the address of qty and this
address can be stored in a variable as shown below:
ptr = &qty;
In C, every variable must be declared for its data type before it is used. Even this
holds good for the pointers too. We know that ptr is not an ordinary variable like any
integer variable. We declare the data type of the pointer variable as that of the type of
the data that will be stored at the address to which it is pointing to. Since ptr is a
variable, which contains the address of an integer variable qty, it can be declared as:
int *ptr;
# include <stdio.h>
main( )
{
int qty = 5;
int *ptr; /* declares ptr as a pointer variable that points to an integer variable
*/
ptr = &qty; /* assigning qty’s address to ptr -> Pointer Assignment */
OUTPUT
/* Program that tries to reference the value of a pointer even though the pointer is
uninitialized */
# include <stdio.h>
main()
{
int *p; /* a pointer to an integer */
*p = 10;
printf(“the value is %d”, *p);
printf(“the value is %u”,p);
}
This gives you an error. The pointer p is uninitialized and points to a random location
in memory when you declare it. It could be pointing into the system stack, or the
global variables, or into the program’s code space, or into the operating system.
When you say *p=10; the program will simply try to write a 10 to whatever random
location p points to. The program may explode immediately. It may subtly corrupt
data in another part of your program and you may never realize it. Almost always, an
uninitialized pointer or a bad pointer address causes the fault.
This can make it difficult to track down the error. Make sure you initialize all
pointers to a valid address before dereferencing them.
24
Within a variable declaration, a pointer variable can be initialized by assigning it the Pointers
address of another variable. Remember the variable whose address is assigned to the
pointer variable must be declared earlier in the program. In the example given below,
let us assign the pointer p with an address and also a value 10 through the *p.
Example 10.5
Let us say,
# include <stdio.h>
main( )
{
int *p; /* a pointer to an integer */
int x;
p = &x;
*p=10;
printf("The value of x is %d",*p);
printf("\nThe address in which the x is stored is %d",p);
}
OUTPUT
The value of x is 10
The address in which the x is stored is 52004
This statement puts the value of 20 at the memory location whose address is the value
of px. As we know that the value of px is the address of x and so the old value of x is
replaced by 20. This is equivalent to assigning 20 to x. Thus we can change the value
of a variable indirectly using a pointer and the indirection operator.
Example 10.6
# include<stdio.h>
main( )
{
int i = 100;
int *pi;
int **pii;
pi = &i;
pii = π
OUTPUT
Address of i = 65524
Address of i = 65524
Address of i = 65524
Address of pi = 65522
Address of pi = 65522
Address of pii = 65520
Value of i = 100
Value of i = 100
Value of i = 100
Value of i = 100
Consider the following memory map for the above shown example:
pii pi i Variable
65522 65524 100 Value
Example 10.7
# include<stdio.h>
# define NULL 0
main()
{
int *pi = NULL;
printf(“The value of pi is %u”, pi);
}
26
OUTPUT Pointers
The value of pi is 0
1. How is a pointer variable being declared? What is the purpose of data type
included in the pointer declaration?
…………………………………………………………………………………………
…………………………………………………………………………………………
…………………………………………………………………………………………
2. What would be the output of following programs?
…………………………………………………………………………………………
…………………………………………………………………………………………
…………………………………………………………………………………………
3. Explain the effect of the following statements:
(iii) int x;
void *ptr = &x;
*(int *) ptr = 10;
…………………………………………………………………………………………
…………………………………………………………………………………………
…………………………………………………………………………………………
However, ptr++ will cause the pointer ptr to point the next address value of its type.
For example, if ptr is a pointer to float with an initial value of 65526, then after the
operation ptr ++ or ptr = ptr+1, the value of ptr would be 65530. Therefore, if we
increment or decrement a pointer, its value is increased or decreased by the length of
the data type that it points to.
2. If ptr1 and ptr2 are properly declared and initialized pointers, the following
operations are valid:
Note that there is a blank space between / and * in the last statement because if you
write /* together, then it will be considered as the beginning of a comment and the
statement will fail.
3. Expressions like ptr1 == ptr2, ptr1 < ptr2, and ptr2 != ptr1 are permissible
provided the pointers ptr1 and ptr2 refer to same and related variables. These
comparisons are common in handling arrays.
Suppose p1 and p2 are pointers to related variables. The following operations cannot
work with respect to pointers:
In the first method, when arguments are passed by value, a copy of the values of
actual arguments is passed to the calling function. Thus, any changes made to the
variables inside the function will have no effect on variables used in the actual
argument list.
However, when arguments are passed by reference (i.e. when a pointer is passed as
an argument to a function), the address of a variable is passed. The contents of that
address can be accessed freely, either in the called or calling function. Therefore, the
function called by reference can change the value of the variable used in the call.
28
Pointers
Here is a simple program that illustrates the difference.
Example 10.8
Write a program to swap the values using the pass by value and pass by reference
methods.
/* Program that illustrates the difference between ordinary arguments, which are
passed by value, and pointer arguments, which are passed by reference */
# include <stdio.h>
main()
{
int x = 10;
int y = 20;
void swapVal ( int, int ); /* function prototype */
void swapRef ( int *, int * ); /*function prototype*/
printf("PASS BY VALUE METHOD\n");
printf ("Before calling function swapVal x=%d y=%d",x,y);
swapVal (x, y); /* copy of the arguments are passed */
printf ("\nAfter calling function swapVal x=%d y=%d",x,y);
printf("\n\nPASS BY REFERENCE METHOD");
printf ("\nBefore calling function swapRef x=%d y=%d",x,y);
swapRef (&x,&y); /*address of arguments are passed */
printf("\nAfter calling function swapRef x=%d y=%d",x,y);
}
OUTPUT
29
Structures, Pointers PASS BY REFERENCE METHOD
and File Handling
Before calling function swapRef x=10 y=20
Within function swapRef *px=20 *py=10
After calling function swapRef x=20 y=10
In the function swapVal, arguments x and y are passed by value. So, any changes to
the arguments are local to the function in which the changes occur. Note the values of
x and y remain unchanged even after exchanging the values of x and y inside the
function swapVal.
Now consider the function swapRef. This function receives two pointers to integer
variables as arguments identified as pointers by the indirection operators that appear
in argument declaration. This means that in the function swapRef, arguments x and y
are passed by reference. So, any changes made to the arguments inside the function
swapRef are reflected in the function main( ). Note the values of x and y is
interchanged after the function call swapRef.
Example 10.9
Write a program to find the perimeter and area of a rectangle, if length and breadth
are given by the user.
#include <stdio.h>
void main()
{
float len,br;
float peri, ar;
void periarea(float length, float breadth, float *, float *);
printf("\nEnter the length and breadth of a rectangle in metres: \n");
scanf("%f %f",&len,&br);
periarea(len,br,&peri,&ar);
printf("\nPerimeter of the rectangle is %f metres", peri);
printf("\nArea of the rectangle is %f sq. metres", ar);
}
OUTPUT
30
Here in the above program, we have seen that the function periarea is returning two Pointers
values. We are passing the values of len and br but, addresses of peri and ar. As we
are passing the addresses of peri and ar, any change that we make in values stored at
addresses contained in the variables *perimeter and *area, would make the change
effective even in main() also.
Example: 10.10
# include<stdio.h>
void main( )
{
float *a;
float *func( ); /* function prototype */
a = func( );
printf ("Address = %u", a);
}
float *func( )
{
float r = 5.2;
return (&r);
}
OUTPUT
Address = 65516
This program only shows how a function can return a pointer. This concept will be
used later while handling arrays.
1. Tick mark ( √ )whether each of the following statements are true or false.
(v) A function can return more than one value. True False
31
Structures, Pointers
and File Handling
10.7 ARRAYS AND POINTERS
Pointers and arrays are so closely related. An array declaration such as int arr[ 5 ]
will lead the compiler to pick an address to store a sequence of 5 integers, and arr is a
name for that address. The array name in this case is the address where the sequence
of integers starts. Note that the value is not the first integer in the sequence, nor is it
the sequence in its entirety. The value is just an address.
Now, if arr is a one-dimensional array, then the address of the first array element can
be written as &arr[0] or simply arr. Moreover, the address of the second array
element can be written as &arr[1] or simply (arr+1). In general, address of array
element (i+1) can be expressed as either &arr[ i] or as (arr+ i). Thus, we have two
different ways for writing the address of an array element. In the latter case i.e,
expression (arr+ i) is a symbolic representation for an address rather than an
arithmetic expression. Since &arr[ i] and (ar+ i) both represent the address of the ith
element of arr, so arr[ i] and *(ar + i) both represent the contents of that address i.e.,
the value of ith element of arr.
However, we can assign the value of one array element to another through a pointer,
for example,
Example 10.11
# include<stdio.h>
main()
{
OUTPUT:
y
(arr+1) 4 5 6 Second 1-d array
*(arr + 2) *(*(arr+2) + 2)
The way there can be an array of integers, or an array of float numbers, similarly,
there can be array of pointers too. Since a pointer contains an address, an array of
pointers would be a collection of addresses. For example, a multidimensional array
can be expressed in terms of an array of pointers rather than a pointer to a group of
contiguous arrays.
int *arr[3];
int arr[3][5];
Example 10.12
# include <stdio.h>
# include <stdlib.h>
# define MAXROWS 3
void main( )
{
int *ptr1[MAXROWS], *ptr2 [MAXROWS], *ptr3 [MAXROWS];
int rows, cols, i, j;
void inputmat (int *[ ], int, int);
void dispmat (int *[ ], int, int);
void calcdiff (int *[ ], int *[ ], int *[ ], int, int);
OUTPUT
In this program, ptr1, ptr2, ptr3 are each defined as an array of pointers to integers.
Each array has a maximum of MAXROWS elements. Since each element of ptr1,
ptr2, ptr3 is a pointer, we must provide each pointer with enough memory for each
row of integers. This can be done using the library function malloc included in
stdlib.h header file as follows:
This function reserves a block of memory whose size (in bytes) is equivalent to cols
* sizeof(int). Since cols = 3, so 3 * 2 (size of int data type) i.e., 6 is allocated to each
ptr1[ 1 ], ptr1[ 2 ] and ptr1[ 3 ]. This malloc function returns a pointer of type void.
This means that we can assign it to any type of pointer. In this case, the pointer is
type-casted to an integer type and assigned to the pointer ptr1[ 1 ], ptr1[ 2 ] and
ptr1[ 3 ]. Now, each of ptr1[ 1 ], ptr1[ 2 ] and ptr1[ 3 ] points to the first byte of the
memory allocated to the corresponding set of one-dimensional integer arrays of the
original two-dimensional array.
35
IGNOU STUDY STORE
We provide the highest quality study materials at
+91 7541886112
the affordable price. Get the best deals on:
Solved Assignments:-
If you need a PDF of solved assignment questions that you
can easily use to write your handwritten assignment and
submit it to your study center, feel free to contact me
directly on WhatsApp. Just send your subject code and
medium, and I'll provide you with an affordable price. Once
you make the payment through any UPI method, I'll promptly DM us on WhatsApp:
send you the solved assignment PDF. Thank you. +91 7541886112
Structures, Pointers
and File Handling
The process of calculating and allocating memory at run time is known as dynamic
memory allocation. The library routine malloc can be used for this purpose.
Instead of using conventional array notation, pointer notation has been used for
accessing the address and value of corresponding array elements which has been
explained to you in the previous section. The difference of the array elements within
the function calcdiff is written as
Each initialize a variable to the string “INDIA”. The second declaration creates a
pointer variable country that points to the letter I in the string "INDIA" somewhere in
memory.
Once the base address is obtained in the pointer variable country, *country would
yield the value at this address, which gets printed through,
Here is a program that dynamically allocates memory to a character pointer using the
library function malloc at run-time. An advantage of doing this way is that a fixed
block of memory need not be reserved in advance, as is done when initializing a
conventional character array.
Example 10.13
# include <stdio.h>
# include <conio.h>
# include <stdlib.h>
main()
{
char *palin, c;
int i, count;
i = i-1;
palin[i] = '\0';
count = i;
if (palindrome(palin,count) == 1)
printf ("\nEntered word is not a palindrome.");
else
printf ("\nEntered word is a palindrome");
}
OUTPUT
char *country[ ] = {
“INDIA”, “CHINA”, “BANGLADESH”, “PAKISTAN”, “U.S”
};
The *country[ ] of the declaration indicates an array of five elements. The char* of
the declaration indicates that each element of array country is of type “pointer to
char”. Thus, country [0] will point to INDIA, country[ 1] will point to CHINA, and
so on.
Thus, even though the array country is fixed in size, it provides access to character
strings of any length. However, a specified amount of memory will have to be
allocated for each string later in the program, for example, 37
Structures, Pointers
and File Handling
country[ i ] = (char *) malloc(15 * sizeof (char));
The country character strings could have been placed into a two-dimensional array
but such a data structure must have a fixed number of columns per row, and that
number must be as large as the largest string. Therefore, considerable memory is
wasted when a large number of strings are stored with most strings shorter than the
longest string.
Example 10.14
Write a program to enter a list of strings and rearrange them in alphabetical order,
using a one-dimensional array of pointers, where each pointer indicates the beginning
of a string:
# include <stdio.h>
# include <conio.h>
# include <stdlib.h>
# include <string.h>
main( )
{
char *country[ 5 ];
int i;
for (i = 0; i < 5; i++)
{
country[ i ] = (char *) malloc (15 * sizeof (char));
}
printf ("Enter five countries on a separate line\n");
readinput (country, 5);
reorder (country, 5);
printf ("\nReordered list\n");
writeoutput (country, 5);
getch( );
}
OUTPUT
Reordered list
BANGLADESH
CHINA
INDIA
PAKISTAN
SRILANKA
The limitation of the string array concept is that when we are using an array of
pointers to strings we can initialize the strings at the place where we are declaring the
array, but we cannot receive the strings from keyboard using scanf( ).
…………………………………………………………………………………………
…………………………………………………………………………………………
2. How the indirection operator can be used to access a multidimensional array
element.
…………………………………………………………………………………………
…………………………………………………………………………………………
39
Structures, Pointers 3. A C program contains the following declaration.
and File Handling
float temp[ 3 ][ 2 ] = {{13.4, 45.5}, {16.6, 47.8}, {20.2, 40.8}};
……………………………………………………………………………………
……………………………………………………………………………………
……………………………………………………………………………………
10.10 SUMMARY
In this unit we have studied about pointers, pointer arithmetic, passing pointers to
functions, relation to arrays and the concept of dynamic memory allocation. A
pointer is simply a variable that contains an address which is a location of another
variable in memory. The unary operator &, when preceded by any variable returns its
address. C’s other unary pointer operator is *, when preceded by a pointer variable
returns a value stored at that address.
Pointers are often passed to a function as arguments by reference. This allows data
items within the calling function to be accessed, altered by the called function, and
then returned to the calling function in the altered form. There is an intimate
relationship between pointers and arrays as an array name is really a pointer to the
first element in the array. Access to the elements of array using pointers is enabled
by adding the respective subscript to the pointer value (i.e. address of zeroth element)
and the expression preceded with an indirection operator.
As pointer declaration does not allocate memory to store the objects it points at,
therefore, memory is allocated at run time known as dynamic memory allocation. The
library routine malloc can be used for this purpose.
1. Refer to section 10.4. The data type included in the pointer declaration, refers to
the type of data stored at the address which we will be storing in our pointer.
2. (i) Compile-time Error : Lvalue Required. Means that the left side of an
assignment operator must be an addressable expression that include a variable
or an indirection through a pointer.
1 (i) True.
(ii) True.
(iii) False.
(iv) True.
(v) True.
(vi) True.
(ii) Address of the first element of the last row of array temp i.e. address of
element 20.2.
(iii) Will give you 0. To get the value of the last element of the first array i.e. the
correct syntax would be *(*(temp+0)+1).
(iv) Address of the last element of last row of array temp i.e. of 40.8.
(v) Displays the value 47.8 i.e., second element of last row of array temp.
(vi) Displays the value 20.2 i.e., first element of last row of array temp.
41
Structures, Pointers
and File Handling
UNIT 11 THE C PREPROCESSOR
Structure
11.0 Introduction
11.1 Objectives
11.2 # define to Implement Constants
11.3 # define to Create Functional Macros
11.4 Reading from Other Files using # include
11.5 Conditional Selection of Code using #ifdef
11.5.1 Using #ifdef for different computer types
11.5.2 Using #ifdef to temporarily remove program statements
11.6 Other Preprocessor Commands
11.7 Predefined Names Defined by Preprocessor
11.8 Macros Vs Functions
11.9 Summary
11.10 Solutions / Answers
11.11 Further Readings
11.0 INTRODUCTION
Theoretically, the “preprocessor” is a translation phase that is applied to the source
code before the compiler gets its hands on it. The C Preprocessor is not part of the
compiler, but is a separate step in the compilation process. C Preprocessor is just a
text substitution tool, which filters your source code before it is compiled. The
preprocessor more or less provides its own language, which can be a very powerful
tool for the programmer. All preprocessor directives or commands begin with the
symbol #.
The preprocessor makes programs easier to develop, read and modify. The
preprocessor makes C code portable between different machine architectures &
customizes the language.
The preprocessor performs textual substitutions on your source code in three ways:
File inclusion: Inserting the contents of another file into your source file, as if you
had typed it all in there.
Macro substitution: Replacing instances of one piece of text with another.
Conditional compilation: Arranging that, depending on various circumstances,
certain parts of your source code are seen or not seen by the compiler at all.
The next three sections will introduce these three preprocessing functions. The syntax
of the preprocessor is different from the syntax of the rest of C program in several
respects. The C preprocessor is not restricted to use with C programs, and
programmers who use other languages may also find it useful. However, it is tuned to
recognize features of the C language like comments and strings.
11.1 OBJECTIVES
During compilation all occurrences of begin and end get replaced by corresponding
{ and }. So the subsequent C compilation stage does not know any difference!
For Example,
The C preprocessor simply searches through the C code before it is compiled and
replaces every instance of MAXSIZE with 256.
# define FALSE 0
# define TRUE !FALSE
The literal TRUE is substituted by !FALSE and FALSE is substituted by the value 0 at
every occurrence, before compilation of the program. Since the values of the literal
are constant throughout the program, they are called as constant.
# define M 5
# define SUBJECTS 6
# define PI 3.142857
# define COUNTRY INDIA
Note that no semicolon (;) need to be placed as the delimiter at the end of a # define
line. This is just one of the ways that the syntax of the preprocessor is different from
the rest of C statements (commands). If you unintentionally place the semicolon at the
end as below:
char line[MAXLINE];
43
Structures, Pointers the preprocessor will expand it to:
and File Handling
which gives you the syntax error. This shows that the preprocessor doesn’t know
much of anything about the syntax of C.
Macros are inline code, which are substituted at compile time. The definition of a
macro is that which accepts an argument when referenced. Let us consider an example
as shown below:
Example 11.1
OUTPUT
In this case, v is equated with x in the macro definition of square, so the variable y is
assigned the square of v. The brackets in the macro definition of square are necessary
for correct evaluation. The expansion of the macro becomes:
y =( v * v);
Macros can make long, ungainly pieces of code into short words. Macros can also
accept parameters and return values. Macros that do so are called macro functions. To
create a macro, simply define a macro with a parameter that has whatever name you
like, such as my_val. For example, one macro defined in the standard libraries is
“abs”, which returns the absolute value of its parameter. Let us define our own version
of ABS as shown below. Note that we are defining it in upper case not only to avoid
conflicting with the existing “abs”.
#define can also be given arguments which are used in its replacement. The
definitions are then called macros. Macros work rather like functions, but with the
following minor differences:
Example 11.2
OUTPUT
A macro definition
must be all on one line!
Largest number among 6, 11 and 3 is 3
The macro STR1 is replaced with “A macro definition \n” in the first printf()
function. The macro STR2 is replaced with “must be all on one line! \n” in the
second printf function. The macro EXPR1 is replaced with 1+2+3 in third printf
statement. The macro EXPR2 is replaced with EXPR1 +5 in fourth printf statement.
The macro ABS(–3) is replaced with (– 3<0) ? – (– 3) : 3. And evaluation 3 is
replaced. The largest among the three numbers is diplayed.
Example 11.3
Write a program to find out square and cube of any given number using macros.
/* Program to find the square and cube of any given number using macro directive */
# include<stdio.h>
# define sqr(x) (x * x)
# define cub(x) (sqr(x) * x)
main()
{
int num;
printf(“Enter a number: ”);
scanf(“%d”, &num);
printf(“ \n Square of the number is %d”, sqr(num));
printf(“ \n Cube of the number is %d\n”, cub(num));
}
45
Structures, Pointers
and File Handling
OUTPUT
Enter a number: 5
Square of the number is 25
Cube of the number is 125
Example 11.4
C
CO
COB
COBO
COBOL
COBOL
COBO
COB
CO
C
main()
{
int x, y;
static char string[ ] = “COBOL”;
printf(“\n”);
LOOP;
}
When the above program is executed the reference to macro (loop) is replaced by the
set of statements contained within the macro definition.
OUTPUT
C
CO
COB
COBO
COBOL
COBOL
COBO
COB
CO
C
46
IGNOU STUDY STORE
We provide the highest quality study materials at
+91 7541886112
the affordable price. Get the best deals on:
Solved Assignments:-
Yadi aapko solved assignment question paper ki PDF chahiye,
jisse aap aasani se handwritten assignment likhkar apne study
center mein submit kar sakein, to aap mujhse directly
WhatsApp par contact kar sakte hain. Bas apna subject code
aur medium type karke bhejiyega, fir main aapko affordable
price bataunga. Payment online kisi bhi UPI se karne ke baad,
main aapko solved assignment PDF turant bhej dunga. DM us on WhatsApp:
Dhanyavaad. +91 7541886112
The C Preprocessor
Recollect that CALL BY VALUE Vs CALL BY REFERENCE given in the previous
uint. By CALL BY VALUE, the swapping was not taking place, because the visibility
of the variables was restricted to with in the function in the case of local variables.
You can resolve this by using a macro. Here is swap in action when using a macro:
Now we have swapping code that works. Why does this work? It is because the CPP
just simply replaces text. Wherever swap is called, the CPP will replace the macro call
with the macro meaning, (defined text).
You should be very careful in using Macros. In particular the textual substitution
means that arithmetic expressions are liable to be corrupted by the order of evaluation
rules (precedence rules). Here is an example of a macro, which won’t work.
z = DOUBLE(p) * q;
z = p + p * q;
And since * has a higher priority than +, the compiler will treat it as.
z = p + (p * q);
#define DOUBLE(n) (n + n)
Here, the braces around the definition force the expression to be evaluated before any
surrounding operators are applied. This should make the macro more reliable.
…………………………………………………………………………………………
…………………………………………………………………………………………
3. Define a macro called AREA, which will calculate the area of a circle in terms of
radius.
…………………………………………………………………………………………
…………………………………………………………………………………………
47
Structures, Pointers 4. Define a macro called CIRCUMFERENCE, which will calculate the circumference
and File Handling
of a circle in terms of radius.
…………………………………………………………………………………………
…………………………………………………………………………………………
5. Define a macro to display multiplication table.
…………………………………………………………………………………………
…………………………………………………………………………………………
6. Define a macro to find sum of n numbers.
…………………………………………………………………………………………
…………………………………………………………………………………………
………………………………………………………………………………………….
#include <filename.h>
or
#include “filename.h”
The above instruction causes the contents of the file “filename.h” to be read, parsed,
and compiled at that point. The difference between the suing of # and “ ” is that,
where the preprocessor searches for the filename.h. For the files enclosed in < > (less
than and greater than symbols) the search will be done in standard directories (include
directory) where the libraries are stored. And in case of files enclosed in “ ” (double
quotes) search will be done in “current directory” or the directory containing the
source file. Therefore, “ ” is normally used for header files you’ve written, and # is
normally used for headers which are provided for you (which someone else has
written).
Library header file names are enclosed in angle brackets, < >. These tell the
preprocessor to look for the header file in the standard location for library definitions.
This is /usr/include for most UNIX systems. And c:/tc/include for turbo compilers
on DOS / WINDOWS based systems.
Use of #include for the programmer in multi-file programs, where certain information
is required at the beginning of each program file. This can be put into a file by name
“globals.h” and included in each program file by the following line:
#include "globals.h"
If we want to make use of inbuilt functions related to input and output operations, no
need to write the prototype and definition of the functions. We can simply include the
file by writing:
#include <stdio.h>
48
The C Preprocessor
and call the functions by the function calls. The standard header file stdio.h is a
collection of function prototype (declarations) and definition related to input and
output operations.
The extension “.h”', simply stands for “header” and reflects the fact that #include
directives usually sit at the top (head) of your source files. “.h” extension is not
compulsory – you can name your own header files anything you wish to, but .h is
traditional, and is recommended.
Placing common declarations and definitions into header files means that if they
always change, they only have to be changed in one place, which is a much more
feasible system.
The preprocessor has a conditional statement similar to C’s if-else. It can be used to
selectively include statements in a program. The commands for conditional selection
are; #ifdef, #else and #endif.
#ifdef
The syntax is as follows:
#ifdef IDENTIFIER_NAME
{
statements;
}
This will accept a name as an argument, and returns true if the name has a current
definition. The name may be defined using a # define, the -d option of the compiler, or
certain names which are automatically defined by the UNIX environment. If the
identifier is defined then the statements below #ifdef will be executed
#else
The syntax is as follows:
#else
{
statements; 49
Structures, Pointers }
and File Handling
#else is optional and ends the block started with #ifdef. It is used to create a 2 way
optional selection. If the identifier is not defined then the statements below #else will
be executed.
#endif
Example 11.5
#include<stdio.h>
#define TWO
main()
{
int a, b, c;
clrscr();
#ifdef TWO
{
printf("\n Enter two numbers: \n");
scanf("%d %d", &a,&b);
if(a>b)
printf("\n Maximum of two numbers is %d", a);
else
printf("\n Maximum is of two numbers is %d", b);
}
#endif
} /* end of main*/
OUTPUT
Explanation
Conditional selection is rarely performed using #define values. This is often used
where two different computer types implement a feature in different ways. It allows
the programmer to produce a program, which will run on either type.
50
The C Preprocessor
A simple application using machine dependent values is illustrated below.
#include <stdio.h>
main()
{
#ifdef HP
{
printf("This is a HP system \n");
…………………….
……………………. /* code for HP systems*/
}
#endif
#ifdef SUN
{
printf("This is a SUN system \n");
……………………. /* code for SUN Systems
}
#endif
}
Since all you’re using the macro HP or SUN to control the #ifdef, you don’t need to
give it any replacement text at all. Any definition for a macro, even if the replacement
text is empty, causes an #ifdef to succeed.
#include <stdio.h>
main()
{
…………….
#ifdef NEVER
{
…………………….
……………………. /* code is skipped */
#endif
}
Example 11.6
Example 11.7
The preprocessor converts the line multiply(m*n) into printf(“m*n” “ = %f”, m*n);
And then into printf(“m*n = %f”, m*n);
## - Token merge, creates a single token from two adjacent ones within a macro
definition.
Example 11.8
Example 11.9
#ifdef OS_MSDOS
#include <msdos.h>
#elifdef OS_UNIX
#include ``default.h''
#else
52
#error Wrong OS!! The C Preprocessor
#endif
# line
#line number "string" – informs the preprocessor that the number is the next number
of line of input. "string" is optional and names the next line of input. This is most
often used with programs that translate other languages to C. For example, error
messages produced by the C compiler can reference the file name and line numbers of
the original source files instead of the intermediate C (translated) source files.
#pragma
It is used to turn on or off certain features. Pragmas vary from compiler to compiler.
Pragmas available with Microsoft C compilers deals with formatting source listing
and placing comments in the object file generated by the compiler. Pragmas
available with Turbo C compilers allows to write assembly language statements in C
program.
#pragma token-sequence
Example 11.10
#include <stdio.h>
#define CHOICE 100
int my_int = 0;
#if (CHOICE == 100)
void set_my_int()
{ my_int = 35; }
#else
void set_my_int()
{
my_int = 27;
}
#endif
main ()
{
set_my_int();
printf("%d\n", my_int);
}
OUTPUT
35
53
Structures, Pointers The my_int is initialized to zero and CHOICE is defined as 100. #if derivative checks
and File Handling
whether CHOICE is equal to 100. Since CHOICE is defined as 100, void set_my_int
is called and int is set 35. And the same is displayed on to the screen.
Example 11.11
#include <stdio.h>
#define CHOICE 100
int my_int = 0;
#undef CHOICE
#ifdef CHOICE
void set_my_int()
{
my_int = 35;
}
#else
void set_my_int()
{
my_int = 27;
}
#endif
main ()
{
set_my_int();
printf("%d\n", my_int);
}
OUTPUT
27
54
The C Preprocessor
11.8 MACROS Vs FUNCTIONS
Till now we have discussed about macros. Any computations that can be done on
macros can also be done on functions. But there is a difference in implementations
and in some cases it will be appropriate to use macros than function and vice versa.
We will see the difference between a macro and a function now.
Macros Functions
Macro calls are replaced with macro In function call, the control is passed to a
expansions (meaning). function definition along with arguments,
and definition is processed and value may
be returned to call
Macros run programs faster but Functions make program size smaller and
increase the program size. compact.
If macro is called 100 numbers of If function is called 100 numbers of times,
times, the size of the program will the program size will not increase.
increase.
It is better to use Macros, when the It is better to use functions, when the
definition is very small in size. definition is bigger in size.
…………………………………………………………………………………………
…………………………………………………………………………………………
2. Write a macro to add user defined header file by name madan.h to your program.
…………………………………………………………………………………………
…………………………………………………………………………………………
4. Write a macro to find out whether the given character is upper case or not.
…………………………………………………………………………………………
…………………………………………………………………………………………
…………………………………………………………………………………………..
55
Structures, Pointers
and File Handling 11.9 SUMMARY
The preprocessor makes programs easier to develop and modify. The preprocessor
makes C code more portable between different machine architectures and customize
the language. The C Preprocessor is not part of the compiler, but is a separate step in
the compilation process. All preprocessor lines begin with #. C Preprocessor is just a
text substitution tool on your source code in three ways: File inclusion, Macro
substitution, and Conditional compilation.
File inclusion - inserts the contents of another file into your source file.
Macro Substitution - replaces instances of one piece of text with another.
Conditional Compilation - arranges source code depending on various circumstances.
1. # include<stdio.h>
# define f(x) x*x + 2 * x + 4
main()
{
int num;
printf("enter value x: ");
scanf("%d",&num);
printf("\nvalue of f(num) is %d", f(num));
}
2. # include<stdio.h>
# define swap(t, x, y) { t tmp = x; x = y; y = tmp; }
main( )
{
int a, b;
float p, q;
printf("enter integer values for a, b: ");
scanf("%d %d", &a, &b);
printf("\n Enter float values for p, q: ");
scanf("%f %f", &p, &q);
swap(int, a, b);
printf(" \n After swap the values of a and b are %d %d", a, b);
swap(float, p, q);
printf("\n After swap the values of p and q are %f %f", p, q);
}
3. # include<stdio.h>
# define AREA(radius) 3.1415 * radius * radius
main( )
{
int radius;
printf(“Enter value of radius: ”);
scanf(“%d ”, &radius );
printf(“\nArea is %d”, AREA(radius));
}
4. # include<stdio.h>
# define CIRCUMFERENCE(radius) 2 * 3.1415 * radius
main( )
56
{ The C Preprocessor
int radius;
printf(“Enter value for radius ”);
scanf(“%d ”, &radius );
printf(“Circumference is %d”, CIRCUMFERENCE(radius));
}
5. # include<stdio.h>
# define MUL_TABLE(num) for(n=1;n<=10;n++) \
printf("\n%d*%d=%d",num,n,num*n)
main()
{
int number; int n;
printf("enter number");
scanf("%d",&number);
MUL_TABLE(number);
}
6. # include<stdio.h>
# define SUM(n) ( (n * (n+1)) / 2 )
main()
{
int number;
printf("enter number");
scanf("%d", &number);
printf("\n sum of n numbers %d", sum(number)); }
1. # include <math.h>
2. #include "madan.h"
3. 7
4. # include<stdio.h>
# define isupper(c) (c>=65 && c<=90)
main()
{
char c;
printf("Enter character:");
scanf("%c",&c);
if(isupper(c))
printf("\nUpper case");
else
printf("\nNo it is not an upper case character");
}
57
IGNOU STUDY STORE
We provide the highest quality study materials at
+91 7541886112
the affordable price. Get the best deals on:
Handwritten Solved Assignment Soft Copies :-
Yadi aapko Handwritten Solved Assignment Soft Copies PDF
chahiye, jo aap apne study center mein G-Form ya email ke
through directly submit kar sakein, to aap mujhse WhatsApp
par contact kar sakte hain. Yeh copies kisi bhi other seller se
better hain, aur main 90%+ marks ka wada karta hoon. Main
aapko affordable price bataunga, aur online kisi bhi UPI se DM us on WhatsApp:
payment karne ke baad, main turant aapko ye PDF bhej
dunga. +91 7541886112
Structures, Pointers
and File Handling
UNIT 12 FILES
Structure
12.0 Introduction
12.1 Objectives
12.2 File Handling in C Using File Pointers
12.2.1 Open a file using the function fopen( )
12.2.2 Close a file using the function fclose( )
12.3 Input and Output using file pointers
12.3.1 Character Input and Output in Files
12.3.2 String Input / Output Functions
12.3.3 Formatted Input / Output Functions
12.3.4 Block Input / Output Functions
12.4 Sequential Vs Random Access Files
12.5 Positioning the File Pointer
12.6 The Unbufferred I/O - The UNIX like File Routines
12.7 Summary
12.8 Solutions / Answers
12.9 Further Readings
12.0 INTRODUCTION
The examples we have seen so far in the previous units deal with standard input and
output. When data is stored using variables, the data is lost when the program exits
unless something is done to save it. This unit discusses methods of working with files,
and a data structure to store data. C views file simply as a sequential stream of bytes.
Each file ends either with an end-of-file marker or at a specified byte number recorded
in a system maintained, administrative data structure. C supports two types of files
called binary files and text files.
The difference between these two files is in terms of storage. In text files, everything
is stored in terms of text i.e. even if we store an integer 54; it will be stored as a 3-byte
string - “54\0”. In a text file certain character translations may occur. For example a
newline(\n) character may be converted to a carriage return, linefeed pair. This is what
Turbo C does. Therefore, there may not be one to one relationship between the
characters that are read or written and those in the external device. A binary file
contains data that was written in the same format used to store internally in main
memory.
For example, the integer value 1245 will be stored in 2 bytes depending on the
machine while it will require 5 bytes in a text file. The fact that a numeric value is in a
standard length makes binary files easier to handle. No special string to numeric
conversions is necessary.
The disk I/O in C is accomplished through the use of library functions. The ANSI
standard, which is followed by TURBO C, defines one complete set of I/O functions.
But since originally C was written for the UNIX operating system, UNIX standard
defines a second system of routines that handles I/O operations. The first method,
defined by both standards, is called a buffered file system. The second is the
unbuffered file system.
In this unit, we will first discuss buffered file functions and then the unbuffered file
functions in the following sections.
58
Files
12.1 OBJECTIVES
As already mentioned in the above section, a sequential stream of bytes ending with
an end-of-file marker is what is called a file. When the file is opened the stream is
associated with the file. By default, three files and their streams are automatically
opened when program execution begins - the standard input, standard output, and
the standard error. Streams provide communication channels between files and
programs.
For example, the standard input stream enables a program to read data from the
keyboard, and the standard output stream enables to write data on the screen.
Opening a file returns a pointer to a FILE structure (defined in <stdio.h>) that
contains information, such as size, current file pointer position, type of file etc., to
perform operations on the file. This structure also contains an integer called a file
descriptor which is an index into the table maintained by the operating system namely,
the open file table. Each element of this table contains a block called file control block
(FCB) used by the operating system to administer a particular file.
The standard input, standard output and the standard error are manipulated using file
pointers stdin, stdout and stderr. The set of functions which we are now going to
discuss come under the category of buffered file system. This file system is referred to
as buffered because, the routines maintain all the disk buffers required for reading /
writing automatically.
To access any file, we need to declare a pointer to FILE structure and then associate it
with the particular file. This pointer is referred as a file pointer and it is declared as
follows:
FILE *fp;
Once a file pointer variables has been declared, the next step is to open a file. The
fopen() function opens a stream for use and links a file with that stream. This function
returns a file pointer, described in the previous section. The syntax is as follows:
where mode is a string, containing the desired open status. The filename must be a
string of characters that provide a valid file name for the operating system and may
include a path specification. The legal mode strings are shown below in the table 12.1:
59
Structures, Pointers
and File Handling
Table 12.1: Legal values to the fopen( ) mode parameter
MODE MEANING
The following code fragment explains how to open a file for reading.
Code Fragment 1
#include <stdio.h>
main ()
{
FILE *fp;
if ((fp=fopen(“file1.dat”, “r”))==NULL)
{
printf(“FILE DOES NOT EXIST\n”);
exit(0);
}
}
The value returned by the fopen( ) function is a file pointer. If any error occurs while
opening the file, the value of this pointer is NULL, a constant declared in <stdio.h>.
Always check for this possibility as shown in the above example.
This function flushes any unwritten data for stream, discards any unread buffered
input, frees any automatically allocated buffer, and then closes the stream. The return
value is 0 if the file is closed successfully or a constant EOF, an end-of file marker, if
an error occurred. This constant is also defined in <stdio.h>. If the function fclose() is
not called explicitly, the operating system normally will close the file when the
program execution terminates.
# include <stdio.h>
main ( )
{
FILE *fp;
if ((fp=fopen(“file1.dat”, “r”))==NULL)
{
printf(“FILE DOES NOT EXIST\n”);
exit(0);
}
……………..
……………..
……………..
…………….
/* close the file */
fclose(fp);
}
Once the file is closed, it cannot be used further. If required it can be opened in same
or another mode.
…………………………………………………………………………………………
…………………………………………………………………………………………
……………………………………………………………………………………..….
After opening the file, the next thing needed is the way to read or write the file. There
are several functions and macros defined in <stdio.h> header file for reading and
writing the file. These functions can be categorized according to the form and type of
data read or written on to a file. These functions are classified as:
• getc()
• putc()
getc( ) is used to read a character from a file and putc( ) is used to write a character to
a file. Their syntax is as follows:
The file pointer indicates the file to read from or write to. The character ch is formally
called an integer in putc( ) function but only the low order byte is used. On success
putc( ) returns a character(in integer form) written or EOF on failure. Similarly getc( )
returns an integer but only the low order byte is used. It returns EOF when end-of-file
is reached. getc( ) and putc( ) are defined in <stdio.h> as macros not functions.
To check the end of file, C includes the function feof( ) whose prototype is:
It returns 1 if end of file has been reached or 0 if not. The following code fragment
explains the use of these functions.
Example 12.1
#include <stdio.h>
main( )
{
FILE *fp1;
FILE *fp2;
int ch;
if((fp1=fopen(“f1.dat”,”r”)) == NULL)
{
printf(“Error opening input file\n”);
exit(0);
}
if((fp2=fopen(“f2.dat”,”w”)) == NULL)
{
printf(“Error opening output file\n”);
exit(0);
62
} Files
while (!feof(fp1))
{
ch=getc(fp1);
putc(ch,fp2);
}
fclose(fp1);
fclose(fp2);
}
OUTPUT
If the file ”f1.dat” is not present, then the output would be:
Error opening input file
If the disk is full, then the output would be:
Error opening output file
If there is no error, then “f2.dat” would contain whatever is present in “f1.dat” after
the execution of the program, if “f2.dat” was not empty earlier, then its contents
would be overwritten.
If we want to read a whole line in the file then each time we will need to call character
input function, instead C provides some string input/output functions with the help of
which we can read/write a set of characters at one time. These are defined in the
standard library and are discussed below:
• fgets( )
• fputs( )
These functions are used to read and write strings. Their syntax is:
The integer parameter in fgets( ) is used to indicate that at most num-1 characters are
to be read, terminating at end-of-file or end-of-line. The end-of-line character will be
placed in the string str before the string terminator, if it is read. If end-of-file is
encountered as the first character, EOF is returned, otherwise str is returned. The
fputs( ) function returns a non-negative number or EOF if unsuccessful.
Example 12.2
Write a program read a file and count the number of lines in the file, assuming that a
line can contain at most 80 characters.
/*Program to read a file and count the number of lines in the file */
#include<stdio.h>
#include<conio.h>
#include<process.h>
void main()
{
FILE *fp;
int cnt=0;
char str[80];
63
Structures, Pointers
and File Handling
/* open a file in read mode */
if ((fp=fopen("lines.dat","r"))== NULL)
{ printf("File does not exist\n");
exit(0);
}
/* read the file till end of file is encountered */
while(!(feof(fp)))
{ fgets(str,80,fp); /*reads at most 80 characters in str */
cnt++; /* increment the counter after reading a line */
}
}/* print the number of lines */
printf(“The number of lines in the file is :%d\n”,cnt);
fclose(fp);
}
OUTPUT
Let us assume that the contents of the file “lines.dat” are as follows:
This is C programming.
I love C programming.
These functions are used for formatted input and output. These are identical to scanf()
and printf() except that the first argument is a file pointer that specifies the file to be
read or written, the second argument is the format string. The syntax for these
functions is:
int fscanf(FILE *fp, char *format,. . .);
int fprintf(FILE *fp, char *format,. . .);
Both these functions return an integer indicating the number of bytes actually read or
written.
Example 12.3
Write a program to read formatted data (account number, name and balance) from a
file and print the information of clients with zero balance, in formatted manner on the
screen.
64
Files
/* Program to read formatted data from a file */
#include<stdio.h>
main()
{
int account;
char name[30];
double bal;
FILE *fp;
if((fp=fopen("bank.dat","r"))== NULL)
printf("FILE not present \n");
else
do{
fscanf(fp,"%d%s%lf",&account,name,&bal);
if(!feof(fp))
{
if(bal==0)
printf("%d %s %lf\n",account,name,bal);
}
}while(!feof(fp));
}
OUTPUT
This program opens a file “bank.dat” in the read mode if it exists, reads the records
and prints the information (account number, name and balance) of the zero balance
records.
103 Swathi 0
105 Udit 0
Block Input / Output functions read/write a block (specific number of bytes from/to a
file. A block can be a record, a set of records or an array. These functions are also
defined in standard library and are described below.
• fread( )
• fwrite( )
These two functions allow reading and writing of blocks of data. Their syntax is:
int fread(void *buf, int num_bytes, int count, FILE *fp);
int fwrite(void *buf, int num_bytes, int count, FILE *fp);
65
Structures, Pointers In case of fread(), buf is the pointer to a memory area that receives the data from the
and File Handling
file and in fwrite(), it is the pointer to the information to be written to the file.
num_bytes specifies the number of bytes to be read or written. These functions are
quite helpful in case of binary files. Generally these functions are used to read or write
array of records from or to a file. The use of the above functions is shown in the
following program.
Example 12.4
Write a program using fread( ) and fwrite() to create a file of records and then read
and print the same file.
void main()
{
struct stud
{
char name[30];
int age;
int roll_no;
}s[30],st;
int i;
FILE *fp;
/* writing to a file*/
fwrite(s,sizeof(struct stud),30,fp);
fclose(fp);
OUTPUT
This program reads 30 records (name, age and roll_number) from the user, writes one
record at a time to a file. The file is closed and then reopened in read mode; the
records are again read from the file and written on to the screen.
66
IGNOU STUDY STORE
We provide the highest quality study materials at
+91 7541886112
the affordable price. Get the best deals on:
Handwritten Solved Assignment Soft Copies:-
If you need Handwritten Solved Assignment Soft Copies in
PDF format that you can directly submit to your study center
via G-Form or email, feel free to contact me on WhatsApp.
These copies are superior to those offered by any other seller,
and I guarantee 90%+ marks. I'll provide you with an
affordable price, and after making the payment online DM us on WhatsApp:
through any UPI method, I'll promptly send you the PDF. +91 7541886112
Files
Check Your Progress 2
1. Give the output of the following code fragment:
#include<stdio.h>
#include<process.h>
#include<conio.h>
main()
{
FILE * fp1, * fp2;
double a,b,c;
fp1=fopen(“file1”, “w”);
fp2=fopen(“file2”, “w”);
fp1=fopen(“file1”, “r”);
fp2=fopen(“file2”,“r”);
fclose(fp1);
fclose(fp2);
}
…………………………………………………………………………………………
…………………………………………………………………………………………
…………………………………………………………………………………………
…………………………………………………………………………………………
…………………………………………………………………………………………
…………………………………………………………………………………………
We have seen in section 12.0 that C supports two type of files – text and binary files,
also two types of file systems – buffered and unbuffered file system. We can also
differentiate in terms of the type of file access as Sequential access files and random
access files. Sequential access files allow reading the data from the file in sequential
manner which means that data can only be read in sequence. All the above examples 67
Structures, Pointers that we have considered till now in this unit are performing sequential access.
and File Handling
Random access files allow reading data from any location in the file. To achieve this
purpose, C defines a set of functions to manipulate the position of the file pointer. We
will discuss these functions in the following sections.
To support random access files, C requires a function with the help of which the file
pointer can be positioned at any random location in the file. Such a function defined in
the standard library is discussed below:
The function fseek( ) is used to set the file position. Its prototype is:
The first argument is the pointer to a file. The second argument is the number of bytes
to move the file pointer, counting from zero. This argument can be positive, negative
or zero depending on the desired movement. The third parameter is a flag indicating
from where in the file to compute the offset. It can have three values:
These three constants are defined in <stdio.h>. If successful fseek( ) returns zero.
Another function rewind() is used to reset the file position to the beginning of the file.
Its prototype is:
fseek(fp,0,SEEK_SET);
Another function ftell() is used to tell the position of the file pointer. Its prototype is:
Example 12.5
Write a program to search a record in an already created file and update it. Use the
same file as created in the previous example.
#include<stdio.h>
#include<conio.h>
#include<stdio.h>
#include<process.h>
#include<string.h>
void main()
{
int r,found;
struct stud
{
68
char name[30]; Files
int age;
int roll_no;
}st;
FILE *fp;
/* open the file in read/write mode */
if((fp=fopen("f1.dat","r+b"))==NULL)
{ printf("Error while opening the file \n");
exit(0);
}
OUTPUT
Let the roll_no of the record to be updated be 106. Now since this roll_no is not
present the output would be:
If the roll_no to be searched is 103, then if the new name is Sham, the output would
be the file with the contents:
Geeta 18 101
Leena 17 102
Sham 23 103
Lokesh 21 104
Amit 19 105
69
Structures, Pointers
and File Handling 12.6 THE UNBUFFERED I/O – THE UNIX LIKE FILE
ROUTINES
The buffered I/O system uses buffered input and output, that is, the operating system
handles the details of data retrieval and storage, the system stores data temporarily
(buffers it) in order to optimize file system access. The buffered I/O functions are
handled directly as system calls without buffering by the operating system. That is
why they are also known as low level functions. This is referred to as unbuffered I/O
system because the programmer must provide and maintain all disk buffers, the
routines do not do it automatically.
The low level functions are defined in the header file <io.h>.
These functions do not use file pointer of type FILE to access a particular file, but
they use directly the file descriptors, as explained earlier, of type integer. They are
also called handles.
Mode:
The access parameter is used in UNIX environment for providing the access to
particular users and is just included here for compatibility and can be set to zero.
open() function returns –1 on failure. It is used as:
Code fragment 2
int fd;
if ((fd=open(filename,mode,0)) == -1)
{ printf(“cannot open file\n”);
exit(1); }
If the file does not exist, open() the function will not create it. For this, the function
creat() is used which will create new files and re-write old ones. The prototype is:
It returns a file descriptor; if successful else it returns –1. It is not an error to create an
already existing file, the function will just truncate its length to zero. The access
parameter is used to provide permissions to the users in the UNIX environment.
The function close() is used to close a file. The prototype is:
70
Files
Reading, Writing and Positioning in File
The functions read() and write() are used to read from and write to a file. Their
prototypes are:
The first parameter is the file descriptor returned by open(), the second parameter
holds the data which must be typecast to the format needed by the program, the third
parameter indicates the number of bytes to transferred. The return value tells how
many bytes are actually transferred. If this value is –1, then an error must have
occurred.
Example 12.6
Write a program to copy one file to another to illustrate the use of the above functions.
The program should expect two command line arguments indicating the name of the
file to be copied and the name of the file to be created.
main()
{
arr buf;
name fname, sname;
int fd1,fd2,size;
open(argv[2],O_WRONLY);
size=read(fd1,buf,80); /* read till end of file */
while (size>0)
{ write(fd2,buf,80);
size=read(fd1,buf,80);
}
close(fd1);
close(fd2);
}
71
Structures, Pointers OUTPUT
and File Handling
If the number of arguments given on the command line is not correct then output
would be:
One file is opened in the read mode, and another file is opened in the write mode. The
output would be as follows is the file to be read is not present (let the file be f1.dat):
The output would be as follows if the disk is full and the file cannot be created (let the
output file be f2.dat):
lseek()
The function lseek() is provided to move to the specific position in a file. Its prototype
is:
This function is exactly the same as fseek() except that the file descriptor is used
instead of the file pointer.
Using the above defined functions, it is possible to write any kind of program dealing
with files.
2. Write a proper C statement with proper arguments that would be called to move the
file pointer back by 2 bytes.
…………………………………………………………………………………………
…………………………………………………………………………………………
12.7 SUMMARY
In this unit, we have learnt about files and how C handles them. We have discussed
the buffered as well as unbuffered file systems. The available functions in the standard
library have been discussed. This unit provided you an ample set of programs to start
with. We have also tried to differentiate between sequential access as well as random
access file. The file pointers assigned to standard input, standard output and standard
72 error are stdin, stdout, and stderr respectively. The unit clearly explains the different
type of modes oof opening the file. As seen there are several functions available to Files
read/write from the file. The usage of a particular function depends on the application.
After reading this unit one must be able to handle large data bases in the form of files.
2. Text files and binary files differ in terms of storage. In text files everything is
stored in terms of text while binary files stores exact memory image of the data i.e.
in text files 154 would take 3 bytes of storage while in binary files it will take 2
bytes as required by an integer.
2. The advantage of using these functions is that they are used for block read/write,
which means we can read or write a large set of data at one time thus increasing
the speed.
3. fscanf() and fprintf() functions are used for formatted input and output from a file.
73
Structures, Pointers APPENDIX-A
and File Handling
THE ASCII SET
The ASCII (American Standard Code for Information Interchange) character set
defines 128 characters (0 to 127 decimal, 0 to FF hexadecimal, and 0 to 177 octal).
This character set is a subset of many other character sets with 256 characters,
including the ANSI character set of MS Windows, the Roman-8 character set of HP
systems, and the IBM PC Extended Character Set of DOS, and the ISO Latin-1
character set used by Web browsers. They are not the same as the EBCDIC character
set used on IBM mainframes. The first 32 values are non-printing control characters,
such as Return and Line feed. You generate these characters on the keyboard by
holding down the Control key while you strike another key. For example, Bell is value
7, Control plus G, often shown in documents as ^G. Notice that 7 is 64 less than the
value of G (71); the Control key subtracts 64 from the value of the keys that it
modifies. The table shown below gives the list of the control and printing characters.
76