Вы находитесь на странице: 1из 22

Birla Institute of Technology & Science, Pilani K. K.

Birla Goa Campus,


Computer Programming (CS F111)
Second Semester 2013-2014
Lab-6 (Loops in C)

Objectives
1. Loops
1.1. for loops
1.2.while loops
1.3.do …. while loops
2. break ….. continue
2.1. break
2.2. continue
3. Makefile
4. Exercises
5. Additional Exercises

1. Loops
Looping is required to execute a segment of a program repeatedly. Often a situation arises to repeat some
portion of the program either a specified number of times or until a particular condition is being satisfied.
To perform this repetitive operation, a loop control structure is required. C language provides three loop
control statements:
(i) for statement, (ii) while statement and (iii) do-while statement.

1.1.for loop
First initialization is made. The condition testing is carried out. If the condition test is TRUE (non-zero) then
the loop body is executed. After a complete iteration of the loop body, the expression (increment or
decrement) is executed and again the condition is checked for the next iteration. This continues till the
condition test is FALSE (zero).The flowchart of for loop is shown in figure below.

1
for loop Syntax:

for ( variable initialization; condition; variable update )


{
/* Code to execute while the condition is true */
}

The variable initialization allows you to either declare a variable and give it a value or give a value to an
already existing variable. Second, the condition tells the program that while the conditional expression is
true the loop should continue to repeat itself. The variable update section is the easiest way for a ‘for loop’
to handle changing of the variable values. It is possible to do things like x++, x = x + 10, or even x =
random(5). ‘for loop’ will be executed as long as test condition is TRUE (non-zero).

Either initialization or test condition or variable update can be empty. Test condition is evaluated before
executing loop body. Loop body can have a single statement or a group of statements. If it has a single

2
statement then there is no need to enclose it in flower braces but if it has more than one statement then it
should be enclosed in flower braces.

Example 1.1: Program to find factorial of a number


/*
Pre-condition: n >= 0 and within range of signed integer
Post-condition: Factorial of n will be displayed
*/

#include<stdio.h>
int main()
{
int n,count,factorial=1;
printf(“Enter a number:”);
scanf(“%d”,&n);
if(n<0)
printf(“Can’t compute Factorial of negative number”);
else
{
for (count=1; count<=n; count++) //count is initialized to 1
{
factorial=factorial*count;
}
printf(“Factorial of %d is: %d\n”,n,factorial);
}
return 0;
}

Example 1.2: Program to find all the factors of a given number


/*
Pre-condition: n > 0 and within range of signed integer
Post-condition: All the factors of n will be displayed
*/

#include<stdio.h>
int main()
{
int n,i;
printf(“Enter a positive number ”);
scanf(“%d”,&n);
if(n<=0)
printf(“Can’t compute Factors of negative numbers or zero”);

3
else
{
printf(“Factors of %d are: \n“,n);
for(i=1;i<=n;i++)
{
if(n%i==0)
printf(“%d\n”,i);
}
}
return 0;
}

Example 1.3: Program to find sum of first n numbers where n is entered by the user
/*
Pre-condition: n >= 0 and within range of signed integer
Post-condition: Display sum of first n numbers
*/

#include<stdio.h>
int main()
{
int n,count,sum=0; // sum is initialized to zero
printf(“Enter a number: ”);
scanf(“%d”,&n);
if(n<0)
printf(“WRONG INPUT”);
else
{

for(count=1;count<=n;count++)
{
sum+=count;
}
printf(“Sum=%d\n”,sum);
}
return 0;
}

4
Nested for loop:-
C programming language allows to use one loop inside another loop. The syntax of nested for loop is as
below:

for ( initialization ; condition; increment )


{
for ( initialization; condition; increment )
{
statement(s);
}
statement(s);
}

Example 1.4: Program to find prime numbers between 2 to 100.


/*
Pre-condition: NA
Post-condition: Display prime numbers b/w 2 to 100
*/

#include<stdio.h>
int main()
{
int a,b;
for(a=2;a<=100;a++)
{
for(b=2;b<=(a/b);b++)
{
if(!(a%b))
break;
}
if(b>(a/b))
printf(“%d is prime”,a);
}
return 0;
}

