You are on page 1of 86

CSC103 Programming Fundamentals

Programming Fundamentals
CSC-103

Lab Manual

Name

Registration Number

Class

Instructor’s Name

COMSATS University Islamabad (CUI) , Islamabad Campus Page 1


CSC103 Programming Fundamentals

Introduction
This Lab Manual is for CSC-103 Programming Fundamentals course. The labs
constitute 25 % of the total marks for this course.

During the labs students will work individually. You are required to complete the
‘Pre-Lab’ section of the lab before coming to the lab. You will be graded for this
and the ‘In-Lab’ tasks during the in-lab viva. You will complete the ‘Post-Lab’
section of each lab before coming to the next week’s lab.

You are not allowed to wander in the lab or consult other groups when performing
experiments. Similarly the lab reports must contain original efforts. CUI has a
zero tolerance anti-plagiarism policy.

Apart from these weekly labs you will complete three mini projects. One mini
project will count towards theory assignments. The other two mini-projects will
count towards your Lab Terminal score. The grading policy is already discussed in
the Course Description File.

COMSATS University Islamabad (CUI) , Islamabad Campus Page 2


CSC103 Programming Fundamentals

Acknowledgement
The labs for CSC-103 Programming Fundamentals were designed by Dr. Omar
Ahmad. The manuals were prepared by Mr. Dilshad Sabir. The first version was
completed in Session Spring 2019. Typesetting and formatting of this version was
supervised by Dr. Omar Ahmad.

History of Revision
Version
and Date Team Comments
of Issue

This is the first editable draft of CSC – 103


lab manual. Labs were designed by Dr.
Version 1. Dr. Omar Ahmad Omar Ahmad and Mr. Dilshad Sabir.
March 2019 Mr. Dilshad Sabir
For comments and suggestions please
contact: omer_ahmed@comsats.edu.pk

Version 2 For comments and suggestions please


Dr. Omar Ahmad
March 2020 contact: omer_ahmed@comsats.edu.pk

COMSATS University Islamabad (CUI) , Islamabad Campus Page 3


CSC103 Programming Fundamentals

Safety Precautions
• Be calm and relaxed, while working in lab.

• First check your measuring equipment.

• When working with voltages over 40 V or current over 10 A , there must be at least two

people in the lab at all time.

• Keep the work area neat and clean.

• Be sure about the locations of fire extinguishers and first aid kit.

• No loose wires or metals pieces should be lying on the table or neat the circuit.

• Avoid using long wires, that may get in your way while making adjustments or

changing leads.

• Be aware of bracelets, rings, and metal watch bands (if you are wearing any of them).

Do not wear them near an energized circuit.

• When working with energize circuit use only one hand while keeping rest of your body

away from conducting surfaces.

• Always check your circuit connections before power it ON.

• Always connect connection from load to power supply.

• Never use any faulty or damage equipment and tools.

• If an individual comes in contact with a live electrical conductor.

o Do not touch the equipment, the cord, the person.

o Disconnect the power source from the circuit breaker and pull out the plug using

insulated material.

COMSATS University Islamabad (CUI) , Islamabad Campus Page 4


CSC103 Programming Fundamentals

Table of Contents
Introduction .................................................................................................................................. 2
Acknowledgement ........................................................................................................................ 3
History of Revision ...................................................................................................................... 3
Safety Precautions ........................................................................................................................ 4
Lab # 01 Introduction to Development Tools, Basics of C Programming and Debugging ......... 8
Objectives ................................................................................................................................. 8
Pre Lab ..................................................................................................................................... 8
In-Lab ..................................................................................................................................... 16
Post Lab Task: ........................................................................................................................ 19
Critical Analysis / Conclusion ............................................................................................... 20
Lab # 02 Basic Steps for Algorithm Development and Piece-Wise Functions using if/else
Statement .................................................................................................................................... 21
Objectives: .............................................................................................................................. 21
Pre-Lab Reading 1: The 4-Step Process of Algorithm Development .................................... 21
Pre-Lab Reading 2: Using if – else Constructs in C Programs .............................................. 27
In Lab Tasks: .......................................................................................................................... 28
Post Lab Task: ........................................................................................................................ 29
Critical Analysis / Conclusion ............................................................................................... 30
Lab # 03 Using Loops to Print Number Sequences and Patterns............................................... 31
Objectives: .............................................................................................................................. 31
Pre-Lab Reading: Loops in C Language: ............................................................................... 31
In Lab: .................................................................................................................................... 34
Critical Analysis / Conclusion ............................................................................................... 35
Lab # 04 Working with State Machines and Different Data Types ........................................... 36
Objectives: .............................................................................................................................. 36
Pre-Lab Reading 1: State Machine Based Program Design ................................................... 36
Pre-Lab Reading 2: Data Types in C Language ..................................................................... 37
In Lab: .................................................................................................................................... 40
Post Lab Task: ........................................................................................................................ 41
Critical Analysis / Conclusion ............................................................................................... 42
Lab # 05 Working with Custom Functions in C ........................................................................ 43

COMSATS University Islamabad (CUI) , Islamabad Campus Page 5


CSC103 Programming Fundamentals

Objectives: .............................................................................................................................. 43
Pre Lab Reading: Functions in C ........................................................................................... 43
In-Lab Task 1: ........................................................................................................................ 45
In-Lab Task 2: ........................................................................................................................ 46
Post Lab Task: ........................................................................................................................ 46
Critical Analysis / Conclusion ............................................................................................... 47
Lab 06 Functions, scope of variables and argument passing ..................................................... 48
Objectives: .............................................................................................................................. 48
Pre-Lab Reading 1: Scope of Variables. ................................................................................ 48
In-Lab Task 01: ...................................................................................................................... 51
In-Lab Task 02: ...................................................................................................................... 51
Post Lab Task: ........................................................................................................................ 52
Critical Analysis / Conclusion ............................................................................................... 53
Lab # 07 The Compilation Process ............................................................................................ 54
Objectives: .............................................................................................................................. 54
Pre-Lab Reading 1: GNU C Compiler (GCC) Compilation Process ..................................... 54
Pre-Lab Reading 2: Splitting Your Code in Multiple Files ................................................... 57
In-Lab Task 1: ........................................................................................................................ 60
In-Lab Task-2: ........................................................................................................................ 60
Post-Lab Task:........................................................................................................................ 60
Critical Analysis / Conclusion ............................................................................................... 61
Lab # 08 Functions and Pointers in C ........................................................................................ 62
Objectives: .............................................................................................................................. 62
Pre-Lab Reading 1: Addresses of variables and Pointers in C ............................................... 62
Pre-Lab Reading 2: Returning multiple values from a function ............................................ 64
In-Lab Task 1: ........................................................................................................................ 65
In-Lab Task 2: Color Space Conversion ................................................................................ 65
Post Lab Task: Recursion ....................................................................................................... 66
Critical Analysis / Conclusion ............................................................................................... 67
Lab # 09 Working with Arrays and Pointers.............................................................................. 68
Objectives: .............................................................................................................................. 68
Reading Task 1: Working with Arrays .................................................................................. 68

COMSATS University Islamabad (CUI) , Islamabad Campus Page 6


CSC103 Programming Fundamentals

Reading Task 2: Selection Sort Algorithm ............................................................................ 68


In-Lab Task 1: Finding Minimum and Maximum Values in an Array .................................. 69
In-Lab Task 2: Implementing Selection Sort ......................................................................... 69
Post-Lab Task: Implement Insertion Sort Algorithm ............................................................. 71
Critical Analysis / Conclusion ............................................................................................... 72
Lab # 10 Working with 2D Array in C ...................................................................................... 73
Objectives: .............................................................................................................................. 73
Reading Task 1: Working with Arrays .................................................................................. 73
Reading Task 2: The Magic Square ....................................................................................... 73
In-Lab Task 1: 2D Arrays and user defined functions ........................................................... 74
In-Lab Task 2: Implementing the algorithm for the Magic Square ....................................... 75
Critical Analysis / Conclusion ............................................................................................... 78
Lab # 11 Working with Strings in C .......................................................................................... 79
Objectives: .............................................................................................................................. 79
Reading Task 1: Working with Arrays .................................................................................. 79
In-Lab Task 1: ........................................................................................................................ 81
In-Lab Task 2 a: ..................................................................................................................... 82
In-Lab Task 2 b: ..................................................................................................................... 82
Critical Analysis / Conclusion ............................................................................................... 83
Lab # 12 Structures in C ............................................................................................................. 84
Objectives: .............................................................................................................................. 84
Reading Task 1: Working with Structures ............................................................................. 84
In-Lab Task 1: ........................................................................................................................ 84
In-Lab Task 2 a: ..................................................................................................................... 84
In-Lab Task 2 b: ..................................................................................................................... 84
Critical Analysis / Conclusion ............................................................................................... 85

COMSATS University Islamabad (CUI) , Islamabad Campus Page 7


Lab # 01 Introduction to Development Tools, Basics of C Programming and Debugging

Lab # 01 Introduction to Development Tools, Basics


of C Programming and Debugging

Objectives
• Learn to use IDE such as Code Blocks for compiling and debugging computer programs
written in C language.

Softwares Used

• Code Blocks IDE


• MinGW C Compiler

Pre Lab
Get the Code Block IDE and MinGW C Compiler setup files from the lab and install them on
your computer.

Creating a New Project using Code Blocks:


1. File → New → Project
2. Select Console Application

3. Press Next

COMSATS University Islamabad (CUI) , Islamabad Campus Page 8


Lab # 01 Introduction to Development Tools, Basics of C Programming and Debugging

4. Select option C

5. Enter Project Name and its Path, press Next

COMSATS University Islamabad (CUI) , Islamabad Campus Page 9


Lab # 01 Introduction to Development Tools, Basics of C Programming and Debugging

6. Press Finish

7. Project is created, double click on Sources and click on main file, now you can modify
C code as per your notion.

COMSATS University Islamabad (CUI) , Islamabad Campus Page 10


Lab # 01 Introduction to Development Tools, Basics of C Programming and Debugging

Using the Debugger:


1. Debugger tool is employed to check the logical errors (errors occur due to algorithm
transformation to code). They are not detectable by complier.

2. To add a breakpoint, right click on line and click on Add breakpoint. It is the point from
where complier will execute program line by line.

COMSATS University Islamabad (CUI) , Islamabad Campus Page 11


Lab # 01 Introduction to Development Tools, Basics of C Programming and Debugging

3. Red circle (break point) is added to line

4. To add debugger select View→Toolbars→Debugger

COMSATS University Islamabad (CUI) , Islamabad Campus Page 12


Lab # 01 Introduction to Development Tools, Basics of C Programming and Debugging

5. Debugger toolbar appears

6. Click on play option it will show yellow triangle, now program is appeared to start

COMSATS University Islamabad (CUI) , Islamabad Campus Page 13


Lab # 01 Introduction to Development Tools, Basics of C Programming and Debugging

7. Along with a console window appears, it is your output window

8. By clicking on next line in debugger menu output appears line by line. One can easily
detect the error.

COMSATS University Islamabad (CUI) , Islamabad Campus Page 14


Lab # 01 Introduction to Development Tools, Basics of C Programming and Debugging

COMSATS University Islamabad (CUI) , Islamabad Campus Page 15


Lab # 01 Introduction to Development Tools, Basics of C Programming and Debugging

In-Lab
In-Lab Task 1: Fix syntax errors in given C program.
Make a new C project (console application) using CodeBlocks and type the following code in
the main.c file. Build the code, fix the indicated errors, and run it.

