Algorithm and Algorithm Development
1. Introduction to Algorithm
Definition:
An algorithm is a step-by-step procedure or set of rules written in a systematic way
to solve a problem or perform a task within a finite amount of time.
Example (Real-life):
Making tea:
1. Boil water.
2. Add tea leaves.
3. Add sugar and milk.
4. Boil for 5 minutes.
5. Strain and serve.
This is an algorithm in daily life.
2. Characteristics of a Good Algorithm
For an algorithm to be valid, it must have these properties:
1. Finiteness: It should terminate after a finite number of steps.
2. Definiteness: Each instruction should be clear, precise, and unambiguous.
3. Input: Zero or more inputs should be clearly specified.
4. Output: Must produce at least one output (result).
5. Effectiveness: Steps should be simple and basic enough to be carried out.
6. Generality: Should solve not only one specific case, but a whole class of problems.
3. Importance of Algorithms
Foundation of problem-solving in computer science.
Guides programmers to write efficient code.
Helps in resource optimization (time & memory).
Independent of programming language – can be implemented in C, Java, Python,
etc.
Provides clarity before coding starts.
4. Steps in Algorithm Development
Algorithm development is the process of creating an efficient solution for a given problem.
Step 1 – Problem Definition
Understand the problem thoroughly.
Identify input, process, and output.
Step 2 – Problem Analysis
Break down the problem into smaller sub-problems.
Decide constraints (e.g., maximum input size, valid ranges).
Step 3 – Algorithm Design
Write step-by-step instructions in pseudocode or flowcharts.
Consider different ways and choose the most efficient.
Step 4 – Verification
Check correctness by applying sample test cases.
Ensure the algorithm gives correct output for all possible inputs.
Step 5 – Implementation (Coding)
Convert algorithm into a programming language.
Step 6 – Testing and Debugging
Test with real and boundary cases.
Debug errors, optimize performance.
Step 7 – Documentation & Maintenance
Document the algorithm for clarity.
Update if new requirements arise.
5. Representation of Algorithms
Algorithms can be represented in different forms:
1. Natural Language
o Steps written in simple English.
o Example: “Read two numbers, compare them, print the larger.”
2. Pseudocode
o Structured English-like representation.
o Example:
o Step 1: Start
o Step 2: Read A, B
o Step 3: If A > B then Print A
o Else Print B
o Step 4: Stop
3. Flowchart
o Graphical representation using standard symbols.
o Shapes:
Oval → Start/Stop
Rectangle → Process
Diamond → Decision
Parallelogram → Input/Output
6. Example Algorithms
Example 1: Find the largest of two numbers
1. Start
2. Input A, B
3. If A > B → Print A
4. Else → Print B
5. Stop
Example 2: Calculate factorial of a number (n!)
1. Start
2. Input n
3. Set fact = 1
4. Repeat i = 1 to n → fact = fact * i
5. Print fact
6. Stop
7. Algorithm Complexity
The efficiency of an algorithm is measured using complexity analysis.
Time Complexity
Amount of time taken by an algorithm to run, as a function of input size.
Common notations:
o O(1) → Constant time
o O(n) → Linear time
o O(log n) → Logarithmic time
o O(n²) → Quadratic time
Space Complexity
Amount of memory used by an algorithm during execution.
Includes memory for variables, data structures, recursion stack, etc.
8. Advantages of Algorithm Development
Provides clarity of thought before coding.
Reduces errors during program development.
Helps in reuse for similar problems.
Easy to analyze and optimize.
✅ Summary
An algorithm is a step-by-step procedure to solve a problem.
Must satisfy finiteness, definiteness, input, output, effectiveness, and generality.
Algorithm development involves: Problem definition → Analysis → Design →
Verification → Implementation → Testing → Maintenance.
Represented using natural language, pseudocode, flowcharts.
Efficiency is measured by time and space complexity.
Algorithm – Definition and Properties
Definition
An algorithm is a finite sequence of well-defined instructions, arranged in a logical order,
that takes some input, processes it, and produces an output to solve a specific problem.
👉 In simple words:
An algorithm is a step-by-step procedure to solve a problem in a finite amount of time.
Example (Real life):
Recipe for making tea (Input: water, tea leaves, sugar, milk → Output: a cup of tea).
Example (Computing):
To find the largest of two numbers A and B:
1. Start
2. Read A and B
3. If A > B → Print A
4. Else → Print B
5. Stop
Properties / Characteristics of an Algorithm
For a procedure to qualify as an algorithm, it must satisfy the following properties:
1. Finiteness
o The algorithm must always terminate after a finite number of steps.
o Example: An algorithm that keeps asking for input endlessly is not finite.
2. Definiteness (Unambiguous)
o Each step must be precisely defined and clear.
o No room for confusion or multiple interpretations.
3. Input
o An algorithm should have zero or more inputs.
o These inputs are provided before or during execution.
4. Output
o An algorithm must produce at least one output (result).
o Output is the solution to the given problem.
5. Effectiveness (Feasibility)
o Each instruction must be basic enough to be executed in a finite time using
available resources.
o Example: “Multiply two numbers” is effective, but “Solve world hunger” is
not.
6. Generality
o An algorithm should be applicable to a class of problems, not just a single
instance.
o Example: An algorithm for finding the maximum number should work for any
set of numbers, not just a specific pair.
✅ Summary:
An algorithm is a step-by-step, finite, and effective procedure that transforms input
into output.
Properties: Finiteness, Definiteness, Input, Output, Effectiveness, Generality.
Flowchart – Definition, Symbols, and Examples
1. Definition of Flowchart
A flowchart is a graphical representation of an algorithm, program logic, or process
using various symbols to show the flow of control step by step.
It helps to visualize the sequence of operations clearly before coding.
👉 In short:
Flowchart = Diagram of an Algorithm
2. Advantages of Flowchart
Easy to understand and communicate logic.
Helps in analyzing problems step by step.
Useful in debugging and program documentation.
Acts as a blueprint before coding.
3. Common Flowchart Symbols
Symbol Meaning Purpose
⬭ (Oval) Terminator Start / End of a process
⬚ (Parallelogram) Input / Output Read data or display result
▭ (Rectangle) Process Calculation or instruction execution
◇ (Diamond) Decision Condition checking (Yes/No, True/False)
⬌ (Arrow) Flow Line Shows the direction of flow
⬛ (Connector / Circle) Connector Connects flow when chart is large
4. Examples of Flowcharts
Example 1: Find the Largest of Two Numbers
Algorithm
1. Start
2. Read A, B
3. If A > B → Print A is largest
4. Else → Print B is largest
5. Stop
Flowchart
⬭ Start
↓
⬚ Input A, B
◇ Is A > B?
/ \
Yes No
↓ ↓
▭ Print A ▭ Print B
⬭ Stop
Example 2: Calculate Factorial of a Number (n!)
Algorithm
1. Start
2. Input n
3. Set fact = 1
4. Repeat i = 1 to n → fact = fact * i
5. Print fact
6. Stop
Flowchart
⬭ Start
⬚ Input n
▭ fact = 1, i = 1
◇ Is i ≤ n?
/ \
Yes No
↓ ↓
▭ fact = fact * i ▭ Print fact
▭i=i+1 ↓
↘———————↙ ⬭ Stop
✅ Summary:
A flowchart is a diagrammatic representation of an algorithm.
Uses symbols: Oval (Start/Stop), Rectangle (Process), Diamond (Decision),
Parallelogram (I/O), Arrows (Flow).
Makes problem-solving and program design easier to understand.
Flowchart – Definition, Symbols, and Examples
1. Definition of Flowchart
A flowchart is a graphical representation of an algorithm, program logic, or process
using various symbols to show the flow of control step by step.
It helps to visualize the sequence of operations clearly before coding.
👉 In short:
Flowchart = Diagram of an Algorithm
2. Advantages of Flowchart
Easy to understand and communicate logic.
Helps in analyzing problems step by step.
Useful in debugging and program documentation.
Acts as a blueprint before coding.
3. Common Flowchart Symbols
Symbol Meaning Purpose
⬭ (Oval) Terminator Start / End of a process
⬚ (Parallelogram) Input / Output Read data or display result
▭ (Rectangle) Process Calculation or instruction execution
◇ (Diamond) Decision Condition checking (Yes/No, True/False)
⬌ (Arrow) Flow Line Shows the direction of flow
⬛ (Connector / Circle) Connector Connects flow when chart is large
4. Examples of Flowcharts
Example 1: Find the Largest of Two Numbers
Algorithm
1. Start
2. Read A, B
3. If A > B → Print A is largest
4. Else → Print B is largest
5. Stop
Flowchart
⬭ Start
⬚ Input A, B
◇ Is A > B?
/ \
Yes No
↓ ↓
▭ Print A ▭ Print B
⬭ Stop
Example 2: Calculate Factorial of a Number (n!)
Algorithm
1. Start
2. Input n
3. Set fact = 1
4. Repeat i = 1 to n → fact = fact * i
5. Print fact
6. Stop
Flowchart
⬭ Start
⬚ Input n
▭ fact = 1, i = 1
◇ Is i ≤ n?
/ \
Yes No
↓ ↓
▭ fact = fact * i ▭ Print fact
▭i=i+1 ↓
↘———————↙ ⬭ Stop
✅ Summary:
A flowchart is a diagrammatic representation of an algorithm.
Uses symbols: Oval (Start/Stop), Rectangle (Process), Diamond (Decision),
Parallelogram (I/O), Arrows (Flow).
Makes problem-solving and program design easier to understand.
📘 Conversion of Flowchart to Programming Language
1. Introduction
A flowchart shows the logic of an algorithm using symbols.
To implement it on a computer, the flowchart must be converted into a
programming language (like C, C++, Java, Python, PHP, etc.).
Each symbol in the flowchart corresponds to a specific code structure in
programming.
2. Mapping Flowchart Symbols to Code
Flowchart Symbol Meaning Equivalent in Programming Language
⬭ Oval (Terminator) Start/End main() function start/end OR program start/end
⬚ Parallelogram (I/O) Input/Output
cin, scanf(), input() for input
cout, printf(), print() for output
▭ Rectangle (Process) Computation
Assignment/Processing statements
e.g., sum = a + b;
Conditional statements
◇ Diamond (Decision) Condition
if…else, switch
⬌ Arrow (Flow line) Sequence Execution order of statements
⬛ Connector Link in flow goto, function call, or loop continuation
3. Example Conversions
Example 1: Largest of Two Numbers
Flowchart Steps:
1. Start
2. Input A, B
3. If A > B → Print A
4. Else → Print B
5. Stop
Conversion into C program:
#include <stdio.h>
int main() {
int A, B;
printf("Enter two numbers: ");
scanf("%d %d", &A, &B);
if (A > B)
printf("Largest number = %d", A);
else
printf("Largest number = %d", B);
return 0;
Example 2: Factorial of a Number
Flowchart Steps:
1. Start
2. Input n
3. fact = 1, i = 1
4. Repeat until i ≤ n → fact = fact * i
5. Increment i
6. Print fact
7. Stop
Conversion into Python program:
n = int(input("Enter a number: "))
fact = 1
i=1
while i <= n:
fact = fact * i
i=i+1
print("Factorial =", fact)
4. Steps in Converting Flowchart to Language
1. Identify Inputs and Outputs → Convert them to scanf()/cin/input() and
printf()/cout/print().
2. Identify Processes → Convert to assignment statements.
3. Identify Decisions → Convert to if…else or switch.
4. Identify Loops → Convert to for, while, or do…while.
5. Connect everything inside main() (C/Java) or script (Python).
✅ Summary
Flowchart gives the logic.
Programming language implements it in syntax form.
Input/Output → I/O functions
Processes → Assignments/Calculations
Decisions → If/Else, Switch
Loops → While, For, Do-While
📘 Flowchart vs Algorithm vs Program Code
Example 1: Find the Largest of Two Numbers
Algorithm
Flowchart Program Code (C Language)
(Steps)
⬭ Start → ⬚ Input A, 2. Input A,
1. Start
c<br>#include <stdio.h><br>int main() {<br> int A, B;<br>
Yes → ▭ Print A → ⬭ 3. If A > B,
B → ◇ Is A > B? → B
printf("Enter two numbers: ");<br> scanf("%d %d", &A,
&B);<br><br> if (A > B)<br> printf("Largest = %d", A);<br>
→ No → ▭ Print B → 4. Else Print
Stop Print A
else<br> printf("Largest = %d", B);<br><br> return
0;<br>}<br>
⬭ Stop B
5. Stop
Example 2: Factorial of a Number
Algorithm
Flowchart Program Code (Python)
(Steps)
1. Start
2. Input n
⬭ Start → ⬚ Input n → ▭
3. Set fact=1,
i=1 python<br>n = int(input("Enter a number:
→ ▭ fact=fact*i → ▭ i=i+1 →
fact=1, i=1 → ◇ i ≤ n? → Yes
4. Repeat until "))<br>fact = 1<br>i = 1<br><br>while i <=
back to decision → No → ⬚
i ≤ n → fact = n:<br> fact = fact * i<br> i = i +
fact * i 1<br><br>print("Factorial =", fact)<br>
Print fact → ⬭ Stop
5. Increment i
6. Print fact
7. Stop
✅ Summary
Flowchart → Diagram (pictorial view of logic).
Algorithm → Step-by-step written procedure.
Program Code → Actual implementation in a programming language.
Introduction to Program Design
1. What is Program Design?
Program design is the process of planning and structuring a program before writing
the actual code.
It involves analyzing a problem, deciding how to solve it, and representing the
solution in a clear format (algorithm, pseudocode, flowchart) so it can be translated
into a programming language.
👉 In simple words:
Program design = Bridge between problem statement and coding.
2. Importance of Program Design
Provides a clear roadmap before coding.
Makes programs easier to understand, test, and debug.
Saves time and reduces errors.
Ensures efficiency in terms of execution time and memory.
Improves reusability of program modules.
3. Steps in Program Design
1. Problem Definition
o Understand the problem thoroughly.
o Define input, processing, and expected output.
2. Problem Analysis
o Break down the problem into smaller sub-problems (modular approach).
o Identify constraints and requirements.
3. Design the Algorithm
o Write step-by-step instructions.
o Represent using pseudocode or flowcharts.
4. Control Structures
o Decide the control flow of the program:
Sequence (steps executed in order)
Selection (if…else, switch)
Iteration (loops: for, while, do-while)
5. Data Structures
o Decide how to store data: variables, arrays, structures, files, etc.
6. Verification
o Check correctness of the algorithm using test cases.
7. Coding
o Translate design into a programming language (C, Python, Java, etc.).
8. Testing and Debugging
o Run the program, check outputs, fix errors.
9. Documentation & Maintenance
o Write program documentation.
o Update the design if new requirements arise.
4. Program Design Tools
Algorithms (step-by-step instructions in plain language).
Pseudocode (structured, language-independent code).
Flowcharts (graphical representation of logic).
Decision Tables/Trees (for complex conditions).
5. Example of Program Design
Problem: Find the sum of first N natural numbers.
Step 1: Problem Definition
Input: N
Process: sum = 1 + 2 + 3 + … + N
Output: sum
Step 2: Algorithm
1. Start
2. Input N
3. Set sum = 0
4. For i = 1 to N → sum = sum + i
5. Print sum
6. Stop
Step 3: Flowchart
Start → Input N → sum=0 → i=1 → Is i ≤ N? → Yes → sum=sum+i → i=i+1 → Repeat
→ No → Print sum → Stop
Step 4: Program (Python)
N = int(input("Enter a number: "))
sum = 0
for i in range(1, N+1):
sum += i
print("Sum =", sum)
✅ Summary
Program design is the process of planning a solution before coding.
Steps: Problem Definition → Analysis → Algorithm → Flowchart/Pseudocode →
Coding → Testing → Maintenance.
Tools: Algorithms, Pseudocode, Flowcharts.
Good design = clear, efficient, error-free, reusable program.
Errors in Programming — Detailed Notes
1) What is an “error”?
An error is anything that prevents a program from compiling, running, or producing the
correct/expected result. In practice you’ll see:
Fault/bug: the underlying mistake in code or design.
Error: the manifestation (e.g., a compiler error, thrown exception).
Failure: the externally visible wrong behavior/output at runtime.
2) Big picture: Compile-time vs Run-time
Compile-time (before the program
Aspect Run-time (while the program runs)
runs)
Who detects The language runtime/OS, your code,
Compiler, static analyzer, linker
it? external systems
Lexical, syntax, type, some Exceptions, I/O errors, memory errors,
Typical types
semantic, linker logic bugs
Correct code/form/types, add Validate inputs, handle exceptions, fix
Fix strategy
missing symbols logic, manage resources
3) Compile-time errors (and friends)
A. Lexical/Syntax Errors
Violations of the language grammar.
C example (missing semicolon):
int x = 5 // error: expected ';'
Python example (bad indentation):
def f():
print("hi") # IndentationError
Fix: correct the syntax; turn on compiler warnings (-Wall -Wextra in C/C++).
B. Type Errors
Mismatched types or incompatible operations (mostly in statically typed languages).
int n = "12"; // Type mismatch: String → int
Fix: convert types explicitly or change declarations.
C. Semantic Errors (compile-time)
Statements are syntactically valid but semantically illegal.
int a[3];
a[5] = 10; // some compilers won’t catch this; static analyzers might
Fix: correct the meaning/intent; add bounds checks.
D. Linker Errors
Symbols can’t be resolved at link time.
// main.c
extern void helper();
int main(){ helper(); }
// (no helper.c linked) → undefined reference to `helper`
Fix: include/compile/link the correct object files or libraries; ensure matching signatures.
4) Run-time errors (and exceptions)
A. Exceptions & traps
The runtime halts normal flow and raises an exception/error.
Python
try:
print(10 / 0)
except ZeroDivisionError:
print("Cannot divide by zero")
Java
try {
int x = a[10]; // ArrayIndexOutOfBoundsException
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Index out of bounds");
Design note (Java): checked exceptions (must declare/handle) vs unchecked (runtime)
exceptions.
B. I/O & environment errors
File not found, permission denied, network timeouts, DNS failures, out-of-disk, etc.
C. Memory errors (systems languages)
Null dereference, buffer overflow, use-after-free, double free.
C (leak & fix):
// BAD: leak if fopen fails later
char *buf = malloc(1024);
// GOOD: check + free on all paths
char *buf = malloc(1024);
if (!buf) { perror("malloc"); return 1; }
/* ... */
free(buf);
Tools: AddressSanitizer, Valgrind.
D. Concurrency errors
Race conditions, deadlocks, livelocks.
Deadlock pattern (two locks in opposite order):
# Pseudocode
lock(A); lock(B); # Thread 1
lock(B); lock(A); # Thread 2 → potential deadlock
Prevention: consistent lock ordering, timeouts/try-lock, lock hierarchy, immutable data,
message passing.
E. Numerical errors
Overflow/underflow, precision loss (floating-point), catastrophic cancellation.
print(0.1 + 0.2 == 0.3) # False due to FP representation
Mitigate: use decimal/BigDecimal for money; scale integers; reformulate algorithms; check
ranges.
5) Logical errors (the “program runs but results are wrong”)
Wrong formula, wrong condition, off-by-one, misordered operations.
# Sum 1..n – BUG (range upper bound excluded)
n=5
s = sum(range(1, n)) # 1+2+3+4 -> 10 (should be 15)
Detect: tests, invariants, code review, property-based testing.
Fix: correct the logic; add regression tests.
6) Warnings vs errors
Warnings signal suspicious code but do not stop compilation. Treat warnings as
errors in CI (-Werror) to catch bugs early.
7) Error handling strategies
A. Return codes vs Exceptions
Return codes (C): simple, but easy to ignore; pair with errno/perror.
FILE *f = fopen("in.txt", "r");
if (!f) { perror("fopen"); return 1; }
Exceptions (Java/Python): separate happy path from error path; ensure you don’t
swallow exceptions silently.
B. Defensive programming
Validate inputs, check preconditions, sanitize external data.
Use assertions for internal invariants (remove in production if costly).
def sqrt_nonneg(x):
assert x >= 0
# ...
C. Resource safety
Always release resources (files, sockets, locks).
o Python: with context managers
o C++: RAII smart pointers
o Java: try-with-resources
try (var br = Files.newBufferedReader(Path.of("a.txt"))) {
// use br
}
D. Resilience for transient faults
Retries with exponential backoff & jitter, timeouts, idempotent operations, circuit
breakers.
E. User-facing errors
Clear, actionable messages; no internal stack traces in UI; log details privately with
correlation IDs.
8) Systematic debugging workflow
1. Reproduce reliably (isolate inputs, pin versions).
2. Observe: read the exact error message/stack trace; check logs/metrics.
3. Minimize: create a small repro; bisect recent changes.
4. Instrument: add logging, assertions; use a debugger (breakpoints, watch variables).
5. Hypothesize → test: change one thing at a time.
6. Fix: simplest correct change.
7. Prevent regressions: write a test that would have caught it; keep it in CI.
9) Common error patterns & quick fixes
Off-by-one (OBOE): double-check loop bounds (< vs <=).
Null dereference/NPE: check for null; use Optional/nullable types.
Shadowing/uninitialized variables: enable warnings; initialize at declaration.
String/number conversions: validate and handle parse failures.
Time/date bugs: time zones, DST, leap seconds; use UTC internally.
Locale bugs: number/date formatting differs by locale; specify locale explicitly.
10) Testing to catch errors early
Unit tests for small units; integration for components; end-to-end for flows.
Boundary tests (empty, min/max, null), property-based tests (invariants), fuzzing for
parsers.
Aim for meaningful coverage; focus on risk-based areas (parsing, concurrency,
money, security).
11) Small, concrete code examples
C: robust divide with error check
#include <stdio.h>
#include <errno.h>
int safe_div(int a, int b, int *out) {
if (b == 0) { errno = EDOM; return -1; }
*out = a / b;
return 0;
int main() {
int r;
if (safe_div(10, 0, &r) < 0) { perror("divide"); return 1; }
printf("%d\n", r);
12) Quick checklists
Before committing code
Builds with no warnings (or warnings = errors).
Unit tests pass; new tests for new behavior and bug fixes.
Inputs validated; outputs sane; resources closed.
Logs are informative but not noisy; errors are actionable.
When you hit an error
Capture exact message + stack trace.
Reproduce in a minimal case.
Check recent changes & environment differences.
Add a regression test after fixing.
Basics of C Programming
1. Introduction & History
C was developed by Dennis Ritchie (Bell Labs) in 1972.
Designed for system programming (OS, compilers) and general-purpose
programming.
Characteristics: procedural, structured, close to hardware (efficient), portable, small
runtime.
2. Why learn C?
Foundation for many languages (C++, C#, Java).
Excellent for understanding memory, pointers, data layout, and performance.
Widely used in embedded systems, OS kernels, compilers, and high-performance
libraries.
3. C Standards (brief)
Common standards: C89/C90, C99, C11, C17.
Use -std= option with gcc (e.g., -std=c11) for specific standard behavior.
4. Structure of a C Program
Typical skeleton:
#include <stdio.h> // preprocessor (header inclusion)
#define MAX 100 // macro
// function prototypes
int add(int a, int b);
int main(void) { // program entry point
// declarations and statements
printf("Hello, C!\n");
return 0;
// function definitions
int add(int a, int b) {
return a + b;
main() returns int. Program exit value 0 = success.
Comments: // single-line and /* multi-line */.
5. Compilation Process (4 main steps)
Given prog.c:
1. Preprocessing: handles #include, #define → produces .i (preprocessed source).
gcc -E prog.c -o prog.i
2. Compilation: converts to assembly .s.
gcc -S prog.i -o prog.s
3. Assembling: assembly → object code .o.
gcc -c prog.s -o prog.o
4. Linking: .o + libraries → executable.
gcc prog.o -o prog
Common one-line: gcc -std=c11 -Wall -Wextra -O2 -g prog.c -o prog
6. Character Set & Tokens
Tokens: keywords, identifiers, constants, strings, operators, punctuators.
Keywords include: int, float, char, if, else, switch, for, while, return, struct, typedef,
enum, static, extern, const.
7. Data Types & Sizes
Basic built-in types:
char (1 byte), int (typically 4 bytes on common systems), short, long, long long
float (4 bytes), double (8 bytes), long double
void (no value)
Use sizeof(type) to find sizes on target machine. Sizes can be implementation-defined.
Type qualifiers: signed, unsigned, short, long.
Fixed-width types: <stdint.h> provides int32_t, uint64_t, etc.
8. Variables & Storage Classes
Declarations:
int a; // definition, uninitialized (automatic storage)
static int s; // static storage, initialized to 0 if not provided
extern int x; // declaration (defined elsewhere)
register int r; // suggestion to keep in register (legacy)
Scope: where name is visible (block/local, file/global).
Lifetime: how long storage exists (automatic, static).
Initialization: automatic locals are indeterminate until initialized; static/globals
default to 0.
9. Constants & Literals
Integer: 123, 0x7B (hex), 075 (octal)
Floating: 3.14, 2.0e-3
Character: 'A' (single quotes) — note 'A' is an int value in C.
String: "hello" (array of chars with \0 termination)
const qualifier: const int MAX = 100; — read-only variable.
Macros:
#define PI 3.14159
#define MAX(a,b) ((a) > (b) ? (a) : (b))
Be careful with macro side effects; prefer inline or functions for complex logic.
10. Operators
Arithmetic: + - * / %
Relational: == != > < >= <=
Logical: && || !
Bitwise: & | ^ << >> ~
Assignment: = += -= *= /= %= &= |= ^= <<= >>=
Unary: ++ -- + - ! ~ & *
Ternary: ?:
Comma operator: , (evaluates left then right)
Precedence & associativity matters — use parentheses to be explicit.
Important: pre-increment ++i vs post-increment i++ — when used inside expressions,
results differ.
11. Input / Output (stdio.h)
printf() for formatted output. Format specifiers: %d, %ld, %u, %f, %lf, %c, %s, %p.
scanf() for input — must pass addresses. Use carefully (scanf can be dangerous with
strings).
Safer alternatives for strings: fgets() and parse.
Examples:
int n;
printf("Enter n: ");
scanf("%d", &n);
char buf[100];
fgets(buf, sizeof buf, stdin); // safer string input
12. Control Structures
Conditional:
if (condition) { ... }
else if (cond2) { ... }
else { ... }
switch (expr) {
case 1: ...
break;
default: ...
switch uses integer-like expressions; break prevents fall-through (fall-through is allowed
intentionally).
Loops:
for (init; cond; incr) { ... }
while (cond) { ... }
do { ... } while (cond); (executes body at least once)
Use break and continue to control loop flow.
13. Functions
Declaration (prototype) and definition:
int sum(int a, int b); // prototype
int sum(int a, int b) { // definition
return a + b;
Parameter passing: C uses pass-by-value (copies). To modify caller data, pass
pointers.
Return values: single value; use pointers/structs for multiple results.
Recursion: supported (watch stack depth).
Function pointers: int (*fptr)(int, int) = ∑ — used for callbacks.
inline suggestion may be used for small functions (C99 onward).
14. Arrays
Declared as type name[size]. Indexing from 0 to size - 1.
int a[5] = {1,2,3,4,5};
Multidimensional arrays: int mat[3][4];
Array decays to pointer when passed to a function: void f(int arr[]) is void f(int *arr).
sizeof behavior: inside same scope, sizeof(a) gives total bytes; after decay sizeof on
parameter gives pointer size.
Pitfall: no bounds checking by language — programmer must ensure safety.
15. Strings
Null-terminated char arrays: 'h','e','l','l','o','\0'.
C standard library <string.h> contains strcpy, strncpy, strcat, strcmp, strlen, memcpy,
memmove.
Use strncpy/snprintf carefully — still need to ensure NUL termination.
Avoid gets() — it's removed from standards (unsafe).
16. Pointers (core of C)
Pointer: variable holding memory address of another variable.
int x = 10;
int *p = &x; // p points to x
printf("%d\n", *p); // dereference -> 10
Pointer arithmetic: p + 1 moves by sizeof(*p).
NULL pointer: initialize unused pointers to NULL.
Common bugs: dangling pointer (pointing to freed memory), uninitialized pointer,
dereferencing NULL.
Pointers and arrays interplay: a[i] same as *(a + i).
Pointers to pointers: int **pp;
Pointers to functions and pointers to structs (use -> to access via pointer).
17. Dynamic Memory Management
Headers: <stdlib.h> (malloc, calloc, realloc, free).
int *arr = malloc(n * sizeof *arr);
if (!arr) { perror("malloc"); exit(EXIT_FAILURE); }
arr = realloc(arr, new_n * sizeof *arr);
free(arr); // must free when done
malloc returns void* — cast not required in C.
Always check for NULL.
Avoid memory leaks and double-free. Tools: Valgrind, AddressSanitizer (-
fsanitize=address).
18. Structures, Unions & Enums
Structs:
struct Student {
int id;
char name[50];
float marks;
};
struct Student s1 = {1, "Alice", 85.5};
struct Student *sp = &s1;
printf("%s\n", sp->name);
typedef to simplify: typedef struct Student Student; or typedef struct { ... } Student;
Union: share same memory for members (size = largest member). Useful for memory-saving
and low-level programming.
Enum:
enum Color { RED, GREEN, BLUE };
enum Color c = RED;
19. Preprocessor & Macros
Lines beginning with # processed before compilation.
#include <stdio.h> inserts header contents.
#define simple macros — careful with side effects:
#define SQR(x) ((x)*(x))
Use header guards to prevent double inclusion:
#ifndef MYHEADER_H
#define MYHEADER_H
...
#endif
or #pragma once.
20. File I/O
Use FILE * and functions: fopen, fclose, fread, fwrite, fgets, fputs, fprintf, fscanf, fseek, ftell.
FILE *fp = fopen("data.txt", "r");
if (!fp) { perror("fopen"); exit(1); }
char line[256];
while (fgets(line, sizeof line, fp)) {
printf("%s", line);
fclose(fp);
Modes: "r","w","a","r+","w+","rb","wb".
21. Error Handling
Standard errno in <errno.h>, with perror() and strerror().
Return non-zero exit codes on failure (exit(EXIT_FAILURE)).
22. Memory Layout (conceptual)
Text/code segment: compiled code (read-only usually).
Data segment: global/static variables (initialized/uninitialized).
Heap: dynamically allocated memory (malloc).
Stack: automatic local variables and function call frames.
Understanding this helps debug segmentation faults and memory corruption.
23. Storage Classes & Scope Summary
auto (default for local variables), register (hint), static (file or function scope
persistent), extern (external linkage).
Scope = region where identifier is visible; linkage = across translation units.
24. Common Errors & Debugging Tips
Common mistakes:
Uninitialized variables → unpredictable values.
Buffer overflow / off-by-one indexing.
Wrong format specifier in printf/scanf.
Dangling pointers (free then use).
Forgetting to free() memory.
Undefined behavior (UB) — extremely bad and hard to debug.
Tools & flags:
Compile with warnings: -Wall -Wextra -Wshadow -Wconversion -Werror (treat
warnings as errors in CI).
Debug: -g compile flag, use gdb.
Use sanitizers: -fsanitize=address,undefined (detect many UB and memory errors).
Valgrind for memory leaks.
Debugging steps:
1. Reproduce. 2. Read error message/stack trace. 3. Minimize test case. 4. Use
printf/logging or debugger. 5. Fix and write a regression test.
25. Best Practices
Initialize variables.
Prefer size_t for sizes/indices.
Use const where appropriate.
Check return values (I/O, memory allocation).
Free resources reliably (free, fclose).
Keep functions small and focused.
Use header files for declarations and .c for definitions.
Avoid macro pitfalls; prefer static inline functions for type-safety.
Write tests and use version control.
26. Example Programs (illustrative)
1) Hello + input example
#include <stdio.h>
int main(void) {
char name[50];
printf("Enter your name: ");
if (fgets(name, sizeof name, stdin)) {
printf("Hello, %s", name);
return 0;
}
2) Sum of N numbers (shows loops, arrays)
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int n;
printf("N: ");
if (scanf("%d", &n) != 1 || n <= 0) { puts("Invalid N"); return 1; }
int *a = malloc(n * sizeof *a);
if (!a) { perror("malloc"); return 1; }
for (int i = 0; i < n; ++i) {
printf("a[%d]: ", i);
if (scanf("%d", &a[i]) != 1) { puts("Bad input"); free(a); return 1; }
long sum = 0;
for (int i = 0; i < n; ++i) sum += a[i];
printf("Sum = %ld\n", sum);
free(a);
return 0;
3) Function + struct + file write (concise)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
int id;
char name[50];
} Rec;
int write_rec(const char *fname, Rec *r) {
FILE *f = fopen(fname, "ab");
if (!f) return -1;
fwrite(r, sizeof *r, 1, f);
fclose(f);
return 0;
int main(void) {
Rec r = {1, "Alice"};
if (write_rec("db.bin", &r) != 0) perror("write_rec");
return 0;
27. Exercises (practice)
1. Write a function to reverse a string in-place.
2. Implement strstr() (substring search).
3. Write a program to count word frequency in a text file (use fopen, fgets).
4. Implement dynamic 2D array (matrix) with malloc and free it.
5. Implement a recursive factorial and an iterative version; compare.
Structure of a C Program
Every C program follows a standard structure. It is organized into several sections:
1. Documentation Section
This is where you write comments about the program.
Helps others understand the purpose of the program.
Not executed by the compiler.
/*
Program: Calculate Sum of Two Numbers
Author: Dr. Vinita Nagda
Date: 06/09/2025
*/
2. Preprocessor Section
Contains preprocessor directives like #include, #define.
Executes before compilation.
#include <stdio.h> // standard input-output library
#define PI 3.14159 // macro definition
3. Global Declaration Section
Declarations outside of main() are considered global.
Variables, constants, and function prototypes can be declared here.
int globalVar = 10; // global variable
void display(); // function prototype
4. main() Function Section
Every C program must have one main() function.
Program execution starts here.
Contains:
o Variable declarations
o Executable statements
o Function calls
int main() {
int a, b, sum; // variable declaration
a = 10; b = 20; // assignment
sum = a + b; // statement
printf("Sum = %d", sum); // output
return 0; // program ends successfully
5. Subprogram Section (User-defined Functions)
Functions defined by the programmer.
Improve modularity and reusability.
void display() {
printf("Hello from display function!");
📊 Diagram of C Program Structure
+---------------------------------------------------+
| Documentation Section (comments) |
+---------------------------------------------------+
| Preprocessor Section (#include, #define) |
+---------------------------------------------------+
| Global Declaration Section (variables, prototypes)|
+---------------------------------------------------+
| main() Function |
|{ |
| Local Declarations |
| Executable Statements |
|} |
+---------------------------------------------------+
| Subprogram Section (User-defined functions) |
+---------------------------------------------------+
✅ Example Program with Structure
/* Documentation Section */
#include <stdio.h> // Preprocessor Section
int globalVar = 5; // Global Declaration Section
void greet(); // Function prototype
int main() { // Main Function Section
int x = 10, y = 20; // Local variable declaration
int sum = x + y; // Executable statement
printf("Sum = %d\n", sum);
greet(); // Function call
return 0;
/* Subprogram Section */
void greet() {
printf("Welcome to C Programming!\n");
Explanation of C Programming Components
1. # (Hash Symbol)
It indicates a preprocessor directive.
Preprocessor runs before the compiler and handles instructions like including header
files or defining macros.
Example:
#include <stdio.h>
tells the preprocessor to include the Standard I/O library.
2. #include
Used to add header files (libraries) to the program.
Two formats:
1. #include <filename> → searches in standard library (system path).
Example: #include <stdio.h>
2. #include "filename" → searches in current working directory.
Example: #include "myheader.h"
3. <stdio.h>
Standard Input Output Header file.
Contains functions like:
o printf() (output)
o scanf() (input)
o getchar(), putchar(), etc.
4. <conio.h>
Console Input Output Header file (mainly in Turbo C, not in modern compilers like
GCC).
Contains functions:
o clrscr() → clears the screen.
o getch() → waits for a key press before closing the output window.
5. main() Function
Every C program must have a main().
It is the entry point of execution.
Without it, program will not run.
int main()
Standard form.
Returns an integer value (usually 0) to the operating system to indicate successful
execution.
int main() {
return 0;
void main()
Used in old compilers (like Turbo C).
Means main doesn’t return anything.
Not recommended in modern standards (ANSI/ISO C requires int main()).
6. clrscr()
Stands for clear screen.
Clears console output.
Defined in <conio.h>.
Mostly used in Turbo C, not supported in GCC/modern compilers.
7. getch()
Stands for get character.
Waits for the user to press a key.
Prevents the program output screen from closing immediately.
Defined in <conio.h>.
8. printf()
Used for output (printing on the screen).
Defined in <stdio.h>.
Syntax:
printf("format string", variables);
Example:
printf("Sum = %d", sum);
9. scanf()
Used for input (reading from user).
Defined in <stdio.h>.
Syntax:
scanf("format string", &variables);
Example:
scanf("%d", &age);
10. Why we use & in scanf()
& means address of operator.
scanf() needs the memory address of the variable where the input should be stored.
Example:
int x;
scanf("%d", &x); // &x gives address of x
Without &, the value cannot be stored in the variable.
11. Format Specifiers
Format specifiers tell what type of data is being input or output.
Specifier Meaning Example
%d Integer int age = 21; printf("%d", age);
%f Float (6 decimal places default) float pi = 3.14; printf("%f", pi);
Specifier Meaning Example
%c Character char grade = 'A'; printf("%c", grade);
%s String printf("%s", "Hello");
%lf Double double d=10.234; printf("%lf", d);
%ld Long Integer long int l=123456; printf("%ld", l);
%u Unsigned int unsigned int x=100; printf("%u", x);
%p Pointer (address) printf("%p", &x);
%.2f Float with 2 decimal places printf("%.2f", pi);
✅ Example Program Using All
#include <stdio.h>
#include <conio.h>
int main() {
int age;
float salary;
char grade;
long int population;
clrscr(); // clear screen (only in Turbo C)
printf("Enter age: ");
scanf("%d", &age);
printf("Enter salary: ");
scanf("%f", &salary);
printf("Enter grade: ");
scanf(" %c", &grade); // space before %c to avoid buffer issue
printf("Enter population: ");
scanf("%ld", &population);
printf("\n--- OUTPUT ---\n");
printf("Age = %d\n", age);
printf("Salary = %.2f\n", salary);
printf("Grade = %c\n", grade);
printf("Population = %ld\n", population);
getch(); // waits for a key press (only Turbo C)
return 0;
👉 Now you know:
Why #include and <stdio.h> are used.
Difference between int main() and void main().
Use of clrscr(), getch().
Why & is required in scanf().
Full table of format specifiers.
urbo C vs Modern GCC (ANSI/ISO C) in C Programming
Feature / Turbo C (Old Modern GCC / ANSI C
Notes
Function Compiler) (Standard)
main() void main() Standard C requires int main() to
int main() (mandatory)
function (allowed) return an integer.
Return from Often omitted return 0; required in int Returning 0 = successful
main (void main()) main() execution.
<stdio.h>, <stdio.h>, <stdlib.h>,
<conio.h> is DOS-specific, not
Header files <conio.h>, <math.h> etc. (<conio.h>
available in modern compilers.
<math.h> etc. not supported)
Available in Instead use system commands
clrscr() <conio.h> to clear Not available (system("clear") in Linux or
screen system("cls") in Windows).
Available in
Use getchar() (from <stdio.h>) in
getch() <conio.h> to wait Not standard
standard C.
for a key press
C99 introduced // single-line
Comments /* ... */ only Both /* ... */ and //
comments.
32 + additional from
Keywords 32 standard
C99/C11 (_Bool, Modern C has more keywords.
supported keywords
_Complex, _Atomic, etc.)
Format %d, %f, %c, %ld, Same (%d, %f, %c, %ld,
Supported everywhere.
specifiers %s %s, etc.)
String
<string.h> <string.h> No difference.
handling
Runs inside Turbo Runs in terminal/IDE
Modern development uses
Execution IDE (Blue Screen (Code::Blocks, Dev-C++,
GCC/Clang.
😅) GCC, VS Code, etc.)
✅ Example in Turbo C (Old style)
#include <stdio.h>
#include <conio.h>
void main() {
int age;
clrscr(); // clear screen (Turbo C only)
printf("Enter age: ");
scanf("%d", &age);
printf("Age = %d", age);
getch(); // wait for key press
✅ Example in GCC (Modern Standard C)
#include <stdio.h>
#include <stdlib.h> // for system()
int main() {
int age;
system("cls"); // Windows clear screen
// system("clear"); // Linux clear screen
printf("Enter age: ");
scanf("%d", &age);
printf("Age = %d\n", age);
getchar(); // wait for key press
return 0;
👉 Summary:
Use int main() (not void main()).
Avoid <conio.h>, clrscr(), and getch() in modern compilers.
Use getchar() and system("cls"/"clear") instead.
Stick to ANSI/ISO standards for portability.
C Language Keywords
1. What are Keywords?
Keywords are reserved words in C.
They have predefined meanings and cannot be used as identifiers (variable names,
function names, etc.).
They form the syntax rules of the language.
All keywords are written in lowercase.
2. Number of Keywords
C language (ANSI standard C89/C90) → 32 keywords
Later standards like C99 and C11 introduced some extra keywords (_Bool, _Complex,
_Atomic, etc.).
Here we’ll focus on the 32 standard keywords (commonly taught).
3. List of 32 Standard Keywords in C
Keyword Meaning / Usage
auto Declares automatic (local) variables (default storage class).
break Terminates a loop or switch statement.
case Defines a branch in a switch statement.
char Declares a character variable (1 byte).
const Declares constants (read-only variables).
continue Skips the current iteration of a loop and goes to the next one.
default Defines the default branch in a switch statement.
do Used with while loop (do...while).
Keyword Meaning / Usage
double Declares double-precision floating-point variable.
else Defines the alternative block in an if condition.
enum Declares an enumeration (set of named integer constants).
extern Declares a variable or function that is defined elsewhere.
float Declares floating-point variable.
for Loop structure (for loop).
goto Transfers control to a labeled statement.
if Conditional statement.
int Declares integer variable.
long Declares long integer variable.
register Suggests storing variable in CPU register for faster access.
return Returns a value from a function.
short Declares short integer variable.
signed Declares a signed data type (default).
sizeof Returns size of a data type or variable (in bytes).
static Declares static variable (retains value across function calls).
struct Declares a structure (user-defined data type).
switch Multi-way branching statement.
typedef Creates an alias (new name) for a data type.
union Declares a union (like structure but with shared memory).
unsigned Declares unsigned data type (no negative values).
void Specifies no return type or empty parameter list.
volatile Tells compiler variable may change unexpectedly (e.g., hardware).
while Loop structure (while loop).
4. Example Program Using Keywords
#include <stdio.h>
#include <stdlib.h>
int main() {
int i; // int keyword
const float PI = 3.14; // const keyword
for(i = 1; i <= 5; i++) { // for, int
if(i % 2 == 0) // if keyword
continue; // continue keyword
printf("%d ", i); // printf (library function)
return 0; // return keyword
Output:
135
5. Additional Keywords in C99/C11 (Advanced)
_Bool → Boolean data type (true/false).
_Complex → Complex number type.
_Imaginary → Imaginary number type.
_Atomic, _Alignas, _Alignof, _Generic, _Noreturn, _Thread_local, _Static_assert.
👉 These are not always used in beginner-level programming.
✅ So in summary:
32 keywords in standard C (must-know).
All are reserved and cannot be redefined.
Used to define structure, control, and data types in programs.
Tokens in C — Detailed Explanation
What is a token?
A token is the smallest meaningful unit of a C program that the compiler recognizes. The
compiler reads the source text and breaks it into tokens. Tokens are the building blocks used
by the parser to understand the program.
Common example: in the statement
int sum = a + b;
the tokens are: int | sum | = | a | + | b | ;
The six categories of tokens
1. Keywords
2. Identifiers
3. Constants / Literals
4. Operators
5. Separators / Punctuators
6. String and character literals (sometimes grouped with constants)
(Comments and whitespace are not tokens — they separate tokens and are ignored by the
compiler.)
1. Keywords
Reserved words with special meaning in C (int, if, while, return, struct, etc.).
Cannot be used as identifiers (variable/function names).
Example usage:
if (x > 0) return x;
Tokens: if | ( | x | > | 0 | ) | return | x | ;
2. Identifiers
Names created by the programmer: variable names, function names, type names,
macro names, etc.
Syntax rule: an identifier must begin with a letter (A–Z, a–z) or underscore _,
followed by letters, digits or underscores:
identifier → [A-Za-z_] [A-Za-z0-9_]*
Case-sensitive (Count ≠ count).
Examples: sum, _temp, value123, main.
Pitfalls:
o Cannot start with a digit (1x is invalid).
o Cannot use a keyword (int = 5; is invalid).
o Avoid names beginning with an underscore followed by a capital letter or
double underscore (__) because they are reserved for implementation.
3. Constants / Literals
Constants are tokens that represent fixed values. Types and formats:
Integer constants
Decimal: 0, 123, -5 (the sign is an operator token - + literal 5)
Octal (leading 0): 075 (equals decimal 61)
Hexadecimal (leading 0x/0X): 0xFF, 0X10
Suffixes: add u or U for unsigned, l/L for long, ll/LL for long long. Examples: 123U,
0x1FL, 42ULL.
Floating-point constants
Forms: 123.45, 123., .45, with optional exponent e or E: 1.23e4, 4E-2.
Suffixes: f/F for float, l/L for long double.
Examples: 3.14, 6.02e23, 2.0f.
Character constants
Single quotes: 'A', '9', '\n', '\t', '\\'.
Escape sequences: \n, \t, \0, \', \", \\, \xhh (hex), \ooo (octal).
Multi-character constants like 'AB' are implementation-defined and should be
avoided.
String literals
Double quotes: "Hello", "Line\n".
Adjacent string literals are concatenated at compile time: "Hello, " "World!" →
"Hello, World!".
Escape sequences same as character constants.
4. Operators
Operators are tokens that denote operations. Categories:
Arithmetic: + - * / %
Relational: == != > < >= <=
Logical: && || !
Assignment: = += -= *= /= %= <<= >>= &= |= ^=
Increment / Decrement: ++ --
Bitwise: & | ^ ~ << >>
Conditional (ternary): ?:
Comma operator: , (evaluates left then right)
Important rules
Maximal munch (longest match): the lexer takes the longest possible token.
Example: >>= is a single token, not >> + =.
Precedence & associativity decide how expressions are grouped (e.g., * before +).
Use parentheses to make intent explicit.
5. Separators / Punctuators
Symbols used to organize code:
; (statement terminator)
, (separator)
() (parentheses)
{} (block)
[] (array subscripting)
. (member access)
-> (pointer member access)
# (preprocessor directive indicator — not a normal token within code)
6. String and character literal token rules
A string literal token is produced as one token (includes the quotes). The compiler
stores it as an array of characters with a trailing \0.
Two string tokens next to each other are concatenated by the compiler.
Example:
printf("Hello, " "World!\n");
tokens: printf ( "Hello, World!\n" ) ;
Lexical rules & tokenization behavior (practical points)
1. Whitespace & comments separate tokens.
o Spaces, tabs, newlines are ignored except as separators.
o Comments (/* ... */ and // ...) are removed and do not produce tokens.
2. Longest-match rule (maximal munch).
o The lexer picks the longest valid token at each position.
o Example: input a <<= 2; → tokens: a | <<= | 2 | ; (not << + =).
3. Need for separators:
o Without whitespace, tokens can merge: intx=5; is a single identifier intx, not
int x. So whitespace (or a punctuator) is necessary to separate tokens where
needed.
4. Preprocessor stage:
o Preprocessor directives (#include, #define) are handled before full
tokenization of the program. Macros can expand to more tokens.
Examples: show tokenization
Example 1:
int a = 10;
Tokens: int | a | = | 10 | ;
Example 2:
float x = 3.14e-2;
Tokens: float | x | = | 3.14e-2 | ;
Example 3 (string concatenation):
char *s = "Hello, " "World!";
Tokens: char | * | s | = | "Hello, World!" | ;
Example 4 (maximal munch):
a >>= 2;
Tokens: a | >>= | 2 | ;
Common pitfalls & errors due to tokens
Using a keyword as an identifier
int if = 5; // error
Not separating tokens
intx = 5; // declares identifier 'intx', likely a bug
Wrong format of literals
o Writing 09 (leading 0 makes it octal; 9 is invalid in octal).
o Using invalid suffixes, e.g., 123Z is invalid.
Forgetting semicolon results in a syntax error because ; is a token that terminates
statements.
Ambiguous parsing if you rely on implicit concatenation (e.g., macros producing
unexpected tokens). Be explicit.
Interaction with preprocessor/macros
Macro expansions produce sequences of tokens that get re-tokenized by the
compiler.
Example:
#define INC(x) x + 1
int a = INC(2)*2; // expands to: int a = 2 + 1 * 2; (beware of precedence)
Use parentheses in macros: #define INC(x) ((x) + 1)
Quick regex-ish patterns (informal) — useful for recognizing tokens
Identifier: [A-Za-z_][A-Za-z0-9_]*
Decimal integer: [0-9]+
Hex integer: 0[xX][0-9A-Fa-f]+
Octal integer: 0[0-7]+
Floating: ([0-9]+(\.[0-9]*)?|\.[0-9]+)([eE][+-]?[0-9]+)?[fFlL]?
Character: '(\\.|[^\\'])'
String: "(\\.|[^\\"])*"
(These are illustrative patterns — full lexical grammar in the standard is more precise.)
Short checklist for students
Know the six token types and be able to identify them in code.
Remember identifier rules and that keywords are reserved.
Recognize integer and floating literal forms (decimal, octal, hex, exponents, suffixes).
Understand maximal-munch: the lexer picks the longest token.
Be careful with macros: they expand into tokens and can change meaning.
Whitespace and comments separate tokens — sometimes you need a space to avoid
merging tokens.
Practice exercises (with answers)
1. Tokenize this line:
2. long int count = 0xFF + 075 - 10;
Answer: long | int | count | = | 0xFF | + | 075 | - | 10 | ;
3. Is 3.14e-2f a valid token?
Answer: Yes — a floating literal with exponent and f suffix (float type).
4. What happens to "Hello" "World" in C?
Answer: The two string literal tokens are concatenated into one "HelloWorld" at
compile time.
5. Identify tokens in:
6. if(a==b&&c!=d) do_something();
Answer: if | ( | a | == | b | && | c | != | d | ) | do_something | ( | ) | ;
Summary
Tokens are the atomic units compiler uses: keywords, identifiers, constants,
operators, separators, and string/char literals.
Lexical rules (whitespace, comments, maximal munch) determine how source text is
split into tokens.
Understanding tokens prevents many beginner mistakes (bad identifiers, wrong
literals, macro traps).
Data Types in C Programming
1. What are Data Types?
A data type defines the type of data a variable can hold, how much memory it will
occupy, and what kind of operations can be performed on it.
In C, data types are broadly divided into Primary (basic), Derived, Enumeration, and
User-defined.
2. Categories of Data Types
(A) Primary / Basic Data Types
1. int
o Used to store integers (whole numbers, positive or negative, without
decimal).
o Example: int age = 25;
o Size: usually 4 bytes (depends on system).
2. float
o Used to store decimal (real) numbers with single precision.
o Example: float pi = 3.14;
o Size: 4 bytes.
3. double
o Stores real numbers with double precision (more accurate than float).
o Example: double rate = 19.234567;
o Size: 8 bytes.
4. char
o Used to store a single character or small integer value.
o Example: char grade = 'A';
o Size: 1 byte.
(B) Derived Data Types
Derived from the basic types:
Array → collection of similar type (e.g., int marks[5];)
Pointer → stores address of another variable (e.g., int *ptr;)
Structure → groups different types (e.g., struct student)
Union → similar to structure, but shares memory.
Function → returns values of particular type.
(C) Enumeration Data Type (enum)
User-defined data type with a set of named integer constants.
Example:
enum week { Mon, Tue, Wed, Thu, Fri, Sat, Sun };
Here, Mon=0, Tue=1, ... unless values are specified manually.
(D) User-defined Data Types
Created by programmers:
typedef → gives new name to existing data type.
typedef unsigned int uint;
uint age = 25;
struct → defines a collection of different data items.
union → memory-sharing structure.
enum → enumeration constants.
3. Data Type Modifiers
In C, basic data types can be modified using modifiers to change storage size or type range.
Modifiers:
short
long
signed
unsigned
Example with int:
short int → usually 2 bytes
long int → usually 4 or 8 bytes
unsigned int → only positive values allowed
4. Size and Range of Data Types (Typical 32-bit system)
Data Type Size (bytes) Range (approx.)
char 1 -128 to 127 (signed) / 0 to 255 (unsigned)
short int 2 -32,768 to 32,767
unsigned short 2 0 to 65,535
int 4 -2,147,483,648 to 2,147,483,647
unsigned int 4 0 to 4,294,967,295
long int 4 or 8 system-dependent
unsigned long 4 or 8 system-dependent
float 4 ~6 decimal digits precision
Data Type Size (bytes) Range (approx.)
double 8 ~15 decimal digits precision
long double 10, 12, or 16 ~19 decimal digits precision
👉 Actual sizes vary depending on compiler and machine architecture.
You can check sizes with sizeof() function:
printf("Size of int: %zu", sizeof(int));
5. Format Specifiers in C
When printing or scanning values, we use format specifiers:
%d → int
%u → unsigned int
%ld → long int
%f → float
%lf → double
%c → char
%s → string
%p → pointer (address)
Example:
int age = 20;
float pi = 3.14;
printf("Age = %d, Pi = %f", age, pi);
6. Example Program
#include <stdio.h>
int main() {
int age = 25;
float pi = 3.14;
double big = 12345.6789;
char grade = 'A';
printf("Age = %d\n", age);
printf("Pi = %f\n", pi);
printf("Big number = %lf\n", big);
printf("Grade = %c\n", grade);
return 0;
Output:
Age = 25
Pi = 3.140000
Big number = 12345.678900
Grade = A
✅ In summary:
C provides basic, derived, enum, and user-defined data types.
Modifiers like short, long, unsigned, signed change storage and range.
Always use correct format specifiers in printf and scanf.
Constants in C Programming
🔹 1. What is a Constant?
A constant is a fixed value that does not change during the execution of a C program.
Unlike variables, once defined, constants cannot be modified.
Constants make programs more readable and reliable.
Example:
const float PI = 3.14159;
Here, PI is a constant and its value remains the same throughout the program.
🔹 2. Types of Constants in C
(A) Integer Constants
Whole numbers without a fractional part.
Can be written in decimal, octal, or hexadecimal form.
Examples:
int a = 10; // Decimal (base 10)
int b = 012; // Octal (base 8 → value 10 in decimal)
int c = 0xA; // Hexadecimal (base 16 → value 10 in decimal)
Rules:
No commas or spaces (1,000 ❌, should be 1000 ✅).
Must not have a decimal point.
May include a suffix: u (unsigned), l (long), ul (unsigned long).
Example: 100U, 25L, 123UL.
(B) Floating-Point Constants
Numbers with a fractional part or in exponential (scientific) notation.
Default type: double.
Examples:
float x = 3.14;
double y = -0.0001;
double z = 1.23e4; // 1.23 × 10^4 = 12300
Rules:
Must have at least one digit.
Must have a decimal point or exponent.
Suffixes: f or F → float, l or L → long double.
Example: 2.5f, 0.123L.
(C) Character Constants
A single character enclosed in single quotes ' '.
Stored as an integer (ASCII value of the character).
Examples:
char grade = 'A';
char digit = '9';
char newline = '\n'; // escape sequence
'A' has ASCII value 65, '9' has ASCII value 57.
Escape sequences:
'\n' → newline
'\t' → tab
'\0' → null character
'\'' → single quote
\" → double quote
\\ → backslash
(D) String Constants (Literals)
Sequence of characters enclosed in double quotes " ".
Stored in memory as an array of characters ending with a null character \0.
Examples:
char name[] = "C Programming";
printf("Hello World"); // "Hello World" is a string constant
(E) Enumeration Constants (enum)
Special user-defined constants that assign names to integers.
Example:
enum week { MON, TUE, WED, THU, FRI, SAT, SUN };
Here: MON=0, TUE=1, WED=2 … SUN=6 by default.
🔹 3. Defining Constants in C
There are two main ways to define constants:
(i) Using #define (Preprocessor)
#define PI 3.14159
#define MAX 100
No memory is allocated, compiler replaces every occurrence with value.
Cannot change value later.
(ii) Using const keyword
const int MAX = 100;
const float PI = 3.14;
Allocates memory and type-checked by compiler.
More secure than #define.
🔹 4. Example Program
#include <stdio.h>
#define PI 3.14159 // using #define
int main() {
const int MAX = 100; // using const
float radius = 5.0;
float area = PI * radius * radius;
printf("Maximum = %d\n", MAX);
printf("Area of Circle = %.2f\n", area);
return 0;
}
Output:
Maximum = 100
Area of Circle = 78.54
🔹 5. Difference between #define and const
Feature #define const
Type-checking No Yes
Memory allocation No (just replacement) Yes
Scope Global Local or global
Debugging Harder Easier
✅ Summary
Constants are fixed values.
Types: Integer, Floating, Character, String, Enum.
Defined using #define or const.
const is preferred in modern C programming.
Operators in C Programming
1️⃣ What is an Operator?
An operator is a symbol that tells the compiler to perform a specific operation on
one or more operands.
Operands can be constants, variables, or expressions.
Example:
int a = 10, b = 5;
int sum = a + b; // '+' is an operator
2️⃣ Types of Operators in C
A) Arithmetic Operators
Used to perform mathematical calculations.
Operator Description Example Result
+ Addition 5+3 8
- Subtraction 5-3 2
* Multiplication 5*3 15
/ Division 10 / 2 5
% Modulus (remainder) 10 % 3 1
++ Increment a++ or ++a 11 if a=10
-- Decrement a-- or --a 9 if a=10
Notes:
a++ → Post-increment: returns original value then increments.
++a → Pre-increment: increments first then returns value.
B) Relational Operators
Used to compare two values, return 1 (true) or 0 (false).
Operator Description Example Result
== Equal to a==b 1 if equal
!= Not equal to a!=b 1 if not equal
> Greater than a>b 1 if true
< Less than a<b 1 if true
>= Greater than or equal a>=b 1 if true
<= Less than or equal a<=b 1 if true
C) Logical Operators
Used to perform logical operations (AND, OR, NOT).
Operator Description Example Result
&& Logical AND (a>0 && b>0) 1 if both true
` ` Logical OR
! Logical NOT !(a>0) 1 if condition false
D) Assignment Operators
Used to assign values to variables.
Operator Description Example Equivalent
= Simple assignment a = 5 –
+= Add and assign a += 5 a=a+5
-= Subtract and assign a -= 5 a=a-5
*= Multiply and assign a *= 5 a=a*5
/= Divide and assign a /= 5 a=a/5
%= Modulus and assign a %= 5 a=a%5
E) Bitwise Operators
Operate on individual bits of integers.
Operator Description Example Result
& Bitwise AND 5 & 3 1
` ` Bitwise OR `5
^ Bitwise XOR 5 ^ 3 6
~ Bitwise NOT ~5 -6 (two’s complement)
<< Left shift 5 << 1 10
>> Right shift 5 >> 1 2
F) Conditional (Ternary) Operator
Syntax: condition ? expression1 : expression2
Returns expression1 if condition is true, else expression2.
Example:
int a = 10, b = 5;
int max = (a > b) ? a : b; // max = 10
G) Comma Operator
Allows multiple expressions in a single statement; evaluates left to right and returns
rightmost value.
Example:
int a, b, c;
c = (a = 5, b = 10, a + b); // c = 15
H) Sizeof Operator
Returns size (in bytes) of a data type or variable.
Syntax: sizeof(type) or sizeof(variable)
Example:
printf("%zu", sizeof(int)); // 4 bytes
I) Pointer Operators
* → dereference pointer (value at address)
& → address-of operator
Example:
int a = 10;
int *ptr = &a; // & gives address of a
printf("%d", *ptr); // * gives value at ptr → 10
J) Member Operators
Used for structures/unions:
o . → access member using object
o -> → access member using pointer
Example:
struct student {
int roll;
char grade;
} s1;
s1.roll = 101; // using .
struct student *ptr = &s1;
ptr->grade = 'A'; // using ->
3️⃣ Operator Precedence & Associativity
Precedence → which operator is evaluated first.
Associativity → direction of evaluation (left-to-right or right-to-left).
Precedence Level Operators Associativity
1 (Highest) () [] . -> Left → Right
2 ! ~ ++ -- * & (unary) Right → Left
3 */% Left → Right
4 +- Left → Right
5 << >> Left → Right
6 < <= > >= Left → Right
7 == != Left → Right
8 & Left → Right
9 ^ Left → Right
10 ` `
11 && Left → Right
Precedence Level Operators Associativity
12 `
13 ?: Right → Left
14 (Lowest) = += -= *= /= %= etc. Right → Left
Tip: Use parentheses () to avoid ambiguity.
4️⃣ Example Program Using Multiple Operators
#include <stdio.h>
int main() {
int a = 10, b = 3, c;
c = a + b; // arithmetic +
printf("Sum = %d\n", c);
if(a > b && b != 0) { // relational + logical &&
printf("a is greater than b\n");
a += 5; // assignment operator
printf("a = %d\n", a);
int mask = 6; // 110 in binary
int result = a & mask; // bitwise AND
printf("Bitwise AND = %d\n", result);
int max = (a > b) ? a : b; // conditional
printf("Max = %d\n", max);
return 0;
}
Output:
Sum = 13
a is greater than b
a = 15
Bitwise AND = 6
Max = 15
✅ Summary
Operators perform arithmetic, logical, relational, bitwise, assignment, conditional,
and pointer operations.
Precedence & associativity rules determine evaluation order.
C has rich operators allowing low-level manipulation, making it powerful but
requiring careful use.
Operators in C Programming
1️⃣ What is an Operator?
An operator is a symbol that tells the compiler to perform a specific operation on
one or more operands.
Operands can be constants, variables, or expressions.
Example:
int a = 10, b = 5;
int sum = a + b; // '+' is an operator
2️⃣ Types of Operators in C
A) Arithmetic Operators
Used to perform mathematical calculations.
Operator Description Example Result
+ Addition 5+3 8
Operator Description Example Result
- Subtraction 5-3 2
* Multiplication 5*3 15
/ Division 10 / 2 5
% Modulus (remainder) 10 % 3 1
++ Increment a++ or ++a 11 if a=10
-- Decrement a-- or --a 9 if a=10
Notes:
a++ → Post-increment: returns original value then increments.
++a → Pre-increment: increments first then returns value.
B) Relational Operators
Used to compare two values, return 1 (true) or 0 (false).
Operator Description Example Result
== Equal to a==b 1 if equal
!= Not equal to a!=b 1 if not equal
> Greater than a>b 1 if true
< Less than a<b 1 if true
>= Greater than or equal a>=b 1 if true
<= Less than or equal a<=b 1 if true
C) Logical Operators
Used to perform logical operations (AND, OR, NOT).
Operator Description Example Result
&& Logical AND (a>0 && b>0) 1 if both true
` ` Logical OR
! Logical NOT !(a>0) 1 if condition false
Operator Description Example Result
D) Assignment Operators
Used to assign values to variables.
Operator Description Example Equivalent
= Simple assignment a=5 –
+= Add and assign a += 5 a=a+5
-= Subtract and assign a -= 5 a=a-5
*= Multiply and assign a *= 5 a=a*5
/= Divide and assign a /= 5 a=a/5
%= Modulus and assign a %= 5 a=a%5
E) Bitwise Operators
Operate on individual bits of integers.
Operator Description Example Result
& Bitwise AND 5&3 1
` ` Bitwise OR `5
^ Bitwise XOR 5^3 6
~ Bitwise NOT ~5 -6 (two’s complement)
<< Left shift 5 << 1 10
>> Right shift 5 >> 1 2
F) Conditional (Ternary) Operator
Syntax: condition ? expression1 : expression2
Returns expression1 if condition is true, else expression2.
Example:
int a = 10, b = 5;
int max = (a > b) ? a : b; // max = 10
G) Comma Operator
Allows multiple expressions in a single statement; evaluates left to right and returns
rightmost value.
Example:
int a, b, c;
c = (a = 5, b = 10, a + b); // c = 15
H) Sizeof Operator
Returns size (in bytes) of a data type or variable.
Syntax: sizeof(type) or sizeof(variable)
Example:
printf("%zu", sizeof(int)); // 4 bytes
I) Pointer Operators
* → dereference pointer (value at address)
& → address-of operator
Example:
int a = 10;
int *ptr = &a; // & gives address of a
printf("%d", *ptr); // * gives value at ptr → 10
J) Member Operators
Used for structures/unions:
. → access member using object
-> → access member using pointer
Example:
struct student {
int roll;
char grade;
} s1;
s1.roll = 101; // using .
struct student *ptr = &s1;
ptr->grade = 'A'; // using ->
3️⃣ Operator Precedence & Associativity
Precedence → which operator is evaluated first.
Associativity → direction of evaluation (left-to-right or right-to-left).
Precedence Level Operators Associativity
1 (Highest) () [] . -> Left → Right
2 ! ~ ++ -- * & (unary) Right → Left
3 */% Left → Right
4 +- Left → Right
5 << >> Left → Right
6 < <= > >= Left → Right
7 == != Left → Right
8 & Left → Right
9 ^ Left → Right
10 ` `
11 && Left → Right
Precedence Level Operators Associativity
12 `
13 ?: Right → Left
14 (Lowest) = += -= *= /= %= etc. Right → Left
Tip: Use parentheses () to avoid ambiguity.
4️⃣ Example Program Using Multiple Operators
#include <stdio.h>
int main() {
int a = 10, b = 3, c;
c = a + b; // arithmetic +
printf("Sum = %d\n", c);
if(a > b && b != 0) { // relational + logical &&
printf("a is greater than b\n");
}
a += 5; // assignment operator
printf("a = %d\n", a);
int mask = 6; // 110 in binary
int result = a & mask; // bitwise AND
printf("Bitwise AND = %d\n", result);
int max = (a > b) ? a : b; // conditional
printf("Max = %d\n", max);
return 0;
}
Output:
Sum = 13
a is greater than b
a = 15
Bitwise AND = 6
Max = 15
✅ Summary
Operators perform arithmetic, logical, relational, bitwise, assignment, conditional,
and pointer operations.
Precedence & associativity rules determine evaluation order.
C has rich operators allowing low-level manipulation, making it powerful but
requiring careful use.
📘 Operators in C Programming
1️⃣ What is an Operator?
An operator is a symbol that tells the compiler to perform a specific operation on
one or more operands.
Operands can be variables, constants, or expressions.
Example:
int a = 10, b = 5;
int sum = a + b; // '+' is the operator
2️⃣ Types of Operators
A) Arithmetic Operators
Operator Meaning Example
+ Addition a+b
- Subtraction a-b
* Multiplication a*b
/ Division a/b
% Modulus (remainder) a%b
++ Increment a++ or ++a
-- Decrement a-- or --a
B) Relational Operators
Operator Meaning Example
== Equal to a == b
!= Not equal to a != b
> Greater than a>b
< Less than a<b
>= Greater or equal a >= b
<= Less or equal a <= b
C) Logical Operators
Operator Meaning Example
&& Logical AND a>0 && b>0
` `
! Logical NOT !(a>0)
D) Assignment Operators
Operator Meaning Example
= Assign a=5
+= Add and assign a += 5
-= Subtract assign a -= 5
*= Multiply assign a *= 5
/= Divide assign a /= 5
%= Modulus assign a %= 5
E) Bitwise Operators
Operator Meaning Example
& AND a&b
` ` OR
^ XOR a^b
~ NOT ~a
<< Left shift a << 1
>> Right shift a >> 1
F) Other Operators
Conditional / Ternary: condition ? expr1 : expr2
Comma operator: , evaluates multiple expressions, returns the last value.
sizeof operator: returns size of a type/variable in bytes.
Pointer operators: * (dereference), & (address-of)
Member operators: . (structure member), -> (pointer to structure member)
3️⃣ Operator Precedence and Associativity
Operator precedence decides which operator is evaluated first in an expression.
Associativity decides the order of evaluation when operators have same
precedence.
Precedence Operator(s) Description Associativity
Parentheses, array
1 (Highest) () [] . -> subscript, structure Left → Right
member
! ~ ++ -- + - * Unary operators,
2 Right → Left
& (type) typecast
Multiplication,
3 */% Left → Right
division, modulus
4 +- Addition, subtraction Left → Right
5 << >> Bitwise shift Left → Right
6 < <= > >= Relational Left → Right
Equality and
7 == != Left → Right
inequality
8 & Bitwise AND Left → Right
9 ^ Bitwise XOR Left → Right
10 ` ` Bitwise OR
11 && Logical AND Left → Right
12 ` `
13 ?: Ternary conditional Right → Left
= += -= *= /=
14 Assignment operators Right → Left
%= etc.
15 (Lowest) , Comma operator Left → Right
4️⃣ Example Demonstrating Precedence
#include <stdio.h>
int main() {
int a = 10, b = 5, c = 2;
int result;
result = a + b * c; // * has higher precedence than +
printf("Result = %d\n", result); // 10 + (5*2) = 20
result = (a + b) * c; // parentheses override precedence
printf("Result = %d\n", result); // (10+5)*2 = 30
return 0;
}
Output:
Result = 20
Result = 30
✅ Summary
Operators perform operations on variables/constants.
Types: Arithmetic, Relational, Logical, Assignment, Bitwise, Conditional, Pointer,
Sizeof, Member, Comma.
Precedence decides which operator is applied first.
Associativity resolves order when precedence is the same.
Tip: Use parentheses () to make code clear and avoid mistakes.
Memory Units and Size in C Programming
1️⃣ Memory in a Computer
A computer’s memory is organized as a sequence of bytes.
Each byte has a unique address.
C variables occupy memory according to their data type.
Memory Units:
Unit Size Notes
Bit 1 bit Smallest unit, 0 or 1
Byte 8 bits Stores 1 character
Kilobyte 1024 bytes 1 KB = 1024 bytes
Megabyte 1024 KB 1 MB = 1024 × 1024 bytes
Gigabyte 1024 MB 1 GB = 1024 × 1024 × 1024 bytes
2️⃣ Memory Representation of Data Types in C
Data Type Typical Size (Bytes) Description
char 1 Single character or small integer
int 2 or 4 Whole numbers
short int 2 Smaller integer
long int 4 or 8 Larger integer
float 4 Single-precision decimal number
double 8 Double-precision decimal number
long double 10, 12, or 16 Extended-precision decimal number
pointer 4 or 8 Stores memory address
⚠️Note: Size may vary depending on the compiler and machine architecture (32-bit
vs 64-bit).
3️⃣ Size of Data Types Using sizeof()
sizeof() is a compile-time operator that returns the size of a variable or data type in
bytes.
Example:
#include <stdio.h>
int main() {
printf("Size of char: %zu bytes\n", sizeof(char));
printf("Size of int: %zu bytes\n", sizeof(int));
printf("Size of float: %zu bytes\n", sizeof(float));
printf("Size of double: %zu bytes\n", sizeof(double));
printf("Size of pointer: %zu bytes\n", sizeof(int*));
return 0;
}
Sample Output (32-bit system):
Size of char: 1 bytes
Size of int: 4 bytes
Size of float: 4 bytes
Size of double: 8 bytes
Size of pointer: 4 bytes
4️⃣ Memory Layout of a C Program
A C program’s memory is divided into sections:
Section Description
Text / Code Stores program instructions
Data Segment Stores global and static variables
Heap Dynamic memory allocated by malloc() etc.
Stack Stores local variables, function calls, return addresses
5️⃣ Memory Example With Variables
#include <stdio.h>
int main() {
char c = 'A'; // 1 byte
int i = 100; // 4 bytes
float f = 3.14; // 4 bytes
double d = 3.14159; // 8 bytes
printf("Size of c: %zu\n", sizeof(c));
printf("Size of i: %zu\n", sizeof(i));
printf("Size of f: %zu\n", sizeof(f));
printf("Size of d: %zu\n", sizeof(d));
return 0;
}
Output:
Size of c: 1
Size of i: 4
Size of f: 4
Size of d: 8
6️⃣ Memory and Data Type Modifiers
C allows modifiers to change memory usage and range:
Modifier Example Notes
short short int x; Reduces size of integer
long long int y; Increases size of integer
signed signed int z; Can store negative and positive numbers
unsigned unsigned int w; Only stores positive numbers (doubles max)
Example:
unsigned int a; // can store 0 to 4,294,967,295 (4 bytes)
7️⃣ Summary
Memory is measured in bits → bytes → KB → MB → GB.
Each data type has a specific size and range.
Use sizeof() to check memory size of variables/data types.
Modifiers (short, long, unsigned) change memory size or range.
Proper memory understanding is crucial for optimization, pointers, and data
structures.
UNIT-1
ALGORITHM AND ALGORITHM DEVELOPMENT:
Algorithm
An algorithm is an effective, efficient and best method which can be used to express solution
of any problem within a finite amount of space and time and in a well-defined formal
language. Starting from an initial state the instructions describe a process or computational
process that, when executed, proceeds through a finite number of well-defined successive
states, eventually producing "output"and terminating at a final ending state.
In other words, we can say that,
Step by step procedure for solving any problem is known as algorithm.
An algorithm is a finite set of instructions that, if followed, accomplishes a particular task.
An algorithm is a sequence of computational steps that transform the input into a valuable
or required output.
Any special method of solving a certain kind of problem is known as algorithm.
All Algorithms must satisfy the following criteria -
Properties of algorithm
1) Input
There are more quantities that are extremely supplied.
2) Output
At least one quantity is produced.
3) Definiteness
Each instruction of the algorithm should be clear and unambiguous.
4) Finiteness
The process should be terminated after a finite number of steps.
5) Effectiveness
Every instruction must be basic enough to be carried out theoretically or by using paper and
pencil.
Flowchart is a diagrammatic representation of an algorithm. Flowchart are very helpful in
writing program and explaining program to others.
Flowchart symbols
Different symbols are used for different states in flowchart, For example: Input/Output and
decision making has different symbols. The table below describes all the symbols that are
used in making flowchart
Common Flowchart Symbols
Rectangle Shape - Represents a process
Oval or Pill Shape - Represents the start or end
Diamond Shape - Represents a decision
Parallelogram - Represents input/output
Example of simple algorithm
Qualities of a good algorithm
Input and output should be defined precisely.
Each steps in algorithm should be clear and unambiguous.
Algorithm should be most effective among many different ways to solve a problem.
An algorithm shouldn't have computer code. Instead, the algorithm should be written in
such a way that, it can be used in similar programming languages.
Write an algorithm to add two numbers entered by user.
Step 1: Start
Step 2: Declare variables num1, num2 and sum.
Step 3: Read values num1 and num2.
Step 4: Add num1 and num2 and assign the result to sum.
sum←num1+num2
Step 5: Display sum
Step 6: Stop
Errors
Syntax errors: Errors that occur when you violate the rules of writing C/C++ syntax are
known as syntax errors. This compiler error indicates something that must be fixed before
the code can be compiled. All these errors are detected by compiler and thus are known as
compile-time errors.
Most frequent syntax errors are:
Missing Parenthesis (})
Printing the value of variable without declaring it
Missing semicolon like this:
// C program to illustrate
// syntax error
#include<stdio.h>
void main()
int x = 10;
int y = 15;
printf("%d", (x, y)) // semicolon missed
}
Error:
error: expected ';' before '}' token
Syntax of a basic construct is written wrong. For example : while loop
// C program to illustrate
// syntax error
#include<stdio.h>
int main(void)
// while() cannot contain "." as an argument.
while(.)
printf("hello");
return 0;
Error:
error: expected expression before '.' token
while(.)
In the given example, the syntax of while loop is incorrect. This causes a syntax error.
Run-time Errors : Errors which occur during program execution(run-time) after successful
compilation are called run-time errors. One of the most common run-time error is division
by zero also known as Division error. These types of error are hard to find as the compiler
doesn’t point to the line at which the error occurs.
For more understanding run the example given below.
// C program to illustrate
// run-time error
#include<stdio.h>
void main()
{
int n = 9, div = 0;
// wrong logic
// number is divided by 0,
// so this program abnormally terminates
div = n/0;
printf("resut = %d", div);
Error:
warning: division by zero [-Wdiv-by-zero]
div = n/0;
In the given example, there is Division by zero error. This is an example of run-time error i.e
errors occurring while running the program.
Logical Errors : On compilation and execution of a program, desired output is not obtained
when certain input values are given. These types of errors which provide incorrect output
but appears to be error free are called logical errors. These are one of the most common
errors done by beginners of programming.
These errors solely depend on the logical thinking of the programmer and are easy to detect
if we follow the line of execution and determine why the program takes that path of
execution.
// C program to illustrate
// logical error
int main()
int i = 0;
// logical error : a semicolon after loop
for(i = 0; i < 3; i++);
printf("loop ");
continue;
getchar();
return 0;
No output
Tokens
C tokens, Identifiers and Keywords are the basics in a C program. All are explained in this
page with definition and simple example programs.
1. C TOKENS:
C tokens are the basic buildings blocks in C language which are constructed together to write
a C program.
Each and every smallest individual units in a C program are known as C tokens.
C tokens are of six types. They are,
Keywords (eg: int, while),
Identifiers (eg: main, total),
Constants (eg: 10, 20),
Strings (eg: “total”, “hello”),
Special symbols (eg: (), {}),
Operators (eg: +, /,-,*)
C TOKENS EXAMPLE PROGRAM:
int main()
int x, y, total;
x = 10, y = 20;
total = x + y;
printf ("Total = %d \n", total);
int main()
int x, y, total;
x = 10, y = 20;
total = x + y;
printf ("Total = %d \n", total);
where,
main – identifier
{,}, (,) – delimiter
int – keyword
x, y, total – identifier
main, {, }, (, ), int, x, y, total – tokens
Data types
Data types in C Language
Data types specify how we enter data into our programs and what type of data we enter. C
language has some predefined set of data types to handle various kinds of data that we can
use in our program. These datatypes have different storage capacities.
C language supports 2 different type of data types:
Primary data types:
These are fundamental data types in C namely integer (int), floating point (float), character
(char) and void.
Every C compiler supports five primary data types:
Void: As the name suggests, it holds no value and is generally used for specifying the type of
function or what it returns. If the function has a void type, it means that the function will not
return any value.
Int: Used to denote an integer type.
Char: used to denote a character type.
float, double: Used to denote a floating point type.
int *, float *, char *: Used to denote a pointer type.
After taking suitable variable names, they need to be assigned with a data type. This is how
the data types are used along with variables:
int age;
char letter;
float height, width;
Derived data types:
Derived data types are nothing but primary datatypes but a little twisted or grouped
together like array, reference, and pointer.
C supports three derived data types:
Arrays: Arrays are sequences of data items having homogeneous values. They have adjacent
memory locations to store values.
Reference: Function pointers allow referencing functions with a particular signature.
Pointer: These are powerful C features which are used to access the memory and deal with
their addresses.
User defined data types
C supports three user defined data types:
Structure: It is a package of variables of different types under a single name. This is done to
handle data efficiently. "struct" keyword is used to define a structure.
Union: These allow storing various data types in the same memory location. Programmers
can define a union with different members, but only a single member can contain a value at
a given time. It is used for
Enum: Enumeration is a special data type that consists of integral constants, and each of
them is assigned with a specific name. "enum" keyword is used to define the enumerated
data types.
Constants
Constants: Constants are also like normal variables. But, only difference is, their values can
not be modified by the program once they are defined. Constants refer to fixed values. They
are also called as literals.
Constants may belong to any of the data type.Syntax:
const data_type variable_name; (or) const data_type *variable_name;
Types of Constants:
Integer constants – Example: 0, 1, 1218, 12482
Real or Floating point constants – Example: 0.0, 1203.03, 30486.184
Octal & Hexadecimal constants – Example: octal: (013 )8 = (11)10, Hexadecimal: (013)16 =
(19)10
Character constants -Example: ‘a’, ‘A’, ‘z’
String constants -Example: “GeeksforGeeks”
Operators and its precedence
Precedence of operators
If more than one operators are involved in an expression, C language has a predefined rule
of priority for the operators. This rule of priority of operators is called operator precedence.
In C, precedence of arithmetic operators( *, %, /, +, -) is higher than relational operators(==, !
=, >, <, >=, <=) and precedence of relational operator is higher than logical operators(&&, ||
and !).
Example of precedence
(1 > 2 + 3 && 4)
This expression is equivalent to:
((1 > (2 + 3)) && 4)
i.e, (2 + 3) executes first resulting into 5
then, first part of the expression (1 > 5) executes resulting into 0 (false)
then, (0 && 4) executes resulting into 0 (false)
Output
Associativity of operators
If two operators of same precedence (priority) is present in an expression, Associativity of
operators indicate the order in which they execute.
Example of associativity
1 == 2 != 3
Here, operators == and != have same precedence. The associativity of both == and != is left
to right, i.e, the expression on the left is executed first and moves towards the right.
Thus, the expression above is equivalent to :
((1 == 2) != 3)
i.e, (1 == 2) executes first resulting into 0 (false)
then, (0 != 3) executes resulting into 1 (true)
Output
typedef in C Language
🔹 1. What is typedef?
typedef is a keyword in C used to create an alias (nickname) for an existing data
type.
It improves readability, portability, and makes complex declarations simpler.
👉 It does not create a new data type — it just renames an existing one.
🔹 2. Syntax
typedef existing_type new_name;
Example:
typedef unsigned int uint;
uint age = 25; // same as: unsigned int age = 25;
🔹 3. Why use typedef?
Makes the program easier to read.
Provides portability (easy to modify types when moving between systems).
Simplifies complex declarations (e.g., pointers to functions, structures).
🔹 4. Examples of typedef
(A) Simple Alias
#include <stdio.h>
typedef unsigned int uint;
int main() {
uint x = 100; // instead of unsigned int x
printf("%u", x);
return 0;
Output:
100
(B) typedef with struct
Without typedef:
struct Student {
char name[20];
int age;
};
struct Student s1;
With typedef:
typedef struct {
char name[20];
int age;
} Student;
Student s1; // No need to write 'struct' every time
(C) typedef with Pointers
typedef int* IntPtr;
int main() {
IntPtr p1, p2; // both are int pointers
int x = 10, y = 20;
p1 = &x;
p2 = &y;
printf("%d %d", *p1, *p2);
return 0;
(D) typedef with Arrays
typedef int Marks[5];
int main() {
Marks m = {90, 85, 80, 95, 88}; // same as int m[5]
for(int i=0; i<5; i++) {
printf("%d ", m[i]);
return 0;
(E) typedef with Function Pointers
#include <stdio.h>
typedef int (*operation)(int, int);
int add(int a, int b) { return a+b; }
int mul(int a, int b) { return a*b; }
int main() {
operation op; // function pointer type
op = add;
printf("Sum = %d\n", op(5,3));
op = mul;
printf("Product = %d\n", op(5,3));
return 0;
🔹 5. typedef vs #define
Feature typedef #define
Purpose Creates alias for a data type Creates alias for a value/text
Checked by compiler ✅ Yes (type-safe) ❌ No (simple text replacement)
Better for data types, structs,
Usage Better for constants, macros
pointers
Example typedef unsigned int uint; #define uint unsigned int
🔹 6. Real-Life Usage
1. Replacing long/complex types → typedef unsigned long int ULI;
2. Structs → typedef struct Employee Emp;
3. Platform-independent code → typedef int32_t myInt;
4. Function pointers in callback functions.
✅ Summary
typedef = nickname for data types.
Improves readability, portability, and simplicity.
Commonly used with structs, pointers, arrays, function pointers.
Preferred over #define when dealing with data types.
Macros in C Language
🔹 1. What is a Macro?
A macro is a preprocessor directive in C that defines a symbolic name or expression.
It allows code substitution before compilation.
Macros are not variables; they do not consume memory.
Macros are handled by the preprocessor, which runs before compilation.
🔹 2. Syntax
#define MACRO_NAME replacement_text
Example:
#define PI 3.14159
#define MAX 100
Here, PI and MAX are macros.
Wherever the preprocessor finds PI or MAX, it replaces it with 3.14159 or 100 before
compilation.
🔹 3. Types of Macros
(A) Object-like Macros
Replaces a constant or expression.
Syntax:
#define NAME value
Example:
#define PI 3.14159
#define MAX 100
Usage:
float area = PI * r * r;
int limit = MAX;
(B) Function-like Macros
Similar to inline functions.
Takes arguments and replaces with an expression.
Syntax:
#define SQUARE(x) ((x)*(x))
Example:
#include <stdio.h>
#define SQUARE(x) ((x)*(x))
int main() {
int a = 5;
printf("Square of %d = %d", a, SQUARE(a));
return 0;
Output:
Square of 5 = 25
⚠️Always use parentheses () in macro definition to avoid precedence issues.
(C) Macros with Multiple Lines
Use backslash \ to continue macro on next line.
Example:
#define PRINT_SUM(a,b) \
printf("Sum = %d\n", (a) + (b))
(D) Conditional Macros
Used with preprocessor conditional compilation.
Example:
#define DEBUG
#ifdef DEBUG
#define LOG(x) printf("Debug: %s\n", x)
#else
#define LOG(x)
#endif
🔹 4. Advantages of Macros
1. No memory consumption (unlike constants).
2. Can define constants, expressions, and code snippets.
3. Can improve readability by replacing magic numbers with names.
🔹 5. Disadvantages of Macros
1. No type checking → errors may go unnoticed.
2. Can lead to unexpected results if parentheses are not used.
3. Harder to debug than constants or inline functions.
Example of pitfall:
#define SQUARE(x) x*x
int a = 5;
printf("%d", SQUARE(a+1)); // Expands to 5+1*5+1 = 11 ❌
Correct way:
#define SQUARE(x) ((x)*(x))
🔹 6. Difference Between macro and const
Feature Macro (#define) Constant (const)
Memory No Yes
Type checking No Yes
Scope Global Can be local/global
Debugging Hard Easy
Evaluation Preprocessor replaces text Evaluated at compile-time
🔹 7. Example Program Using Macros
#include <stdio.h>
#define PI 3.14159
#define SQUARE(x) ((x)*(x))
int main() {
float r = 5.0;
printf("Area of Circle = %.2f\n", PI * SQUARE(r));
return 0;
Output:
Area of Circle = 78.54
✅ Summary
Macros are preprocessor directives for code substitution.
Types: Object-like, Function-like, Multiline, Conditional.
Advantage: No memory usage, improves readability.
Disadvantage: No type checking, careful with parentheses.
Prefer const or inline functions in modern C when type safety is required.
Type Conversion in C Language
🔹 1. What is Type Conversion?
Type Conversion is the process of converting a variable from one data type to
another.
It allows arithmetic or assignment between different data types.
Two types of type conversion in C:
1. Implicit Type Conversion (Type Casting / Type Promotion)
2. Explicit Type Conversion (Type Casting by Programmer)
2️⃣ Implicit Type Conversion (Type Promotion)
Also called type promotion.
Done automatically by the compiler when different data types are mixed in
expressions.
The compiler promotes the lower data type to a higher data type to avoid data loss.
Rules of Type Promotion (Simplified)
Lower Type Promoted To
char int
short int
float double
int + float float
int + double double
Example:
#include <stdio.h>
int main() {
int i = 10;
float f = 3.5;
float result;
result = i + f; // int is promoted to float
printf("Result = %.2f", result); // 13.50
return 0;
Here, i is automatically converted to float before addition.
3️⃣ Explicit Type Conversion (Type Casting)
Also called type casting.
Done manually by the programmer.
Syntax:
(type) expression
Example:
#include <stdio.h>
int main() {
float f = 3.7;
int i;
i = (int)f; // explicit conversion from float to int
printf("i = %d", i); // 3 (fractional part lost)
return 0;
Example 2: Mixed Arithmetic
int a = 5, b = 2;
float result;
result = (float)a / b; // cast 'a' to float before division
printf("Result = %.2f", result); // 2.50
Without casting, 5/2 gives 2 (integer division).
4️⃣ Type Conversion in Expressions
In arithmetic expressions, C follows usual arithmetic conversions:
1. If any operand is long double, all operands are converted to long double.
2. Else if any operand is double, all operands are converted to double.
3. Else if any operand is float, all operands are converted to float.
4. Else if any operand is unsigned long, all operands converted to unsigned long.
5. Else integer types are converted to int.
Example:
int a = 5;
float b = 2.5;
double c = 3.5;
double result;
result = a + b + c; // a -> float, then result -> double
printf("Result = %.2f", result); // 11.00
5️⃣ Important Points
1. Implicit conversion: automatic, safer, may cause precision loss.
2. Explicit conversion: manual, programmer decides, more control.
3. Type casting should be done carefully, especially from float → int (fractional part
lost) or larger → smaller types (data loss possible).
4. Type casting is also used in pointer conversions, function arguments, and struct
conversions.
6️⃣ Example Program Demonstrating Both
#include <stdio.h>
int main() {
int a = 5, b = 2;
float x;
// Implicit conversion
x = a + 2.5; // a promoted to float
printf("Implicit conversion: %.2f\n", x);
// Explicit conversion
x = (float)a / b; // a cast to float for precise division
printf("Explicit conversion: %.2f\n", x);
return 0;
Output:
Implicit conversion: 7.50
Explicit conversion: 2.50
✅ Summary
1. Type conversion allows operations between different data types.
2. Implicit conversion (promotion) is automatic.
3. Explicit conversion (type casting) is manual using (type).
4. Important in mixed arithmetic, pointer conversions, and precision control.