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:
4.1 Flowcharts: Graphical representation of an algorithm using symbols like ovals (start/end),
parallelograms (input/output), rectangles (processes), and diamonds (decisions).
4.2 Pseudocode: An informal, plain-language description of the steps in the algorithm. It’s structured
like code but doesn’t follow specific programming syntax.
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.
6. Compilation and Debugging
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. 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:
Writing the steps of the algorithm in plain English (or any natural language). This approach
may lack clarity and precision.
2. Flowcharts:
3. Pseudocode:
Example of an Algorithm
Problem Statement: Write an algorithm to input two numbers, add them, and display the result.
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:
Function: Represents an input or output operation, such as reading data from the user or
displaying results.
Example:
Function: Represents a decision point, where the process can branch based on a condition
(true/false).
Example:
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.
Problem Statement: Design a flowchart to input two numbers, add them, and display the result.
1. Start: Use the Oval to represent the start of the process.
2. Input Numbers: Use the Parallelogram for taking inputs.
3. Process (Add Numbers): Use the Rectangle to add the two numbers.
4. Output Result: Use another Parallelogram to display the sum.
5. End: Use the Oval to represent the end of the process
Advantages of Flowcharts
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
INPUT number1
INPUT number2
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.
Nibble → 4 bits
Byte → 8 bits
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.
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.
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 suitable
Capacity: It provides significantly more storage than primary memory and is used for storing files,
applications, operating systems, and backups.
There are different methods of accessing memory, depending on the type of memory being used:
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.
❖ 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.
#include <stdio.h>
// Global variable
void demoFunction() {
// Local variable
printf("Inside demoFunction:\n");
int main() {
demoFunction();
printf("\nInside main:\n");
return 0;
1.7 Values
A value is the actual data or information stored inside a variable. It can be of various types, such as:
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:
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
{
printf("b is greater than or equal to a");
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:
a) Removal of Comments: all the comments will be removed from the code.
d) Conditional compilation: Compiles code based on certain conditions (e.g., using #ifdef and
#endif).
Example:
int main() {
return 0;
2. Compiling
a) Compiling is the process where the preprocessed source code is translated into assembly code or
intermediate code. Checks for syntax errors and generates filename.s or [Link] file. This
phase involves:
a) Syntax Analysis: Checking the source code for syntax errors.
b) Semantic Analysis: Ensuring that the code adheres to the language's rules and meanings.
c) Optimization: Improving the code to make it more efficient without changing its behavior.
Output: The result of this phase is usually an filename.s or [Link] file that contains machine
code in a form that is not yet executable.
mov eax, 1
add eax, 2
3. Assembling
Assembling is the step where the object file produced by the compiler is converted into machine
code. This is where your code becomes hardware-friendly, but still not executable on its own.
Produces an object file (.o or .obj).This phase involves:
a) Generating Machine Code: Converting the assembly code into binary machine code.
b) 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:
a) Combining Object Files: Merging multiple object files into a single executable file.
b) Resolving External References: Linking function calls and variable references between
different object files or libraries.
c) 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 in C
1. Compiler
2. Assembler
3. Linker
● Example: GNU ld
Note: GCC usually handles all these steps internally when you run gcc hello.c -o hello.
Errors in programming are categorized into various types, primarily syntax errors and semantic
errors. Understanding these errors is crucial for debugging and developing robust programs.
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.
❖ 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;
Wrong Algorithm:
int calculateArea(int length, int width) {
Logical Mistakes:
int main() {
} else {
return 0;
Uninitialized Variables:
int main() {
int total;
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.
The development of a running computer program in C involves several distinct phases. Each phase
plays a crucial role in transforming high-level C code into an executable program. Understanding
these phases is essential for writing efficient and error-free C programs.
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.
#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:
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 [Link]) 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.
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., [Link] 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.
The character set in C defines the set of characters that can be used in the source code. These
characters are used to write identifiers, keywords, operators, and other elements of the language.
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:
1. Using const Keyword: This method creates a typed constant variable.
a) You must initialize it at the time of declaration.
b) Any attempt to modify it later will result in a compile-time error.
#define PI 3.14159
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:
❖ auto, extern, register, static, const, volatile, signed, unsigned → Storage classes & type
qualifiers
Example:
int main() {
printf("Positive\n");
}
Data Types: In C language, data types define the type of data a variable can store
and how much memory it occupies.
C is a statically typed language. The name of the variable along with the type of data it
intends to store must be explicitly declared before actually using it.
C is also a strongly typed language, which means that the automatic or implicit
conversion of one data type to another is not allowed.
Basic Types: They are arithmetic types and are further classified
used to define variables that can only assign certain discrete integer
throughout the program.
The type void: The type specifier void indicates that no value is
available.
Derived types: They include (a) Pointer types, (b) Array types,
(c) Structure types, (d) Union types and (e) Function types.
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.
Format
Size Specifier
Data Type (bytes) Range
unsigned short
2 0 to 65,535 %hu
int
-2,147,483,648 to
4 %d
int 2,147,483,647
-2,147,483,648 to
4 %ld
long int 2,147,483,647
unsigned long
4 0 to 4,294,967,295 %lu
int
unsigned long 0 to
8 %llu
long int 18,446,744,073,709,551,615
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;
Example:
float pi = 3.14;
Type Casting can be used to avoid data loss or to ensure compatibility between different data types.