#include <stdio.h>
#include <stdlib.h>

int main()
{
int N = 0; // Take a number N.
printf("Enter a number for which you want to find the factorial: \n");
Scanf("%d", &N); // Get input from the user
printf("\nYou entered: %d\n\n", n); // Display what the user entered.

int R = 0; // Take a variable R to hold result


int x = 0; // And another x to count
x = N-1; // Let x equal to N-1
R = N // let R = N
do
{

R = R * x; // multiply R with x and store result in R.

X = X-1; // subtract 1 from x

}while(x>=1); // repeat above steps from multiplication till x is


greater than or equal to 1

Printf(‘The factorial of %d is %d\n\n’ N, R); // Output R to console


return 0;
}

Code Listing 1

COMSATS University Islamabad (CUI) , Islamabad Campus Page 16


Lab # 01 Introduction to Development Tools, Basics of C Programming and Debugging

In-Lab Task 2: Solving a piece-wise function


𝑛2 − 5𝑛, 𝑛 ≤ −10
𝑛 + 19, −10 < 𝑛 < −2
𝑓[𝑛] = 𝑛3 − 50𝑛, 𝑛 ≥ −2

{ 𝑛 𝑖𝑠 𝑎𝑛 𝑖𝑛𝑡𝑒𝑔𝑒𝑟

Fill the table using the above equation for values of n from -20 to 20. You will be using this
table to compare the output of the program in the next task and fixing some logical errors.

n f[n] n f[n]

COMSATS University Islamabad (CUI) , Islamabad Campus Page 17


Lab # 01 Introduction to Development Tools, Basics of C Programming and Debugging

In-Lab Task 3: Finding Logical Errors in Code using Debugger


Type and build the following code in a new CodeBlocks project. Compare the output of the
program with the table in task 1. Find any logical error and write the correct program.

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int range_min = -20;
int range_max = 20;

int n;
int output;

printf("For the range %d to %d, ", range_min, range_max);


printf("The output of the function is: \n");

for(n=range_min; n<range_max; n++)


{
if(n < -10)
{
output = (n^2) - (5*n);
}
else if((n<-10)&&(n<=-2))
{
output = n + 19;
}
else
{
output = (n^3) - (50*n);
}
printf("%d ", output);

}
printf("\n\n");
return 0;
}

Code Listing 2

COMSATS University Islamabad (CUI) , Islamabad Campus Page 18


Lab # 01 Introduction to Development Tools, Basics of C Programming and Debugging

Post Lab Task:


Modify the above C program for the following piecewise function and report the problems you
face. Use integer variables for your program.

−𝑛 − 4, 𝑛<3
𝑛2 − 7, 3 ≤ 𝑛 ≤ 10
120
𝑓[𝑛] = + 𝑛, 𝑛 > 10
𝑛

