KEMBAR78
Unit-1 C Programming Notes | PDF | Pointer (Computer Programming) | Algorithms
0% found this document useful (0 votes)
90 views105 pages

Unit-1 C Programming Notes

Uploaded by

venteysharma
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
90 views105 pages

Unit-1 C Programming Notes

Uploaded by

venteysharma
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 105

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) = &sum; — 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.

You might also like