1.2.while loop
While loop is an entry-controlled looping structure. The ‘while’ loop allows execution of statements inside
block of loop only if condition in loop succeeds. In while loop, the condition is checked first. If it is true
then the body of the loop is executed, otherwise it exits the loop. The flow chart of while loop is given in the
below figure.

5
while Loop Syntax:-

while (test expression)


{
statements to be executed.
}

Example 1.5: Program to find GCD and LCM of two numbers.


/*
Pre-condition: num1 > 0 and num2 > 0,both within range of signed integer
Post-condition: Display the GCD and LCM of num1 and num2
*/

#include<stdio.h>
int main()
{
int num1,num2,x,y,t,gcd,lcm;
printf(“Enter two integers:”);
scanf(“%d %d”,&num1,&num2);
if(num1 > 0 && num2 > 0)
{
x=num1;
y=num2;
while(num2 != 0)
{
t=num2;
num2=num1%num2;
num1=t;
}
gcd=num1;

6
lcm=(x*y)/gcd;
/*The minimum value of G.C.D should be 1*/
printf(“The GCD of %d and %d is %d\n”,x,y,gcd);
printf(“The LCM of %d and %d is %d\n”,x,y,lcm);
}
else
printf(“WRONG INPUT”);
return 0;
}

Example 1.6: Program to find reverse of a given number


/*
Pre-condition: n within range of signed integer
Post-condition: Display the reverse of a given number
*/

#include<stdio.h>
int main()
{
int n,reverse=0,rem;
printf(“Enter an integer number:”);
scanf(“%d”,&n);
while(n!=0)
{
rem = n%10;
reverse=reverse*10+rem;
n=n/10;
}
printf(“Reverse of the number is %d:”,reverse);
return 0;
}

1.3. do …. while

It is an exit controlled looping structure. Here the body of the loop is executed first and then the condition is
checked. If the condition is true then the loop is continued otherwise it exits the loop .Thus this loop is
executed at least once without considering the condition. The flow chart of do…. while loop is shown in
figure below.

7
do while Loop Syntax:-
do {
some code/s;
}while (test expression);

for loop and while loop evaluate loop repetition condition before the first execution of the loop whereas
do .. while evaluates only after the first execution.

Example 1.7: Write a program to add all the numbers entered by the user until it user
enter 0.
/*
Pre-condition: num should be within range of signed integer
Post-condition: Display the addition of all the numbers until user
enter’s zero
*/

#include<stdio.h>
int main()
{
int num,sum=0;
do
{
printf(“Enter a number \n”);
scanf(“%d”,&num);
sum+=num;
}
while(num!=0);
printf(“Sum is:%d”,sum);
return 0;
}

8
2. break and continue
There are two statements built in C, break; and continue; to interrupt the normal flow of control of a
program. Loops perform a set of operation repeatedly until certain condition becomes false but, it is
sometimes desirable to skip some statements inside loop and terminate the loop immediately without
checking the test expression. In such cases, break and continue statements are used.

2.1. break
The break statement in C passes control out of the smallest (loop or switch) statement containing it to the
statement immediately following. “break” statement is used only in switch statement or iteration statement.
It is used to exit a loop before terminating condition occurs (or to exit switch statement when case is done).
When a break statement is encountered inside a loop, the loop is immediately exited and the program
continues with the statement immediately following the loop. When the loops are nested, the break would
only exit the loop containing it. That is the break will exit only a single loop.
The figure below explains working of break in all three types of loop

Example 2.1: Program to find a maximum of n number entered by the user. If user
enter number greater then 100 , end the program.
/*
Pre-condition: lim and num should be in range of signed integer
Post-condition: Display the maximum of all the numbers until user
enter’s num > 100
*/

#include<stdio.h>
int main()
{
int lim ,i ,num ,max=0;
printf(“Enter the limit”)
scanf(“%d”,lim);

9
for(i=1;i<=lim;i++)
{
printf(“Enter the number:”);
scanf(“%d”,&num);
//if entered number is greater than 100 exit loop
if (num > 100)
break;
if(num > max)
max=num;
}
printf(“Maximun is:%d”,max);
return 0;
}