{𝑤ℎ𝑒𝑟𝑒 𝑛 𝑖𝑠 𝑎𝑛 𝑖𝑛𝑡𝑒𝑔𝑒𝑟 𝑣𝑎𝑟𝑖𝑎𝑏𝑙𝑒

COMSATS University Islamabad (CUI) , Islamabad Campus Page 19


Lab # 01 Introduction to Development Tools, Basics of C Programming and Debugging

Critical Analysis / Conclusion


(By Student about Learning from the Lab)

Lab Assessment

Pre Lab /1

In Lab /5

Data Analysis /4 /10

Data
Post Lab /4 /4
Presentation

Writing Style /4

Instructor Signature and Comments

COMSATS University Islamabad (CUI) , Islamabad Campus Page 20


Lab # 02 Basic Steps for Algorithm Development and Piece-Wise Functions using if/else Statement

Lab # 02 Basic Steps for Algorithm Development and


Piece-Wise Functions using if/else Statement

Objectives:
• Learn to develop algorithms for different computational problems
• Learn basic input-out in C using printf() and scanf() functions
• Learn basics of conditional execution using if/else statements

Required Tools:

Software Tools:
• Code Blocks IDE or similar.

Pre-Lab Reading 1: The 4-Step Process of Algorithm Development

Step 1: Work an Example Yourself

The first step in trying to design an algorithm is to work at least one instance of the problem—
picking specific values for each parameter—yourself (by hand). Often this step will involve
drawing a diagram of the problem at hand, in order to work it precisely. The more precisely
you can perform this problem (including the more precisely you can draw a diagram of the
situation if applicable), the easier the remainder of our steps will be. A good example of the
sort of picture you might draw would be the diagrams drawn in many science classes
(especially physics classes). The figure shows multiple copies of the box for this step layered
one on top of the other, as you may need to perform this step multiple times to generalize the
algorithm properly.

Figure 0-1 The 4-Step Process for Algorithm Development


One of the examples of an algorithm that we mentioned early in this chapter was determining if
a number is prime. If you were trying to write a function to determine if a number is prime,
your first step would be to pick a number and figure out if it is prime. Just saying "ok, I know 7

COMSATS University Islamabad (CUI) , Islamabad Campus Page 21


Lab # 02 Basic Steps for Algorithm Development and Piece-Wise Functions using if/else Statement

is prime," is not of much use—you just used a fact you know and did not actually work out the
problem. For a problem such as this one, which has a "yes or no" answer, we probably want to
work at least one example that comes up with a "yes" answer, and one that comes up with a
"no" answer.

Another example would be if we wanted to write a program to compute x raised to the y power.
To do Step 1, we would pick particular values for x and y, and work them by hand. We might
try x = 3 and y = 4, getting an answer of 3^4 = 81.

If you get stuck at this step, it typically means one of two things. The first case is that the
problem is ill-specified—it is not clear what you are supposed to do. In such a situation, you
must resolve how the problem should be solved before proceeding. In the case of a classroom
setting, this resolution may require asking your professor or TA for more details. In an
industrial setting, asking your technical lead or customer may be required. If you are solving a
problem of your own creation, you may need to think harder about what the right answers
should be and refine your definition of the problem.

The second case where Step 1 is difficult is when you lack domain knowledge—the knowledge
of the particular field or discipline the problem deals with. In our primality example, if you did
not remember the definition of a prime number, that would be an example of lacking domain
knowledge—the problem domain is mathematics, and you are lacking in math knowledge. No
amount of programming expertise nor effort ("working harder") will overcome this lack of
domain knowledge. Instead, you must consult a source of domain expertise—a math textbook,
website, or expert. Once you have the correct domain knowledge, you can proceed with
solving your instance of the problem. Note that domain knowledge may come from domains
other than math. It can come from any field, as programming is useful for processing any sort
of information.

Sometimes, domain knowledge may come from particular fields of computer science or
engineering. For example, if you intend to write a program that determines the meaning of
English text, the relevant domain field is actually a sub-field of computer science, called
Natural Language Processing. Here the domain knowledge would be the specific techniques
developed to write programs that deal with natural language. A source of domain knowledge
on English (an English professor or textbook) is unlikely to contain such information.

Step 2: Write Down What You Just Did

For this step, you must think about what you did to solve the problem, and write down the
steps to solve that particular instance. Another way to think about this step, is to write down a
clear set of instructions that anyone else could follow to reproduce your answer for the
particular problem instance that you just solved. If you do multiple instances in Step 1, you
will repeat Step 2 multiple times as well, once for each instance you did in Step 1. If an
instruction is somewhat complex, that is all right, as long as the instruction has a clear

COMSATS University Islamabad (CUI) , Islamabad Campus Page 22


Lab # 02 Basic Steps for Algorithm Development and Piece-Wise Functions using if/else Statement

meaning—later, we will turn these complex steps into their own programming problems,
which will get solved separately.

The difficult part of Step 2 is thinking about exactly what you did to accomplish the problem.
The difficulty here is that it is very easy to mentally gloss over small details, "easy" steps, or
things that you do implicitly. This difficulty is best illustrated by the peanut butter and jelly
exercise we mentioned earlier. Implicit assumptions about what to do, or relying on common
sense lead to imprecise or omitted steps. The computer will not fill in any steps you omit, thus
you must be careful to think through all the details.

Returning to our example of computing x to the y, we might write down the following steps for
x = 3 and y = 4:

The steps are very precise—and leave nothing to guess work. Anyone who can perform basic
arithmetic can follow these steps to get the right answer. Computers are very good at
arithmetic, so none of these steps is even complex enough to require splitting into a sub-
problem.

Step 3: Generalize Your Steps

Having solved one or more problems from the class we are interested in and written down the
particular steps we executed to solve them, we are ready to try to generalize those steps into an
algorithm. In our Step 2 steps, we solve particular instances, but now we need to find the
pattern that allows us to solve the whole class. This generalization typically requires two
activities. First, we must take particular values that we used and replace them with
mathematical expressions of the parameters. Looking at our Step 2 steps for computing 3^4,
we would see that we are always multiplying 3 by something in each step. In the more general
case, we will not always use 3—we are using 3 specifically because it is the value that we
picked for x. We can generalize this slightly by replacing this occurrence of 3 with x:

COMSATS University Islamabad (CUI) , Islamabad Campus Page 23


Lab # 02 Basic Steps for Algorithm Development and Piece-Wise Functions using if/else Statement

The second common way to generalize steps is to find repetition—the same step repeated over
and over. Often the number of times that the pattern repeats will depend on the parameters. We
must generalize how many times to do the steps, as well as what the steps are. Sometimes, we
may find steps which are almost repetitive, in which case we may need to adjust our steps to
make them exactly repetitive. In our 3^4 example, our multiplication steps are almost
repetitive—both multiply x by "something," but that "something" changes (3 then 9 then 27).
Examining the steps in more detail, we will see that the "something" we multiply is the answer
from the previous step. We can then give it a name (and an initial value) to make all of these
steps the same:

Now, we have the same exact step repeated three times. We can now contemplate how many
times this step repeats as a function of x and/or y. We must be careful not to jump to the
conclusion that it repeats x times because x = 3—that is just a coincidence in this case. In this
case, it repeats y - 1 times. The reason for this is that we need to multiply 4*3s together, and we
already have one in n at the start, so we need y - 1 more. This would lead to the following
generalized steps:

We need to make one more generalization of a specific value to a function of the parameters.
We start with n = 3; however, we would not always want to start with 3. In the general case, we
would want to start with n = x:

Sometimes you may find it difficult to see the pattern, making it hard to generalize the steps.
When this happens, returning to Steps 1 and 2 may help. Doing more instances of the problem
will provide more information for you to consider, possibly giving you insight into the patterns
of your algorithm.

COMSATS University Islamabad (CUI) , Islamabad Campus Page 24


Lab # 02 Basic Steps for Algorithm Development and Piece-Wise Functions using if/else Statement

Step 4: Test Your Algorithm

After Step 3, we have an algorithm that we think is right. However, it is entirely possible that
we have messed up along the way. The primary purpose of Step 4 is to ensure our steps are
actually right before we proceed. To accomplish this, we test our algorithm with different
values of the parameters than the ones we used to design our algorithm. We execute our
algorithm by hand and compare the answer it obtains to the right answer. If they differ, then we
know our algorithm is wrong. The more test cases (values of parameters) we use, the more
confident we can become that our algorithm is correct. Unfortunately, it is impossible to ensure
that our algorithm is correct by testing. The only way to be completely sure that your algorithm
is correct is to formally prove its correctness (using a mathematical proof), which is beyond the
scope of this specialization.

One common type of mistake is misgeneralizing in Step 3. As we just discussed, one might
think that the steps repeated x times because x = 3 and the steps repeated 3 times. If we had
written that down in Step 3, our algorithm would only work when x = y – 1; otherwise we
would count the wrong number of times and get the wrong answer. If that were the case, we
would hopefullydetect the problem by testing our algorithm by hand in Step 4. When we detect
such a problem, we must go back and re-examine the generalizations we made in Step 3. Often,
this is best accomplished by returning to Steps 1 and 2 for whatever test case exposed the
problem. Redoing Steps 1 and 2 will give you a concrete set of steps to generalize differently.
You can then find where the generalization you came up with before is wrong, and revise it
accordingly.

Another common type of mistake is that there are cases we did not consider in designing our
algorithm. In fact, in our x^y example, we did not consider what happens when y = 0, and our
algorithm handles this case incorrectly. If you execute the algorithm by hand with x = 2, y = 0,
you should get 2^0=1; however, you will get an answer of 2. Specifically, you will start with n
= x = 2. We would then try to count up from 1 to 0 – 1 = –1, of which there are no numbers, so
we would be done counting right away. We would then give back n (which is 2) as our answer.

To fix our algorithm, we would go back and revisit Steps 1 and 2 for the case that failed (x = 2,
y = 0). This case is a bit tricky since we just know that the answer is 1 without doing any work
(x^0=1 for any x). The fact that the answer requires no work makes Step 2 a little different—
we just give an answer of 1. While this simplicity may seem nice, it actually makes it a little
more difficult to incorporate it into our generalized steps. We might be tempted to write
generalized steps like these:

COMSATS University Islamabad (CUI) , Islamabad Campus Page 25


Lab # 02 Basic Steps for Algorithm Development and Piece-Wise Functions using if/else Statement

These steps check explicitly for the case that gave us a problem (y = 0), give the right answer
for that case, then perform the more general algorithm. For some problems, there may be
corner cases which require this sort of special attention. However, for this problem, we can do
better. Note that if you were unable to see the better solution and were to take the above
approach, it is not wrong per se, but it is not the best solution.

Instead, a better approach would be to realize that if we count no times, we need an answer of
1, so we should start n at 1 instead of at x. In doing so, we need to count 1 more time (to y
instead of to y– 1)—to multiply by x one more time:

Whenever we detect problems with our algorithm in Step 4, we typically want to return to
Steps 1 and 2 to get more information to generalize from. Sometimes, we may see the problem
right away (e.g., if we made a trivial arithmetic mistake, or if executing the problematic test
case by hand gives us insight into the correct generalization). If we see how to fix the problem,
it is fine to fix it right away without redoing Steps 1 and 2, but if you are stuck, you should
redo those steps until you find a solution. Whatever approach you take to fixing your
algorithm, you should re-test it with all the test cases you have already used, as well as some
new ones.

Determining good test cases is an important skill that improves with practice. For testing in
Step 4, you will want to test with cases which at least produce a few different answers (e.g., if
your algorithm has a "yes" or "no" answer, you should test with parameters which produce
both "yes" and "no"). You should also test any corner cases—cases where the behavior may be
different from the more general cases. Whenever you have conditional decisions (including
limits on where to count), you should test potential corner cases right around the boundaries of
these conditions. For example, if your algorithm makes a decision based on whether or not x <
3 , you might want to test with x = 2, x = 3, and x = 4. You can limit your "pencil and paper"
testing somewhat, since you will do more testing on the actual code once you have written it.

COMSATS University Islamabad (CUI) , Islamabad Campus Page 26


Lab # 02 Basic Steps for Algorithm Development and Piece-Wise Functions using if/else Statement

Pre-Lab Reading 2: Using if – else Constructs in C Programs


Now that we understand comparison operators, and can compare expressions, we can discuss
the evaluation of if/else statements. The syntax for an if/else statement is shown in figure
below.

Figure 0-2 The Syntax of If/Else Block

The keyword if is followed by an expression in parenthesis. This expression is evaluated to a


value, to determine whether the “then” block or the “else” block is executed. The “then” block
of code comes immediately after the expression. C does not have a then keyword (although
some languages do), however, this block of code serves the same purpose regardless of the
syntactic particulars of the language—it is executed if the conditional expression evaluates to
true. After the “then” block, we have the keyword else, followed by the “else” block. This
block of code is executed if the conditional expression evaluates to false.

When your execution arrow reaches an if statement, evaluate the conditional expression.
Evaluating this expression proceeds just like evaluating any other expression. If the result is
true, move the execution arrow immediately inside the “then” block and continue executing
statements as usual. When your execution reaches the close curly brace that ends the “then”
block, skip over the else block, placing your execution arrow immediately after the close curly
brace of the “else” block, and continue executing statements from there.

If the result of the conditional expression is false, you should instead skip the “then” block and
execute the “else” block. Move your execution arrow into the start of the “else” block, and
continue executing statements from there. When your execution arrow reaches the close curly
brace that ends the “else” block, simply move it past that curly brace (which has no effect—it
just denotes the end of the block) and continue executing statements normally.

C permits if with no else, which is equivalent to an empty “else” block (as if the programmer
had written else {}). If you execute an if with no else, then simply imagine the empty “else”

COMSATS University Islamabad (CUI) , Islamabad Campus Page 27


Lab # 02 Basic Steps for Algorithm Development and Piece-Wise Functions using if/else Statement

block. If the conditional expression evaluates to true, you should execute the “then” block as
previously described, however, there is no “else” block to skip. Instead, continue executing
statements immediately after the end of the “then” block (skipping over the nonexistent “else”
block). If the conditional expression evaluates to false, then skip the “then” block, and execute
whatever statements follow it (doing nothing for the “else” block).

if/else statements may be nested—one (or more) may occur in the “then” or “else” block of
another if/else statement. When you encounter nested statements, the same rules apply. The
inner statement is just one of the (possibly) many statements in the block, and is executed
according to its rules—the condition is evaluated, whichever of the “then” or “else” blocks is
appropriate is executed, and then execution continues after the end of the “else” block. When
the execution arrow reaches the end of the outer “then” or “else” block, it behaves no
differently than if there were no inner if statement. The next video demonstrates the execution
of some if/else statements.

In Lab Tasks:

Task 1: Develop an Algorithm

Following figure shows a pattern of squares generated for different input values of N (for N=0
to N=5). Develop a general algorithm to fill in the grid for any input N. Use the 4 step process
that was discussed in the class (and is given below for reference)

The four – step algorithm development process:

1. Work an example yourself.

2. Write down what you just did.

3. Generalize your steps.

4. Test your algorithm.

COMSATS University Islamabad (CUI) , Islamabad Campus Page 28


Lab # 02 Basic Steps for Algorithm Development and Piece-Wise Functions using if/else Statement

Figure 0-3 A pattern of squares problem

Task 2: Write a C Program to Implement a Piecewise Function

Write a C program for following piecewise function. Program must take input from user and
calculate and print the function result on screen.

−𝑛 − 4, 𝑛<3
𝑛2 − 7, 3 ≤ 𝑛 ≤ 10
120
𝑓[𝑛] = + 𝑛, 𝑛 > 10
𝑛

{𝑤ℎ𝑒𝑟𝑒 𝑛 𝑖𝑠 𝑎𝑛 𝑖𝑛𝑡𝑒𝑔𝑒𝑟 𝑣𝑎𝑟𝑖𝑎𝑏𝑙𝑒

Post Lab Task:


Write a program that takes integer input from user and tells (displays on the output console
screen) whether it is even or odd.

COMSATS University Islamabad (CUI) , Islamabad Campus Page 29


Lab # 02 Basic Steps for Algorithm Development and Piece-Wise Functions using if/else Statement

Critical Analysis / Conclusion


(By Student about Learning from the Lab)

Lab Assessment

Pre Lab /1

In Lab /5

Data Analysis /4 /10

Data
Post Lab /4 /4
Presentation

Writing Style /4

Instructor Signature and Comments

COMSATS University Islamabad (CUI) , Islamabad Campus Page 30


Lab # 03 Using Loops to Print Number Sequences and Patterns

Lab # 03 Using Loops to Print Number Sequences


and Patterns

Objectives:
• Learn to use loops for repetitive tasks.
• Practice conditional execution in loops to generate patterns of asterisks.

Required Tools:

Software Tools:
• CodeBlocks IDE or similar

Pre-Lab Reading: Loops in C Language:


Programs often repeat the same block of code multiple times, using a loop. As you may recall
from the examples in Section 1.7, algorithms often have repetitive behavior. Finding repetitive
patterns is crucial to generalizing over inputs, as your program may need to perform similar
work multiple times for different pieces of the input—and the number of repetitions will
change with the characteristics of the inputs. There is another way to express repetition, called
recursion, which you will learn about later.

While loops

There are three kinds of loops in C. The first of these is the while loop. The syntax for a while
loop is shown in Figure 2.9. The keyword while is followed by an expression in parenthesis.
Much like an if statement, this expression is evaluated to determine whether or not to enter the
block of code immediately following it, which is known as the body of the loop. If the
conditional expression evaluates to true, the execution arrow moves inside the body of the loop
and its statements are executed normally. The while loop differs from the if statement in what
happens when the execution arrow reaches the closing curly brace. In the case of a while loop,
it jumps up to the top of the loop, immediately before the while keyword. The conditional
expression is then re-evaluated, and if it is still true, execution re-enters the loop body. If the
conditional expression evaluates to false, then the execution arrow skips to immediately after
the closing curly brace of the loop body, and proceeds from there.

COMSATS University Islamabad (CUI) , Islamabad Campus Page 31


Lab # 03 Using Loops to Print Number Sequences and Patterns
Do-while Loops

Another type of loop in C is the do-while loop. Unlike a while loop, which checks its
conditional expression at the top of the loop, the do-while loop checks its conditional
expression at the bottom of the loop—after it has executed the body. While this distinction may
seem contrived— either way the condition is checked between iterations—it is important at the
start of the loop. A while loop may execute its body zero times, skipping the entire loop, if the
condition is false initially. By contrast, a do-while loop is guaranteed to execute its body at
least once because it executes the loop body before ever checking the condition. Figure 2.10
shows the syntax of a do-while loop. The keyword do is followed by the loop body. After the
loop body, the keyword while is followed by the conditional expression and a semicolon.
Execution of a do-while loop proceeds by first entering the loop body and executing all of the
statements contained in it. When the execution arrow reaches the while at the end of the loop
body, its conditional expression is evaluated. If the expression evaluates to true, then the
execution arrow jumps back to the start of the loop body. If the expression evaluates to false,
then it moves past the end of the loop and execution continues with the next statement after the
loop.

For Loops

The third type of loop in C is a for loop. The for loop is syntactic sugar—it does not introduce
any new behavior, but instead provides a more convenient syntax for a common programming
idiom. In the case of for loops, the common idiom is counting from one number to another.
Figure 2.11 shows the syntax of a for loop, and how it is de-sugared into a while loop—that is,
how we could write the for loop in terms of the already familiar while loop. Knowing how the
for loop de-sugars to a while loop tells us how to execute it. We can imagine the equivalent
while loop, and follow the execution rules we have already learned for it. The for keyword is
followed by three pieces, separated by semicolons, inside of parenthesis. The first of these is
the “initialization statement”. It happens once before the first time the loop’s condition is
checked. In the de-sugaring, this statement appears right before the while loop. The second
piece is not a statement (even though it is followed by a semicolon), but rather the conditional
expression for the loop. In the de-sugaring, this expression is the conditional expression of the
while loop. The third statement is the “increment statement”. In the de-sugaring, it appears
immediately before the close curly brace of the loop body. After all of these is the loop body,
which (except for the addition of the “increment statement” at the end) is the loop body of the
while loop in the de-sugared version. If you examine Figure 2.11 carefully, you will notice that
there is a set of curly braces around the entire piece of while-based code. These curly braces
are there for a subtle, but important reason. The scope of any variables declared in the
“initialization statement” of the for loop have a scope which is limited to the for loop. Recall
that a variable typically has a scope which is limited to the curly braces which enclose its
declaration. For a variable declared in the start of the for loop, the scope appears to be an
exception to this rule, however, it is not if we think of it in terms of the de-sugaring shown
above with the curly braces surrounding the declaration.

COMSATS University Islamabad (CUI) , Islamabad Campus Page 32


Lab # 03 Using Loops to Print Number Sequences and Patterns
Nesting

Just as if/else statements may be nested, loops may also be nested. Similarly, loops follow
exactly the same rules no matter how they are nested. In fact, if/else statements and loops may
be nested within each other in any combinations. The rules are always the same regardless of
any combinations or depths of nesting.

Continue and break

Sometimes a programmer wants to leave the loop body early, rather than finishing all of the
statements in side of it. There are two possible behaviors that a programmer might want when
leaving the loop body early. One behavior would be to exit the loop completely, making the
execution arrow jump to immediately after the close curly brace which ends the loop (the same
place that it goes when the loop’s condition evaluates to false). This behavior is obtained by
using the break; statement—which we have already seen in the context of switch/case.
Whenever the execution arrow encounters a break statement, it executes the statement by
jumping out of the innermost enclosing loop (whether it is a while, do-while, or for loop), or
switch statement. If the break statement is inside multiple of these which are nested together
(e.g. a loop inside a case of a switch statement), then it exits only the most immediately
enclosing one. If a break statement occurs and is not inside one of these loops or a switch
statement, it is an error in the program. The other possible behavior that the programmer might
want to have is for the execution arrow to jump back to the top of the loop. This behavior is
accomplished with the continue; statement. Executing the continue statement jumps to the top
of the innermost enclosing loop (if it is not in a loop, it is an error). In the case of a for loop,
the “increment statement” in the for loop is executed immediately before the jump. This fact
complicates the de-sugaring of a for loop into a while loop slightly relative to the explanation
given above. If the for loop contains any continue statements, then the “increment statement” is
written not only before the close curly brace of the loop, but also before any continue
statements.

COMSATS University Islamabad (CUI) , Islamabad Campus Page 33


Lab # 03 Using Loops to Print Number Sequences and Patterns

In Lab:
Task 1:
Write a program that prints all even numbers from N to M, where N and M are user input
integers.

Task 2:
Write C programs that output the following patterns exactly. Use loops to implement the
repetitive part of the code. No functions or arrays are allowed.

COMSATS University Islamabad (CUI) , Islamabad Campus Page 34


Lab # 03 Using Loops to Print Number Sequences and Patterns

Critical Analysis / Conclusion


(By Student about Learning from the Lab)

Lab Assessment

Pre Lab /1

In Lab /5

Data Analysis /4 /10

Data
Post Lab /4 /4
Presentation

Writing Style /4

Instructor Signature and Comments

COMSATS University Islamabad (CUI) , Islamabad Campus Page 35


Lab # 04 Working with State Machines and Different Data Types

Lab # 04 Working with State Machines and Different


Data Types

Objectives:
• Learn to use state machine as a program design tool
• Practice the conditional execution of code combined with loops by implementing state
machines.
• Learn about different data types.

Software Tools:
• CodeBlocks IDE or similar.

Pre-Lab Reading 1: State Machine Based Program Design


Automata-based programming is a programming paradigm in which the program or part of it is
thought of as a model of a finite state machine (FSM) or any other (often more complicated)
formal automaton (see automata theory). Sometimes a potentially infinite set of possible states
is introduced, and such a set can have a complicated structure, not just an enumeration.

FSM-based programming is generally the same, but, formally speaking, doesn't cover all
possible variants, as FSM stands for finite state machine, and automata-based programming
doesn't necessarily employ FSMs in the strict sense.

Read through the tutorial on FSM in file ‘FSM Tutorial.pdf’.

COMSATS University Islamabad (CUI) , Islamabad Campus Page 36


Lab # 04 Working with State Machines and Different Data Types
Pre-Lab Reading 2: Data Types in C Language
C supports a very small number of data types, each with a unique combination of size and
interpretation. They are shown in Figure 3.3. As the caption of this figure notes, the sizes listed
are common, and what we will use in general discussion in this book, but not guaranteed. In
particular, it depends on the hardware, and the compiler—the program which turns your code
into instructions that the computer can actually execute (more on this in Chapter ??).

Figure 1: Data Types in C

Figure 2: A subset of ASCII number-to-character mappings

Char Data Type


A char (pronounced either “car” or “char”) is the smallest data type—a mere 8 bits long—and
is used to encode characters. With only 8 bits, there are only 28 = 256 possible values for a
char (from 00000000 to 11111111). On most machines you will use, these 8 bits are interpreted
via the American Standard Code for Information Interchange (or ASCII) character-encoding
scheme, which maps 128 number sequences to letters, basic punctuation, and upper- and
lower-case letters. A subset of this mapping is shown in Figure 3.4; please don’t try to
memorize it. Another, much more expressive character-encoding scheme you may encounter
(particularly when needing to encode non-English characters) is Unicode (which requires more
than 1 byte).

If you look at the first line of code in Figure 3.5, you can see the char c declared and initialized
to the value 'A'. Notice that we wrote A in single quotation marks—these indicate a character
literal . In the same way that we could write down a string literal in Section 2.3.2, we can also
write down a character literal: the specific constant character value we want to use. Writing

COMSATS University Islamabad (CUI) , Islamabad Campus Page 37


Lab # 04 Working with State Machines and Different Data Types
down this literal gives us the numerical value for A without us having to know that it is 65. If
we did need to know, we could consult an ASCII table like the one in Figure 3.4. Being able to
write 'A' instead of 65 is another example of abstraction—we do not need to know the ASCII
encoding, we can just write down the character we want.

Int Data Type:

We have said that an int is a 32-bit value interpreted as an integer directly from its binary
representation. As it turns out, this is only half of the story—the positive half of the story. If we
dedicate all 32 bits to expressing positive numbers, we can express 232 values, from 0 up to

Figure 3: Example of char and int

4,294,967,295. We request this interpretation by using the qualifier unsigned in the


declaration, as shown in the second line of Figure 3.5. What about negative numbers? ints are
actually represented using an encoding called two’s complement, in which half of the 232
possible bit patterns are used to express negative numbers and the other half to express positive
ones. Specifically, all numbers with the most significant bit equal to 1 are negative numbers. A
32-bit int is inherently signed (i.e., can have both positive and negative values) and can express
values from −2, 147, 483, 648 to 2, 147, 483, 647. Note that both unsigned and signed ints
have 232 possible values. For the unsigned int they are all positive; for the signed int, half are
positive and half are negative. Another pair of qualifiers you may run into are short and long
which decrease or increase the total number of bits dedicated a particular variable, respectively.
For example, a short int (also referred to and declared in C simply as a short) is often only 16
bits long. Technically, the only requirement that the C language standard imposes is that a
short int has fewer than or equal to as many bits as an int, and that a long int has greater than or
equal to as many bits as an int.

Float Double Data Types

The final two basic data types in C allow the programmer to express real numbers. Since there
are an infinite number of real numbers, the computer cannot express them all (that would
require an infinite number of bits!). Instead, for values that cannot be represented exactly, an
approximation of the value is stored. If you think about the fact that that computers can only
store values as 0s and 1s, you may wonder how it is possible to store a real number, which has
a fractional part. In much the same way that decimal representations of a number can have a
fractional portion with places to the right of a decimal point (the tenth’s, hundredth’s,

COMSATS University Islamabad (CUI) , Islamabad Campus Page 38


Lab # 04 Working with State Machines and Different Data Types
thousandth’s, etc. places), binary representations of numbers can have fractional portions after
the binary point. The places to the right of the binary point are the half’s, quarter’s, eighth’s,
etc. places. One way we could (but often do not) choose to represent real numbers is fixed
point. We could take 32 bits, and interpret them as having the binary point in the middle. That
is, the most significant 16 bits would be the “integer” part, and the least 16 bits would be the
“fractional” part. While this representation would be conceptually simple, it is also rather
constrained—we could not represent very large numbers, nor could we represent very small
numbers precisely. Instead, the most common choice is similar to scientific notion. Recall that
in decimal scientific

Figure 4: Floating Point Representation. A float has 32 bits and a double has 64 bits to express

notation, number 403 can be expressed as 4.03 × 102. Computers use floating point notation,
the same notation but implicitly in base 2: m × 2e. m is called the mantissa (though you may
also hear it referred to as the significand). e is the exponent. A float has 32 bits used to
represent a floating point number. These 32 bits are divided into three fields. The lowest 23
bits encode the mantissa; the next 8 bits encode the exponent. The most significant bit is the
sign bit, s, which augments our formula as follows: (−1)s × m × 2e. (When s = 1, the number is
negative. When s = 0, the number is positive.) A double has 64 bits and uses them by
extending the mantissa to 52 bits and the exponent to 11 bits. Examples of both a float and a
double are shown in Figure 3.6.

COMSATS University Islamabad (CUI) , Islamabad Campus Page 39


Lab # 04 Working with State Machines and Different Data Types
In Lab:

Task 1:
Write a C program that solves a simple user-entered mathematical expression. It should take
input from the user (two floating type values and operations like *, /, + and -), calculate the
result and show it on screen. e.g. if the user inputs “5 + 6” the program should add numbers 5
and 6 and print the answer 11 on to the console.

Pre-requisites: understanding of ‘int’, ‘char’ and ‘float’ type variables in C.


Use format specifiers ‘%f’ for ‘float’; ‘%d’ for ‘int’ and ‘%c’ for ‘char’ type variables).

Task 2:
Following program prints a menu. It then takes input from user and displays the entered choice.
Type-in the C program given below into a new project, compile and run to see how it works.
#include <stdio.h>
#include <stdlib.h>

int main()
{
int choice=0;
while(choice!=4)
{
printf("\n\tMENU DEMONSTRATION");
printf("\n\t------------------------------");
printf("\n\n\t 1. OPTION 1");
printf("\n\t 2. OPTION 2");
printf("\n\t 3. OPTION 3");
printf("\n\t 4. EXIT");
printf("\n\n Enter Your Choice: ");
scanf("%d",&choice);
switch(choice)
{
case 1:
printf("\nYOU SELECTED OPTION %d",choice);
break;
case 2:
printf("\nYOU SELECTED OPTION %d",choice);
break;
case 3:
printf("\nYOU SELECTED OPTION %d",choice);
break;
case 4:
printf("\nYOU SELECTED OPTION %d",choice);
exit(0);
default:
printf("\nINVALID SELECTION...Please try again");
}
getchar();
}
}

Code Listing 1 Example Program

COMSATS University Islamabad (CUI) , Islamabad Campus Page 40


Lab # 04 Working with State Machines and Different Data Types
Task 3:
Modify the above program to implement following sate machine. Here ‘a’ and ‘b’ are user input characters. The
program should print out appropriate messages to the console when a user enters a character.

Figure 5 A Simple State Machine

Post Lab Task:


Write a C program to implement the following state machine.

Figure 5 State Machine for Post Lab Task

COMSATS University Islamabad (CUI) , Islamabad Campus Page 41


Lab # 04 Working with State Machines and Different Data Types

Critical Analysis / Conclusion


(By Student about Learning from the Lab)

Lab Assessment

Pre Lab /1

In Lab /5

Data Analysis /4 /10

Data
Post Lab /4 /4
Presentation

Writing Style /4

Instructor Signature and Comments

COMSATS University Islamabad (CUI) , Islamabad Campus Page 42


Lab # 05 Working with Custom Functions in C

Lab # 05 Working with Custom Functions in C

Objectives:
• Learn to use custom functions in C
• Learn to implement mathematical functions in programs using C functions.
• Learn to use math.h library

Tools:

Software Tools:

• CodeBlocksIDE or similar.

Pre Lab Reading: Functions in C


A function gives a name to a parameterized computation—it is the implementation in code of a
specific algorithm. All of the code that you will read or write (in this book) will be inside of
functions. There are two sides to using functions in your programming: declaring a function—
which provides the definition for how a function behaves—and calling a function—which
executes the definition of the function on specific values of the parameters.

Figure 1 Variables organized into frames

Figure 2 shows a function declaration. The function’s name may be any valid identifier, just
like a variable’s name. In this particular example, the function’s name is myFunction.
Immediately before the function’s name is its return type—the type of value that this function
will compute. As mentioned earlier, we will learn more about types later. For now, we will just
work with ints, which are numbers. The fact that this function returns an int means that its
“answer” is an int. After the function’s name comes a set of parenthesis, with the parameter list

COMSATS University Islamabad (CUI) , Islamabad Campus Page 43


Lab # 05 Working with Custom Functions in C
inside. The parameter list looks like a comma separated list of variable declarations. Here, the
function takes two parameters, x, and y, both of which are ints. The similarity between
parameters and variable declarations is not a coincidence—the parameters behave much like
variables, but they are initialized by the function call (which we will discuss shortly).

Figure 2 A function declaration

The body of the function then comes between a set of curly braces, and is comprised of zero or
more statements. The body of this function has two statements. The first statement in this
function’s body is the now familiar declaration and initialization of a variable: z is declared as
a variable of type int, and initialized to the value of the expression x - 2 * y.

The second statement within the body of this function is a new type of statement which we
have not seen before: a return statement. A return statement starts with the keyword return,
which is then followed by an expression. The effect of this statement is to say what the
“answer” is for the current function, leaving its computation and returning to the code which
called it.

To understand this last concept completely, we must first see the other aspect of using a
function—calling the function. A function is another kind of expression, whose value is
whatever “answer” the called function comes up with when it is executed with the specified
arguments— values of its parameters. This “answer” is more formally called the function’s
return value.

Evaluating a function call is more complex than evaluating the other kinds of expressions that
we have seen so far—it may take many steps of executing the code in the function to determine
its answer. In fact, code may call one function, which itself may call other functions before
finally coming up with an answer. While this may seem daunting, we can do it properly by
following a few rules for executing function calls by hand.

As a first step towards reading code with function calls, we must first group together the
variables belonging to one particular function into a larger box, labeled with the function’s

COMSATS University Islamabad (CUI) , Islamabad Campus Page 44


Lab # 05 Working with Custom Functions in C
name, which is called a frame (or stack frame, since they are located on the call stack). Figure
1 shows an example of this organization.

Notice that in the example of Figure 1, one of the functions is named main. The function
named main is special—execution of a program starts at the start of main. We start by drawing
an empty frame for main, and putting the execution arrow right before the first line of code in
main. We then execute statements of the code until main returns, which ends the program.

Calls to functions may appear in expressions, in which case we must evaluate the function to
determine its return result. To do this evaluation, we take the following steps:

1. Draw a frame for the function being called. Place a box in that frame for each
parameter that this function takes.
2. Initialize the parameters by evaluating the corresponding expressions in the function
call, and copying the resulting values into the parameter’s box in the called function’s
frame.
3. Mark the location of the function call, and note that location in the corner of the
function’s frame.
4. Move the execution arrow immediately before the first line of code in the called
function.
5. Evaluate the lines of code inside the called function.
6. When you reach a return statement, evaluate its argument to a value. Note down this
return value.
7. Return the execution arrow back to where the function was called—you know this
location because you noted it in the corner of the frame. You will return the arrow to
the middle of the line of code (rather than the typical “between them”) because that line
of code is part-way done.
8. Erase the frame for the called function.
9. Use the return value of the function as the value of the function call in the expression in
which it appears.

In-Lab Task 1:

Write a C function 'int test_prime(int);' that takes in a positive number as input and returns true
(1) if the input number is prime or false (0) if the input is not prime. Then using this function,
write a C program that takes a number (N) as input from the user and prints out the first N
prime numbers.

COMSATS University Islamabad (CUI) , Islamabad Campus Page 45


Lab # 05 Working with Custom Functions in C
In-Lab Task 2:
(a) Write a C program that asks user to input a value for 𝜃 in degrees .It should then
calculate the value of the mathematical function 𝐲 and print its value on screen. Write
separate functions to implement 𝑓1 (𝜃) 𝑎𝑛𝑑 𝑓2 (𝜃) .

Hint: include the ‘math.h’ library and use the following functions. Remember that these
functions expect inputs to be in Radians.

double sin(double x);


double cos(double x);
𝑦 = 𝑓1 (𝜃) + 𝑓2 (𝜃)
𝜃 2 𝜃 2
𝑓1 (𝜃) = (cos ) , 𝑓2 (𝜃) = − (sin )
2 2
(b) Modify the above program to calculate the value of 𝑦.
Hint: include the ‘math.h’ library and use the following function:

double sqrt(double x);

𝑦 = 𝑓1 (𝜃) + 𝑓2 (𝜃) + 𝑓3 (𝜃)

𝜃 2
𝑓1 (𝜃) = (cos )
2

1 + cos 2𝜃
𝑓2 (𝜃) = 0.5√
2

1
𝑓3 (𝜃) =
2

Post Lab Task:


Write a C program that takes two floating type inputs from the user and calculates their
average, individual factorials, and a function 𝑓(𝑥, 𝑦) = √𝑥 2 + 𝑦 2. Use separate C functions to
compute the average, factorial and the function ‘f’. The program should print the results in the
main function.

COMSATS University Islamabad (CUI) , Islamabad Campus Page 46


Lab # 05 Working with Custom Functions in C

Critical Analysis / Conclusion


(By Student about Learning from the Lab)

Lab Assessment

Pre Lab /1

In Lab /5

Data Analysis /4 /10

Data
Post Lab /4 /4
Presentation

Writing Style /4

Instructor Signature and Comments

COMSATS University Islamabad (CUI) , Islamabad Campus Page 47


Lab 06 Functions, scope of variables and argument passing

Lab 06 Functions, scope of variables and argument


passing

Objectives:
• Understand the scope of variables when working with custom functions
• Provide more practice for custom functions

Pre-Lab Reading 1: Scope of Variables.


A scope is a region of a program. Variable Scope is a region in a program where a variable is
declared and used. So, we can have three types of scopes depending on the region where these
are declared and used:
• Local variables are defined inside a function or a block
• Global variables are outside all functions
• Formal parameters are defined in function parameters

Local Variables:
Variables that are declared inside a function or a block are called local variables and are said to
have local scope. These local variables can only be used within the function or block in which
these are declared. We can use (or access) a local variable only in the block or function in which
it is declared. It is invalid outside it.
Local variables are created when the control reaches the block or function containing the local
variables and then they get destroyed after that. Consider the following code:

#include <stdio.h>

void fun1()
{
/*local variable of function fun1*/
int x = 4;
printf("%d\n",x);
}
int main()
{
/*local variable of function main*/
int x = 10;
{
/*local variable of this block*/
int x = 5;
printf("%d\n",x);
}
printf("%d\n",x);
fun1();
}

COMSATS University Islamabad (CUI) , Islamabad Campus Page 48


Lab 06 Functions, scope of variables and argument passing

The output of this code will be:


5

10

The value of the variable ‘x’ is 5 in the block of code ({ }) defined inside the function ‘main’ and
the value of this variable ‘x’ in the ‘main’ function outside this block of code ({ }) is 10. The
value of this variable ‘x’ is 4 in the function ‘fun1’.
Global Variables:
Variables that are defined outside of all the functions and are accessible throughout the program
are global variables and are said to have global scope. Once declared, these can be accessed and
modified by any function in the program. We can have the same name for a local and a global
variable but the local variable gets priority inside a function. Consider the following code:

#include <stdio.h>

/*Global variable*/
int x = 10;

void fun1()
{
/*local variable of same name*/
int x = 5;
printf("%d\n",x);
}

int main()
{
printf("%d\n",x);
fun1();
}

The output of this program will be:


10

You can see that the value of the local variable ‘x’ was given priority inside the function ‘fun1’
over the global variable have the same name ‘x’.
Formal Parameters:

COMSATS University Islamabad (CUI) , Islamabad Campus Page 49


Lab 06 Functions, scope of variables and argument passing

Formal Parameters are the parameters which are used inside the body of a function. Formal
parameters are treated as local variables in that function and get a priority over the global
variables. Consider the following code:

#include <stdio.h>

/*Global variable*/
int x = 10;

void fun1(int x)
{
/*x is a formal parameter*/
printf("%d\n",x);
}

int main()
{
fun1(5);
}

The output will be:


5

COMSATS University Islamabad (CUI) , Islamabad Campus Page 50


Lab 06 Functions, scope of variables and argument passing

In-Lab Task 01:


Given the C program in the following code listing, complete the function sum_of_prod() that
takes 4 inputs (floating point numbers) and returns the their sum of products. Observe the outputs
generated by the program and explain what is happening with the Global variables and the
Formal Parameters.

#include <stdio.h>

int n1, n2, n3, n4;

int main(void)
{
printf("Enter four numbers separated by commas: ");
scanf("%d,%d,%d,%d", &n1, &n2, &n3, &n4);

printf("\nThe sum of products for n1 to n4 is: ");


printf("%d\n", sum_of_prod(in1, in2, in3, in4));

printf("\nThe sum of products for 3, 6, 4, 2 is: ");


printf("%d\n", sum_of_prod(3,6,4,2));

return(0);
}

/* This function returns the sum of products as follows

result = [n1 n2] * [n3


n4]
*/
int sum_of_prod(int n1, int n2, int n3, int n4)
{
/* Complete this function */
}

In-Lab Task 02:


Write a C program that inputs the value of n from the user and calculates the value of the
function

y = f1[n] + f2[n]

where
5
𝑓1 (𝑛) = ∑26
𝑛=1 (𝑛+5)+3

COMSATS University Islamabad (CUI) , Islamabad Campus Page 51


Lab 06 Functions, scope of variables and argument passing

𝑓2 (𝑛) = ∑(−1)𝑛−1 (2𝑛)


𝑛=1

The program should print the value of y on the console screen as well. Write separate functions
to compute f1[n] and f2[n]

Post Lab Task:


Write a similar program as In lab task 01 but for the following functions f1[n] and f2[n]

(−1)𝑛
𝑓1 (𝑛) =
(𝑛 + 1)!
4

𝑓2 (𝑛) = ∑ 2𝑛
𝑛=0

COMSATS University Islamabad (CUI) , Islamabad Campus Page 52


Lab 06 Functions, scope of variables and argument passing

Critical Analysis / Conclusion


(By Student about Learning from the Lab)

Lab Assessment

Pre Lab /1

In Lab /5

Data Analysis /4 /10

Data
Post Lab /4 /4
Presentation

Writing Style /4

Instructor Signature and Comments

COMSATS University Islamabad (CUI) , Islamabad Campus Page 53


Lab # 07 The Compilation Process

Lab # 07 The Compilation Process

Objectives:
• Understand the C compilation process.
• Learn to use Command Line Interface (CLI) of GNU C Compiler (GCC).
• Learn to compile single code files using GCC, CLI
• Learn to compile multiple code files using GCC, CLI

Pre-Lab Reading 1: GNU C Compiler (GCC) Compilation Process


Compiling a C program is a multi-stage process. At an overview level, the process can be split
into four separate stages:

1. Preprocessing
2. Compilation
3. Assembly
4. Linking

We will be using the following piece of code to illustrate this process. Save this code in a file
(using any text editor) and name it “test1.c”

#include<stdio.h>

int main(void)
{
int x = 0; // A variable to hold some data
int y = 5; // and another variable

printf("The sum of x and y is: %d", (x+y));

return(0);
}

Code Listing 3: A Simple C Program

Pre-processing:

This is the first phase through which source code is passed. This phase includes:

• Removal of Comments
• Expansion of Macros

COMSATS University Islamabad (CUI) , Islamabad Campus Page 54


Lab # 07 The Compilation Process

• Expansion of the included files.

In this stage, lines starting with a ‘#’ character are interpreted by the preprocessor as
preprocessor commands. These commands form a simple macro language with its own syntax
and semantics. This language is used to reduce repetition in source code by providing
functionality to inline files, define macros, and to conditionally omit code.
Before interpreting commands, the preprocessor does some initial processing. This includes
joining continued lines (lines ending with a \) and stripping comments.
To print the result of the preprocessing stage, pass the -E option to gcc:
gcc -E “Path\test1.c” -o “Path\test1.i”
or call the sub-process cpp as follows
cpp “Path\test1.c” -o “Path\test1.i”
Given the “test1.c” example above, the preprocessor will produce the contents of the stdio.h
header file joined with the contents of the test1.c file, stripped free from its leading comments.
[lines omitted for brevity]

# 625 "C:/Program Files/CodeBlocks/MinGW/include/stdio.h" 3


FILE* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) wpopen (const
wchar_t*, const wchar_t*);

