Programming in C - 81-100
Programming in C - 81-100
Syntax: continue;
4.10 Summary
In C by default, statements are executed in sequence, one after another.
We can, however, modify that sequence by using control flow constructs.
C language possesses decision making capabilities and supports the
following statements known as the control or decision making statements:
goto, if, switch. The goto statement is used to branch unconditionally from
one point to another in the program. The simplest way to modify the control
flow of a program is with an if statement. switch statements serve as a
simple way to write long if statements when the requirements are met.
The most basic loop in C is the while loop. A while loop has one control
expression, and executes as long as that expression is true. do..while loop
is used in a situation where we need to execute the body of the loop before
the test is performed. The for loop is used to execute the set of statements
repeatedly for a fixed number of times. It is an entry controlled loop. break
statement is used to exit any loop. Unlike the break which causes the loop
to be terminated, the continue, causes the loop to be continued with the
next iteration after skipping any statements in between.
4. if
5. true
6. value
7. false
8. while
9. true
10. do…while
11. false
12. false
13. true
4. 0 5 10 15
x = 30
5. 1 2 3 4
x=4
4.14 Exercises
1. Explain different types of if statements with examples.
2. Explain the syntax of switch statement with an example.
3. Write a program to check whether a given number is odd or even using
switch statement.
4. Write a program to find the smallest of 3 numbers using if-else
statement.
5. Write a program to find the roots of a quadratic equation.
6. Compare the following statements
a) while and do…while
b) break and continue
7. Write a program to compute the sum of digits of a given number using
while loop.
8. Write a program that will read a positive integer and determine and
print its binary equivalent using do…while loop.
9. The numbers in the sequence
1 1 2 3 5 8 13 ………..
are called Fibonacci numbers. Write a program using do…while loop
to calculate and print the first n Fibonacci numbers.
10. Find errors, if any, in each of the following segments. Assume that all
the variables have been declared and assigned values.
(a)
while (count !=10);
{
count = 1;
sum = sum + x;
count = count + 1;
}
(b)
do;
total = total + value;
scanf(“%f”, &value);
while (value ! =999);
11. Write programs to print the following outputs using for loops.
(a) 1 b) 1
22 2 2
333 3 3 3
4444 4 4 4 4
12. Write a program to read the age of 100 persons and count the number
of persons in the age group 50 to 60. Use for and continue statements.
13. Write a program to print the multiplication table using nested for loops.
Unit 5 Functions
Structure:
5.1 Introduction
Objectives
5.2 Function Basics
5.3 Function Prototypes
5.4 Recursion
5.5 Function Philosophy
5.6 Summary
5.7 Terminal Questions
5.8 Answers for Self Assessment Questions
5.9 Answers for Terminal Questions
5.10 Exercises
5.1 Introduction
In the previous unit, you studied about the control statements and its usage
in C. You also studied how those control statements are helpful in making
decisions when various types of conditions and options are available in the
problem. In this unit, you will study about what a function is.
A function is a “black box'' that we've locked part of our program into. The
idea behind a function is that it compartmentalizes part of the program, and
in particular, that the code within the function has some useful properties:
It performs some well-defined task, which will be useful to other parts of the
program. It might be useful to other programs as well; that is, we might be
able to reuse it (and without having to rewrite it).
The rest of the program doesn't have to know the details of how the function
is implemented. This can make the rest of the program easier to think about.
The function performs its task well. It may be written to do a little more than
is required by the first program that calls it, with the anticipation that the
calling program (or some other program) may later need the extra
functionality or improved performance. (It's important that a finished function
do its job well, otherwise there might be a reluctance to call it, and it
therefore might not achieve the goal of reusability.)
By placing the code to perform the useful task into a function, and simply
calling the function in the other parts of the program where the task must be
performed, the rest of the program becomes clearer: rather than having
some large, complicated, difficult-to-understand piece of code repeated
wherever the task is being performed, we have a single simple function call,
and the name of the function reminds us which task is being performed.
Since the rest of the program doesn't have to know the details of how the
function is implemented, the rest of the program doesn't care if the function
is re-implemented later, in some different way (as long as it continues to
perform its same task, of course!). This means that one part of the program
can be rewritten, to improve performance or add a new feature (or simply to
fix a bug), without having to rewrite the rest of the program.
Functions are probably the most important weapon in our battle against
software complexity. You'll want to learn when it's appropriate to break
processing out into functions (and also when it's not), and how to set up
function interfaces to best achieve the qualities mentioned above: reusability,
information hiding, clarity, and maintainability.
Objectives:
After studying this unit, you should be able to:
explain the importance of functions
implement the concepts of formal arguments and actual arguments
explain function declaration(function prototypes) and function definition
use the concept of recursion
explain how the concept of functions reduces software complexity
On the first line we see the return type of the function (int), the name of the
function (multbyfour), and a list of the function's arguments, enclosed in
parentheses. Each argument has both a name and a type; multbyfour
accepts one argument, of type int, named x. The name x is arbitrary, and is
used only within the definition of multbyfour. The caller of this function only
needs to know that a single argument of type int is expected; the caller does
not need to know what name the function will use internally to refer to that
argument. (In particular, the caller does not have to pass the value of a
variable named x.)
Next we see, surrounded by the familiar braces, the body of the function
itself. This function consists of one declaration (of a local variable retval) and
two statements. The first statement is a conventional expression statement,
which computes and assigns a value to retval, and the second statement is
a return statement, which causes the function to return to its caller, and also
specifies the value which the function returns to its caller.
In general term, a return statement is written as
return expression
The return statement can return the value of any expression, so we don't
really need the local retval variable; this function can also be written as
int multbyfour(int x)
{
return x * 4;
}
How do we call a function? We've been doing so informally since day one,
but now we have a chance to call one that we've written, in full detail. The
arguments in the function call are referred to as actual arguments or actual
parameters, in contrast to the formal arguments that appear in the first line
of the function definition.
Here is a tiny skeletal program to call multbyfour:
#include <stdio.h>
extern int multbyfour(int);
int main()
{
int i, j;
i = 5;
j = multbyfour(i);
printf("%d\n", j);
return 0;
}
This looks much like our other test programs, with the exception of the new
line
extern int multbyfour(int);
This is an external function prototype declaration. It is an external
declaration, in that it declares something which is defined somewhere else.
(We've already seen the defining instance of the function multbyfour, but
may be the compiler hasn't seen it yet.) The function prototype declaration
contains the three pieces of information about the function that a caller
needs to know: the function's name, return type, and argument type(s).
Since we don't care what name the multbyfour function will use to refer to
its first argument, we don't need to mention it. (On the other hand, if a
function takes several arguments, giving them names in the prototype may
make it easier to remember which is which, so names may optionally be
used in function prototype declarations.) Finally, to remind us that this is an
external declaration and not a defining instance, the prototype is preceded
by the keyword extern.
The presence of the function prototype declaration lets the compiler know
that we intend to call this function, multbyfour. The information in the
prototype lets the compiler generate the correct code for calling the function,
and also enables the compiler to check up on our code (by making sure, for
example, that we pass the correct number of arguments to each function we
call).
Down in the body of main, the action of the function call should be obvious:
the line
j = multbyfour(i);
calls B, passing it the value of i as its argument. When multbyfour returns,
the return value is assigned to the variable j. (Notice that the value of main's
local variable i will become the value of multbyfour's parameter x; this is
absolutely not a problem, and is a normal sort of affair.)
This example is written out in “longhand,'' to make each step equivalent.
The variable i isn't really needed, since we could just as well call
j = multbyfour(5);
And the variable j isn't really needed, either, since we could just as well call
printf("%d\n", multbyfour(5));
Here, the call to multbyfour is a subexpression which serves as the second
argument to printf. The value returned by multbyfour is passed
immediately to printf. (Here, as in general, we see the flexibility and
generality of expressions in C. An argument passed to a function may be an
arbitrarily complex subexpression, and a function call is itself an expression
which may be embedded as a subexpression within arbitrarily complicated
surrounding expressions.)
We might wonder, if we wrote it this way, what would happen to the value of
the variable i when we called
j = multbyfour(i);
When our implementation of multbyfour changes the value of x, does that
change the value of i up in the caller? The answer is no. x receives a copy
of i's value, so when we change x we don't change i.
However, there is an exception to this rule. When the argument you pass to
a function is not a single variable, but is rather an array, the function does
not receive a copy of the array, and it therefore can modify the array in the
caller. The reason is that it might be too expensive to copy the entire array,
and furthermore, it can be useful for the function to write into the caller's
array, as a way of handing back more data than would fit in the function's
single return value. We will discuss more about passing arrays as
arguments to a function later.
There may be several different calls to the same function from various
places within a program. The actual arguments may differ from one function
call to another. Within each function call, however, the actual arguments
must correspond to the formal arguments in the function definition; i.e the
actual arguments must match in number and type with the corresponding
formal arguments.
scanf(“%d”, &num);
if(psquare(num)) /* main() calls the function psquare() */
{
printf(“%d is a perfect square\n”);
else
printf(“%d is not a perfect square\n”);
}
}
int psquare(int x)
{
int positive(int);
float sqr;
if(positive(x)) /* psquare() in turn calls the function positive() */
{
sqr=sqrt(x));
if(sqr-int(sqr))==0)
return 1;
else
return 0;
}
int positive(int m)
{
if(m>0)
return 1;
else return 0;
}
void demo(void); Here void indicates function neither return any value to the
caller nor it has any arguments.
If you write the function definition after the definition of its caller function,
then the prototype is required in the caller, but the prototype is optional if
you write the definition of the function before the definition of the caller
function. But it is good programming practice to include the function
prototype wherever it is defined.
If prototypes are a good idea, and if we're going to get in the habit of writing
function prototype declarations for functions we call that we've written (such
as multbyfour), what happens for library functions such as printf? Where
are their prototypes? The answer is in that boilerplate line
#include <stdio.h>
we've been including at the top of all of our programs. stdio.h is conceptually
a file full of external declarations and other information pertaining to the
“Standard I/O'' library functions, including printf. The #include directive
arranges all of the declarations within stdio.h that are considered by the
compiler, rather as if we'd typed them all in ourselves. Somewhere within
these declarations is an external function prototype declaration for printf,
which satisfies the rule that there should be a prototype for each function we
call. (For other standard library functions we call, there will be other “header
files'' to include.) Finally, one more thing about external function prototype
declarations: we've said that the distinction between external declarations
and defining instances of normal variables hinges on the presence or
absence of the keyword extern. The situation is a little bit different for
functions. The “defining instance'' of a function is the function, including its
body (that is, the brace-enclosed list of declarations and statements
implementing the function). An external declaration of a function, even
without the keyword extern, looks nothing like a function declaration.
Therefore, the keyword extern is optional in function prototype declarations.
If you wish, you can write
int multbyfour(int);
and this is just like an external function prototype declaration as
extern int multbyfour(int);
(In the first form, without the extern, as soon as the compiler sees the
semicolon, it knows it's not going to see a function body, so the declaration
can't be a definition.) You may want to stay in the habit of using extern in all
external declarations, including function declarations, since “extern =
external declaration'' is an easier rule to remember.
Program 5.3: Program to illustrate that the function prototype is
optional in the caller function. The program is to convert a character
from lowercase to uppercase.
#include<stdio.h>
char lower_to_upper(char ch) /* Function definition precedes main()*/
{
char c;
c=(ch>=’a’ && ch<=’z’) ? (‘A’+ch-‘a’):ch;
return c;
}
main()
{
char lower, upper;
/* char lower_to_upper(char lower); */ /* Function prototype is
optional here*/
printf(“Please enter a lowercase character:”);
scanf(“%c”, &lower);
upper=lower_to_upper(lower);
printf(“\nThe uppercase equivalent of %c is %c\n”, lower, upper);
}
main()
{
double x, y, z;
…
z=fun(x, y);
…
}
5.4 Recursion
Recursion is a process by which a function calls itself repeatedly, until some
specified condition has been met. The process is used for repetitive
computations in which each action is stated in terms of a previous result.
Many repetitive problems can be written in this form.
In order to solve a problem recursively, two conditions must be satisfied.
First, the problem must be written in a recursive form, and the second, the
problem statement must include a stopping condition.
Example 5.3: Factorial of a number. Suppose we wish to calculate the
factorial of a positive integer, n. We would normally express this problem as
n!=1 x 2 x 3 x … x n.
This can also be written as n!=n x (n-1)!. This is the recursive statement of
the problem in which the desired action(the calculation of n!) is expressed in
terms of a previous result (the value of (n-1)! which is assumed to be
known). Also, we know that 0!=1 by definition. This expression provides
stopping condition for the recursion.
Thus the recursive definition for finding factorial of positive integer n can be
written as:
fact(n)={ 1 if n=0
n x fact(n-1) otherwise}
Program 5.4: Program to find factorial of a given positive integer
#include<stdio.h>
main()
{
int n;
long int fact(int);
The aim of the game is to transfer the disks from the leftmost pole to the
rightmost pole, without ever placing a larger disk on top of a smaller disk.
Only one disk may be moved at a time, and each disk must always be
placed around one of the poles.
Manipal University Jaipur Page No.: 100