2.2. continue
The continue statement in C is used to terminate the execution of the loop body for that iteration. “continue”
statement is used only in iteration statement. The loop expression is evaluated to see whether another
iteration should be performed. In case of for loop, after continue statement it executes the loop
increment/decrement statement (also called re-initializer). The continue statement causes the loop to
continue with the next iteration after skipping any statements in between. In while and do-while loop,
continue statement causes the control to go directly to the test-condition and then to continue the iteration
process.
The figure below explains working of break in all three types of loop.

10
Example 2.2: Program to find product of 3 numbers and if user enter 0 skip.
/*
Pre-condition: num should be in range of signed integer
Post-condition: Display the product of 3 numbers
*/
#include<stdio.h>
int main()
{
int i,num,mul=1;
for(i=1;i<=3;i++)
{
printf(“Enter the number \n”);
scanf(“%d”,&num);
/*if ‘0’ is entered by user loop is continued to next
iteration*/
if(num==0)
continue;
mul*=num;
}
printf(“Multiplication of 3 numbers is: %d”,mul);
return 0;
}

3. Makefile
The ‘makefile’ utility is used to save your time and effort when dealing with the compilation & execution of
a project which has several programs as part of it. Typically, in real-life projects, there will be dependencies
that exist between different programs inside the project.

For e.g.: program A is dependent on code inside programs B and C whereas program E is only dependent on
code inside program F. All of them reside in the same project. Here, A needs to be recompiled only if B or
C has been edited. Similarly E needs to be recompiled if any modification in F is done.
Syntax of ‘make’ instruction:

target: dependencies
[tab] system command

A ‘makefile’ essentially consists of rules. Each rule begins with a dependency line which defines a target
followed by a colon (‘:’) and optionally an enumeration of components (files or other targets) on which the

11
target depends. The dependency line is arranged so that the target (left hand of the colon) depends on
components (right hand of the colon). It is common to refer to components as prerequisites of the target.

Let us create a very basic program with ‘makefile’

gedit mainprogram.c

Write the following content in ‘mainprogram.c’

#include <stdio.h>

int main()
{
printf("My first makefile project\n");
return(0);
}

Now, let us create the ‘makefile’ itself:

gedit makefile //Here ‘make’ rules are written. Currently it’s empty.

Execute the following command:

make -f makefile //makefile stands for the filename of the ‘makefile’


Here, makefile is the default name. If simply ‘make’ is typed without any filename, it will search for a file
named ‘makefile’ in current directory and run it.

Example 3.1 (makefile)


gedit makefile

Suppose with the help of ‘makefile’ we want to compile a program and generate its executable file.
Content of ‘makefile’

all:
gcc -o mainprogram mainprogram.c

Now execute ‘makefile’ with below command:

make

12
You will see the following message:

gcc -o mainprogram mainprogram.c

Above o/p refers to the list of commands that were executed. Only one command was executed in this case.
Here, the target name is ‘all’. Since there are no dependencies, the command written in the 2 nd line will
always be executed.

If the target is not specified, then the first target in the list will be executed. (Hence it would be prudent to
write the most general case first)

Example 3.2 (makefile): Compile test.c file using ‘makefile’ with rules for assembly
code, object code and executable code.
test: test.o
gcc -o test test.o
@echo executable code generated
test.o: test.s
gcc -c test.s
@echo object code generated
test.s: test.c
gcc -S test.c
@echo assembly code generated
clean:
rm test test.o test.s
@echo clean complete

Executing make command

make

Output of make command

gcc -S test.c
assembly code generated
gcc -c test.s
object code generated
gcc -o test test.o

Executing make clean command

make clean

13
Output of make clean command

rm test test.o test.s


clean complete

NOTE: Remember to put TAB before writing the system command in makefile

4. GDB: The GNU Project Debugger

GDB, the GNU Project debugger, allows you to see what is going on ‘inside’ a program while it executes --
or what a program was doing at the moment it crashed.