# 3 "Z:\\Programing Fundamentals\\Labs\\Lab 07 Compilation Process\\Test


Code\\test1.c"
int main(void)
{
int x = 0;
int y = 5;

printf("The sum of x and y is: %d", (x+y));

return(0);
}

Figure 0-1 Output of the Preprocessing Step

Compilation:
The second stage of compilation is confusingly enough called compilation. In this stage, the
preprocessed code is translated to assembly instructions specific to the target processor
architecture. These form an intermediate human readable language.
The existence of this step allows for C code to contain inline assembly instructions and for
different assemblers to be used.
Some compilers also support the use of an integrated assembler, in which the compilation stage
generates machine code directly, avoiding the overhead of generating the intermediate assembly
instructions and invoking the assembler.

COMSATS University Islamabad (CUI) , Islamabad Campus Page 55


Lab # 07 The Compilation Process

To save the result of the compilation stage, pass the -S option to gcc:
gcc -S “Path\test1.i” -o “Path\test1.s”
This will create a file named ‘test1.s’, containing the generated assembly instructions. On
Windows 7 the following output is generated:
.file "test1.c"
.def ___main; .scl 2; .type 32; .endef
.section .rdata,"dr"
LC0:
.ascii "The sum of x and y is: %d\0"
.text
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $32, %esp
call ___main
movl $0, 28(%esp)
movl $5, 24(%esp)
movl 28(%esp), %edx
movl 24(%esp), %eax
addl %edx, %eax
movl %eax, 4(%esp)
movl $LC0, (%esp)
call _printf
movl $0, %eax
leave
ret
.ident "GCC: (tdm-1) 5.1.0"
.def _printf; .scl 2; .type 32; .endef

