Unit 1 - Introduction To Programming and Algorithms For Problem Solving
Unit 1 - Introduction To Programming and Algorithms For Problem Solving
PROBLEM SOLVING
Problem-solving is a crucial skill in programming, where the primary goal is to find a solution to a
given problem and implement it using a programming language. This process involves several steps,
from understanding the problem to developing an efficient solution. Here's an overview of the key
components involved in problem-solving through programs.
Before diving into coding, it’s essential to thoroughly understand the problem. This includes
identifying:
Once the problem is broken down, the next step is to develop a step-by-step algorithm to solve it. An
algorithm is a logical sequence of actions or instructions that guide the problem-solving process.
1. Start.
2. Input two numbers, A and B
3. Add the numbers: C = A + B
4. Output the result C
5. End
To better visualize and understand the solution, the algorithm can be represented using:
BEGIN
DECLARE num1, num2, sum AS INTEGER
Once the algorithm is clear, the next step is to translate it into a program using a programming
language such as C, Python, or Java. The program consists of instructions that tell the computer
what to do in order to solve the problem.
A compiler converts a C program into an executable. There are four phases for a C program to
become an executable:
1. Pre-processing: Let us one by one see what these intermediate files contain.
1. Pre-processing
This is the first phase through which source code is passed. This phase includes:
Removal of Comments
Expansion of Macros
Expansion of the included files.
Conditional compilation
The pre-processed output is stored in the filename.i. Let’s see what’s inside filename.i: using $vi
filename.i
In the above output, the source file is filled with lots and lots of info, but in the end, our code is
preserved.
printf contains now a + b rather than add(a, b) that’s because macros have expanded.
Comments are stripped off.
#include<stdio.h> is missing instead we see lots of code. So header files have been expanded and
included in our source file.
2. Compilation: The next step is to compile filename.i and produce an; intermediate compiled output
file filename.s. This file is in assembly-level instructions.
3. Assembly: In this phase the filename.s is taken as input and turned into filename.o by the
assembler. This file contains machine-level instructions. At this phase, only existing code is
converted into machine language, and the function calls like printf() are not resolved .
4. Linking
This is the final phase in which all the linking of function calls with their definitions is done. Linker
knows where all these functions are implemented. Linker does some extra work also: it adds some
extra code to our program which is required when the program starts and ends.
After writing the program, it goes through a compilation process (in the case of compiled languages
like C). The program is checked for:
Logical Errors: The program runs but does not produce the correct output due to flaws in the
algorithm.
Once compiled, the program is tested with various inputs to ensure it works correctly and handles
edge cases. Debugging is the process of identifying and fixing errors in the program.
After debugging, the program is tested with a range of inputs to ensure it meets the problem’s
requirements. Testing includes verifying that the program:
8. Optimization
If the program works but is slow or uses too much memory, optimization techniques can be applied to
make it more efficient. This can involve changing the algorithm to reduce time complexity or using
better data structures.
Problem-solving in programming is often an iterative process. The initial solution may need to be
refined or adjusted as more is learned about the problem or as new constraints are identified.
Solutions evolve over time, becoming more robust and efficient.
1.2 Algorithm
Definition of an Algorithm
Algorithms are used in almost every aspect of computer science, from simple arithmetic operations to
complex artificial intelligence (AI) tasks.
1. Finiteness:
The algorithm must terminate after a finite number of steps. It should not run indefinitely.
2. Definiteness:
Every step in the algorithm must be clear and unambiguous. Each instruction must be well-
defined to avoid confusion or misinterpretation.
3. Input:
The algorithm should accept zero or more inputs. These are values provided to the algorithm to
process and solve the problem.
4. Output:
The algorithm must produce one or more outputs as a result of its processing. The output is the
solution to the given problem.
5. Effectiveness:
The algorithm’s steps must be simple and feasible, so they can be performed with a pencil and
paper or by a computer. The solution must be achieved in a reasonable amount of time and
resources.
6. Generality:
An algorithm should be general enough to handle different sets of inputs and not just work for a
specific case. It must solve all variations of the problem within the scope of the algorithm.
Representation of Algorithms
Algorithms can be represented in different ways to help better understand and communicate the
solution:
1. Natural Language:
Writing the steps of the algorithm in plain English (or any natural language). This approach
may lack clarity and precision.
2. Flowcharts:
Example of an Algorithm
Problem Statement: Write an algorithm to input two numbers, add them, and display the result.
1. Step 1: Start
2. Step 2: Declare three variables: num1, num2, and sum
3. Step 3: Input the values of num1 and num2
4. Step 4: Add the values of num1 and num2, and store the result in sum
5. Step 5: Output the value of sum
6. Step 6: End
Advantages of Algorithms
1. Clarity and Precision: Algorithms provide clear, step-by-step instructions to solve problems,
reducing ambiguity.
2. Efficiency: They optimize time and space usage, improving performance in solving tasks.
3. Reusability: Algorithms can be reused for similar problems, saving time and effort.
4. Modularity: Problems are broken into smaller parts, making debugging and maintenance
easier.
5. Optimization: They help in identifying the most efficient solution for a problem.
6. Standardization: Algorithms offer consistent methods for solving common tasks like sorting
and searching.
7. Easy Debugging: Structured steps make identifying and fixing errors easier.
8. Scalability: Algorithms handle large datasets efficiently, making them suitable for big tasks.
9. Automation: They enable automated processes in computers and machines.
10. Problem-Solving Framework: Provide a systematic approach, fostering logical thinking.
1.3 Flowchart
Definition of a Flowchart
1. Visualization: They provide a clear and intuitive way to understand the process flow.
2. Simplification: Complex algorithms and workflows can be broken down into simple, easy-to-
follow steps.
3. Communication: Flowcharts make it easier to convey the logic of a process or system to
others.
4. Documentation: Flowcharts serve as documentation for processes and can be referenced later
for maintenance or review.
5. Debugging: Flowcharts help identify inefficiencies or errors in the process by offering a visual
breakdown of each step.
Each step in a flowchart is represented by a specific symbol, and arrows show the direction of the
process flow. Here are the common symbols:
1. Oval (Terminator):
2. Rectangle (Process):
3. Parallelogram (Input/Output):
Function: Represents an input or output operation, such as reading data from the user or
displaying results.
Example:
4. Diamond (Decision):
Function: Represents a decision point, where the process can branch based on a condition
(true/false).
Example:
6. Circle (Connector):
Function: Used as a connector to connect flowcharts on the same page or between different
pages.
Usage: Used to continue the flow in complex charts where arrows may be hard to follow.
7. Hexagon (Preparation):
Usage: Often used in system diagrams for data storage or retrieval steps.
Problem Statement: Design a flowchart to input two numbers, add them, and display the result.
1. Clarity: Flowcharts simplify the understanding of complex processes by breaking them down
into clear, manageable steps.
2. Communication: They serve as an excellent tool for communicating ideas and processes
among teams or stakeholders.
3. Problem-Solving: Flowcharts help in identifying bottlenecks, inefficiencies, or redundant steps
in a process.
4. Documentation: Flowcharts can be used as a reference to document the steps of a process or
algorithm.
5. Debugging and Maintenance: By visualizing the process, it becomes easier to debug errors or
make changes to the logic of a system.
1.4 Pseudocode
Pseudocode is a simplified, informal way of writing a program's logic using plain language. It
bridges the gap between human language and programming languages, helping to express algorithms
clearly without worrying about syntax. Pseudocode doesn't follow strict rules like a specific
programming language but follows logical steps that can easily be translated into code.
and adaptable.
❖ Focus on Logic: Pseudocode emphasizes the algorithmic steps and logic of the process rather
Writing Pseudocode
1. Step-by-Step Structure: The pseudocode should list the steps in a sequential order.
2. Use Simple Language: Use clear, plain English to describe actions.
3. Use Standard Programming Constructs: Incorporate familiar terms like IF, ELSE, WHILE,
and FOR loops to represent logic.
4. Avoid Syntax-Specific Details: Don’t include language-specific syntax such as semicolons or
braces.
5. Keep It Flexible: Pseudocode should focus on logic and structure rather than precise details.
Problem: Write pseudocode to add two numbers and display the result.
Start
Declare num1, num2,
Output sum
End
1. Ease of Understanding: Pseudocode uses plain English and logical structures, making it
accessible to anyone, even non-programmers.
2. No Syntax Errors: Since pseudocode does not follow any specific programming language's
syntax, you don't need to worry about syntax errors.
3. Focus on Algorithm Design: It focuses on designing the logic and flow of the algorithm rather
than on coding details.
4. Flexible: It can be adapted to any programming language, allowing the developer to focus on
the problem-solving aspect first.
5. Planning Tool: Pseudocode helps in planning out the structure of programs before actually
coding them, improving the quality of the final implementation.
1.5 Memory
Memory in computing refers to the physical devices that store data temporarily or permanently for
use in computers and other digital devices. Memory is crucial because it holds the data and
instructions that the processor uses to perform tasks. The performance of a system largely depends on
how efficiently it can access and manage memory.
Types of Memory
Primary memory is directly accessible by the CPU and is used to store data that is actively being
worked on or used by running applications. It is called volatile memory because its contents are lost
when the power is turned off.
RAM is a temporary storage area that stores data and instructions for active processes. It allows
for both read and write operations and provides fast access to data. When a computer runs a
program, it loads the program’s data and instructions into RAM for quick access.
Types of RAM:
DRAM (Dynamic RAM): Needs constant refreshing to retain data. It is slower but
cheaper.
SRAM (Static RAM): Does not need refreshing and is faster but more expensive than
DRAM.
Cache Memory:
Cache is a smaller, faster type of memory that stores frequently accessed data to improve
processing speed. It acts as a buffer between the CPU and main memory (RAM).
Levels of Cache:
L1 Cache: Located inside the CPU, it's the smallest and fastest cache.
L2 Cache: Slightly larger and slower, located near or inside the CPU.
L3 Cache: Larger but slower than L1 and L2, shared by multiple CPU cores.
Registers:
Registers are small storage locations within the CPU that store data or instructions being
processed by the processor. They provide the fastest access to data and are directly accessed by
the CPU.
ROM is non-volatile memory that stores critical data and instructions that do not change, such
as the system’s firmware (BIOS). Data in ROM remains even when the computer is powered
off.
Types of ROM:
Speed: Primary memory provides fast access to data, which is critical for high-speed performance.
Volatility: RAM and Cache memory are volatile, meaning data is lost when the system shuts down.
Only ROM retains data after power loss.
Secondary memory is used for long-term data storage and is non-volatile, meaning it retains data
even when the power is off. It is slower than primary memory but offers much larger storage
capacity.
HDDs are traditional magnetic storage devices with spinning platters that store data. They are
commonly used in personal computers and offer large storage capacities at a lower cost, but
they are slower than modern storage technologies.
SSDs use flash memory to store data, making them much faster than HDDs because they have
no moving parts. They provide faster boot times and quicker access to files but are more
expensive per gigabyte than HDDs.
Optical storage media use lasers to read and write data. These discs are used to store data
permanently and are commonly used for distributing software, movies, and games.
Flash drives are portable memory storage devices that use flash memory to store data. They are
small, durable, and convenient for transferring data between devices.
Memory cards are used in cameras, smartphones, and other portable devices to store data. They
are also based on flash memory technology.
Non-Volatility: Secondary memory retains data even when the computer is turned off, making it
Capacity: It provides significantly more storage than primary memory and is used for storing files,
applications, operating systems, and backups.
1. Random Access: Data can be accessed directly from any location in memory. RAM and cache
memory are random access, meaning the processor can quickly retrieve or write data from any
address.
2. Sequential Access: Data is accessed in a sequential manner, which means that to get to a
specific piece of data, you need to go through the preceding data. Magnetic tapes and some file
systems use sequential access.
3. Direct Access: Similar to random access, but data is accessed in blocks or clusters. HDDs and
SSDs use direct access for reading and writing data.
Virtual Memory
Virtual Memory is a technique that allows the computer to compensate for physical memory
shortages by temporarily transferring data from RAM to disk storage. When RAM is insufficient, the
operating system moves inactive data to a portion of the hard drive called a "paging file" or "swap
space," freeing up RAM for active processes. This creates an illusion of having more RAM than is
physically available.
1.6 Variables
In programming, variables, values, and instructions are fundamental concepts used to store,
manipulate, and perform operations on data. These concepts form the core of any computer program,
allowing it to handle dynamic data, execute logic, and solve problems.
Variables
A variable is a named storage location in a program's memory that holds data. It allows the
programmer to store, retrieve, and manipulate values during the execution of a program.
Key Characteristics of Variables:
❖ Name: The name of the variable is used to identify it and reference its stored value. It should be
meaningful to represent the data it holds.
❖ Type: Each variable has a data type that specifies the kind of value it can store (e.g., integers,
floating-point numbers, characters, strings, etc.).
❖ Memory Location: The variable is stored in a specific memory location in the computer's
RAM. The operating system assigns a memory address to each variable.
❖ Mutable: The value of a variable can be changed throughout the program's execution (except
in cases where variables are declared as constants).
Types of Variables:
Depending on the programming language, there are various types of variables, such as:
❖ Local Variables: Variables declared within a function or block of code. They are accessible
only within that function or block.
❖ Global Variables: Variables declared outside of all functions, making them accessible from
any part of the program.
❖ Static Variables: Variables that retain their values between function calls or exist throughout
the life of the program.
Example:
Here, age is an integer variable storing the value 25, and salary is a floating-point variable holding
50000.50.
1.7 Values
A value is the actual data or information stored inside a variable. It can be of various types, such as:
❖ Integers: Whole numbers (e.g., 5, 100, -25)
❖ Floating-point Numbers: Decimal numbers (e.g., 3.14, 0.001)
❖ Characters: Single letters or symbols (e.g., 'a', '$', '7')
❖ Strings: Sequences of characters (e.g., "Hello, World!")
❖ Booleans: Logical values representing true or false
Value Assignment:
Values are assigned to variables using the assignment operator (=). For example:
Types of Values:
❖ Literal Values: Direct values like numbers (5, 3.14) or strings ("hello") written in code.
❖ Derived Values: Values calculated or obtained from expressions or operations, such as x + y.
Type Conversion:
Values may sometimes need to be converted from one type to another, such as converting an integer
to a float or vice versa. This is known as type conversion or type casting.
1.8 Instructions
Instructions are commands or operations that a computer must execute. In programming, instructions
tell the computer what to do with the data stored in variables. Each instruction is part of the program's
overall logic and directs the flow of execution.
Types of Instructions:
❖ Arithmetic Instructions: Used to perform mathematical operations (addition, subtraction,
multiplication, division, etc.).
Example: sum = a + b;
❖ Control Flow Instructions: Direct the sequence of execution of the program. These include
loops, conditionals, and jumps.
❖ Input/Output Instructions: These instructions interact with the user or external devices by
taking input or producing output.
Examples of Instructions:
Arithmetic Instruction:
int a = 5;
int b = 10;
int sum = a + b; // Adds 'a' and 'b' and stores the result in 'sum'
Conditional Instruction:
if (a > b)
{
else
Loop Instruction:
for (int i = 0; i < 5; i++)
The compilation process is a critical phase in the development of programs written in compiled
languages. It involves translating human-readable source code into machine code that the computer's
processor can execute. Understanding this process helps in debugging, optimizing performance, and
improving overall programming skills.
What is a Program?
A program is a set of instructions written in a programming language that performs a specific task or
solves a problem when executed by a computer. Programs are created using source code written in
high-level languages like C, C++, Java, or Python.
The compilation process involves several steps that convert source code into executable machine
code. Here’s a detailed breakdown of each step:
1. Preprocessing
2. Compiling
3. Assembling
4. Linking
1. Preprocessing
Preprocessing is the initial step where the source code is prepared for compilation. This phase
handles tasks such as:
Example:
#define PI 3.14
#include <stdio.h>
In this example, PI is replaced by 3.14, and the contents of stdio.h are included in the source file.
2. Compiling
Compiling is the process where the preprocessed source code is translated into assembly code or
intermediate code. This phase involves:
Output: The result of this phase is usually an object file (with .obj or .o extension) that contains
machine code
Example:
int main()
int x = 10;
return 0;
This code will be converted into assembly code that corresponds to the instructions needed to execute
this program.
3. Assembling
Assembling is the step where the object file produced by the compiler is converted into machine
code. This phase involves:
❖ Generating Machine Code: Converting the assembly code into binary machine code.
❖ Creating an Object File: Producing an object file containing machine code and data.
Output: The result is an object file with machine code that can be combined with other object files to
create an executable program.
4. Linking
Linking is the final phase where the object files are combined to create an executable file. This phase
involves:
❖ Combining Object Files: Merging multiple object files into a single executable file.
❖ Resolving External References: Linking function calls and variable references between
different object files or libraries.
❖ Address Binding: Assigning memory addresses to various parts of the program.
Output: The result is an executable file (with .exe or no extension on Unix-based systems) that can
be run by the operating system.
Example: If your program uses functions from libraries (e.g., printf from stdio.h), the linker will
include the necessary code from those libraries into the final executable.
Compilation Tools
❖ Compilers: Software that performs the compilation (e.g., GCC for C/C++, javac for Java).
❖ Linkers: Tools that handle the linking phase (e.g., GNU ld).
❖ Assemblers: Tools that convert assembly code into machine code.
Syntax Errors
Syntax errors occur when the code does not conform to the grammatical rules of the programming
language. These errors are identified by the compiler or interpreter during the compilation or
interpretation phase and prevent the code from being successfully compiled or executed.
❖ Detected During Compilation: Syntax errors are caught by the compiler or interpreter before
the program runs.
❖ Specific to Language Rules: They violate the specific grammar rules of the programming
language.
❖ Usually Easy to Fix: Often, syntax errors are straightforward to correct because they are
typically clear-cut violations of language syntax.
Missing Punctuation:
int main() {
return 0;
Mismatched Brackets:
int main() {
if (a > b) {
Incorrect Keywords:
int main() {
return 0;
return 0;
In these examples, the compiler would generate errors indicating where the syntax is incorrect, such
as missing semicolons, mismatched braces, or undefined functions.
Error Messages:
Example Message: error: expected ';' before 'return' indicates that a semicolon is missing before the
return statement.
Semantic Errors
Semantic errors occur when the code is syntactically correct but logically incorrect according to the
intended behavior of the program. These errors are not detected during compilation but may cause the
program to behave incorrectly or crash during runtime.
Characteristics of Semantic Errors:
❖ Detected During Execution: Semantic errors become apparent when the program is run and
produce incorrect results or behavior.
❖ Logical Errors: They occur due to incorrect logic or misunderstanding of how certain
operations or constructs should work.
❖ Harder to Fix: Often more challenging to identify and fix because they involve understanding
the logic and purpose of the code rather than just fixing syntax.
int a = 5;
int b = 0;
return 0;
Wrong Algorithm:
int calculateArea(int length, int width) {
Logical Mistakes:
int main() {
} else {
return 0;
Uninitialized Variables:
int main() {
int total;
return 0;
In these examples, the code will compile without errors but produce incorrect or unintended results
when run.
Error Messages:
Example Message: runtime error: division by zero indicates that the code attempted to divide by zero,
which is not allowed.
Source Code is the human-readable code written in the C programming language. It is created using
a text editor or an Integrated Development Environment (IDE) and consists of various instructions,
functions, and constructs that define the program's behavior.
Example:
#include <stdio.h>
int main() {
printf("Hello, World!\n");
return 0;
2. Preprocessing
Preprocessing is the first step in the compilation process. The C preprocessor processes directives
and prepares the source code for compilation. This phase handles:
❖ File Inclusion: Integrates header files using #include.
❖ Macro Expansion: Replaces macros defined by #define with their values.
❖ Conditional Compilation: Includes or excludes code based on conditions (e.g., #ifdef, #endif).
Example:
#define PI 3.14
#include <stdio.h>
The preprocessor replaces PI with 3.14 and includes the contents of stdio.h.
3. Compilation
Compilation translates the preprocessed source code into assembly code or intermediate code. The C
compiler performs the following tasks:
Output: An object file (e.g., program.o or program.obj) that contains machine code in a format that is
not yet executable.
4. Assembling
Assembling converts the assembly code or intermediate code generated by the compiler into machine
code. The assembler performs:
❖ Machine Code Generation: Translates assembly instructions into binary machine code.
❖ Object File Creation: Produces an object file with machine code and data.
Output: An object file with machine code, ready for linking.
Example: The assembler processes hello.o and produces an object file containing machine code.
5. Linking
Linking combines object files and resolves external references to create an executable program. The
linker performs:
❖ Combining Object Files: Merges multiple object files into a single executable file.
❖ Library Linking: Includes code from external libraries if used.
❖ Address Binding: Assigns memory addresses to various parts of the program.
Output: An executable file (e.g., hello.exe or hello on Unix-based systems) that can be run by the
operating system.
Example: The linker processes hello.o and produces an executable file hello.
6. Execution
Execution is the final phase where the executable file is run by the operating system. During
execution:
❖ Program Loading: The operating system loads the executable file into memory.
❖ Instruction Execution: The CPU executes the instructions in the machine code.
❖ Runtime Behavior: The program performs its tasks and produces output or interacts with the
user.
Understanding these phases helps in debugging, optimizing, and developing C programs effectively.
Each phase plays a critical role in transforming source code into a functional and efficient executable
program.
Key Components:
❖ Whitespace Characters: Spaces, tabs, and newline characters used for formatting code.
Example:
int sum = 10 + 20; // 'int', 'sum', '10', '20', '+', '=', and ';' are part of the character
1.13 Constants
Constants are fixed values that do not change during the execution of a program. They can be
categorized into several types:
Types of Constants:
Example:
1.14 Keywords
Keywords are reserved words in C that have special meanings and cannot be used as identifiers
(variable names, function names, etc.). They are part of the C language syntax.
Common Keywords:
Example:
int main() {
printf("Positive\n");
Primitive Data Types are the basic data types provided by C to define variables and constants. They
are the building blocks for more complex data types.
Example:
1.16 Declaration
Declaration is the process of defining variables and their types so that they can be used in a program.
It informs the compiler about the type of data that will be stored in the variable.
Syntax of Declaration:
data_type variable_name;
Example:
int count; // Declaration of an integer variable 'count'
Type Conversion (or type casting) is the process of converting a variable from one data type to
another. This can be done implicitly by the compiler or explicitly by the programmer.
Automatically performed by the compiler when mixing different data types in expressions.
Example:
int a = 10;
float b = 5.5;
Type Casting can be used to avoid data loss or to ensure compatibility between different data types.