GDB can do four main kinds of things (plus other things in support of these) to help you catch bugs:
 Start your program, specifying anything that might affect its behavior.
 Make your program stop on specified conditions.
 Examine what happened, when your program stopped.
 Change things in your program, so you can experiment with correcting the effects of one bug
and go on to learn about another.

Next step is to make sure that you have GDB installed on your system. If it’s not, you can easily install the
‘gdb’ using the following command:

sudo apt-get install gdb

Compiling:
To prepare a program for debugging with gdb, compile it with the ‘-g’ flag.

gcc -g -o [executable name] [file name]

Invoking and Quitting GDB:


To start ‘gdb’
gcc [executable name]
To exit from gdb, type ‘quit’ or ‘q’ in the (gdb) prompt.

14
Write a sample C program with errors for debugging purpose

To learn C program debugging, let us create the following C program that calculates and prints the factorial
of a number. However this C program contains some errors in it for our debugging purpose.

gedit factorial.c

#include<stdio.h>
int main()
{
int i, num, j;
printf ("Enter the number: ");
scanf ("%d", &num );

for (i=1; i<num; i++)


j=j*i;

printf("The factorial of %d is %d\n",num,j);


}

Program compilation

gcc -o factorial factorial.c

Program execution

./factorial

Program Output

Enter the number: 3


The factorial of 3 is 65534

The above O/P is wrong. Let us debug the above program using different commands in gdb.
Step 1: Compile the C program with debugging option -g
Again compile C program with -g option. This allows the compiler to collect the debugging information.

gcc -g -o factorial factorial.c

Note: The above command creates factorial file which will be used for debugging as shown below.

15
Step 2: Launch gdb
Launch the C debugger (gdb) as shown below:

gdb factorial

Step 3: Set up a break point inside C program


Syntax:
break line_number

Other Syntax:
 break [file_name]:line_number
 break [file_name]:func_name

Break point is set in the C program, where you suspect errors. While executing the program, the debugger
will stop at the break point, and gives you the prompt to debug.
So before executing the program, let us place the following break point in our program.

break 10
Breakpoint 1 at 0x804846f: file factorial.c, line 10.

Step 4: Execute the C program in gdb debugger


Syntax:
run [args]

Start program execution by using ‘run’ command in the gdb debugger. You can also give command line
arguments to the program via run [args]. The example program we used here does not require any command
line arguments so let us give ‘run’, and start the program execution.

run

Once you start the execution of your C program, it would execute until the first break point (which we have
set earlier), and give you the prompt for debugging.

Breakpoint 1, main () at factorial.c:10


10 j=j*i;

16
Step 5: Printing the variable values inside gdb debugger
Syntax: print {variable}

(gdb) p i // print i
$1 = 1
(gdb) p j // print j
$2 = 32767
(gdb) p num // print num
$3 = 3
(gdb)

Since in factorial.c we didn’t explicitly initialized the variable j and in gdb its value is shown as 32767
(garbage value), thus resulting in wrong factorial. Fix this issue by initializing variable j as 1, compile the C
program and execute it again. Even after this fix there are some problem in the factorial.c program, as it still
gives wrong factorial value. Try to find them using gdb and fix them.

Step 6: gdb commands: continue, stepping over and in


There are three kind of gdb operations you can choose when the program stops at a break point. They are
continuing until the next break point, stepping in, or stepping over the next program lines.
 c or continue: Debugger will continue executing until the next break point.
 n or next: Debugger will execute the next line as single instruction.
 s or step: Same as next, but does not treats function as a single instruction, instead goes into
the function and executes it line by line.

In factorial.c program, by continuing or stepping through you could have found that one more problem is
because we have used the < in the ‘for loop’ condition checking. So changing that from < to <= will solve
one more issue.
gdb command shortcuts
Use following shortcuts for most of the frequent gdb operations.
 l – list
 p – print
 c – continue
 s – step
 ENTER: pressing enter key would execute the previously executed command again.

17
5. Practice Problems
Note: Practice Pre-condition and Post-condition for the below programs.