Figure 0-2 Generated Assembly File “test1.s”

Assembly:
During this stage, an assembler is used to translate the assembly instructions to object code. The
output consists of actual instructions to be run by the target processor.
To save the result of the assembly stage, pass the -c option to gcc:
gcc -c “Path\test1.c” -o “Path\test1.o”
or invoke the Assembler as follows:
as “Path\test1.s” -o “Path\test1.o”
Running the above command will create a file named ‘test1.o’, containing the object code of the
program. The contents of this file are in a binary format and can be inspected using Notepad++:
Linking:

COMSATS University Islamabad (CUI) , Islamabad Campus Page 56


Lab # 07 The Compilation Process

The object code generated in the assembly stage is composed of machine instructions that the
processor understands but some pieces of the program are out of order or missing. To produce an
executable program, the existing pieces have to be rearranged and the missing ones filled in. This
process is called linking.
The linker will arrange the pieces of object code so that functions in some pieces can
successfully call functions in other ones. It will also add pieces containing the instructions for
library functions used by the program. In the case of the “test1.c” program, the linker will add
the object code for the printf function.
The result of this stage is the final executable program. When run without options, gcc will name
this file test1.exe (on a Windows machine). To name the file something else, pass the -o option
to gcc:
gcc “Path\test1.c” -o “Path\test1.exe”
Or invoke the linker directly passing the Object file as input:
ld “Path\test1.o” -o “Path\test1.exe ...libraries...” (This will only work if the correct path
to libraries is provided. Out of scope for this lab.)
This process can be summarized by the following figure:

Figure 0-3 The Four-Step Compilation Process

Pre-Lab Reading 2: Splitting Your Code in Multiple Files


The programs we have seen so far have all been stored in a single source file. As your programs
become larger, and as you start to deal with other people's code (e.g. other C libraries) you will
have to deal with code that resides in multiple files. Indeed you may build up your own library of
C functions and data structures, that you can re-use in your own scientific programming and data
analysis. Here we will see how to place C functions and data structures in their own file(s) and
how to incorporate them into a new program.

COMSATS University Islamabad (CUI) , Islamabad Campus Page 57


Lab # 07 The Compilation Process

We saw when discussing functions, that one way of including custom-written functions in your
C code, is to simply place them in your main source file, above the declaration of the main()
function. A better way to re-use functions that you commonly incorporate into your C programs
is to place them in their own file, and to include a statement above main() to include that file.
When compiled, it's just like copying and pasting the code above main(), but for the purpose of
editing and writing your code, this allows you to keep things in separate files. It also means that
if you ever decide to change one of those re-usable functions (for example if you find and fix an
error) that you only have to change it in one place, and you don't have to go searching through all
of your programs and change each one.
Header files
A common convention in C programs is to write a header file (with .h suffix) for each source file
(.c suffix) that you link to your main source code. The logic is that the .c source file contains all
of the code and the header file contains the function prototypes, that is, just a declaration of
which functions can be found in the source file.
This is done for libraries that are provided by others, sometimes only as compiled binary "blobs"
(i.e. you can't look at the source code). Pairing them with plain-text header files allows you see
what functions are defined, and what arguments they take (and return).
Example:
Let's say you want to write a program that takes one integer input from the user, and determines
whether that integer is a prime number or not. Now let's say that you don't want to write your
own code for determining primality, so you ask your friend, who you know has written such a
function already. He sends you a pair of files (primes.h and primes.c). His header file (primes.h)
looks like this:

int isPrime(int n); // returns 0 if n is not prime, 1 if n is prime

Code Listing 4 The Header File for Prime Numbers “primes.h”

So we know a couple of things from this header file. It declares a function prototype for
isPrime(). We can see this function takes a single integer as an input argument, and returns an
integer value: 1 if the input value is a prime number, and 0 if it is not. Now we know all we need
to know in order to use this function (without even looking at the function's source code, which
resides in primes.c).
Here is what the primes.c file look like:

COMSATS University Islamabad (CUI) , Islamabad Campus Page 58


Lab # 07 The Compilation Process

int isPrime(int n)
{

// returns 0 if not prime, 1 if prime

if (n<2) return 0; // first prime number is 2


if (n==2) return 1; // ensure 2 is identified as a prime
if ((n % 2)==0) return 0; // all even numbers above 2 are not prime

int i;
for (i=3; i*i < n; i++) { // test divisibility up to sqrt(n)
if ((n % i) == 0) {
return 0;
}
}
return 1;
}

Code Listing 5 Source File "primes.c"

Here is what our program go.c looks like.


/** go.c
Asks the user for an input and then tells whether the entered number is prime
or not.
Compile with: gcc -o go.exe go.c primes.c
**/

#include <stdio.h>
#include <stdlib.h>
#include "primes.h"

int main(void)
{
int N;
int prime;

while(1)
{
printf("Enter a number");
scanf("%d", &N);

if(isPrime(N) != 0)
printf("The number %d is prime ",N);
else
{
printf("The number %d is not prime ",N);
break;
}
}
return 0;

Code Listing 6 The Main Program "go.c"

COMSATS University Islamabad (CUI) , Islamabad Campus Page 59


Lab # 07 The Compilation Process

Search path
The compiler will look in several places for header files that you include with the #include
directive, depending on how you use it. If you use include with the angled brackets (e.g. #include
<stdio.h>) then the compiler will look in a series of "default" system-wide locations (see Search
Path for details). If you use double-quotes (e.g. #include "neuron.h") then the compiler will look
in the directory containing the current file. It's possible to add other directories to the search path
by using the -Idir compiler option, where dir is the other directory. You might have to do this if
you link your code to an external C library that is not part of the standard C library, and does not
reside in the usual "system" default locations.

In-Lab Task 1:
Using the Notepad (the Windows text editor), save the program given in Code Listing 1 as a C
file (test1.c). Then use the GNU CLI to compile the program and generate the intermediate files
like, test1.i, test1.s, test1.o and finally test1.exe.

You will find the GNU Compiler in C:\Program Files\CodeBlocks\MinGW\Bin.

Hint: You will have to provide the complete path to source and destination files in double quotes
(e.g. “Path\test1.c”).

In-Lab Task-2:
Using the Notepad (the Windows text editor), save the programs given in Code Listing 2, 3 and 4
as c/h files (primes.h, primes.c, and go.c). Then use the GNU CLI to compile the program and
generate the intermediate files like, go.i, go.s, go.o and finally go.exe.

Post-Lab Task:
Submit a hand written report on what difficulties you faced in the lab, what sources of
information did you refer to to solve your problems, and what were the solutions you
implemented.

Reference Links:
1. https://www.gribblelab.org/CBootCamp/12_Compiling_linking_Makefile_header_files.html
2. https://www3.ntu.edu.sg/home/ehchua/programming/cpp/gcc_make.html
3. https://www.classes.cs.uchicago.edu/archive/2017/winter/51081-1/LabFAQ/lab2/compile.html#compilation_steps
4. https://www.gribblelab.org/CBootCamp/
5. https://www.geeksforgeeks.org/compiling-a-c-program-behind-the-scenes/
6. https://www.youtube.com/watch?v=VDslRumKvRA
7. https://www.youtube.com/watch?v=N2y6csonII4

COMSATS University Islamabad (CUI) , Islamabad Campus Page 60


Lab # 07 The Compilation Process

Critical Analysis / Conclusion


(By Student about Learning from the Lab)

Lab Assessment

Pre Lab /1

In Lab /5

Data Analysis /4 /10

Data
Post Lab /4 /4
Presentation

Writing Style /4

Instructor Signature and Comments

COMSATS University Islamabad (CUI) , Islamabad Campus Page 61


Lab # 08 Functions and Pointers in C

Lab # 08 Functions and Pointers in C

Objectives:
• Learn the basics of Pointers in C language
• Learn argument passing by reference to C functions
• Learn to return multiple outputs from functions using pointers

Pre-Lab Reading 1: Addresses of variables and Pointers in C


When a C programmer says that a certain variable is a “pointer”, what does that mean? It is hard
to see how a variable can point to something, or in a certain direction. It is hard to get a grip on
pointers just by listening to programmer’s jargon. In our discussion of C pointers, therefore, we
will try to avoid this difficulty by explaining pointers in terms of programming concepts we
already understand. The first thing we want to do is explain the rationale of C’s pointer notation.

Consider the declaration,


int i = 3 ;
This declaration tells the C compiler to:
a) Reserve space in memory to hold the integer value.
b) Associate the name i with this memory location.
c) Store the value 3 at this location.
We may represent i’s location in memory by the following memory map.

