ITP Week 3
ITP Week 3
Statement: A statement is an expression terminated by a semicolon. A program consists of many such statements.
A statement needs NOT to be an entire line in a program. Whenever a C compiler sees a semicolon (;) in a line, which is not
in a string or in a comment, it considers it as the end of the current statement. Thus, there can be more than one statement
in a single line.
For example:
For the C compiler, there are in total four statements in the above snippet, which are listed as follows:
Statement 1: c = a + b;
Statement 2: i++;
Statement 4: 25;
In fact, ‘25;’ is also a statement. It is an expression whose value is True. Since we are not assigning it to a variable or not
doing anything with it, this expression is just ignored by the compiler.
A block is also called a compound statement since it consists of one or many statements combined as a single unit.
For example:
Blocks can be used in scenarios where we want to make a decision in a program, and based on the outcome of the decision,
whether True or False, we want to execute a particular block.
Conditional Statements in C: The If Statement
The if statement is one of the simplest conditional statements in C, which helps us make a decision and choose a
corresponding path of action. Branching in C language is primarily done using the if statement.
Syntax:
Condition is an expression in C that is either True or False or it evaluates to either True or False. A Conditional expression
can be written as:
• True or False
• Statement using relational operators such as ==, >= , <=, !=, <, and > Example:
o (x == 0)
• Non-zero or true
• Zero or false
Examples:
Syntax of an if statement:
The statement gets executed only if the condition evaluates to true or non-zero.
The block of statements gets executed only if the condition evaluates to true or non-zero.
Flowchart of an if statement:
Figure 2: A C program to check if the entered number is positive, using a conditional if statement.
The program in Figure 2 is to check if an entered number is positive. It gets the number in variable ‘a’ from the user and
checks it in a condition in line 6 using an if statement. The conditional statement is ‘(a > 0)’. Whether ‘a’ is greater than 0 or
not. The value of this conditional statement is either True, when ‘a’ is greater than 0, and it is False when ‘a’ is not greater
than 0. This value of the conditional statement decides whether the if statement block will be executed or skipped. The
statements in the block (lines 7 to 9) are executed if the condition is true, otherwise the statements are ignored or skipped.
The program in Figure 1 thus runs differently depending on the entered number. Following are some example cases:
1. If the number is 23 Output: Enter a number 23 Number is positive Rest of the program Program execution:
Variable is initialized at line 3 and the user is prompted to ‘Enter a number’ at line 4. The program waits for the user
to type a number and press Enter. When the user enters 23, at line 5, variable ‘a’ is assigned a new value 25 using
scanf(). The ‘scanf’ is a standard input function provided by the C programming language to take input from the
user and store it at a location corresponding to the address of a variable. Now, with the value stored at the address
of ‘a’ as 23 (that is, a is equal to 23), at line 6, the value of the conditional statement (a > 0) becomes True, since 23
is greater than 0. Thus, program flow enters the block at line 7 and executes the statements sequentially. In this
program, there is only one statement in the block, line 8. After executing the statement in the block and printing
‘Number is positive’, the program flow continues sequentially with the next statements, that is, lines 10 and 11. At
line 10, the program prints ‘Rest of the program’ in a new line and the program exits and stops the execution at line
11.
2. If the number is -20 Output: Enter a number -20 Rest of the program If the user enters the number ‘-20’, the value
of the conditional statement (a > 0) in line 6 becomes ‘False’ since the value stored at the address of ‘a’ is -20 and -
20 is NOT greater than 0. Thus, the program control entirely skips the if statement block (between curly braces,
line 8) and directly executes the next statement in the flow, that is, line 10. Thus, the program prints only ‘Rest of
the program’.
3. If the number is 0 Output: Enter a number 0 Rest of the program Similar to Case II, the input is 0, which is NOT
greater than 0. Hence, the entire if statement block was skipped to print only ‘Rest of the program’.
The If-Else Statement
The if statement without else executes a block only if the condition is true. But the program does nothing if the condition
is false, and the rest of the program is executed.
When we also want to define a statement or block of statements, which should be executed when the condition is false, we
use the optional else clause. The if-else statement executes a block if the condition is true, otherwise executes another
block if the condition is false.
Syntax:
If the condition is true, the program executes only statements in ‘block1’ and not ‘block2’. Otherwise, if the condition is
false, it executes only ‘block2’. The execution flow of ‘rest of the program’ is independent of the if-else statement, and it is
executed as it is in either case.
Nested if statement: This is an if statement inside another if statement when there are no else clauses. This occurs in the
following scenarios:
Syntax:
Nested if-else statement: An if-else statement inside the if block or else block of another if-else statement is called a
nested if-else statement. Please note that there can always be an if without an else clause.
Syntax:
Similarly, we can have any number of such nestings, although it may make the code appear bulky.
Let us consider a C code snippet of a program to find the largest of three numbers in Figure 3. Let us assume the three
numbers are unique. The program in line 5 stores three integers provided by the user in variables a, b, and c.
First, we check if a is greater than b in line 6. If a is greater than b, this means b is not the largest; either a or c is the largest
number. Whichever of a or c is greater, that number is the largest. To compare between a and c, we put a nested if-else
statement in the if block that is lines 8–11. If now, a is greater than c, this implies a is the largest, thus, print “A”. At line 9,
condition 1 (is a > b?) and condition 2 (is a > c?) both are True. Otherwise, if a is not greater than c, that is, c is greater than
a, then print “C” in line 11 since C is the largest.
If our first condition, if a is greater than b, is False, then else block is executed, that is, in lines 14–19. Here, b is greater
than a, thus, either b or c is the largest. So, we put another nested if-else statement (lines 15–18) but inside the else block
this time, to compare between b or c. If b is greater than c, in line 16, we print “B” as the largest number since b is greater
than both a and c. Otherwise, if b is lesser than c, this implies c is the largest since c has already been established as a
greater number than a. Thus, we print “C” in the else statement of the nested if-else statement in line 18.
Figure 3: A C program to find the largest of three numbers.
Program control in line 6 checks is a greater than b? False! 2 is not greater than 8. Thus, control goes directly to the else
part in line 13. Now inside else, it checks is b greater than c? in line 15. Yes! 8 is greater than 4. Thus, the program
successfully prints out B as the largest number. And after line 16, the control goes to line 20 to the “End of the program”.
Output:
Please note that with such usage of nested if-else statements, we ensured that exactly one of the four statements/blocks
would be executed out of line 9 or 11 or 16 or 18. Thus, in such scenarios, branching decision-making or nested if-else
statements can be used.
A switch statement is a compact way of writing a multiway decision that tests whether an expression matches one of several
constant integer values and branches accordingly.
Syntax
A switch case statement is used when we want to execute a certain matching statement or block of statements for a
particular integer value, which the expression evaluates to.
• The ‘case’ keyword is used to match the value of the expression to a statement or block of statement. const-expr
is a constant integral value (not a keyword) that accompanies ‘case’ keyword.
• The ‘break’ keyword is used to stop the execution inside the switch statement block. Once statements inside the
switch block start getting executed pertaining to a case match until a ‘break’ is found, the execution will not stop,
and all the statements will be executed irrespective of their cases. If ‘break’ is not used, the flow would fall through
the next case and execute the statements until the switch statement naturally terminates or a ‘break’ is found.
• The ‘default’ keyword is used to specify statement(s) that need to be executed when there is no case match. There
can only be a limited number of cases that can be written in a switch statement. To handle any other value, which
is not already specified in a case, the ‘default’ keyword is used.
If expr evaluates to const-expr1, statements1 are executed and the ‘break’ is encountered and thus the control comes out
of the switch statement. Otherwise, if expr evaluates to const-expr2, statements2 are executed. If expression evaluates to
a value, which is not specified in any case, then default statements are executed.
Examples
In Figure 4, the integer value of expression ‘language’ is 10. So, the execution flow will directly jump to case 10. As there is
no case 10 (only case 1, case 2, and case 3 are present), the flow goes to the ‘default’ and prints “Other programming
language” and terminates. Thus, the output is:
Figure 5: A C snippet to match a ‘number’ using a switch case statement.
The code snippet in Figure 5 is a very unusual written switch statement. There are no statements as well as no breaks in
cases 1, 2, 4, and 5. Please note that any case can have 0 or more statements or it may or may not have a ‘break’ statement.
When there is no break, the execution flow keeps on falling through the next cases.
The value of the expression number is 5, so it will directly jump to case 5. Since no statements are there in case 5 and, also,
no break is present, the flow falls through the next case, i.e., case 6, and prints “Four, Five, or Six.” Then, it sees a break in
line 12 and gets out of the statement to termination.
Reading Summary
PracticeLab1_Question1
a) Write a C program that takes three integers as input from the user. Print True when all the three integers
are equal, and False otherwise. Do not use switch statements or loops in your program.
b) Now, modify the above program to print True when none of the three integers entered by the user is
equal to another, and False otherwise.
PracticeLab1_Question2
Write a C program that accepts as inputs the marks obtained by a student in a particular exam and then
prints the description of marks obtained based on the following rules.
>=90 - Extraordinary
>=65 - Good
>=50 - Average
else - Fail
It is important to note that the program written in the file has some compile time and runtime errors. You
need to resolve them so that the program works correctly. You can use the below test cases for your
reference.
Compilation/Execution Steps:
• Open a new terminal by clicking on the menu bar and selecting ->Terminal ->New Terminal
Set the path in the terminal: Type the below command and click Enter. (Refer to the md file in the lab for
more details).
Run the C file using the following command in the terminal once the a.out file is created:
./a.out
Note: Every time you make a change in your program or the filename.c file, it is required to compile the
program again using "gcc filename.c" to reflect that change in your a.out. Otherwise, you will be accessing
an a.out file of the previous version of your code and changes you made will not be reflected in the output.
Reading: Loops and While Loop
Reading Objective:
This reading introduces you to looping. You will learn how repetitive and iterative tasks can be achieved using a while loop.
Loops in C:
Looping is used when we want to repeatedly execute a particular statement or a block of statements a number of times to
solve a problem, which is repetitive in nature. Loops are also called repetitive constructs.
• Sum all the digits on a positive number (the number can have any number of digits)
In the above problems, loops are very effective in writing the program.
If a loop doesn’t terminate, it will keep on executing (goes into an infinite loop) using resources such as RAM, CPU, storage,
etc. This may result in a runtime error. A loop, thus, should have a finite number of steps.
For example, in Figure 1, suppose we have a key variable x = 25. In step 2, we check the control expression in line 3 if x
is less than 50. If it is true, then we print the current value of x, incrementing the key variable, x by 1. And we go back to the
beginning of the loop and reevaluate the control expression since we have updated the key variable. Repeat this step until
the condition turns false. If it turns false, go to step 3.
Step 2 is thus a looping step. The conditional statement checks a key variable, and some statements in lines 5, 6, and 7 are
executed repeatedly in the loop until the condition remains true. These statements constitute the body of the loop. The
loop will terminate since the statements in the loop also change the key variable, ‘x,’ increasing it to ultimately make the
condition false.
While Loop in C
‘While’ loops are simple loops that repeat a particular statement or block of statements as long as the control expression
evaluates to True. The structure is similar to the general loop above. There is a key variable, control expression involving
the key variable and body of the loop, which is executed while the expression remains True.
Syntax
These statements are executed until exp (a control expression) remains true. Following area few examples of Control
Expressions:
• while (answer == ‘Y’): remain in a loop until the value of the answer variable is true.
• while (count): a variable can also be an expression. Here if the count is an integer, if it is non-zero, a loop is
executed, and if it is zero, the loop is terminated.
• while (5): 5 is always a non-zero; thus, it is always True. Thus, there will be an infinite loop unless there is a
mechanism to come out of the loop, which we will see later in this reading.
• while (base>0 && power>=0): relational sub-expressions joined using a logical AND operator to form a
relational expression.
Example:
Consider a C program snippet in Figure 2 to print numbers till 3 using a while loop construct. In line 1, variable var is
initialized with value 1. This will act as the key variable in our loop. Line 2 starts the while loop, which should run the loop
body until ‘var’ remains less than or equal to 3. The loop body is the block of the statement(s) in curly braces in line 4.
The execution flow enters the loop with the value of var as 1. Since 1 is less than or equal to 3, the control expression is true,
and line 4 is executed. It prints the current value of var, that is, 1, and after executing line 4, the value of var is incremented
by 1 (since we have written var++) to become 2. The control flow loops back to line 2 to again compare the value of var with
3. Since it is 2 that is still less than or equal to 3, the body is executed once again. The current value of the variable is printed,
that is, 2, and its value is incremented by 1 to 3. Again, the condition is checked, which is true since 3 is less than or equal
to 3, and line 4 is executed one last time, printing the value of var, 3, and incrementing it to 4. When the flow loops back to
line 2 to check the condition, it now evaluates to false since 4 is not less than or equal to 3, and the loop terminates.
A Null Body
There is a difference between while (num > 0) and while (num > 0);
But a while loop in C can also have a null body. As we know, any statement in C ends with a semicolon ( ; ). Thus, a
standalone semicolon represents an empty statement. If instead of any statement or block of statements in the body of
the ‘while’ loop, there is just a semicolon, it represents an empty body.
Please note that such empty loops are generally unwanted since they can be infinite. Do NOT put a semicolon after
‘while()’, unless it is intentionally required.
The loop will still run, use up, and waste computer resources, but in each iteration, it does nothing. And if the loop is started,
it will most probably never terminate since the condition for which the loop started remains true, and the key variable is
not modified in any iteration.
To write a program to calculate the sum of the first N positive integers, you may define the value of N using a pre-processor
directive.
Refer to the C program in Figure 3. In line 6, a while loop is placed, which is used to find the sum of N numbers and store it
in the variable ‘sum’, which is initially set to 0. We are counting from 1 to number N using the variable ‘index’ and adding
the value of the current number (index) at each step, updating the new sum in variable ‘sum’. In each step, the control
variable, index, is incremented by 1, and the loop will terminate when the index becomes greater than N. Thus, after N
steps,the loop terminates with the final and desired sum.
or
Line 11 is out of the while loop and will be executed just after the loop breaks. The loop is terminated when the variable
‘index’ becomes just greater than N, that is, N+1. Hence, the output of the program is:
Let us take a look at the value of variables in each iteration of the while loop in this program:
But what if we wanted the sum of the first 100 positive integers instead of 10? or 50? In an already written program, you can
simply change the value of ‘N’ in line 2 and run the program to get quick results. Following are a few examples with different
values of ‘N’:
Let us write a C program to ensure that the user enters a positive integer. That is:
So, the program should keep on asking the user to input a positive number until the user inputs such a number. This
implies the usage of a loop in code. Now, we will use a while loop, as seen in the program in Figure 4.
The user enters a number for the first time in line 6. It is checked in line 7 if the number is positive before entering the loop.
If it is positive, do not enter the loop and print its square in line 12. But if it is a negative number, enter the loop, and ask for
the number again. Since the number itself is in the condition as a key variable, the loop will keep on asking for input (using
scanf) until a positive number is seen. And whenever a positive number is entered, the loop terminates, and the program
prints its square.
Figure 4: A C program to print the square of an input number, ensuring the user enters a positive number
‘While’ loop is very important in this scenario since we don’t know how many times the loop may run. Depending on the
user’s input, it may run 0 or 100, or countless times.
A while loop within a while loop is called a nested while loop. Following is the simplest syntax of a nested while loop:
Refer to the program in Figure 5. There are two loops, one outer and one inner. The outer loop in line 6 is to iterate over N
students, and for each student, there is the inner loop in line 11 to iterate over their subjects. Thus, the inner loop will run
3 times corresponding to the three subjects. The key variables are incremented to make sure the loops do not run infinitely.
For the outer loop, the key variable ‘index’ is incremented in line 21, which is the last line of the body of the outer ‘while’.
And for the inner loop ‘j’ is incremented in line 16, which is the last line of the body of the inner while.
Figure 5: A C program to compute the average marks of each student using a Nested While Loop
We have seen a loop running for N iterations. But what if we decide in one of those iterations that we want to skip that
iteration or come out of the loop entirely? These are made possible with the help of continue and break statements.
• break: It forces control to come out of the immediately enclosing loop. We have already seen that the break
statement is used to come out of the Switch statement as well.
• continue: It skips the subsequent statements in the body of the immediately enclosing loop and proceeds to its
next iteration.
Example
Let us consider an example of writing a program to calculate the sum of positive numbers entered by the user such that:
• When a negative value is entered, ignore it; prompt the user to enter a positive integer.
Refer to the program code in Figure 6 that solves this problem and uses break and continue statements.
In line 6, we start an infinite loop since 1 means always true. But we don’t want an infinite loop; thus, we will use ‘break’ to
come out of the loop when 0 is entered. Thus, the program terminates the loop, prints the sum in line 16, and immediately
stops as soon as the user enters 0.
Figure 6: A C program to find the sum of all input positive numbers until 0 is entered
If a user enters any negative number, the condition in line 10 becomes true, and the ‘continue’ statement is executed. The
continue statement skips the rest of the loop in that iteration. Hence, lines 12 to 14 are not executed (and the sum is not
updated) when the user enters a negative number.
The user entered only three positive numbers: 1, 2, and 3, and the program printed the sum as 6, ignoring/skipping the
iterations with negative numbers and terminating as soon as the user entered 0.
Reading Summary
• The power of a while loop is that it can be used when the number of iterations is not known
1. Please find the output of a C program intended to print a pattern using integers. The pattern has N
rows, where N is input from the user. The first row begins with the number N and prints all numbers
from N to 1 in decreasing order. The second row starts with the number N-1, and so on. The last row
has the single number 1. The following is the inverted right triangle pattern for N=5:
The program provided in the file has a semantic error, and it is printing the following pattern for N = 5:
Semantic error is different from syntactic error. It means the C code will successfully compile without error
but will not produce the intended results. Modify the provided code to rectify the logical error.
Use a While loop to write C programs that enable the user to enter a number and keep entering till
Write a program to verify the Collatz conjecture. Here, the Collatz conjecture is asking whether repeating
two simple arithmetic operations will eventually transform every positive integer into 1. Consider the
following two operations:
f(odd) = 3*odd + 1
f(even) = even/2
With these two transformations, any number should ultimately reach 1. For example, taking 10 will generate
the following series till 1:
10 5 16 8 4 2 1
This is just a conjecture and not a theorem. You need to verify if all the numbers from 1 to 1000000 follow
this conjecture. Write a program that loops through numbers from 1 to N, and then for each number, it loops
with either of the two operations until number 1 is seen.
If the loop runs infinitely, it means that the conjecture is not holding correctly for that number yet.
[Hint: Explore long long or unsigned long long data types for variable declaration.]
PracticeLab 2_Question_4
a) Complete the C program using a switch case to print the month's name for a corresponding integer the
user enters. The program has to ensure that the user enters integers only from 1 to 12. Consider the
following sample inputs and outputs:
Input - 13
Input - (-1)
Input - 3 Input - 11 Input - 2
Input - 16
Output - March Output - November Output - February
Input - 2
Output - February
b) Modify the above program to print all the months till December, starting from the month corresponding
to the integer input.
Testcase
Input - 9
Output - September
October
November
December
Reading: For Loop
Reading Objective:
In this reading, you will be introduced to the for loop in C and the various parts of a for loop. You will learn the ways to use
a for loop and how it is different from a while loop.
For loop is a powerful iterative construct defined in C. The structure of a for loop is as follows:
1. Initialization
b. The initialization part of the for loop is executed exactly once, and it is when the for loop starts executing
for the first time.
c. Usually, it is used to initialize variables meant to count the number of iterations for which the for loop has
been executed.
d. It is worth noting that any variable declared inside the initialization part (or the body) of the for loop will
be deleted when the for loop exits (You will learn more about why this happens in Week 4, Lesson 2). Hence,
do not declare the variables that store the result of your computation inside the initialization of the for
loop.
2. Condition
b. The condition part of the for loop is either blank or contains a Boolean expression. This expression is
evaluated after every iteration of the loop. If it is True, the loop is executed once again, and if it is False,
then the loop is terminated.
c. When the condition is left blank, the compiler interprets it as True, and thus, the loop is executed infinitely.
d. We can use logical or relational operators to make the condition part of the for loop.
3. Increment/Decrement
b. It is executed after every iteration of the for loop, i.e., if the condition is True, the body of the loop is
executed, and after that, this variable’s value is incremented/decremented, and it is this new value used
for the next check with the condition. Usually, it is used to increment/decrement the value of the counter
variable.
b. This is the single statement or the block of statements that comes just after the for loop statement and is
executed repeatedly by the for loop as long as the condition holds true.
The flow of execution of the for loop can be understood very easily from the flow chart in Fig 2.
Firstly, the initialization part of the for loop is executed(usually initializing value to a variable). Then the condition is
evaluated to be True or False. If the condition is False, the loop is terminated. If the condition is True, then the body of the
loop is executed, and then the increment/decrement statement is executed. Then the condition is evaluated again, and
this continues until the condition finally evaluates to False.
Let’s see how the execution of the above program happens step by step.
1. Firstly, the variable i is declared in line 3, and its value is some garbage value.
2. Then the initialization statement in the for loop is executed, and the value of i becomes 1.
3. The condition statement is executed, i<=3 is checked, which evaluates to True because i = 1.
6. The condition statement is executed, i<=3 is checked, which evaluates to True because i = 2.
9. The condition statement is executed, i<=3 is checked, which evaluates to True because i = 3
11. The increment statement is executed, i++, and the value of i becomes 4.
12. Condition statement is executed, i<=3 is checked, which evaluates to False because i = 4
13. The loop terminates, and return 0 is executed, which terminates the entire program.
In the above example, there is only one statement inside the for loop, so we can omit the use of curly brackets around that
statement and rewrite the above code as shown below.
However, if we happen to mistakenly add the return 0 statement inside the for loop, as shown below, then the execution
will be different, as explained below.
1. Firstly, the variable i is declared in line 3, and its value is some garbage value.
2. Then the initialization statement in the for loop is executed, and the value of i becomes 1.
3. The condition statement is executed, i<=3 is checked, which evaluates to True because i = 1.
There are some variations that we can do in a for loop. These are discussed below:
1. We can change the increment for the counter to any value in the increment statement. In fact, we can declare/initialize
multiple variables inside the for loop and increment/decrement multiple variables inside the increment section of the for
loop.
2. Instead of declaring the counter variable inside the for loop, we can declare it outside the loop also as shown below.
When the variable is declared outside the loop, the variable still exists after the termination of the loop, whereas if we had
declared the variable inside the initialization statement of the for loop, then the variable would have been deleted after the
termination of the loop.
3. Instead of incrementing the counter in the increment/decrement part of the for loop, we can also increment/decrement
the counter variable inside the body of the for loop.
4. We can omit either or all the 3 parts of the for loop, i.e., initialization, condition, and increment/decrement of the for
loop. For example, the below code executes an infinite loop.
5. We can also put an empty statement as the only statement in the body of the for loop. For example, the below code
consists of an empty statement in the body of the loop.
Examples of For Loops
In the above program, the variable i is used for iterating over all natural numbers, the variable sum is used to store the sum
of odd numbers, and the counter variable count is used to store how many odd numbers have already been visited. We
make the loop execute for the value of i = 1, then 2, then 3, then 4, and so on. In case i is even, we skip that iteration of the
loop using a continue statement. Else, we add i to the sum variable and increment the count variable. When the count
becomes equal to N, we break out of the loop.
Note: When the continue statement is executed inside a for loop, the control resumes execution from the
increment/decrement step of the for loop. Break statement in for loop works similarly to break statement in while loop,
both terminate the loop and resume program execution from the next statement after the loop.
Example 2: Write a C program using a for loop to print the sum of all numbers from 1 to 1000 (including both 1
and 1000), which are multiples of 3 but not multiples of 4.
In the above program, we iterate over all the numbers from 1 to 1000. For each number, we check whether it is a multiple
of 3, and not a multiple of 4. If yes, it is added to the final sum. At last, we print the value of the sum.
Example 3: Write a C program to print the following pattern using for loops:
* *
* * *
* * * *
* * * * *
Take the value of N (the number of rows in the pattern) as input from the user.
In the above program, we take input from the user in a variable n. Then we declare two variables, i_row and i_col, to store
the index of the current row and column in which we are printing the pattern. We iterate over the number of rows using the
i_row variable. In each row, we print stars equal to the index of the row using the i_col variable, and then we print a new
line character. Note that the printf statement in line 9 is the only statement in the body of the for loop in line 8, and the for
loop in line 7 contains lines 8–10 in its body. The above code is an example of a nested for loop. The key takeaway should
be that the outer loop gets initialized first, then the condition is checked, and if it is True, program control goes into the
body of the loop. In this case, the body has another inner for loop, which again does its own initialization and checks its
condition. If the condition is True, it keeps executing the body of the inner loop as long as its condition remains True. Once
it becomes False, it comes out of the inner for loop, and now only the increment happens to the outer for loop, again checks
the condition and gives control to the inner for loop, and this continues until the outer for loop condition becomes false.
for loop
while loop
for loop
Figures 3 and 4 show how easy it is to write a for loop as a while loop, and a while loop as a for loop. But still, the structure
of both the loops is such that it is preferred to use the for loop when we already know the number of iterations for which
the loop will be executed, and the while loop is preferred when we do not have a fixed number of iterations of the loop, we
only have a termination condition. For example, if we want to keep asking the user to enter an integer till he/she enters a
valid integer, we have a termination condition, i.e., the user enters a valid integer, but there is no fixed number of iterations
of the loop, so we use a while loop. Whereas, to find the sum of the first N odd numbers, we know the number of iterations
of the loop, so we use a for loop.
Try to execute all the programs discussed in this reading in Coursera labs. You will learn best when you try to write and
execute these programs yourself.
Reading Summary:
• How to choose between a while and for loop for a given problem
C Programming Practice Lab3
Assignment Questions:
1. Compile a C program using the file included along with this question. The file contains a C program
that is intended to take a natural number as input from the user and print the sum of squares from
1 to N.
Please note that upon compiling this program, the compiler shows some errors. You need to resolve the
errors and successfully compile the program. You can check whether the program has successfully
compiled by testing it over the following test cases.
The C program file attached with this question compiles successfully. Upon execution, the program enables
the user to enter a positive number and then prints some numbers before terminating.
Go through the program and find out the functionality of the above program. Pay special attention to the
use of continue and break statements inside the for loop and explore the use of these statements.
1. The C program in the file attached to this question intends to print an alternating pattern of 1’s and
0’s, based on the number of rows entered by the user as follows:
101010……
010101……
…………….
…………….
where the number entered by the user is the number of rows and columns to be printed in the pattern. Fill
in the blanks A, B, C, and D with appropriate expressions so that the program works correctly. Consider the
following test cases for your reference.
Testcase 1 Testcase 2
Input - 5
Input - 2
Output - 10101
Output - 10
01010
01
10101
Testcase 1 Testcase 2
01010
10101
2. Now, change what you entered in the blanks A, B, C, and D, so that the program prints a triangle of
alternating 0’s and 1’s instead of a square. Consider the following test cases for your reference.
Testcase 1 Testcase 2
Input - 5
Input - 3 Output -1
Output - 1 01
01 101
101 0101
10101
Write a C program that takes two positive numbers, a and b, as input from the user. If either of the numbers
is less than or equal to zero, then terminate the program there itself. Use a for loop to print the value of a
raised to the power b, that is, abab.
Below are some test cases for your reference. You can use the C program file attached with this question as
a template. The variables in this program are declared with unsigned long long int datatype because when
performing power operation, the result can be more than the maximum limit of value that an int variable
can store in C.
if(a==b){
if(a==c){
printf("True\n");
}
else{
printf("False\n");
}
}
else{
printf("False\n");
}
/*
//alternate soln
if(a==b && a==c){
printf("True\n");
}
else{
printf("False\n");
}
*/
return 0;
}
PracticeLab1_Question1(b)
#include<stdio.h>
int main(){
int a, b, c;
printf("Enter three integers a, b, and c - ");
scanf(" %d %d %d",&a,&b,&c);
}
else{
printf("False\n");
}
/*
//alternate soln
if(a==b)
printf("False\n");
if(a==c)
printf("False\n");
if(b==c)
printf("False\n");
else
printf("True\n");
*/
return 0;
}
PracticeLab1_Question2
#include<stdio.h>
int main(){
int marks;
printf("Please enter your marks: ");
if(marks >=90)
printf("Your grade is Extraordinary");
int N;
printf("Please Enter a number greater than 0: ");
scanf(" %d", &N);
while( N<=0)
{
printf("Please Enter a number greater than 0: ");
scanf(" %d", &N);
}
printf("Ok, number entered is greater than 0");
printf("Please Enter a number greater than 20 AND less than 100: ");
scanf(" %d", &N);
while( N<=20 || N>=100)
{
printf("Please Enter a number greater than 20 AND less than 100:
");
return 0;
}
Practice Lab 2_Question 3
#include<stdio.h>
int main(){
j = i;
// printf("%llu ", j); //uncomment if you want to see the series
// loop until the current number becomes 1
while(j!=1)
{
if(j%2 == 0){
j/=2;
}
else{
j = 3*j +1;
}
int main(){
int month_number; // 1 to 12
switch(month_number){ case 1:
printf("January"); break;
return 0;
/*
input: 9
output: September
October
November
December
*/
int main(){
int month_number; // 1 to 12
switch(month_number){
case 1: printf("January\n");
case 2: printf("February\n");
case 3: printf("March\n");
case 4: printf("April\n");
case 5: printf("May\n");
case 6: printf("June\n");
case 7: printf("July\n");
case 8: printf("August\n");
case 9: printf("September\n");
return 0;
int main(){
int N;
int sum = 0;
sum += i*i;
}
printf("Sum of squares from 1 to %d is %d\n", N, sum);
return 0;
int N;
printf("Enter the value of N - ");
scanf(" %d", &N);
int sum = 0;
return 0;
}
Practice Lab 3_Question 2
The program prompt asks the user to enter a positive number (although it doesn’t throw an error
if zero or a negative number is entered). Then if the number is greater than or equal to 79, it
simply exits. If number entered is less than 79 (even a negative number), the program prints all
the multiples of 5 in the range (start,79). ‘Start’ will be printed only if it is a multiple of 5
otherwise the next immediate multiple of 5 coming after 5 will be printed, similarly at the end as
last number 75 is printed which is the last multiple of 5 before 79.
#include<stdio.h>
int main(){
int num_rows;
printed - ");
printf("%d",(i+j+1)%2);
int num_rows;
printed - ");
printf("%d",(i+j+1)%2);
printf("\n");
printf("\n");
return 0;
}
printf("\n");
return 0;
}
Practice Lab 3_Question 4
#include<stdio.h>
int main(){
ans *= a;
printf("%llu^%llu = %llu\n",a,b,ans);
return 0;
}
Control Structures—
7 Decision Making
Chapter 7, Sections 7.1-7.7, 7.10, 7.12, and 7.15.
WHAT TO LEARN
TABLE 7.1 Operators Used for Decision Making (in order of precedence)
Operator(s) Signi cance Associativity
! Logical NOT R-L
% Modulus L-R
<, <=, >, >= Relational L-R
==, != Relational (Equality) L-R
&& Logical AND L-R
|| Logical OR L-R
?: (ternary operator) Conditional R-L
Execution of this statement begins by evaluating expression. If this value is true, then one or more
statements are executed. Curly braces are not required for a single statement but they are needed
for a compound statement. Here’s a simple example:
if (hours_left > 6) if syntax requires use of parentheses
rate = 25; Next statement should be indented
printf(“Refund amount = %f\n”, rate * amount);
Here, 25 is assigned to rate if hours_left is greater than 6. Note that the printf statement is
executed unconditionally and has nothing to do with the binary outcome of the control expression.
The difference in indentation reveals our true intention and is consistent with what the compiler
also sees.
A compound statement needs curly braces at its two ends. The following compound statement
comprises three simple ones:
if (amount > 10000) {
printf(“You can’t withdraw more than 10000 with this debit card\n”);
printf(“Key in an amount not exceeding 10000\n”);
scanf(“%d”, &amount); if ends at this ;
}
Note there is no semicolon following the } symbol. In the absence of curly braces, only the first
printf would have been executed conditionally.
Note: When used with a single statement, if ends at the semicolon used as statement terminator.
For a compound statement, if ends at the terminating ; of the last statement.
Caution: All control expressions used by the decision-making and loop constructs must be enclosed
within parentheses. The compiler will generate an error if you use if count > 0 or
while count++ <= MAX_COUNT.
We have not used parentheses in the expression year % 4 == 0 because the % has a higher precedence
than == (Table 7.1). The modulus operation is thus performed first. The else part contains the code
for handling a non-leap year. Parentheses are left out in the expression 4 - year % 4 also because
the % has a higher priority than -.
In the last two printf statements, the first argument actually comprises two concatenated strings.
C allows this concatenation (9.12.2), but note that the combined string is actually a single argument
even if the strings are located on two physical lines.
214 Computer Fundamentals & C Programming
Tip: Always look for potential errors right at the beginning of the program. It’s pointless proceeding
with program execution with erroneous data. Use the if statements to check for them and then
use return with specific values to prematurely terminate the program.
you must ensure that the expressions are mutually exclusive. This means that two expressions must
never evaluate to true in a single traversal of the structure.
Note: The return 0; statement at the bottom of the program is never executed because the program
exits through the paths provided by the other return statements placed in the inner ladder.
This return statement placed at the bottom should be removed.
if (expression is true)
if (expression is true)
if (expression is true)
statement;
...
else
statement;
else
statement;
else
statement;
FIGURE 7.4 The Nested if-if-else Statement (Form 4)
The figure shows the indentation you must adopt when using nested if structures. Without proper
indentation, it is easy to visually pair an if with the wrong else. The pairing scheme is quite simple:
The innermost if pairs with the innermost else, the immediate outer if pairs with the immediate
outer else, and so on until the outermost if pairs with the outermost else. The symmetry breaks
down when you drop an else for one of the ifs, but more of that soon.
Let’s look at a simple example that demonstrates the usefulness of this derived construct. Consider
the need to print the sum of three positive integers obtained from user input, but only after validation.
Here’s the code snippet that handles the logic:
if (a > 0)
if (b > 0)
if (c > 0)
/* Cleared the validity check */
printf(“Sum of three integers = %d\n”, a + b + c);
else
printf(“c is not a positive integer\n”);
else
printf(“b is not a positive integer\n”);
else
printf(“a is not a positive integer\n”);
Control Structures—Decision Making 219
When code is presented in this way, there should be no problem in pairing an if with its else.
The first three if statements represent the AND condition (a > 0 && b > 0 && c > 0), so the first
printf signifies the action to take when all three expressions evaluate to true. The other printf
statements are associated with the else clauses and they tell us what happens when each of the
variables is less than or equal to zero.
In some cases, we need to drop some of the else keywords, or even all of them. The latter is easy
to handle, but we have to handle the other situations with care. Before we do that, let’s have a look
at a program which contains a symmetric nested if structure.
The combination of the three expressions itself constitutes a larger expression—the conditional
expression. This expression has the value exp2 if exp1 evaluates to true, and exp3 otherwise. Even if
this construct has been discussed in Chapter 6 as a special form of expression, it is also important
for decision making. In fact, this operator easily replaces those if-else statements that merely set a
variable. Consider the following if statement which is shown side-by-side with the ternary version:
if-else Version Equivalent Conditional Expression
if (total > 1000) rate = total > 1000 ? 0.90 : 0.95;
rate = 0.90;
else
rate = 0.95;
Using a conditional expression, the leap year problem becomes even shorter. Simply set the variable
is_leap_year to ‘y’ or ‘n’ depending on the value of a logical expression. Use parentheses if they
help to provide clarity:
char is_leap_year;
is_leap_year = (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)
? ‘y’ : ‘n’;
Now, printf and scanf are also expressions because both return a value, so can we use printf in
this way?
count = inta < 0 ? printf(“Invalid value\n”) : printf(“Valid integer\n”);
Yes, this is a valid statement. In the process of evaluation of printf, the side effect (printing) also
shows up. The variable count stores the return value of printf, i.e., the number of characters printed.
Note that the ; at the end is the terminator of the assignment statement. The first printf doesn’t
have a terminator, so why should the second printf have one?
switch (exp) {
case value1 : statements1;
break;
case value2 : statements2;
break;
...
default : statements;
}
switch first evaluates exp which must be an integer or character variable or constant. It next tries to
match exp with value1. If the match succeeds, switch executes one or more statements represented
by statements1. If the match fails, switch attempts to match exp with value2 and so on until control
moves to the keyword default (if present). This option is thus invoked when all previous matching
operations fail. For this purpose, switch is assisted by three keywords—case, break and default.
The entire set of options and their associated action are enclosed in curly braces.
Every case represents an option that specifies the statements to be executed in case matching is
successful. In most cases, a case is followed by break. When it is encountered, further matching is
halted and control moves past the end of switch to the statement following the }. In the absence of
break, however, control “falls through” to the next case option for the next break, or past the end
of switch if it doesn’t find one. Program 7.9 clearly shows us why switch was designed to behave
in this unusual manner.
Here’s a simple code fragment that shows the working of switch. It validates a user-input integer
for the values 1 and 2:
printf(“Enter a 1 or 2: “);
scanf(“%d”, &response);
switch (response) {
case 1: printf(“You entered 1\n”);
break;
case 2: printf(“You entered 2\n”);
break;
default: printf(“Invalid option\n”); No break required ...
} ... will break anyway
The default keyword (if present) doesn’t need a break since control will anyway break out of the
construct at the point where it could have occurred. However, switch operates with the following
restrictions:
exp can be any expression as long as it evaluates to an integer or character constant like
1, 2 or ‘y’.
The labels value1, value2, etc. can only be integer or character constants or constant expressions
(like 3 + 5). Floating point values and variables are not permitted here.
The label is always followed by a colon, and the statements associated with it must be
terminated by semicolons.
The default label is optional, but if present, is usually placed as the last option (not
mandatory though).
Two or more labels can have one break statement. This feature gives switch the power of the
logical OR operator.
It is permissible to have an empty case (one without any statement).
Can a relational expression be used as exp? Sure it can, but the evaluation would yield only one
of two values. You can use switch to match the labels 0 and 1, but then if is ideally suited for this
task. Program 7.9 uses a relational expression for exp.
8 Control Structures—Loops
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
Job over
Output of Pseudo-Code
Before a loop begins, a key variable is initialized (1). This variable is used to evaluate a control
expression (2). If the evaluation is true (3), the loop body is executed (4 to 6), otherwise control moves
to the next statement after the loop (6). The key variable is then changed in the loop body (5) before
control moves back to the beginning of the loop (2). The control expression is now re-checked (2)
before the next iteration (traversal or repeat) can begin. If the loop is designed to run a finite
number of times, the control expression will eventually turn false and cause the loop to terminate.
Even though all of the three loops offered by C broadly conform to the above scheme, there are
minor differences between them. First, the initialization may be done in the loop construct itself
(for loop) instead of being done outside. Second, the control expression may be evaluated at
the end (do-while loop) instead of at the beginning. Finally, a control expression can’t prevent
a do-while loop from performing at least one iteration even though it can prevent the other loops
from running at all.
A loop iteration can either be suspended (to start a new one) or terminated altogether without
re-testing the control expression. This is achieved with the continue and break keywords that can
be invoked anywhere in the loop body. You have already used this feature in one program of the
previous chapter, so you’ll find it a convenient alternative to the traditional method of using the
control expression to determine loop continuity.
238 Computer Fundamentals & C Programming
A loop is generally designed to execute a finite number of times, but many applications need
a loop to run all the time. Such loops are known as infinite loops. We have seen one of them in the
previous chapter (while (1)). Many Internet services use infinite loops to check whether a mail
has been received or a user has keyed in text in a messaging application. However, even infinite
loops can be terminated by other means.
The while loop is virtually identical to the generic loop that was depicted in Figure 8.1. An expression
containing a key variable is evaluated to true or false before loop iteration. If false, the loop is not
entered at all, otherwise the body of the loop is executed. After execution, control reverts to the top to
test expression that will determine whether the next iteration can begin. Since the key variable changes
with every iteration, eventually its value causes expression to turn false and terminate the loop.
However, we can sometimes update the key variable in the control expression itself and get rid of one
statement in the loop body. The following code related to the program while_intro.c will also work:
short i = 0, sum = 0; i initialized to 0 not 1
while (++i <= 10) { ++i instead of i
sum += i;
printf(“%hd “, sum);
}
printf(“\nSum of first 10 integers = %hd\n”, sum); Prints 55
The updating of the key variable i has now been moved to the control expression, but this movement
needs the initial value of i to be changed as well.
Note: When you change the key variable in the control expression to one having prefix or postfix
operators, you also need to change either the relational operator (say, > to >=) or the initial value of
the key variable.
while (number != 0) {
last_digit = number % 10; /* Extracts last digit */
number = number / 10; /* Removes last digit */
sum += last_digit;
printf(“%hd “, last_digit);
}
printf(“\nSum of digits: %hd\n”, sum);
return 0;
}
The program is inflexible; we can’t use this technique to print the digits in the sequence they
occur in the number. We need to save every digit, not with five variables, but with an array of five
elements. We’ll revisit the program in Section 10.7.1.
Here, 55 is the sum of its two predecessors, 34 and 21, while 21 is the sum of 13 and 8. Program
8.4 prints and sums n terms of the sequence where n is provided by the user. The program employs
a while loop that runs n times. In each iteration, the sum of the variables prev1 and prev2 are saved
in sum and printed. Note that the first two terms are generated from the logic which has not treated
them in an exceptional manner. This has been made possible by careful selection of the initialized
values of four variables.
/* fibonacci_ite.c: Uses the iterative technique to generate terms of
the Fibonacci series and compute the sum of terms. */
#include <stdio.h>
int main(void)
{
short num;
unsigned long prev1 = 0, prev2 = 0, sum = 1, sum_terms = 0;
short i = 0;
printf(“Enter last term of series: “);
scanf(“%hd”,&num);
while (i++ < num) {
printf(“%ld “, sum); /* Prints each term */
sum_terms += sum; /* Sums all terms */
prev1 = prev2;
prev2 = sum;
sum = prev1 + prev2; /* Sums previous two terms */
}
printf(“\nSum of first %hd terms = %ld\n”, num, sum_terms);
return 0;
}
The Fibonacci sequence can also be generated by using a recursive function, i.e., a function that
calls itself repeatedly. Section 11.14.3 examines this function and its demerits compared to the
iterative approach used here.
8.4 LOADING THE CONTROL EXPRESSION
Repetition creates opportunities for using functions as control expressions. For instance, the getchar
function, a member of the I/O family of functions, fetches a character from the keyboard and
returns its ASCII value. The putchar function uses this value to display the character. Consider
the following code snippet:
int c;
c = getchar(); Gets the first character
while (c != EOF) { EOF is end-of-file
putchar(c); Displays the character
c = getchar(); Fetches the next character
}
This appears to be a simple way of retrieving a string of text from keyboard input. But because
getchar returns the ASCII value of the fetched character, you can move the getchar statement
itself to the control expression:
while ((c = getchar()) != EOF)
putchar(c);
This works perfectly and looks clean as well because a single getchar is used. The != has a higher
precedence than the =, so parentheses must be provided around the assignment (c = getchar()). This
ensures that the return value of getchar is assigned to c before c is compared to EOF (end-of-file).
Many functions return a value. scanf returns the number of items successfully read and printf
returns the number of characters written, so these functions can also be used as control expressions:
while (scanf(“%d”, &num) == 1)
while (printf(“Enter the amount: “))
Both getchar and putchar are discussed in Chapter 9 which examines the major I/O functions.
The scanf and printf functions are also examined in the same chapter.
Tip: Don’t merge too many statements with the control expression if that destroys clarity. Program
clarity is more important than compactness. In the preceding case, you should stop after moving
getchar to the control expression. The putchar statement is better left in the loop body.
Since there is no limit on the depth of nesting (i.e., the number of inner loops possible), you can
handle multi-dimensional data quite easily.
Control Structures—Loops 247
Takeaway: In a nested while structure there is a one-to-many relationship between the outer
and inner loop. For every iteration of the outer loop, the inner loop must complete its set of
iterations before the next iteration of the outer loop can begin.
The outer while loop repeatedly prompts for two integers. After performing the necessary validation,
the program passes on valid numbers to the inner loop. For each iteration of this loop, total is
assigned the values base, base * base, base * base * base, and so forth until the key variable num
equals power that is set by user input.
Note: The maths library supports the pow function which does the same job as this program.
Chapter 12 features a program that uses this function. For a program containing pow, the compilation
process is different: the linker must be explicitly invoked to include the code of pow in the executable.
statements;
break;
statements;
continue;
statements;
}
statements;
if (a == 0 && b == 0 && c == 0) {
printf(“All values zero. Quitting ...\n”);
return 1;
}
else if (a < 0 || b < 0 || c < 0) {
printf(“Negative integer not allowed\n”);
continue; /* Goes to while (1) */
}
else
break; /* Goes to next printf statement */
}
printf(“Sum of %d %d %d: %d\n”, a, b, c, a + b + c);
return 0;
}
The while loop works on the principle of initializing a key variable before the loop, testing it in
the control expression and updating the key variable in the body. The three expressions in for do
the same work but at one place. The initialization is done by exp1, the key variable check is done
by exp2, and updating of the key variable is done by exp3. These expressions, which are delimited
by semicolons, determine whether a loop will run, and if so, how many times.
The left side of Figure 8.7 shows the use of a for loop to print the ASCII values of the uppercase
letters. The right side shows the equivalent code using while. All three expressions in for are not
evaluated in every loop iteration, so let’s understand the sequence of operations used by for in
this program:
1. The first expression (chr = 65 and exp1 in syntax) initializes the key variable (chr).
2. The second expression (chr < 91 and exp2), which is the control expression for this loop, is
evaluated. If the evaluation is true, the loop is entered.
254 Computer Fundamentals & C Programming
PROGRAM OUTPUT:
A=65 B=66 C=67 D=68 E=69 F=70 G=71 H=72 I=73 J=74 K=75 L=76 M=77 N=78 O=79 P=80
Q=81 R=82 S=83 T=84 U=85 V=86 W=87 X=88 Y=89 Z=90
FIGURE 8.7 Difference in Form Between for (left) and while (right)
3. If the result of evaluation in Step 2 is true, the printf statement is executed.
4. After an iteration has been completed, control moves to the third expression (chr++ and exp3)
where the key variable is incremented.
5. Control now goes back to Step 2 where the control expression is re-tested. The loop starts the
next iteration if chr is still less than 91.
6. chr will eventually have the value 91. The control expression will then turn false and prevent
loop re-entry. The return statement terminates the program.
Like while, for is an entry-controlled loop because exp1 and exp2 jointly determine whether
the loop will be entered at all. This loop is special because of the flexibility of expression usage.
Any of these three expressions can comprise comma-separated multiple expressions, or it can be
dropped altogether. Using this feature, you can dismantle the set of three expressions to provide
a “while”-like look to for:
int chr = 65; exp1
for (; chr < 91;) { exp2
printf(“%c=%d “, chr, chr);
chr++; exp3
}
Here, exp1 and exp3 have been moved out, leaving their slots with null expressions. The semicolons
are mandatory even if the expressions are absent. Like in while, some statements of the loop body
can also be moved to the control expression.
Takeaway: In the first iteration of a for loop, the sequence is exp1 followed by exp2.
In subsequent iterations, it is exp3 followed by exp2. exp1 is evaluated only once—before the
loop is entered.
Control Structures—Loops 255
The machine values of A and a in ASCII are 65 and 97, respectively. Machines that support other
character sets (like EBCDIC) have different values. For the program to be independent of the
character set, we need to store the difference of these two values in a separate variable (diff).
We can then derive the lowercase value of a letter from knowledge of its uppercase value.
The program is portable because instead of using chr + 32, we have used chr + diff.
The for loop initializes the key variable chr to ‘A’ before it evaluates the control expression
chr <= ‘Z’. Since this is true and will remain true for the next 25 iterations, the loop is entered.
Next, printf prints the value of ‘a’ in a space 3 characters wide (because of %3hd) before beginning
the next iteration. A simple equality test in the loop ensures the printing of nine entries in each line.
After completing one iteration, control moves to the top where chr is incremented and the control
expression re-evaluated. The entire cycle is repeated until the value of chr exceeds ‘Z’, when the
loop terminates. However, in every ninth iteration, printf prints a newline and count is reset to zero.
256 Computer Fundamentals & C Programming
Tip: When designing programs that change the case of letters, follow the preceding technique
of storing the difference between a lowercase and uppercase letter in a variable, and then use
this value for case conversion. Your programs won’t be portable if you derive the value of ‘a’ by
adding 32 to ‘A’ simply because this relation is true only for ASCII systems.
The nth term in the series is represented as n2. The following program (Program 8.12) completes the
series up to n terms where n is set by the user. The program also evaluates the complete expression
by choosing the + and - operators correctly. The annotations adequately explain the working of
the program.
The value of exp1 (containing the two comma operators) is now ‘A’ (the value of the right-most
expression), but that is of no consequence to us in this program. What matters to us is that the
three expressions together can be treated as exp1.
The expression exp2 of this for loop behaves in an unusual manner. Every iteration of the loop
runs scanf to assign the next input character to the variable c. The loop thus reads a complete
line of input and terminates when it encounters EOF. Because there is no key variable here,
we don’t need to use exp3 at all. Its absence is indicated by the solitary ; at the end of the complete
expression. Like Program 8.11, this program is also portable.
Note: The return value of the scanf expression acts as a key variable in this program. Its side effect
is also utilized by the program.
Note: In most cases, the for loop uses the same variable as the three components of the combined
expression. However, this is not the case in Program 8.13; the variables diff and c are completely
unrelated to each other. Be prepared to see for loops where exp1, exp2 and exp3 are represented by
three different variables.
Repeated division by 2 in the first for loop generates the values 0 and 1 of type short. Because the
array, binary_digits, is of type char, these short values are transformed to char using a conditional
expression. After the first for loop has completed its run, binary_digits has all the remainders.
A second for loop now reads this array backwards by repeatedly decrementing the value of index
which was set by the previous loop.
/* pyramid.c: Prints a pyramid pattern with the * using nested for loops. */
#include <stdio.h>
int main(void)
{
short i, j, k, rows;
printf(“Number of rows? “);
scanf(“%hd”, &rows);
for (i = 1; i <= rows; i++) {
for (j = 1; j <= rows - i; j++)
printf(“ “); /* Prints spaces before pattern */
for (k = 0; k != 2 * i - 1; k++)
printf(“*”);
printf(“\n”);
}
return 0;
}
Each line is printed by increasing the number of asterisks by 2 and decreasing the number of leading
spaces by 1. This logic is captured by the control expressions of two for loops in Program 8.15.
The expression j <= rows - 1 controls the number of spaces, and the expression k != 2 * i - 1
controls the number of asterisks.
WHAT NEXT?
All work in C is performed by functions, and we must know the ones that interact with the terminal.
The next chapter makes a detailed examination of the essential input/output (I/O) functions.
A loop generally operates by first initializing a key variable, testing it in the control expression and
then updating it in the loop body.
A loop may run a finite or infinite number of times. An infinite loop is created if the control expression
never turns false.