5.1. Get a stream of text from user , replace the vowels in it with '_' (underscore) and
print it.
#include "stdio.h"
#include "stdlib.h"
int main()
{
char str[100];
char vowel_list[ ] = {'a','e','i','o','u'};
printf("Enter a stream of text : \n");
fgets (str, 100, stdin);
// Notice the use of fgets instead of scanf
int i = 0;
while(str[i] != '\0')
{
int j;
for(j=0;j<5;j++)
{
if(str[i] == vowel_list[j])
{
str[i]='_';
break;
}
}
i++;
}
printf("After formatting: \n");
printf("%s",str);
return 0;
}

5.2. Generate Fibonacci numbers for range 10, starting from a number specified by the
user. Find corresponding Lucas numbers from the generated Fibonacci numbers.
Lucas num, L(n) = F(n-1) + F(n+1)
#include "stdio.h"
#include "stdlib.h"
int main()
{
int n, first = 0, second = 1, next, c;
int fibo[10];

18
printf("Enter the number of terms\n");
scanf("%d",&n);
printf("First %d terms of Fibonacci series are :-\n",n);
for ( c = 0 ; c < n ; c++ )
{
if ( c <= 1 )
next = c;
else
{
next = first + second;
first = second;
second = next;
}
fibo[c] = next;
}
printf("Lucas :\n");
for(c=1;c<8;c++)
printf("%d ",fibo[c-1] + fibo[c+1]);
return 0;
}

5.3. Find the sum of the following series: (Take n from the User)

(A) 1+ (2/2!) + (3/3!) + …… (n/n!).


#include "stdio.h"
#include "stdlib.h"
int main()
{
int limit;
int factorial;
float sum = 0;
printf("Enter limit: ");
scanf("%d",&limit);
int i,j;
for(j=1;j<limit;j++)
{
factorial = 1;
for(i=1;i<=j;i++)
factorial*=i;
sum+=(float)j/factorial;
}
printf("\nSum of series: %f\n",sum);
return 0;
}

19
(B) y=1/2! + 2/3! + 3/4! + …..+n/(n+1)!
#include "stdio.h"
#include "stdlib.h"
int main()
{
int limit;
int factorial;
float sum = 0;
printf("Enter limit: ");
scanf("%d",&limit);
int i,j;
for(j=1;j<limit;j++)
{
factorial = 1;
for(i=1;i<=j+1;i++)
factorial*=i;
sum+=(float)j/factorial;
}
printf("\nSum of series: %f\n",sum);
return 0;
}

(C) ∑x=1 to n x!
#include "stdio.h"
#include "stdlib.h"
int main()
{
int limit;
int factorial;
float sum = 0;
printf("Enter limit: ");
scanf("%d",&limit);
int i,j;
for(j=1;j<limit;j++)
{
factorial = 1;
for(i=1;i<=j;i++)
factorial*=i;
sum+=(float)j/factorial;
}
printf("\nSum of series: %f\n",sum);
return 0;
}

20
5.4. Find if the given number is Armstrong number or not.
#include "stdio.h"
#include "stdlib.h"
int main()
{
int num, sum = 0, temp, rem;
printf("Enter an integer\n");
scanf("%d",&num);
temp = num;
while( temp != 0 )
{
rem = temp%10;
sum = sum + rem*rem*rem;
temp = temp/10;
}
if ( num == sum )
printf("%d is an armstrong number.\n",num);
else
printf("%d is not an armstrong number.\n",num);
return 0;
}

5.5. Get 10 numbers as input from the user and find the sum of positive numbers.
#include “stdio.h”
#include "stdlib.h"
int main()
{
int i,num,sum=0;
printf("Enter 10 numbers:\n");
for(i=0;i<10;i++)
{
printf("Num 0%d: ",i);
scanf("%d",&num);
if(num>0)
sum+=num;
else
continue;
}
printf("\nSum of +ve numbers: %d\n",sum);
return 0;
}

21
6. Additional Exercises
Write programs using (i) for loop only, (ii) while loop only (iii) any combination of these two to solve the
following

1. 1 – 3 + 5 – 7 + 9 ……. N (Take N from the User)

2. WAP to generate following pattern.


1
1 2 1
1 2 3 2 1

Note (for this week only):


1. No compulsory question.
2. But ... in lab you have to solve 2 questions. 

22