We see that the computer has selected memory location 65524 as the place to store the value 3.
The location number 65524 is not a number to be relied upon, because some other time the
computer may choose a different location for storing the value 3. The important point is, i’s
address in memory is a number. We can print this address number through the following
program:

COMSATS University Islamabad (CUI) , Islamabad Campus Page 62


Lab # 08 Functions and Pointers in C

main( )
{
int i = 3 ;
printf ( "\nAddress of i = %u", &i ) ;
printf ( "\nValue of i = %d", i ) ;
}

The output of the above program would be: Address of i = 65524 Value of i = 3 look at the first
printf( ) statement carefully. ‘&’ used in this statement is C’s ‘address of’ operator. The
expression &i returns the address of the variable i, which in this case happens to be 65524. Since
65524 represents an address, there is no question of a sign being associated with it. Hence it is
printed out using %u, which is a format specifier for printing an unsigned integer.
We have been using the ‘&’ operator all the time in the scanf( ) statement. The other pointer
operator available in C is ‘*’, called ‘value at address’ operator. It gives the value stored at a
particular address. The ‘value at address’ operator is also called ‘indirection’ operator.
Observe carefully the output of the following program:
main( )
{
int i = 3 ;
printf ( "\nAddress of i = %u", &i ) ;
printf ( "\nValue of i = %d", i ) ;
printf ( "\nValue of i = %d", *( &i ) ) ;
}

The output of the above program would be:


Address of i = 65524
Value of i = 3
Value of i = 3
Note that printing the value of *( &i ) is same as printing the value of i. The expression &i gives
the address of the variable i. This address can be collected in a variable, by saying,
j = &i ;
But remember that j is not an ordinary variable like any other integer variable. It is a variable that
contains the address of other variable (i in this case). Since j is a variable the compiler must
provide it space in the memory. Once again, the following memory map would illustrate the
contents of i and j.

COMSATS University Islamabad (CUI) , Islamabad Campus Page 63


Lab # 08 Functions and Pointers in C

Pre-Lab Reading 2: Returning multiple values from a function


In C, we cannot return multiple values from a function directly. In this section, we will see how
to use some trick to return more than one value from a function.

We can return more than one values from a function by using the method called “call by
address”, or “call by reference”. In the invoker function, we will use two variables to store the
results, and the function will take pointer type data. So we have to pass the address of the data.

In this example, we will see how to define a function that can return quotient and remainder after
dividing two numbers from one single function.

#include<stdio.h>

void div(int a, int b, int *quotient, int *remainder)


{
*quotient = a / b;
*remainder = a % b;
}
main()
{
int a = 76, b = 10;
int q, r;
div(a, b, &q, &r);
printf("Quotient is: %d\nRemainder is: %d\n", q, r);
}

COMSATS University Islamabad (CUI) , Islamabad Campus Page 64


Lab # 08 Functions and Pointers in C

In-Lab Task 1:
For the given program find (and print) the addresses assigned to all the variables against their
names.

#include<stdio.h>

void test(void);

int m = 22, n = 44;


float a = 50.5, b = 8.79;

int main()
{
int x, y=5, z = 5;
test();
}
void test()
{
char ch1 = ‘F’, ch2 = 69, ch3 = 100;
int x = 5, y = 55, z = 8;
}

In-Lab Task 2: Color Space Conversion


YCbCr, Y′CbCr, or Y Pb/Cb Pr/Cr, also written as YCBCR or Y'CBCR, is a family of color
spaces used as a part of the color image pipeline in video and digital photography systems. Y′ is
the luma component and CB and CR are the blue-difference and red-difference chroma
components. Y′ (with prime) is distinguished from Y, which is luminance, meaning that light
intensity is nonlinearly encoded based on gamma corrected RGB primaries.

Y′CbCr color spaces are defined by a mathematical coordinate transformation from an associated
RGB color space. If the underlying RGB color space is absolute, the Y′CbCr color space is an
absolute color space as well; conversely, if the RGB space is ill-defined, so is Y′CbCr.

COMSATS University Islamabad (CUI) , Islamabad Campus Page 65


Lab # 08 Functions and Pointers in C

Write a C function which takes three integer inputs, corresponding to RGB components of a
colored pixel, and coverts them to the YUV color space. The function should have the following
prototype.

void rgb2ycbcr(int r, int g, int b, float * y, float * Cr, float * Cb);

Example:

int rgb2gray(int r, int g, int b)


{
int result;
result = (int)((0.257*r)+(0.504*g)+(0.098*b));
return(result);
}

Testing your code:

You are given three files:

1. main.c
2. my_lib.h
3. my_lib.o

Complete the function rgb2ycbcr() , compile the project using command line and run the code.

gcc main.c my_lib.o -o output.exe

See if you get the success message.

Post Lab Task: Recursion


Write a recursive version for the Fibonacci function developed in class.

COMSATS University Islamabad (CUI) , Islamabad Campus Page 66


Lab # 08 Functions and Pointers in C

Critical Analysis / Conclusion


(By Student about Learning from the Lab)

Lab Assessment

Pre Lab /1

In Lab /5

Data Analysis /4 /10

Data
Post Lab /4 /4
Presentation

Writing Style /4

Instructor Signature and Comments

COMSATS University Islamabad (CUI) , Islamabad Campus Page 67


Lab # 09 Working with Arrays and Pointers

Lab # 09 Working with Arrays and Pointers

Objectives:
• Learn the basic operations on arrays (e.g. traversal, value swapping, retrieving indices
etc)
• Accessing array elements via pointers.
• Practice array operations by implementing simple sorting algorithms.

Reading Task 1: Working with Arrays


Chapter 08 Arrays (pages 269 to 288) from the book: “Let us C” by Yashavant Kanetkar

Reading Task 2: Selection Sort Algorithm


In computer science, selection sort is a sorting algorithm, specifically an in-place comparison
sort. It has O(n2) time complexity, making it inefficient on large lists, and generally performs
worse than the similar insertion sort. Selection sort is noted for its simplicity, and it has
performance advantages over more complicated algorithms in certain situations, particularly
where auxiliary memory is limited.

The algorithm divides the input list into two parts: the sublist of items already sorted, which is
built up from left to right at the front (left) of the list, and the sublist of items remaining to be
sorted that occupy the rest of the list. Initially, the sorted sublist is empty and the unsorted sublist
is the entire input list. The algorithm proceeds by finding the smallest (or largest, depending on
sorting order) element in the unsorted sublist, exchanging (swapping) it with the leftmost
unsorted element (putting it in sorted order), and moving the sublist boundaries one element to
the right.

Example:

Here is an example of this sort algorithm sorting five elements:

Sorted sublist Unsorted sublist Least element in unsorted list


() (11, 25, 12, 22, 64) 11
(11) (25, 12, 22, 64) 12
(11, 12) (25, 22, 64) 22
(11, 12, 22) (25, 64) 25
(11, 12, 22, 25) (64) 64
(11, 12, 22, 25, 64) ()

COMSATS University Islamabad (CUI) , Islamabad Campus Page 68


Lab # 09 Working with Arrays and Pointers

Selection sort can also be used on list structures that make add and remove efficient, such as a
linked list. In this case it is more common to remove the minimum element from the remainder
of the list, and then insert it at the end of the values sorted so far. For example:

arr[] = 64 25 12 22 11
// Find the minimum element in arr[0...4]
// and place it at beginning
11 25 12 22 64
// Find the minimum element in arr[1...4]
// and place it at beginning of arr[1...4]
11 12 25 22 64
// Find the minimum element in arr[2...4]
// and place it at beginning of arr[2...4]
11 12 22 25 64
// Find the minimum element in arr[3...4]
// and place it

In-Lab Task 1: Finding Minimum and Maximum Values in an


Array
Your task is to perform some functions on integer arrays. Specifically you will write a C program
that does the following:

1. Declare an array of size 20.


2. Initialize the array with random values (use loop, and rand() function).
3. Print all the elements in the array.
4. Print all the elements in the array in the reverse order.
5. Print the array such that every Nth element gets printed. N is user input.

In-Lab Task 2: Implementing Selection Sort


You are given a C program in Code Listing 1, that does the following:

1. Declares an integer array with 50 elements (not initialized).


2. Populates the array with random positive numbers. (Uses a loop and rand() function)
3. Calls the function ‘int find_max(int * ptr_array, int size)’ and prints the value and index
of the largest number.

COMSATS University Islamabad (CUI) , Islamabad Campus Page 69


Lab # 09 Working with Arrays and Pointers

#include <stdio.h>
#include <stdlib.h>

#define ASCENDING 0
#define DESCENDING 1

#define ARRAY_SIZE 50

int find_max(int * ptr_array, int size);


int find_min(int * ptr_array, int size);
void selection_sort(int * ptr_array, int size, int order);

int main(void)
{
int num_array[ARRAY_SIZE]; /// Declare an integer array
int * ptr_ar = &num_array[0]; /// A pointer to the start of the array

for(int i =0; i < ARRAY_SIZE; i++)


{
num_array[i] = rand()%100; /// Initialize the array with random numbers in range 0
to 99
printf("%d ", num_array[i]);/// and print it.
}

int mx_idx = find_max(ptr_ar, ARRAY_SIZE); /// Print the maximum value and its index
printf("\nThe maximum number is %d at index %d \n", num_array[mx_idx], mx_idx);
int mn_idx = find_min(ptr_ar, ARRAY_SIZE); /// Print the minimum value and its index
printf("\nThe minimum number is %d at index %d \n", num_array[mn_idx], mn_idx);

selection_sort(num_array, ARRAY_SIZE, ASCENDING); /// Sort the array using


Selection Sort
for(int i=0; i<ARRAY_SIZE; i++) /// Print the sorted array
printf("%d ", num_array[i]);

return 0;
}
int find_max(int * ptr_array, int size)
{
int max_val = 0;
int max_idx = 0;

for(int i=0; i<size; i++)


{
if(*(ptr_array+i) > max_val)
{
max_val = *(ptr_array+i);
max_idx = i;
}
}
return(max_idx);

}
int find_min(int * ptr_array, int size)
{
return 0;
}
void selection_sort(int * ptr_array, int size, int order)
{

COMSATS University Islamabad (CUI) , Islamabad Campus Page 70


Lab # 09 Working with Arrays and Pointers

Write a similar function ‘int find_min(int * ptr_array, int size)’ and print the value and index of
the smallest number in the array as well.

Implementing Selection Sort

Your second task is to implement the Selection Sort algorithm by making a function with the
following prototype;

void selection_sort(int * ptr_array, int size, int order);

This function takes as input a pointer to the start of the array, and the array size and sorts it in-
place. The last input to the function is the sorting order (0 for ascending and 1 for descending).
You should call the functions (find_max(), find_min()) developed in lab-task 1 to implement
Selection Sort algorithm.

Post-Lab Task: Implement Insertion Sort Algorithm


Your second task is to implement the Insertion Sort algorithm by making a function with the
following prototype;

void insertion_sort(int * ptr_array, int size, int order);

This function takes as input a pointer to the start of the array, and the array size and sorts it in-
place. The last input to the function is the sorting order (0 for ascending and 1 for descending).

References:

1. https://www.toptal.com/developers/sorting-algorithms
2. https://en.wikipedia.org/wiki/Selection_sort
3. https://en.wikipedia.org/wiki/Insertion_sort

COMSATS University Islamabad (CUI) , Islamabad Campus Page 71


Lab # 09 Working with Arrays and Pointers

Critical Analysis / Conclusion


(By Student about Learning from the Lab)

Lab Assessment

Pre Lab /1

In Lab /5

Data Analysis /4 /10

Data
Post Lab /4 /4
Presentation

Writing Style /4

Instructor Signature and Comments

COMSATS University Islamabad (CUI) , Islamabad Campus Page 72


Lab # 10 Working with 2D Arrays in C

Lab # 10 Working with 2D Array in C

Objectives:
• Learn the basic operations on 2D arrays.
• Printing 2D array contents to console screen.
• Accessing 2D array elements via pointers.
• Practicing 2D array operations by implementing a Magic Square algorithm.

Reading Task 1: Working with Arrays


Chapter 08 Arrays (pages 269 to 303) from the book: “Let us C” by Yashavant Kanetkar

Reading Task 2: The Magic Square


The magic square is a square matrix, whose order is odd and where the sum of the elements for
each row or each column or each diagonal is same. The sum of each row or each column or each
diagonal can be found using this formula. n(n2+ 1)/2 where ‘n’ is the order of the matrix.

Figure 1: Magic Square of order 3

A method for constructing magic squares of odd order was published by the French diplomat de
la Loubère in his book, “A new historical relation of the kingdom of Siam” (Du Royaume de
Siam, 1693), in the chapter entitled The problem of the magical square according to the Indians.
The method operates as follows:
1. The method prescribes starting in the central column of the first row with the number 1.

COMSATS University Islamabad (CUI) , Islamabad Campus Page 73


Lab # 10 Working with 2D Arrays in C

2. After that, the fundamental movement for filling the squares is diagonally up and right,
one step at a time.
3. If a filled square is encountered, one moves vertically down one square instead, then
continues as before.
4. When an "up and to the right" move would leave the matrix, it is wrapped around to the
last row or first column, respectively.

Figure 2. Algorithm for filling the Magic Square

In-Lab Task 1: 2D Arrays and user defined functions


• Your task is to declare a 2D array whose dimensions should be entered by the user of the
program.

• Then you should initialize the array with ones (using nested loops).

• Next you have to write a function array_multiply() which takes in the array or its
pointer as argument and multiplies all its entries with a user input number. (Hint: you
will also need to pass in the dimensions of the matrix to this function).

• Similarly write a function array_add() that adds a constant number to all the entries in a
2D array.

• Print the results of calling these functions.

COMSATS University Islamabad (CUI) , Islamabad Campus Page 74


Lab # 10 Working with 2D Arrays in C

In-Lab Task 2: Implementing the algorithm for the Magic Square


In this task you have to make a magic square and display it on the screen. You are given a Starter
Code (Annex I), that does the following:

• Asks the user to enter the order ‘n’ of the magic square (odd numbers only).

• Declares a 2D array of size n x n and initializes it with zeros.

• Prints the magic square on the screen.


Your job is to complete this code by implement the algorithm discussed in the Reading Task 2.
References

1. https://en.wikipedia.org/wiki/Magic_square#A_method_for_constructing_a_magic_
square_of_odd_order

Practice for Magic Square Algorithm:

You can fill in the following 5 x 5 grid to see if you have grasped the working of the algorithm.
You can test your work by checking the sum of rows, columns and the main diagonal. They
should all be the same.

COMSATS University Islamabad (CUI) , Islamabad Campus Page 75


Lab # 10 Working with 2D Arrays in C

ANNEX I: Code Listings for In-Lab Task 2

#include <stdio.h>
#include <stdlib.h>

int magic_square(int n);

int main()
{
int n;
printf("Enter the order of Magic Square (positive Odd Nums only): \n");
scanf("%d", &n);
printf("\n\n");
if(magic_square(n) != 0)
printf("\nPlease enter correct value for n!!");
return 0;
}

COMSATS University Islamabad (CUI) , Islamabad Campus Page 76


Lab # 10 Working with 2D Arrays in C

void magic_square(int n)
{
/// to rule out zero, negative and even inputs
if((n<1) || (n%2 == 0))
return(-1);
/// Declare an n x n array using C VLAs (Variable Length Arrays)
int mSquare[n][n];
/// Initialize the matrix with zeros
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
{
mSquare[i][j] = 0;
}
}
int count = 1; /// The first entry in the Magic Square
///start from middle col in the first row.
int col = (n-1)/2;
int row = 0;
/// Step1: Fill 1 in the middle column first row
mSquare[row][col] = count;
int row_t; /// for temporary storage
int col_t;
/************ INSERT YOUR CODE HERE ********/
/// Print the Magic Square
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
{
printf("%d\t", mSquare[i][j]);
}
printf("\n");
}
return(0);
}

COMSATS University Islamabad (CUI) , Islamabad Campus Page 77


Lab # 10 Working with 2D Arrays in C

Critical Analysis / Conclusion


(By Student about Learning from the Lab)

Lab Assessment

Pre Lab /1

In Lab /5

Data Analysis /4 /10

Data
Post Lab /4 /4
Presentation

Writing Style /4

Instructor Signature and Comments

COMSATS University Islamabad (CUI) , Islamabad Campus Page 78


Lab # 11 Working with Strings in C

Lab # 11 Working with Strings in C

Objectives:
• Learn the basic operations with Strings.
• Differentiate between C Strings and 2D arrays.
• Using built-in C functions for string manipulation.
• Develop custom functions for C String manipulation.

Reading Task 1: Working with Arrays


Strings are one-dimensional array of characters terminated by a null character '\0'. Thus, a null-
terminated string contains the characters that comprise the string followed by a null.

The following declaration and initialization create a string consisting of the word "Hello". To
hold the null character at the end of the array, the size of the character array containing the string
is one more than the number of characters in the word "Hello."

char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};

If you follow the rule of array initialization then you can write the above statement as follows:

char greeting[] = "Hello";

Following is the memory presentation of the above defined string in C

Actually, you do not place the null character at the end of a string constant. The C compiler
automatically places the '\0' at the end of the string when it initializes the array. Let us try to print
the above-mentioned string:

COMSATS University Islamabad (CUI) , Islamabad Campus Page 79


Lab # 11 Working with Strings in C

#include <stdio.h>

int main ()
{
char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
printf("Greeting message: %s\n", greeting );
return 0;
}

When the above code is compiled and executed, it produces the following result:

Greeting message: Hello

C supports a wide range of functions that manipulate null-terminated strings:

Sr.No. Function & Purpose

1
strcpy(s1, s2);
Copies string s2 into string s1.

2
strcat(s1, s2);
Concatenates string s2 onto the end of string s1.

3
strlen(s1);
Returns the length of string s1.

4
strcmp(s1, s2);
Returns 0 if s1 and s2 are the same; less than 0 if s1<s2; greater than 0 if s1>s2.

5
strchr(s1, ch);
Returns a pointer to the first occurrence of character ch in string s1.

6
strstr(s1, s2);
Returns a pointer to the first occurrence of string s2 in string s1.

The following example uses some of the above-mentioned functions:

COMSATS University Islamabad (CUI) , Islamabad Campus Page 80


Lab # 11 Working with Strings in C

#include <stdio.h>
#include <string.h>

int main () {

char str1[12] = "Hello";


char str2[12] = "World";
char str3[12];
int len ;

/* copy str1 into str3 */


strcpy(str3, str1);
printf("strcpy( str3, str1) : %s\n", str3 );

/* concatenates str1 and str2 */


strcat( str1, str2);
printf("strcat( str1, str2): %s\n", str1 );

/* total lenghth of str1 after concatenation */


len = strlen(str1);
printf("strlen(str1) : %d\n", len );

return 0;
}

When the above code is compiled and executed, it produces the following result:

strcpy( str3, str1) : Hello

strcat( str1, str2): HelloWorld

strlen(str1) : 10

In-Lab Task 1:
Write a C Program that does the following:

1. Declares a C-String called ‘m1’ and initializes it with text “Programming is great fun!”.
2. Uses C-function puts() to print this string.
3. Asks the user to enter a String named ‘m2’ (Hint: Use gets() function for this.)
4. Concatenates the two strings and stores the result in ‘m3’.

For example if the user enters m2 as “Not Really!”, m3 should be “Programming is great
fun! Not really!”

5. Inserts the user entered array (m2) into m1 after “Programming is ...”

For the above example, the resultant String would become “Programming is Not really!
great fun!”

COMSATS University Islamabad (CUI) , Islamabad Campus Page 81


Lab # 11 Working with Strings in C

In-Lab Task 2 a:
Write a program that converts a string like "124" to an integer 124.

In-Lab Task 2 b:
Write a program that replaces two or more consecutive blanks in a string by a single blank. For
example, if the input is

“Grim return to the planet of apes!!”

the output should be

“Grim return to the planet of apes!!”

COMSATS University Islamabad (CUI) , Islamabad Campus Page 82


Lab # 11 Working with Strings in C

Critical Analysis / Conclusion


(By Student about Learning from the Lab)

Lab Assessment

Pre Lab /1

In Lab /5

Data Analysis /4 /10

Data
Post Lab /4 /4
Presentation

Writing Style /4

Instructor Signature and Comments

COMSATS University Islamabad (CUI) , Islamabad Campus Page 83


Lab # 12 Structures in C

Lab # 12 Structures in C

Objectives:
• Learn the basics of C Structures.
• Learn to declare structures.
• Accessing elements of a structure.
• Develop programs for using C Structures

Reading Task 1: Working with Structures


Chapter 10 Structures (pages 363 to 378) from the book: “Let us C” by Yashavant Kanetkar.

In-Lab Task 1:
Write a C Program that does the following:

1. Declares a C-Structure called ‘car’.


2. It should contain the following elements
a) A char array of size 20 to hold the make of the car e.g. Suzuki.
b) A char array of size 20 to hold the model of the car e.g. Alto
c) An integer capacity to store the seating capacity.
d) A floating point number to hold the weight of the empty vehicle.
3. Then declare 3 variables of this type of structure.
4. Let the user populate the elements of these variables.
5. Print these structures

In-Lab Task 2 a:
Write a C program that declares an array of structures of type ‘car’ from previous example, and
asks the user to fill in the elements. Once all the structures have been initialized, the program
should present a menu to the user so that he can print a certain structure, or modify its elements.

In-Lab Task 2 b:
There is a structure called employee that holds information like employee code, name, date of
joining. Write a program to create an array of the structure and enter some data into it. Then ask
the user to enter current date. Display the names of those employees whose tenure is 3 or more
than 3 years according to the given current date.

COMSATS University Islamabad (CUI) , Islamabad Campus Page 84


Lab # 12 Structures in C

Critical Analysis / Conclusion


(By Student about Learning from the Lab)

Lab Assessment

Pre Lab /1

In Lab /5

Data Analysis /4 /10

Data
Post Lab /4 /4
Presentation

Writing Style /4

Instructor Signature and Comments

COMSATS University Islamabad (CUI) , Islamabad Campus Page 85

You might also like