C Programm
C Programm
INDEX
Sessions C Fundamentals 64 Hours Page no
Session Basics of C 2 Hours 4–30
Introduction to programs 4
The constituents of any programming language 5
Algorithms, pseudocodes, and flowcharts 6
Introduction to C 14
History, features, and applications, Installation 17–26
Structure of C program (syntax) 26–29
Q&A and Summary 29–30
Session 2 Variables and Data Types 2 Hours 31–56
Overview of variables and data types in C 31–36
Understanding different data types and their usage 36–54
Declaring and initializing variables correctly 31–34
Using format specifiers (%d, %f, %c, %s, etc.) in printf() and 34–36
scanf()
Differentiating between implicit (automatic) and explicit 50–55
(manual) type conversions
Q&A and Summary 55–56
Session 3 Operators and Expressions 2 Hours 57–75
Introduction to Operators and Expressions 57
Types of Operators in C - 57–66
Arithmetic, Relational, Logical,
Bitwise, Assignment and
Compound Assignment Operators
Operator Precedence and Associativity 66–70
Q&A and Summary 70–71
Session 4 Input and output 2 Hours 72–85
Introduction to Input and Output 72–74
Using printf() and scanf() or Console I/O 76–77
Character Input and Output 77–79
File Input and Output Basics 79–83
Q&A and Summary 83–85
Session 5 Condition Statements and AI Code Generation 2 Hours 86–112
Introduction to Conditional Statements in C, if, If-else, Nested if 86–92
Switch Statement, Ternary Operator 92–96
AI-Assisted Code Generation for C Programming 96–98
AI Tools for C Code Generation, AI-Assisted Examples 99–104
Debugging & Optimization 104–110
Q&A and Summary 110–112
Session 6 Loops and AI Code Generation 2 Hours 113–133
2
Introduction to Loops, for Loop, while Loop, do-while Loop 113–126
Loop Control Statements 126–128
AI Code Generation in C 128–132
Q&A and Summary 132–133
Session 7 Arrays (One-dimensional & Two-dimensional) 2 Hours 134–145
Introduction to Arrays 134–135
One-Dimensional (1D) Arrays 135–138
Two-Dimensional (2D) Arrays 139–142
Q&A and Summary 143–145
Session 8 Pointers and AI Code Generation 2 Hours 146–180
Introduction to Pointers, Pointer Basics, Pointers and Arrays 146–169
Dynamic Memory Allocation 169–176
AI Code Generation for Pointers 176–178
Q&A and Summary 179–180
Session 9 Functions and AI Code Generation 2 Hours 181–200
Introduction to Functions 181–182
Defining and Using Functions 182–184
Function Types and Scope, Recursion in C 184–197
AI Code Generation for Functions 197–199
Q&A and Summary 199–200
Session 10 Strings 2 Hours 201–212
Introduction to Strings 199–200
Declaring and Initializing Strings 202–206
String Operations Using Built-in Functions 206–210
Q&A and Summary 211–213
Session 11 Advanced Data Types (Structures) and Sorting 2 Hours 214–229
Introduction to Structures, Declaring, Initializing, and Accessing 214–223
Structures
Sorting Concepts and Algorithms 224–230
225, 227,
Implementing Sorting Algorithms 229
Q&A and Summary 230–231
Session 12 File Handling 2 Hours 232–250
Introduction to File Handling 232–233
File Operations and Files Pointers, Reading from and Writing to 234–242
Files
Working with Binary Files 242–245
File Handling Best Practices 245–248
Q&A and Summary 248–250
3
SESSION 1
BASICS OF C
SESSION OBJECTIVES
• Learners will understand algorithms, pseudocode, and flowcharts, enabling them to
break down problems logically and represent solutions effectively.
• Learners will be able to differentiate between these concepts, develop structured
problem-solving skills, and visualize solutions using flowcharts.
• Learner will explore the evolution, key features, and real-world applications of C,
recognizing its importance in system-level programming.
• Learners will analyze the structure of a C program and grasp its compilation and
execution process, building a strong foundation for writing efficient and structured code.
Introduction to Programs
What is a Program?
A program is a set of instructions written in a programming language that a
computer can execute to perform a specific task or solve a problem.
Programs form the foundation of all computer operations, from running
software applications to controlling devices and processing data.
Purpose of Programming
• Automate tasks
• Solves complex problems
• Create applications (e.g., web, mobile, desktop)
• Manage data
• Control hardware devices
Key Concepts
• Input: Data provided to the program.
• Process: The computation or logic applied to the input.
• Output: The result after processing.
4
Constituents of a Programming Language
A programming language typically consists of the following elements:
1. Syntax
The set of rules defines the combinations of symbols considered correctly
structured programs in that language.
2. Semantics
The meaning behind syntactically correct statements—how they behave
when executed.
3. Keywords
Reserved words that have special meaning (e.g., if, while, for, return).
5. Operators
Symbols that perform operations on variables and values (e.g., +, -, ==, &&).
6. Control Structures
Used to control the flow of execution:
8. Functions/Procedures
Reusable blocks of code are designed to perform a specific task.
9. Input/Output Statements
Allow interaction with the user or other programs/devices (e.g., print(),
scanf()).
5
Algorithms, Pseudocode, and Flowcharts
What is an Algorithm?
An algorithm is a well-defined, step-by-step sequence of instructions used
to solve a specific problem or accomplish a particular task. It provides a
logical approach to problem-solving, ensuring that a given input leads to a
correct and expected output through a finite number of well-structured
steps.
6
o Decrease N by 1
6. Print factorial
7. END
This algorithm computes the factorial of a number using iteration. For
example, if N = 5, the factorial is calculated as 5 × 4 × 3 × 2 × 1 = 120.
What is Pseudocode?
7
• Efficient Problem-Solving: Helps programmers and developers plan
their solutions efficiently before implementing them in a
programming language.
Example:
Algorithm to find the sum of two numbers:
What is a Flowchart?
A flowchart is a visual representation of a sequence of steps in an
algorithm. It uses different symbols to represent different types of actions
or decisions, making it easier to understand how a process flows from start
to finish.
Flowcharts are widely used in programming and problem-solving as they
provide a clear and organized way to visualize complex processes. A
flowchart is a graphical representation of an algorithm using symbols.
Common Symbols:
• Terminator (Start/End): Represented by an oval, it marks the
beginning or end of a flowchart.
o Example: ⬭ Start / End
8
• Input/Output: Represented by a parallelogram, it shows data
input or output operations.
o Example: ▱ Read Data / Display Output
• Arrows: Show the flow direction of the process from one step to
another.
o Example: → (points to the next step)
9
Easy to Moderate High High
Read
Use Case Problem-solving, Initial program Visualizing
logic design design complex logic or
processes
10
7. Visualize Problem-Solving Techniques Using Flowcharts
Flowcharts help break down problems into logical steps, making it easier to
understand and implement solutions effectively. They serve as a visual
guide for programmers, students, and problem-solvers to streamline
processes and improve efficiency.
12
Programming Languages
Programming languages serve as the backbone of software development,
enabling programmers to communicate with computers effectively. There are
numerous programming languages, each designed with specific goals and
applications. This eBook explores the different types of programming languages,
categorized based on abstraction level, paradigm, execution, and usage.
13
• Examples: Java, C++, Python, C#.
3. Based on Execution
3.1 Compiled Languages
Compiled languages are translated into machine code before
execution, making them faster and more efficient.
• Examples: C, C++, Rust, Go.
4. Based on Usage
4.1 General-Purpose Languages
14
Designed for a wide range of applications, from web development to
machine learning.
• Examples: Python, Java, C++, JavaScript.
INTRODUCTION TO C
C is a middle-level, general-purpose programming language that is widely used for
system and application software development. It provides low-level access to
memory and system resources, making it efficient for performance-critical
HISTORY OF C
Year Event Explanation
1960 Development of ALGOL (Algorithmic Language) was
ALGOL developed as a standard for algorithms
and influenced many future languages,
including C.
1963 Birth of CPL CPL was created as an extension of ALGOL,
(Combined aiming for more flexibility but was too
Programming complex for practical use.
Language)
1967 BCPL (Basic BCPL was developed as a simplified version
Combined of CPL, focusing on system programming
Programming and portability. It introduced low-level
Language) by Martin programming constructs that influenced C.
Richards
15
1970 B Language by Ken Ken Thompson, at Bell Labs, developed B,
Thompson which was based on BCPL but removed
unnecessary complexities. It was used for
early UNIX development but had
limitations like inefficient data types.
16
1995 C95 (Minor Updates The ISO committee released a small
to C90) update to C90, improving
internationalization support and adding
new library functions like wchar_t.
1999 C99 Standard This version introduced several
Released improvements, including variable-length
arrays (VLAs), inline functions, new data
types (long long int, _Bool), and restrict
keyword for optimization.
FEATURES OF C
17
1. Structured Programming
• C supports structured programming, which emphasizes dividing.
• Programs into functions or modules, making code more organized,
readable, and maintainable.
• It encourages using control flow statements such as if, else, while, for,
and switch, which help structure logic.
3. Portability
• Programs written in C are highly portable, meaning they can be
executed on different computer architectures with minimal
modifications. This is due to C's reliance on a small set of instructions
that can be implemented on virtually any hardware.
18
APPLICATIONS
1. SYSTEM SOFTWARE
System software refers to the software designed to provide a
platform for running application software and managing hardware
resources.
2. EMBEDDED SYSTEMS
C is widely used in embedded systems programming, which involves
working with hardware and firmware. Microcontrollers and
microprocessors in devices like automotive systems, medical
19
equipment, home appliances, and consumer electronics often use C
for efficiency and control over hardware.
3. PORTABILITY
• Due to its portability, C is often used for developing cross-
platform software.
• C programs can be compiled on different platforms with
minimal changes, making them useful for applications that
need to run on various operating systems.
4. GAMES DEVELOPMENT
While modern game engines often use high-level languages, C is still
used for developing performance-critical components of games, such
as physics engines or low-level graphics rendering.
Many early video games and game consoles were programmed using
C.
5. EMBEDDED SOFTWARE FOR IOT (INTERNET OF THINGS)
C is used in the development of software for IoT devices, which often
have limited resources. The language’s efficiency in terms of memory
usage and performance is essential for these resource-constrained
systems.
INSTALLATION:
To install a C programming environment on Windows, you'll need two main
components:
• VS Code: A text editor to write your code,
• MinGW: A compiler that turns your C code into an executable
program.
20
Step 1: Install VS Code
Go to the VS Code Official website and download the Windows installer.
Once the download is complete, run the installer and follow the installation
process.
Click Finish to complete the installation process.
Visit the official MinGW website and download the MinGW installation
manager.
Step 3: Run the Installer Now, go to your downloads folder and run the
installer you just downloaded. You will be prompted to this screen.
21
• Click on Continue and wait till the download is completed.
• Include gcc-core package
• During installation, you will be prompted to select the components to
install.
• Mark mingw32-base for installation, click on installation and apply
changes.
22
Step 4: Add MinGW to System PATH
✓ Go to the folder and double click on the MinGW folder and copy its
location.
C:\MinGW\bin
✓ search environment variable on the terminal.
✓ In system properties, click on environment variables.
✓ You will be prompted to the screen below.
23
✓ Then, find the Path variable in the System variables section and click
on Edit.
✓ Click New and add the path to the bin directory within your MinGW
installation (i.e., C:\MinGW\bin)
✓ Finally, close all the dialogues with the Ok button.
24
Now, you are all set to run C code inside your VS Code.
Note: Alternatively, you can use IDEs like
Code::Blocks or Visual Studio, which come with their own C compilers.
25
Then, save this file with a .c extension by clicking on File again, then Save
As, and type your filename ending in .c. (Here, we are saving it as hello.c)
Now, write the following code into your file:
Then click on the run button on the top right side of your screen.
26
Not following the above rules will result in errors and your code will not run
successfully.
27
• ; -> This semicolon marks the end of the statement in C, similar to a period
at the end of a sentence in English.
Purpose: The purpose of this line is to output the text Hello World to the console
or terminal where the program is run.
This statement ends the main function and returns a value to the operating
system.
• return: This is a keyword in C that returns a value from the function to its
caller.
• 0: This is the value being returned. In C programs, returning 0 typically
indicates that the program finished successfully. Nonzero values are usually
used to indicate errors.
• ; ->The semicolon marks the end of the statement.
Purpose: This line tells the operating system that the program has executed
successfully. Returning 0 is a standard way to signal success in C programs.
COMMENTS
✓ A comment makes the program easier to read and understand. These are
the statements that are not executed by the compiler or an interpreter.
✓ Comments are hints that we add to our code, making it easier to
understand.
✓ Comments are completely ignored by C compilers.
28
Single-line comments
• They are used to comment out a single line of code or a part of it.
• These comments start with two forward slashes (//), and everything after
the slashes on that line is considered a comment.
Syntax:
// This is a single line comment
Syntax:
/* This is a multi-line comment
which can span multiple lines */
Summary
This module provided a foundational understanding of programming, focusing on
key concepts essential for beginners. It introduced the basics of programs and the
fundamental components of a programming language, including syntax,
semantics, variables, and control structures. The importance of algorithms,
pseudocode, and flowcharts was highlighted as essential tools for designing logical
solutions before coding. Additionally, the C programming language was explored
in depth, covering its evolution, key features, real-world applications, and program
structure. The process of compilation and execution in C was also explained,
detailing how source code is translated into machine-executable instructions. By
mastering these concepts, learners develop problem-solving skills and gain the
ability to write efficient C programs, setting a strong foundation for advanced
programming concepts.
29
Check your knowledge:
30
SESSION 2
VARIABLES AND DATA TYPES
SESSION OBJECTIVES
To provide a foundational understanding of how variables and data types work in the C
programming language. By the end of this module, learners should be able to:
31
Variable Declaration
A variable must be declared before it is used. The declaration tells the
compiler the variable name and data type.
Syntax:
Datatype variable_name;(declaring a variable)
Example:
int num;
Variable Initialization
Variable initialization in C refers to assigning an initial value to a variable at
the time of declaration. If a variable is not initialized, it contains garbage
values (random data already present in memory).
Syntax
data_type variable_name = value;
Example:
int x = 10; // Initialization of an integer variable
Here,
• int → Data type
• x → Variable name
• 10 → Initial value assigned to x
A simple C program that demonstrates the variable usage.
PROGRAM
32
Output:
10
✓ Basically, this program is printing the value of a variable num which is 10.
✓ The first line: #include<stdio.h>: includes the standard input/output
header file (stdio.h) that contains the functions printf and scanf that are
responsible for input and output.
✓ The execution starts from the main function and execute the
statements within the main function.
✓ In main: a variable num is declared and initialised to 10,
✓ Variable Initialization: num is explicitly assigned 10, so it does not
contain a garbage value.
Example:
int a = 5;
char ch = 'A';
float pi = 3.14;
33
Program
Explanation:
• #include<stdio.h>: inclusion of header file.
• main(): the point where execution starts.
• printf(): In this program, it is prompting the user to enter the number
• scanf(“%d”,&num): scanf() – standard input function
FORMAT SPECIFIER
✓ Format specifiers in C define the type of data to be read or printed.
✓ They are used with input (scanf()) and output (printf()) functions to tell
the compiler how to interpret variables.
Format Specifiers in C
In C programming, format specifiers are used in input and output functions
(like printf() and scanf()) to specify the type of data that is being handled.
They tell the compiler how to interpret the value or how to display it.
Format specifiers ensure that the data is printed or inputted in the correct
format, and they are essential for the correct functioning of formatted I/O
operations.
%[width][.precision][modifiers]specifier
Where:
• %: The percent symbol indicates the start of a format specifier.
• width: Specifies the minimum width of the printed output.
• precision: Used for controlling the number of decimal places (for
floating-point values).
• modifiers: Optional flags (such as l for long data types or h for
short data types).
• specifier: The character that tells the type of data to print (d, f, s,
etc.).
35
Specifier Description
%d Signed decimal integer
%i Signed integer (same as %d)
%u Unsigned decimal integer
%f Floating-point number
%lf Double precision floating-point number
%c Single character
%s String of characters
%x Hexadecimal (lowercase letters)
%X Hexadecimal (uppercase letters)
%o Octal number
%p Pointer address
%e Scientific notation (lowercase)
%E Scientific notation (uppercase)
%g General format for floating-point numbers
36
Basic datatypes in C
Primitive Datatypes
Primitive data types are the most basic data types that are used for
representing simple values such as integers, float, characters, etc.
Integer Datatype
The integer datatype in C is used to store the integer numbers (any
number including positive, negative and zero without decimal part).
✓ Octal values, hexadecimal values, and decimal values can be
stored in int data type in C.
We use int keyword to declare integer variable.
Syntax:
int variable_name;
int variable_name = value;
Example:
int a = 10;
✓ Size: 4 bytes
✓ Format Specifier: %d
37
The illustration of integer datatype
Output: 10
Size of int
Size:
• The size of an int depends on the system architecture (compiler
and OS).
• The range of a data type in C refers to the minimum and
maximum values that can be stored in a variable of that data type.
Common sizes:
▪ 16-bit system: int is 2 bytes (range: -32,768 to 32,767).
▪ 32-bit system: int is 4 bytes (range: -2,147,483,648 to
2,147,483,647).
▪ 64-bit system: usually 4 bytes.
Program
Output: 4
Sign modifiers:
The sign modifier controls whether a variable can hold both positive and
negative values or only non-negative (positive and zero) values.
Types:
• signed → Allows both positive and negative values (default for
int and char).
▪ Format specifier: %d
• unsigned → Allows only non-negative values (positive and
zero).
▪ Format specifier: %u
Size modifiers
The size modifier changes the amount of memory allocated for a data
type, affecting its range and precision.
Types:
• short → Uses less memory than a standard int.
39
o format specifier: %d , %i
• long → Uses more memory than a standard int.
o format specifier : %ld
• long long → Uses even more memory than a long int.
o format specifier: %lld.
• short int can hold negative values within its range (-32,768 to
32,767).
• unsigned short int can hold only positive values (0 to 65,535).
Output:
40
2.int and unsigned int:
Program
Output:
Program
41
4. Long long int and unsigned long long int
• long long int is designed for large integer values.
• unsigned long long int has a very large positive range.
Program
Character Datatype
Character data type allows its variable to store only a single character.
• It stores a single character and requires a single byte of memory in
almost all compilers.
Range:
• (-128 to 127) or
• Signed char(0 to 255)
Size: 1 byte
Format Specifier: %c
Syntax of char:
The char keyword is used to declare a variable of character type:
char variable_name;
43
Signed char:
Unsigned char:
• Can store only non-negative values.
• Range: 0 to 255.
Output: A
44
Points
char is essentially a small integer type!
• A char in C is stored as a 1-byte (8-bit) integer.
• Internally, characters are represented by their ASCII values (a
standardized mapping of characters to integers).
• The character 'A' has the ASCII value 65.
• The character 'a' has the ASCII value 97.
• So, when you assign a character to a char variable, it’s actually storing
the integer ASCII code of that character.
Let us print the ascii value of respective character in C
Example
45
24 CAN 25 EM 26 SUB 27 ESC
28 FS 29 GS 30 RS 31 US
32 SPACE 33 ! 34 " 35 #
36 $ 37 % 38 & 39 '
40 ( 41 ) 42 * 43 +
44 , 45 - 46 . 47 /
48 0 49 1 50 2 51 3
52 4 53 5 54 6 55 7
56 8 57 9 58 : 59 ;
60 < 61 = 62 > 63 ?
64 @ 65 A 66 B 67 C
68 D 69 E 70 F 71 G
72 H 73 I 74 J 75 K
76 L 77 M 78 N 79 O
80 P 81 Q 82 R 83 S
84 T 85 U 86 V 87 W
88 X 89 Y 90 Z 91 [
92 93 ] 94 ^ 95 _
96 ` 97 a 98 B 99 C
100 D 101 e 102 F 103 G
... ... 252 ü 253 Ý 254 Þ
255 Ÿ
46
The float type is suitable when memory efficiency is more important than
precision.
• Format Specifier: %f
Syntax
The float keyword is used to declare the variable as a floating point:
float var_name;
1. Size of float in C
• The size of a float in C is typically 4 bytes (32 bits).
• This size is system-dependent but standard on most platforms.
2. Range of float
• Range: ±1.5 × 10⁻⁴⁵ to ±3.4 × 10³⁸ (approximately)
• Precision: Up to 6-7 decimal digits.
Example Program
47
• %f formats the number in standard decimal notation.
• %e formats the number in scientific notation.
• %g uses the shortest representation between %f and %e.
Program
Double
The double keyword in C is used to declare variables that can hold floating-point
numbers with double precision. It is used when a higher precision is required for
numeric calculations that involve fractional values.
Range:
• The range of the double type is typically much larger than the float type.
• A double typically occupies 8 bytes (64 bits) in memory.
• Its range can vary based on the system architecture, but typically:
• Minimum value: around 2.225 x 10^-308.
• Maximum value: around 1.797 x 10^308.
• Precision: Typically, 15-16 decimal digits.
48
Program
Output
49
Void Datatype
The void data type in C is used to specify that no value is present. It does not
provide a result value to its caller.
• It has no values and no operations. It is used to represent nothing
• Void is used in multiple ways as a function return type, function arguments
as void.
For example, if you assign an integer value to a float variable, the programming
language will automatically perform an implicit type conversion, converting the
integer to a float without requiring any manual intervention.
50
Advantages:
• Convenience: Implicit casting saves time and effort because you don't have
to manually convert data types.
• Automatic: It happens automatically, reducing the chance of errors due to
forgetting to convert types.
Disadvantages:
1. Loss of Precision: Sometimes, when converting between data types, there
can be a loss of precision. For example, converting from a float to an integer
may result in losing the decimal part of the number.
2. Unexpected Results: Implicit casting can sometimes lead to unexpected
results if the programmer is not aware of how the conversion rules work.
51
Explicit Type Conversion
Explicit type conversion is performed by the user by using (type) operator. Before
the conversion is performed, a runtime check is done to see if the destination type
can hold the source value.
Explanation:
1. int a, c; – Declares two integer variables a and c.
2. float b; – Declares a floating-point variable b.
3. c = a + (int)b; –
o b is being explicitly cast to an integer using (int)b, which means its
decimal part will be truncated (not rounded).
o Then a (int) and (int)b (also int now) are added.
o The result is assigned to c (an integer).
Advantages:
• Control: Explicit type casting gives the programmer more control over the
conversion process, allowing for precise manipulation of data types.
• Clarity: By explicitly indicating the type conversion, the code becomes more
readable and understandable to other developers.
52
• Avoidance of Loss of Precision: In cases where precision is crucial, explicit
type casting allows the programmer to handle the conversion carefully to
avoid loss of precision.
Disadvantages:
• Complexity: Explicit type casting can introduce complexity to the code,
especially when dealing with multiple data type conversions.
• Potential Errors: If the programmer incorrectly performs explicit type
casting, it may result in runtime errors or unexpected behaviour.
• Additional Syntax: Explicit type casting requires additional syntax or
function calls, which may increase code verbosity.
Let us see the difference between the two types of conversions with examples.
Example: Converting an Integer to Short
Here, we convert an integer I to a short explicitly, then print the value of a. It
specifies type casting and basic output/input operations.
53
Best Practices for Type Casting:
When choosing whether to use implicit or explicit type casting, it is important to
consider the following best practices:
• Prefer implicit casting when it is safe and does not result in data loss.
• Use explicit casting for narrowing conversions or to clarify intent.
• Avoid unnecessary casts that clutter the code and reduce readability.
• Be cautious with downcasting (e.g., float to int) to prevent data loss.
• Do not mix signed and unsigned types without understanding the
implications.
• Use fixed-width types (int32_t, uint8_t, etc.) for portability and clarity.
• Limit pointer type casting to low-level code and use with care.
• Never cast away const unless absolutely necessary and safe.
• Avoid casting inside macros or complex expressions—prefer inline
functions.
• Enable compiler warnings (-Wall, -Wconversion) to detect unsafe casts.
54
Use explicit type casting when you want to ensure that a variable is converted to a
specific data type. Use explicit type casting when you are converting between
incompatible data types. For example, you can explicitly cast a double to an
integer, but you cannot implicitly cast an integer to a double.
Conclusion:
In conclusion, understanding implicit and explicit type casting is essential in
programming. Implicit type casting happens automatically when converting data
types, while explicit type casting requires a manual instruction from the
programmer to convert a value from one type to another. Both methods have
their uses and importance in coding. Developers must grasp these concepts to
ensure the accuracy and efficiency of their programs. By mastering implicit and
explicit type casting, programmers can write more robust and error-free code,
leading to better software development practices.
Summary
In C programming, understanding data types like int, float, double, and char is
essential, as each serves a specific purpose based on the kind of data being
stored. Variables must be declared with the correct type and can be initialized
during or after declaration. Input and output operations use format specifiers such
as %d for integers, %f for floats, %c for characters, and %s for strings in functions
like printf() and scanf(). Type conversions occur either implicitly (automatically,
such as converting int to float) or explicitly (manually, using casting like (int)x).
Proper handling of data types and conversions ensures accuracy and efficiency in
C programs.
55
Check your knowledge:
• What is the difference between float and double?
• Which data type would you use to store a single character?
• Can you declare multiple variables of the same type in one line? Give an
example.
• What is the difference between declaration and initialization of a
variable?
• What will happen if you use a variable without initializing it?
• What format specifier would you use to print a float value?
• Why do we not use & in scanf() for strings?
• What does %lf mean, and when should it be used?
• What is the difference between implicit and explicit type conversion?
• What will be the value of int x = (int)3.9; and why?
• Is float f = 10; an example of implicit or explicit conversion?
56
SESSION 3
Operators and Expressions
SESSION OBJECTIVES
• Understand operators and their role in C.
• Classify and apply different types of operators.
• Analyze operator precedence and associativity.
• Implement operator-based programs
• Optimize expressions for efficient computations.
• Solve operator-based problems and MCQs
Types of Operators in C
These operators are classified into various types based on the kind of
operations they perform:
• Arithmetic Operators
• Relational Operators
• Logical Operators
• Bitwise Operators
• Assignment Operators
• Unary Operators
ARITHMETIC OPERATOR:
In C programming, binary operators are operators that require two
operands to perform an operation. Arithmetic operators are a subset
of binary operators that perform mathematical operations on
numeric data types like int, float, double, etc.
57
The basic arithmetic operators in C are:
• Addition (+): Adds two operands.
• Subtraction (-): Subtracts the right operand from the left
operand.
• Multiplication (*): Multiplies two operands.
• Division (/): Divides the left operand by the right operand.
• Modulo (%): Returns the remainder of the division of the left
operand by the right operand.
Example
OUTPUT:
Points:
o While performing modulo arithmetic operation what if
numerator is less than the denominator? in this case
numerator is returned.
o Float division is not supported in C instead type casting float
into int datatype will returns the result.
o There is a function called fmod() that return exact remainder
after dividing two float values in C.
58
o For to use fmod() in program we need to
include math.h(header file) to program.
o because fmod() is included in math header file
Example Program
Output:
RELATIONAL OPERATOR
Relational operators are used to compare two values or expressions.
These operators help evaluate the relationship between the
operands (values or variables) and return a boolean value (either
true or false), where:
• true is represented by 1
• false is represented by 0
Example Program
59
Output:
LOGICAL OPERATOR
Logical Operators are used to combine two or more conditions/constraints
or to complement the evaluation of the original condition in
consideration. The result of the operation of a logical operator is a Boolean
value either 1(true) or 0(false).
60
• Reverses the boolean value of the condition. If the condition is
true (1), it returns false (0); if the condition is false (0), it returns
true (1).
Syntax:
!condition
Example Program
Output:
BITWISE OPERATOR:
Bitwise operators in C are used for manipulating individual bits of
integer values. These operators allow you to perform logical
operations directly on bits, which can be useful for tasks like
optimizing performance, working with low-level data, or performing
hardware-related tasks
61
• Bitwise compliment operator (~)
Bitwise operators perform operations directly on the binary
representation of numbers, which are sequences of bits (0s and
1s). Every number in the computer's memory is represented as a
series of bits. These operators allow us to manipulate the
individual bits of integers and perform bit-level operations.
5&3
// Binary of 5: 0101
// Binary of 3: 0011
// Result: 0001 (which is 1 in decimal)
62
5|3
// Binary of 5: 0101
// Binary of 3: 0011
// Result: 0111 (which is 7 in decimal)
5^3
// Binary of 5: 0101
// Binary of 3: 0011
// Result: 0110 (which is 6 in decimal)
a = 10
a<<2 shifting a by two bits
63
Step 01: First, we must find the binary representation of the value of
the variable
0 0 0 0 1 0 1 0
0 0 1 0 1 0
Step 02: Take the leftmost 2 bits and remove them and fill the blank
with the remaining bits
0 0 1 0 1 0
128 64 32 16 8 4 2 1
0 0 1 0 1 0 0 0
How it works:
• The bits of the operand are shifted right, and the leftmost bits are
typically filled with 0 (for positive numbers).
• Shifting right by n positions is equivalent to dividing the number
by 2^n.
64
Step 02: Remove the rightmost two bits (number of bits should be
shifted)
0 0 0 0 0 0 0 1 0
0 0 0 0 1 0
0 0 0 0 0 0 1 0
65
• Every 0 becomes a 1, and every 1 becomes a 0.
• Continuing the example of 5, the binary representation after
flipping all bits would be 11111010.
Result:
• The resulting number after the complement operation is now a
new integer.
• In the example, the bitwise complement of 5 (00000101) becomes
-6 in decimal, because in a signed 2’s complement representation,
the binary number 11111010 corresponds to -6.
66
Lower &&, `
=, +=, -=
Lowest Assignment
etc.
For example, 10 * 2/5, in this example, the multiplication (*) and division (/)
operators have equal precedence, so in which case should we run the
operator first so that the result is correct? Will the operator with first
multiplication (*) be correct, or will the operator with division (/) be
correct?
To know all this, we also have to check the Associativity of those operators.
Seeing the associativity of these operators, when we solve the Expression,
the result is correct. The associativity of the operator in the C language
plays a very important role in such conditions.
In this Expression (10 * 2/5), the Associativity of Multiplication (*) and
Division (/) operators is left to Right, so we will first execute 10 * 2, then,
after that, we will divide the result by 5.
67
So, it is clear that the + operator will run after the * and / operators.
But in this expression, first-run multiplication (*) operator or run division (/)
operator? To know this, we have to read the association of these operators.
Output -:
68
• Left-to-Right (Left Associative)
Most binary operators (like +, -, *, /) are left-associative.
x = 10 - 5 - 2;
• Right-to-Left (Right Associative)
Assignment operators and the ternary?: are right-associative.
69
3. Parentheses Override Everything
Parentheses have the highest precedence. They force certain parts of an
expression to be evaluated first, regardless of default precedence or
associativity.
x = (2 + 3) * 4;
Summary
Operators and expressions are fundamental in programming, allowing
manipulation of data and control over program flow. Operators are symbols that
perform specific tasks on operands, forming expressions that evaluate to values.
Common types include arithmetic operators (+, -, *, /, %) for mathematical
calculations, relational operators (>, <, ==, etc.) for comparisons, logical operators
(&&, ||, !) for combining conditions, bitwise operators (&, |, ^, etc.) for low-level
binary operations, and assignment operators (=, +=, etc.) for storing values.
Understanding operator precedence and associativity is crucial as they determine
the order in which operations are executed in complex expressions. These
concepts are essential for writing correct and efficient code, and each type of
operator can be demonstrated through simple example programs.
70
Check Your Knowledge
• What is the difference between an operator and an operand in C? Provide
examples.
• Why is operator precedence important when evaluating expressions in C?
• Explain the difference between the == and = operators with examples.
• What is the purpose of the modulo % operator, and what happens when the
numerator is less than the denominator?
• Why can’t the % operator be used with float or double values directly in C?
What is the alternative?
• Describe the function of the logical operators &&, ||, and! in terms of boolean
output.
• How does the bitwise AND (&) operator work at the binary level? Give a simple
example.
• What is short-circuit evaluation, and how does it apply to && and || operators
in C?
• Explain how the left shift (<<) and right shift (>>) operators affect the value of
an integer.
• What is the result of the bitwise complement (~) operation, and why does it
often return a negative value in C?
• Write a program that takes two integers as input and prints their sum,
difference, product, quotient, and remainder.
• Write a C program to calculate the area and perimeter of a rectangle
Use: area = length * breadth, perimeter = 2 * (length + breadth)
• Given the code below, predict the output and explain:
• Write a program to input a float and an integer, then use fmod() to print the
remainder of their division.
• Write a program to shift a number by 2 bits to the left and to the right and
print both results.
• Write a C program that converts temperature from Celsius to Fahrenheit
Use formula: F = (C * 9/5) + 32
71
SESSION 4
INTRODUCTION TO INPUT AND OUTPUT
SESSION OBJECTIVES
To provide a foundational understanding of how to use printf() and scanf() functions in C and
how to work with files
• Understand how data is received from the user and displayed on the screen.
• Learn about standard input (stdin) and standard output (stdout) streams
• Learn how to use printf() to display formatted output on the console. Understand how
scanf() reads formatted input from the user.
• Use getchar(), putchar(), gets(), and puts() for handling character-based input and
output.Understand the differences between formatted and unformatted input/output
functions.
• Learn how to read from and write to files using functions like fopen(), fclose(), fscanf(),
and fprintf().
• Understand file handling modes (r, w, a, etc.).
• Explore basic file operations such as reading, writing, and appending data.
• By mastering these concepts, learners will be well-equipped to use print the result in the
desired pattern and also, they will understand how to write and read data from files
72
Formatted Input and Output Functions
Formatted input/output functions allow the programmer to specify the
format in which data is read or displayed. These functions are part of the C
standard library and are powerful tools for handling various data types such
as integers, floating-point numbers, characters, and strings.
Key Functions:
• printf() – Used to output data in a formatted manner.
• scanf() – Used to read data in a specific format.
Both printf() and scanf() allow formatting control using format specifiers
like %d, %f, %c, %s, etc., and they can be used to input or output almost
any standard data type.
Input Functions:
getch() – Reads a character from the keyboard without echoing it to the
screen.
getche() – Reads a character from the keyboard and echoes it on the
screen.
getchar() – Reads a character from standard input (keyboard).
Output Functions:
• putch() – Writes a character to the screen.
73
• putchar() – Also writes a character to the screen, commonly used for
simple output.
In C language, printf() is used for output and scanf() is used for input.
Both printf() and scanf() are library functions defined in the header file
<stdio.h>.
74
o In example 1, the message enclosed within the double
quotes “ “ is going to be printed on the console.
• So, whatever you want to print on the console, you need to
enclose that message within double quotes.
• This statement needs to terminate with a semicolon (;)
Input and Output (I/O) operations are essential parts of any programming
language. In C, I/O operations allow programs to interact with the user,
75
read data from devices (like a keyboard or a file), and display information
on the screen or write to files.
C provides a powerful and flexible I/O system via standard libraries, mainly
through functions declared in stdio.h.
Syntax:
Example:
Format Specifiers:
Specifier Description
%d Integer
%f Floating point
%c Character
%s String
scanf() Function
The scanf() function is used to take input from the user via the keyboard.
76
Syntax:
Example:
getchar() Function
The getchar() function is used to read a single character from the standard
input (usually the keyboard). It does not require any parameters and
returns the ASCII value of the character entered.
Syntax:
Example:
77
How It Works:
• The function waits for the user to press a key and then returns the
character.
• Since it returns an int, it can also handle special values like EOF (End Of
File).
Example:
Explanation:
ch = getchar();
• This line uses the getchar() function to read a single character
from the standard input (keyboard).
• Whatever character the user types (followed by Enter) is stored in
the variable ch.
• If the user types multiple characters, only the first character is
captured.
putchar() Function
The putchar() function is used to display a single character to the
standard output (usually the screen). It takes one character as an
argument and returns the character written.
Syntax:
78
How It Works:
You pass a character to putchar(), and it prints it to the console.
It returns the character printed as an int.
Output:
File I/O in C
In C programming, File Input and Output (File I/O) refers to reading data
from files and writing data to files stored on the computer's disk. Instead of
interacting with the user through the keyboard and screen, file I/O allows
programs to store data permanently, making them much more useful for
real-world applications.
79
Working with files
When working with files, you need to declare a pointer of type file. This
declaration is needed for communication between the file and the
program.
Opening a File
Opening a file is performed using the fopen() function defined in the stdio.h
header file.
Explanation:
fopen():
This is a standard library function defined in stdio.h. It is used to open a file
for reading, writing, or appending. It returns a pointer to a FILE object (of
type FILE *), which is then used to access the file.
"fileToOpen":
This is the name of the file you want to open. It should be a string literal
(enclosed in double quotes). It can be just a filename (e.g., "data.txt") or a
full path (e.g., "C:\\Users\\user\\data.txt"). If the file doesn't exist and
you’re opening in read mode ("r"), it will return NULL.
"mode":
This defines the mode in which the file is opened. It’s also a string (enclosed
in quotes). Some common file modes are:
Mode Meaning
"r" Open file for reading (file must exist)
"w" Open file for writing (creates or overwrites)
"a" Open file for appending
"r+" Open for reading and writing (file must exist)
"w+" Open for reading and writing (creates or overwrites)
80
"a+" Open for reading and appending
ptr:
This is a variable (typically of type FILE *) that holds the file pointer
returned by fopen().
Example:
FILE *ptr;
Return Value:
If the file is successfully opened, fopen() returns a valid file pointer. If the
file cannot be opened (e.g., doesn’t exist in read mode), it returns NULL.
Example Usage:
Use fopen() to open a file.
They are just the file versions of printf() and scanf(). The only difference is
that fprintf() and fscanf() expects a pointer to the structure FILE.
81
Example 1: Program to write the data to the file output.txt using fprintf()
Example: Program to read the data to the file output.txt using fscanf()
82
Content of output.txt file:
Example: Program to append the data to the file output.txt using fprintf()
83
Closing a File
The file (both text and binary) should be closed after reading/writing.
Closing a file is performed using the fclose() function.
File I/O in C uses a special file pointer (FILE *), which acts as a connection
between the program and the file.
Summary
In C programming, input and output (I/O) operations are essential for interacting
with users and handling data. Console I/O is performed using the printf() and
scanf() functions, which allow formatted output to the screen and input from the
keyboard. These functions use format specifiers like %d, %f, %s, and %c to handle
various data types. For simpler, character-by-character operations, C also
84
provides getchar() and putchar(), which are useful for reading or displaying
individual characters.
Beyond console interactions, C supports file input and output, enabling data to be
saved to or read from files on disk. File operations use a file pointer (FILE *) and
functions such as fopen(), fprintf(), fscanf(), fgets(), fputs(), and fclose(). Files can
be opened in modes like "r" (read), "w" (write), and "a" (append), among others.
File I/O is powerful for storing program output, logging data, or loading large
input sets, making it an essential feature for real-world applications.
85
SESSION 5
CONDITION STATEMENTS AND AI CODE GENERATION
SESSION OBJECTIVES
• Understand and implement conditional statements in C.
• Learn the use of if statements.
• Learn the use of if-else statements.
• Learn the use of nested if statements.
• Learn the use of switch statements.
• Learn the use of the ternary (? :) operator.
• Introduction to AI tools for C code generation.
• Use AI to write C code.
• Use AI to debug C code.
• Use AI to optimize C code.
• Combine traditional coding with AI assistance.
• Enhance programming skills using both manual and AI-assisted approaches.
• Conditional statements
These statements allow a program to make decisions and execute certain
blocks of code based on whether a condition is true or false. These statements
are fundamental in guiding the program’s execution by providing paths
depending on different situations.
• Looping statements
These statements are used when we need to repeatedly execute a block of
code as long as a condition remains true. These statements allow us to
perform repetitive tasks without writing redundant code.
• case control statements
The switch-case control statement in C allows for decision-making based on
multiple possible conditions for a single variable or expression. It is typically
used when you have many conditions to check, and you want to avoid long if-
else chains.
86
Introduction to Conditional Statements in C: if, if-else, Nested if
In C, programs can choose which part of the code to execute based on some
condition. This ability is called decision making and the statements used for it are
called conditional statements. These statements evaluate one or more conditions
and make the decision whether to execute a block of code or not
1. If Statement:
• If statement is the simplest decision-making statement.
• It is used to decide whether a certain statement or block of
statements will be executed or not
• i.e if a certain condition is true then a block of statements is executed
otherwise not.
• A condition is any expression that evaluates to either a true or false
(or values convertible to true or false).
Syntax:
FLOWCHART
87
How if statement works?
The if statement evaluates the test expression inside the parenthesis ().
• If the test expression is evaluated to true, statements inside the body
of if are executed.
• If the test expression is evaluated to false, statements inside the body
of if are not executed.
1.if ( 3 + 2 % 5 )
printf ( “This works” ) ;
2.if ( a = 10 )
printf ( "Even this works" ) ;
3.if ( -5 )
printf ( "Even this work”);
88
PROGRAM
When the user enters -2, the test expression number<0 is evaluated to
true. Hence, you entered -2 is displayed on the screen.
Outputs:
IF-ELSE STATEMENT
The if statement may have an optional else block. The syntax of the if else
statement is:
Syntax:
if (condition) {
// Code to execute if the condition is true
}
else {
// Code to execute if the condition is false
89
}
Program
When the user enters 7, the test expression number%2==0 is evaluated
false. Hence, the statement inside the body of else is executed.
90
Output
Nested If Statement
It is possible to include an if...else statement inside the body of another
if...else statement.
Program:
Output:
91
ELSE IF LADDER STATEMENT
▪ The if...else statement executes two different codes depending upon
whether the test expression is true or false. Sometimes, a choice has
to be made from more than 2 possibilities.
▪ The if...else ladder allows you to check between multiple test
expressions and execute different statements.
92
Program
Output:
SWITCH STATEMENT
A switch statement in C is a control flow construct that allows a variable or
expression to be tested for equality against multiple constant values. It
serves as an efficient alternative to using multiple if-else statements,
particularly when handling several possible conditions. By enabling the
execution of one specific block of code based on the value of an expression,
the switch statement enhances code readability and maintainability,
making it a preferred choice for managing multi-way branching in a clean
and structured manner.
93
• Expression inside the switch must be an integer or character type.
• Each case label must contain a constant expression (e.g., numbers,
characters).
• The break statement is used to exit the switch block;
• otherwise, execution falls through to the next case.
• The default case is optional but executes when no case matches.
WORKING OF SWITCH:
94
TERNARY OPERATOR
The Conditional (Ternary) Operator in C
The conditional operator in C, commonly referred to as the ternary
operator, is a compact and efficient way to perform conditional logic. As its
name suggests, the ternary operator operates on three operands.
General Syntax
The syntax of the conditional operator follows this structure:
Depending on your use case, there are a few variations of this syntax:
95
1. Direct Assignment
Clearer and more common in practice, this form explicitly separates the
condition for better readability.
This form allows for more complex logic but may be less readable in certain
contexts.
96
Program to Find the Largest of Two Numbers Using Ternary Operator
AI-Assisted Code Generation refers to the use of Artificial Intelligence (AI) tools
and models to automatically write, complete, and optimize code based on natural
language instructions, partial code, or even pseudocode. These tools are trained
on vast datasets that include open-source code, documentation, and
programming patterns, enabling them to understand syntax, logic, and best
practices across multiple programming languages—including C. By interpreting
what a developer wants to achieve, AI can generate relevant code snippets,
suggest improvements, identify bugs, and provide explanations, making coding
more efficient and accessible.
97
The process of AI-assisted code generation typically involves four key steps. First,
the user provides a clear prompt—a simple, goal-based instruction that tells the
AI what kind of code to generate. For example, a user might say, "Write a C
program to check if a number is even." The clearer and more specific the prompt,
the better the results.
Next, the AI processes the request. Using natural language processing (NLP), the
AI interprets the instruction, understands the task, and matches it with patterns
and examples it has learned from a vast amount of code data. It then uses this
knowledge to generate an appropriate solution.
In the third step, the AI generates the code. It creates a complete, working C
program that meets the request. The output usually includes properly structured
code, and it may also provide comments or brief explanations to help the user
understand the logic.
Finally, the user reviews and tests the code. You can copy the code into a C
compiler like Code::Blocks, GCC, or any IDE of your choice. After compiling and
running the program, you can check the output to make sure it works as expected
and make any adjustments if needed.
The process of AI-assisted code generation typically involves several key steps to
help users efficiently generate and refine code with the support of artificial
intelligence.
98
explanations that clarify how the code works, making it easier for learners to
understand.
4. User Reviews and Tests Code
Once the code is generated, you copy it into your preferred C compiler or IDE
(like Code::Blocks, GCC, or Dev C++). You run the program, observe the output,
and test for correctness. It's important to check if the logic holds true for
various inputs, including edge cases.
5. Ask for Modifications or Enhancements
After testing the initial output, you can ask the AI to improve or modify the
code. For example, you might say: “Now add input validation,” “Convert this to
use a ternary operator,” or “Explain the logic.” The AI can then adjust the code
or provide more details to suit your learning or project needs.
6. Refine and Learn
The final step is all about learning and growth. You can manually tweak the
code, test it with unusual or unexpected inputs, and apply what you've learned
to solve similar problems. This hands-on experience helps reinforce coding
concepts and deepens your understanding over time.
99
1. ChatGPT (by OpenAI)
What it is:
ChatGPT is a conversational AI model developed by OpenAI. It understands
and responds to natural language inputs, making it an effective assistant for
generating code, explaining concepts, and solving programming problems in
real time.
Example Prompt:
Sample Output:
100
2. Replit AI
Example Usage:
Type a prompt like:
“Write a C program using switch case to create a simple calculator.”
Then click “Generate Code”, and the AI will provide a complete C program
that runs directly in your browser.
Sample Output:
101
AI-ASSISTED EXAMPLES: AI Prompt-Based C Programs
1. if Statement
Prompt: Write a C program to check if a number is positive.
2. if-else Statement
Prompt: Write a C program to check whether a number is even or odd using
if-else.
102
3. Nested if Statement
Prompt: Write a C program to find the largest among three numbers using
nested if.
103
4. if-else-if Ladder
Prompt: Write a C program to classify a student's grade based on marks
using if-else-if ladder.
5. Switch Statement
Prompt: Write a C program using switch case to display the day of the week
(1 to 7).
104
What is Debugging?
Debugging is the process of identifying, analyzing, and correcting errors—
commonly referred to as bugs—in your C program. These bugs can prevent
a program from compiling, cause it to crash, or produce incorrect results.
Debugging ensures that your code behaves as expected and delivers the
correct output under all conditions.
Whether you're a beginner writing your first C program or an experienced
developer working on a large project, debugging is an essential part of the
software development process.
105
Why Debugging is Important
Effective debugging plays a crucial role in the development cycle. Here's
why:
• Fixes Syntax Errors: These are errors related to incorrect use of C
language rules, such as missing semicolons, brackets, or incorrect
function declarations.
• Corrects Logical Errors: These occur when the syntax is correct, but
the program doesn't perform the intended task. For example, using
the wrong condition in an if statement.
• Improves Program Reliability: A well-debugged program is more
stable, reliable, and less likely to crash or produce unexpected results.
• Enhances Learning: By debugging your own code, you gain a deeper
understanding of how your program works—and why it sometimes
doesn’t.
106
1. Debugging with GDB
GDB (GNU Debugger) is a powerful tool for debugging C programs. It allows
you to run your program step-by-step, inspect variables, and find out where
things go wrong.
• Setting Breakpoints
A breakpoint is a marker that tells GDB to pause execution at a
certain point.
(gdb) break main
• Inspecting Variables
To check the value of a variable:
(gdb) print variable_name
• Continuing Execution
107
To resume execution until the next breakpoint:
(gdb) continue
• Exiting GDB
To exit GDB:
(gdb) quit
108
OPTIMIZATION
Optimization means making your C program run faster, use less memory, or
perform better, without changing what it does.
Think of it like cleaning and improving your code so it’s smarter and more
efficient
Types of Optimizations
1. Compile-Time Optimization refers to the process where the C
compiler automatically improves your code during compilation to
make it:
• Run faster
• Use less memory
• Be more efficient
• All this happens before the program runs – at compile time.
• Because these optimizations are done by the compiler (like gcc,
clang)
109
2. Runtime Compilation
Runtime Optimization refers to the techniques and practices that help your
program behave more efficiently while it's running — even after
compilation.
Technique Explanation
110
Example: Dead Code Elimination
Summary
In this session, we explored conditional statements in C, which are essential for
decision-making in programs. We started with the if, if-else, and nested if
structures, which allow code execution based on whether conditions are true or
false. Then we looked at the switch statement, a cleaner alternative to multiple if-
else chains when dealing with fixed values, and the ternary operator, a shorthand
version of if-else used for simple decisions.
We also introduced AI-assisted code generation tools that help programmers write
C code more efficiently. Tools like ChatGPT, GitHub Copilot, and others can
generate code from natural language prompts, suggest corrections, and even
optimize logic. Practical examples showed how AI can create basic programs like
checking if a number is even or odd. Finally, we covered debugging and
optimization techniques, emphasizing the use of tools like GDB for finding bugs
and applying compiler optimizations to enhance performance.
111
• List the rules and limitations of the switch statement in C. Why can't we use
floating-point expressions in switch?
• How does the ternary operator work in C? Rewrite a simple if-else using the
ternary operator.
• Discuss the advantages of using conditional statements in a program. How
do they improve program logic and flow?
• What is AI-assisted coding tools? How do they support a C programmer
during development?
• Mention three AI-based tools that can generate or assist in writing C code.
How do these tools integrate with IDEs?
• Explain the process of debugging in C. How do tools like GDB help in
identifying logical or runtime errors?
• What are some common techniques to optimize C code for performance?
How does compiler optimization work?
• Write a C program that checks whether a number entered by the user is
even or odd using if-else.
• Create a program that takes an integer input for day (1–7) and prints the
corresponding day name using a switch statement.
• Write a C program using nested if statements to check if a number is
positive, negative, or zero and also if it's even or odd.
• Use the ternary operator to determine and print the greater of two
numbers input by the user.
• Write a menu-driven calculator program using a switch statement with
options for addition, subtraction, multiplication, and division.
112
SESSION 6
LOOPS AND AI CODE GENERATION
SESSION OBJECTIVES
By the end of this session, students will be able to:
• Understand the concept and importance of loops in programming.
• Differentiate between for, while, and do-while loops.
• Apply loop control statements to manipulate loop flow.
• Write efficient loop-based programs in C.
• Explore how AI tools can assist in writing, debugging, and improving C code.
Types of Loops in C:
• Entry-controlled loop: The condition is checked before execution.
Entry-Controlled Loop
Examples in C:
▪ for loop
▪ while loop
113
Exit-Controlled Loop
Example:
• do-while Loop
While Loop
The general form of while is as shown below.
114
• Again, the test expression is evaluated.
OUTPUT:
115
Do While Loop
The do-while loop is an exit control loop in C that executes the loop
body first, then checks the condition. This ensures that the loop runs
at least once, even if the condition is initially false.
SYNTAX:
Program:
Here, even though i < 5 is false, "Hello" is printed once. This confirms
that do-while is exit-controlled.
116
Output:
For Loop
A for loop is a control structure that executes a block of code multiple times
until a specified condition is met.
• It is commonly used when the number of iterations is known.
• The loop checks the condition before executing the loop body.
117
Basic Points on For Loop
Output
Points:
• The initialization, testing and incrementation of loop counter is done
in the for statement itself.
• Instead of i = i + 1, the statements i++ or i += 1 can also be used.
• Since there is only one statement in the body of the for loop, the pair
of braces have been dropped.
Here, the incrementation is done within the body of the for loop and not
in the for statement. Note that, in spite of this, the semicolon ( ; ) after
the condition is necessary.
118
This rule applies:
1.This works: Here the initialization is done in the declaration statement
itself, but still the semicolon before the condition is necessary.
3.This works:
119
Program:
Infinite Loops in C
What is an Infinite Loop?
120
Writing Infinite Loops in C
C offers several ways to write an infinite loop. Here are the most common
patterns:
while(1) Loop
for(;;) Loop
do-while(1) Loop
121
• A do-while loop runs the block at least once, then continues as long
as the condition is true.
• Since 1 is always true, this loop becomes infinite as well.
Here, the loop will only stop if the user enters -1.
This is a controlled infinite loop — common in menu systems or interactive
programs.
Always ensure there's a valid exit condition if the loop isn’t meant to run
forever.
122
1. Right Half Pyramid Pattern in C
The right-half pyramid is nothing but a right-angle triangle whose
hypotenuse is in the right direction. We can print the right half pyramid
pattern using numbers, alphabets, or any other character like a star (*).
Program
123
Output:
Explanation:
• Outer loop: Controls the number of rows.
• Inner loop: Controls the number of columns (here in this problem stars
(*) printed in each row).
• Print * inside the inner loop row times.
• After the inner loop finishes (i.e., a row is complete), print a newline \n.
124
2. Inverted Left Half Pyramid Pattern in C
This pattern is the 180° flipped version of the left half pyramid pattern we
discussed earlier.
Example:
125
Output
126
Syntax
Example
Explanation
In the example above, the loop prints numbers from 0 to 4. When i
becomes 5, the break statement is executed, and the loop terminates. This
is useful when you need to stop the loop based on a condition that occurs
within the loop.
Syntax
Example
127
Explanation
In this example, the loop prints numbers from 0 to 9, except for 5. When i is
5, the continue statement is executed, skipping the printf statement for
that iteration. This allows you to bypass specific conditions within the loop
without terminating it.
Practical Applications
• break: Use the break statement to exit loops early when a condition is
met. This is particularly useful in search operations where you can stop
the loop once the desired element is found.
• continue: Use the continue statement to skip over certain iterations.
This is helpful in scenarios where you want to ignore specific values or
conditions within the loop.
Summary
• Loop control statements enhance the flexibility and control you have
over loops in C. By using break and continue effectively, you can write
more efficient and readable code.
• In the C programming language, there are times when you'll want to
change the looping behaviour. And the continue and the break
statements help you skip iterations and exit from loops under certain
conditions.
AI in Coding:
Modern AI tools like ChatGPT and GitHub Copilot help in generating C code by
understanding prompts, reducing syntax errors, suggesting logic, and even
explaining complex code snippets.
128
How AI Helps with Loops:
• Quick code generation for loops in any language
• Fixing loop logic errors (e.g., infinite loops)
• Optimizing performance (e.g., minimizing nested loops)
• Converting loop types (for ↔ while)
• Explaining loop flow visually or step-by-step
When using AI tools like ChatGPT for coding, you can just say:
"Generate a C program that uses a for loop to print numbers 1 to 10"
And it will give you:
Prompt: "My C program is stuck in an infinite loop. Here's the code. What's
wrong?"
int i = 1;
129
for (; i != 10; ) {
printf("%d ", i);
i += 2;
}
AI Explanation:
130
Loop Flow:
• Outer loop runs 3 times (i = 1 to 3)
• For each i, inner loop runs 2 times (j = 1 to 2)
• Total = 3 x 2 = 6 iterations
131
Converting Loop Types (for ↔ while)
Prompt: "Convert this for loop into a while loop"
for Loop:
Summary
132
Check Your Knowledge
• What is the difference between entry-controlled and exit-controlled loops?
Give examples.
• Can we replace a for loop with a while loop in all situations? Justify with
an example.
• What are nested loops? What are the time complexity implications of using
them?
• Explain how break and continue affect nested loops.
• How does an infinite loop impact memory and CPU usage? How can such a
loop be safely terminated?
• How can AI-generated code sometimes lead to logical errors, even if
syntactically correct?
• Write a C program that prompts the user to enter a positive integer. It then
calculates and prints the factorial of that number using a while loop.
• Write a C program that calculates and prints the sum of cubes of even
numbers up to a specified limit (e.g., 20) using a loop.
• Write a C program that implements a program to check if a given number is a
palindrome using a while loop.
• Write a C program to find and print the first 10 Fibonacci numbers using a
while loop.
• Write a C program that prompts the user to enter a positive integer. Use a
while loop to print the multiplication table for that number up to 10.
• Write a program in C to display a pattern like a right-angle triangle using an
asterisk.
133
SESSION 7
ARRAYS (ONE-DIMENSIONAL & TWO-DIMENSIONAL
SESSION OBJECTIVES
• By the end of this session, students will be able to:
• Understand the concept and purpose of arrays in C programming.
• Declare, initialize, and access elements in one-dimensional (1D) arrays.
• Perform basic operations using 1D arrays, such as input/output, searching, and summing
elements.
• Understand the structure and use of two-dimensional (2D) arrays.
• Declare, initialize, and manipulate elements in 2D arrays using nested loops.
• Apply arrays to solve simple real-life problems programmatically.
134
Why we Need Arrays?
The need for arrays arises when handling large amounts of related data. For
example, imagine storing the marks of 100 students. Instead of creating 100
separate variables such as mark1, mark2, ..., mark100, we can simply use a single
array like marks[100]. This approach not only reduces code complexity but also
makes it easier to manage, access, and manipulate the data efficiently.
Types of Arrays in C
There are two types of arrays based on the number of dimensions it has. They are
as follows:
• One Dimensional Arrays (1D Array)
• Two dimensional Arrays (2D arrays)
Array Declaration
In C, we must declare the array like any other variable before using it.
We can declare an array by specifying its name, the type of its elements, and
the size of its dimensions. When we declare an array in C, the compiler
allocates a memory block of the specified size to the array name.
135
Array Initialization
In C, initialization is the process of assigning an initial value to a variable. When
an array is declared or memory is allocated for it, its elements initially contain
garbage values. Therefore, it is important to initialize the array with meaningful
values before using it. Array initialization can be done in multiple ways,
primarily through compile-time initialization, where values are assigned at the
time of declaration, and run-time initialization, where values are assigned
during program execution. Proper initialization ensures reliable and predictable
behaviour of the program.
136
Run-Time Initialization
Run-time initialization refers to assigning values to array elements during
the execution of the program, typically through user input using
functions like scanf or through logical operations within the program.
In this approach, the values to be stored in the array are not known in
advance. Instead, they are provided or calculated as the program runs.
Although memory for the array is allocated at compile time, the actual
values are set during run time using loops or input mechanisms. This
method is useful when the data to be stored is dynamic or based on user
interaction.
137
Access Array Elements
We can access any element of an array in C using the array subscript
operator [ ] and the index value i of the element.
array_name [index];
One thing to note is that the indexing in the array always starts with 0,
i.e., the first element is at index 0 and the last element is at N – 1
where N is the number of elements in the array.
138
Two-Dimensional Array in C
A Two-Dimensional array or 2D array in C is an array that has exactly two
dimensions. They can be visualized in the form of rows and columns organized
in a two-dimensional plane.
A two-dimensional array or 2D array, is the simplest form of the
multidimensional array. We can visualize a two-dimensional array as one-
dimensional arrays stacked vertically, forming a table with ‘m’ rows and ‘n’
columns. In C, arrays are 0-indexed, so the row number ranges from 0 to (m-1)
and the column number ranges from 0 to (n-1).
Declaration of 2D Array
A 2D array with m rows and n columns can be created as:
type arr_name[m][n];
139
Example:
Initialization of 2D arrays
Explanation:
We can initialize a 2D array by using a list of values enclosed inside ‘{ }’ and
separated by a comma as shown in the example below:
The elements will be stored in the array from left to right and top to bottom. So,
the first 4 elements from the left will be filled in the first row, the next 4 elements
in the second row, and so on. This is clearly shown in the second syntax where
each set of inner braces represents one row.
In array initialization, the number of rows can be omitted; the compiler will
deduce it based on the number of values and the specified number of columns.
So, the below declaration is valid.
This program declares and initializes a 2D integer array with 2 rows and 4
columns. Each row is defined using inner braces, and the compiler automatically
infers the number of rows based on the initialization.
Here’s an example that demonstrates how to access and assign values in a two-
dimensional array using indices:
141
Since array indexes are integer value, hence you can also wire a loop to access
two-dimensional array. Two-dimensional array needs two index values to access
any array element. Therefore, you need two loops. One outer loop to access for
each row of the matrix, second loop for each column of the matrix.
142
Program to Print 2-D array
Summary
• An array in C is a collection of elements of the same data type, stored in
contiguous memory locations.
• Arrays can be one-dimensional (1D), like a list, or two-dimensional (2D), like
a table (matrix).
• Array elements are accessed using indices starting from 0.
A 1D array holds multiple values in a single row.
• Declared as:
143
Check Your Knowledge
• What is an array in C? Why and when would you use one?
• How is memory allocated for arrays in C?
• What are the limitations of using arrays in C?
• How is a 1D array different from a 2D array?
• What is the default initial value of elements in an uninitialized array?
• Can the size of an array be changed at runtime in C? Why or why not?
• Write a program in C to read n number of values in an array and display them
in reverse order.
• Write a program in C to count the total number of duplicate elements in an
array.
Test Data:
Input the number of elements to be stored in the array: 3
Input 3 elements in the array:
element - 0: 5
element - 1: 1
element - 2: 1
Expected Output:
The total number of duplicate elements found in the array is: 1
• Write a program in C to print all unique elements in an array.
Test Data :
Print all unique elements of an array:
------------------------------------------
Input the number of elements to be stored in the array: 4
Input 4 elements in the array :
element - 0: 3
element - 1: 2
element - 2: 2
element - 3: 5
Expected Output :
The unique elements found in the array are: 3 5
144
• Write a program in C to merge two arrays of the same size, sorted in
descending order.
Test Data:
Input the number of elements to be stored in the first array: 3
Input 3 elements in the array :
element - 0: 1
element - 1: 2
element - 2: 3
Input the number of elements to be stored in the second array: 3
Input 3 elements in the array:
element - 0: 1
element - 1: 2
element - 2: 3
Expected Output :
The merged array in descending order is : 3 3 2 2 1 1
• Write a program to find the transpose of a matrix.
• Write a program to multiply two matrices.
145
SESSION 8
POINTERS AND AI CODE GENERATION
SESSION OBJECTIVES
By the end of this session, you will be able to:
• Understand what pointers are and how they work in memory.
• Declare and use pointers for different data types.
• Access and manipulate array elements using pointers.
• Understand the relationship between arrays and pointers.
• Perform dynamic memory allocation using malloc(), calloc(), realloc(), and free().
• Avoid common pointer-related issues like wild pointers, dangling pointers, and memory
leaks.
POINTERS
Pointers are powerful features of C and C++ programming. Before we learn
pointers, let's learn about addresses in C programming.
Address in C
If you have a variable var in your program, &var will give you its address in
the memory. We have used address numerous times while using
the scanf() function.
Here, the value entered by the user is stored in the address of var variable.
Let's take a working example.
Note: You will probably get a different address when you run the above code.
146
C Pointers
A pointer is a variable that stores the memory address of another variable.
Instead of holding a direct value, a pointer holds an address pointing to a
location in memory.
Example:
Here, we have declared a pointer p of int type. You can also declare pointers
in these ways.
147
example:
• Here, the address of c is assigned to the pc pointer. To get the value stored
in that address, we used *pc.
• Note: In the above example, pc is a pointer, not *pc. You cannot and should
not do something like *pc = &c;
• By the way, * is called the dereference operator (when working with
pointers). It operates on a pointer and gives the value stored in that pointer.
We have assigned the address of c to the pc pointer. Then, we changed the value of
c to 1. Since pc and the address of c is the same, *pc gives us 1. Let's take another
example.
Here's a breakdown:
• %p stands for "pointer".
• When you use printf("%p", ptr);, it prints the address stored in the pointer
variable ptr.
• The output is typically in hexadecimal format, often prefixed with 0x.
Size: 8 bytes
• On a 64-bit system, pointers are 8 bytes (64 bits) in size.
• That means any pointer, whether it's pointing to an int, char, float, or a
custom structure, occupies 8 bytes in memory.
• This size allows it to hold any address within a 64-bit address space.
149
Example: Working of Pointers
Let's take a working example.
150
Explanation of the program
1. int* pc, c;
2. c = 22;
3. pc = &c;
4. c = 11;
151
5. *pc = 2;
Memory Representation:
int num = 10;
int *ptr = #
Example Program:
Logic Breakdown:
• num is an integer variable initialized with 10.
• ptr is a pointer that stores the address of num.
152
Common mistakes when working with pointers
Suppose you want pointer pc to point to the address of c. Then,
is equivalent to
In both cases, we are creating a pointer p (not *p) and assigning &c to it. To
avoid this confusion, we can use the statement like this:
153
Relationship Between Arrays and Pointers
An array is a block of sequential data. Let's write a program to print the addresses
of the array elements.
Similarly,
• &x[1] is equivalent to x+1 and x[1] is equivalent to *(x+1).
154
• &x[2] is equivalent to x+2 and x[2] is equivalent to *(x+2).
• ...
• Basically, &x[i] is equivalent to x+i and x[i] is equivalent to *(x+i).
155
Example 2: Arrays and Pointers
156
Example: Pass Addresses to Functions
The addresses of num1 and num2 are passed to the swap() function
using swap(&num1, &num2);. Pointers n1 and n2 accept these arguments in the
function definition. When *n1 and *n2 are changed inside
the swap() function, num1 and num2 inside the main() function are also changed.
Inside the swap() function, *n1 and *n2 swapped. Hence, num1 and num2 are
also swapped. Notice that swap() is not returning anything; its return type is void.
Here, the value stored at p, *p, is 10 initially. We then passed the pointer p to the
addOne() function. The ptr pointer gets this address in the addOne() function.
157
Inside the function, we increased the value stored at ptr by 1 using (*ptr)++;. Since
ptr and p pointers both have the same address, *p inside main() is also 11.
Pointer Arithmetic
What is Pointer Arithmetic?
Pointer arithmetic refers to performing arithmetic operations (like +, -, ++, --) on
pointers. This is especially useful when working with arrays or dynamic memory.
Because pointers "point to" memory addresses, arithmetic operations on them
manipulate the memory address they store, taking into account the size of the
data type they point to.
Basic Pointer Arithmetic Operations
1. Increment: ptr++
What it does: Moves the pointer to the next element in memory. How: It
increases the address stored in the pointer by sizeof(data_type).
Example:
2. Decrement: ptr--
• What it does: Moves the pointer to the previous element in memory.
Example:
3. Addition: ptr + n
• What it does: Moves the pointer forward by n elements.
• Note: This doesn't change the original pointer unless assigned.
158
Example:
4. Subtraction: ptr - n
• What it does: Moves the pointer backward by n elements.
Example:
Important Notes
• Pointer arithmetic is type-aware:
▪ If ptr is of type int *, ptr + 1 actually adds sizeof(int) to the
address.
▪ If it's a char *, then ptr + 1 adds just 1 byte.
o You can also subtract two pointers pointing into the same array:
Visual Example:
159
Arithmetic Operations on Pointers
• Pointer arithmetic includes: Increment (ptr++) – Moves the pointer to
the next memorylocation.Decrement (ptr--) – Moves the pointer to
the previous memory location.
• Addition (ptr + n) – Moves the pointer forward by n locations.
Subtraction (ptr - n) – Moves the pointer backward by n locations.
Types of Pointers in C
Depending on the parameters, pointers can be divided into a wide variety of
types. The following types of pointers are based on the type of variable that is
kept in the memory location that the pointer is pointing to.
Integer Pointers
The memory location of an integer variable is stored in an integer pointer.
Syntax
161
PROGRAM: NULL Pointer Usage
Output:
Logic Breakdown:
• Declare a pointer ptr and initialize it to NULL.
• Use an if condition to check if the pointer is NULL.
• Print a message indicating whether the pointer is NULL or not.
VOID POINTER
A void pointer (also known as a generic pointer) is a pointer that has no
specific data type associated with it. It can hold the address of any data
type, making it flexible for general-purpose programming.
162
Logic Breakdown:
1. Declare a void *ptr that can point to any data type.
2. Assign different variables (int, float, char) to ptr.
3. Before dereferencing, explicitly typecast ptr to the correct data type.
CONSTANT POINTER
A constant pointer is a pointer whose value (i.e., the memory address it
holds) cannot be changed after initialization. Once a constant pointer is
assigned an address, it must always point to the same memory location.
Syntax:
163
Example Program:
Key Points:
▪ Cannot change the address stored in ptr.
▪ Can change the value at the address using *ptr.
▪ ptr = &num2; results in a compilation error.
Pointer to Pointer
A pointer to a pointer, also called a double pointer, is a variable that stores
the address of another pointer. This allows for multiple levels of indirection
and is commonly used in complex data structures, dynamic memory
management, and function arguments that modify pointers.
How It Works
• x contains the value 100
• ptr contains the address of x
• pptr contains the address of ptr
164
Accessing Values:
Use Cases:
• Dynamic memory allocation for multi-dimensional arrays
• Modifying a pointer inside a function
• Parsing command-line arguments (char **argv)
• Working with linked lists and trees
Wild Pointer
A wild pointer is a pointer that has been declared but not initialized, and
thus it points to an unknown or random memory location. Dereferencing
such a pointer can lead to unpredictable results and may cause a program
to crash.
165
Best Practices to Avoid Wild Pointers:
• Always initialize pointers:
int *ptr = NULL;
Array of Pointers
An array of pointers is a collection where each element is a pointer. This
allows you to store references to multiple variables, arrays, or even strings,
providing greater flexibility in memory management.
Syntax:
Accessing Data:
Use Cases:
• Arrays of strings or variable-length arrays
• Jagged (non-uniform) multi-dimensional arrays
• Dynamic data structures like lists of arrays or arrays of objects
166
Array Pointer
The initial element of an array may be referenced by array pointers.
Syntax
Pointer to an Array
A pointer to an array is a pointer that holds the address of an entire array
rather than just a single element. This allows efficient traversal and
manipulation of the array using pointer arithmetic.
167
Key Concept:
• When an array is declared, its name acts as a pointer to the first
element.
• However, a pointer to an array explicitly stores the address of the
whole array.
Syntax:
Output:
Logic Breakdown:
• Declaring an Array
• int arr[5] = {10, 20, 30, 40, 50};
• Creates an array of 5 integers.
• Declaring a Pointer to an Array
• int (*ptr)[5] = &arr;
• ptr stores the address of the entire array, not just the first
element.
168
Dynamic Memory Allocation (DMA)
Dynamic Memory Allocation (DMA) in C is the process of allocating memory during
runtime using pointers. This allows a program to allocate memory based on the
actual requirements during execution rather than during compile time. The
memory is allocated using library functions like malloc(), calloc(), realloc(), and
free(). Here's a breakdown of each concept, including logic and example code for
each type of dynamic memory allocation:
How it works:
• A pointer is declared, and memory for the variable is allocated
dynamically using malloc().
• Once done with the memory, free() is called to deallocate it and
prevent memory leaks.
169
Example
Output:
Logic Breakdown:
1. malloc(sizeof(int)): Allocates memory for one integer
(sizeof(int) returns the size of an integer in bytes).
2. *ptr = 42;: Assigns the value 42 to the dynamically allocated
memory.
3. free(ptr);: Frees the memory once we're done with it,
preventing memory leaks.
170
Syntax:
Example:
Syntax:
Example:
171
Output
Syntax:
Example:
4.
Example:
172
Main Logic:
• First, processData is called with the printElement callback to
print each element of the array.
• Then, we loop through the array and use the sumElement
callback to accumulate the sum of the elements.
• We pass different behaviour (printing or summing) to the
same processData function by changing the callback
function.
Example Program:
173
Output:
Logic Breakdown:
1. malloc(n * sizeof(int)): Allocates memory for n integers, where
n is input by the user.
2. arr[i]: Array elements are accessed and modified just like in a
statically declared array.
3. free(arr): Frees the memory allocated for the array.
174
Example Program:
Output:
Logic Breakdown:
• malloc(sizeof(struct Student)): Allocates memory for one struct
Student object. The size of the structure is obtained using
sizeof(struct Student).
• studentPtr->name and studentPtr->age: Access the structure's
members using the pointer (studentPtr).
• free(studentPtr): Frees the memory allocated for the structure.
175
AI Code Generation
PROMPT 1: Basic Pointer Access
Prompt: Write a C program to:
• Declare an integer variable.
• Declare a pointer and assign it the address of the variable.
• Print the value and address of the variable using both the variable
and the pointer.
Answer:
Answer:
176
PROMPT 3: Dynamic Array Using malloc()
Prompt: Write a C program to:
• Dynamically allocate memory for an integer array of size n (e.g., 5).
• Initialize and print the elements.
• Free the memory.
Answer:
177
PROMPT 4: Pointer to Pointer
Prompt: Create a program that uses a pointer to a pointer to store and
print the value of an integer.
Answer:
178
Summary
Pointers are powerful features in C that allow direct access and manipulation of
memory. A pointer stores the address of another variable, and using the
dereference operator (*), you can access or modify the value at that address.
Pointers are closely related to arrays, as the array name itself acts like a pointer to
its first element, allowing for efficient array traversal and manipulation.
Understanding pointers also lays the foundation for dynamic memory allocation,
where functions like malloc(), calloc(), realloc(), and free() are used to manage
memory at runtime. Proper use of pointers enables flexible and efficient
programming, but care must be taken to avoid issues like memory leaks, dangling
pointers, or wild pointers.
179
• Create a function that counts the number of vowels in a string using pointer
traversal.
• Given an array, print all elements using pointer notation.
• Write a function that takes a 2D array and prints its elements using pointers.
• Dynamically allocate an array of integers, take input, and print the sum of
all elements.
• Implement a simple version of strcpy() using dynamic memory allocation.
• Create a dynamic 2D matrix (MxN), take input, print it, and deallocate the
memory.
• Create a program that dynamically reads a string of unknown length from
the user (like with getline() behavior).
180
SESSION 9
FUNCTIONS AND AI CODE GENERATION
SESSION OBJECTIVES
The objective of this module is to provide a foundational understanding of functions in C
programming, covering their definition, usage, types, and scope. Learners will explore recursive
functions and understand how they differ from iterative approaches. Additionally, the module
introduces the concept of AI-assisted code generation, demonstrating how artificial intelligence
tools can aid in writing and optimizing function-based code in C.
Introduction to Functions
• A function is a self-contained block of statements that performs a coherent
task of some kind.
• Every C program can be thought of as a collection of these functions.
• Using a function is something like hiring a person to do a specific job for
you.
• A program is just a set of definitions of variables and functions.
Communication between the functions is by arguments and values returned
by the functions, and through external variables.
Syntax of Functions in C
The syntax of function can be divided into 3 aspects:
• Function Declaration
• Function Definition
• Function Calls
Function Definition
The function definition consists of actual statements that are executed when the
function is called (i.e., when the program control comes to the function). A C
function is generally defined and declared in a single step because the function
definition always starts with the function declaration, so we do not need to declare
it explicitly.
Function Call
A function call is a statement that instructs the compiler to execute the function.
We use the function name and parameters in the function call.
182
• In the below example, the first sum function is called and 10,30 are passed
to the sum function. After the function call sum of a and b is returned and
control is also returned back to the main function of the program.
• A function call is necessary to bring the program control to the function
definition. If not called, the function statements will not be executed.
Example Program:
183
This C program defines a sum function that adds two integers, then calls it in
main, storing the result in add and printing the sum.
Types of Functions
There are two types of functions in C:
184
1. Library Function:
It is also referred to as a “built-in function”. A compiler package already
exists that contains these functions, each of which has a specific meaning
and is included in the package.
Built-in functions have the advantage of being directly usable without being
defined, whereas user-defined functions must be declared and defined
before being used.
2. User-Defined Functions
• Functions that the programmer creates are known as User-Defined
functions. User-defined functions can be improved and modified
according to the needs of the programmer.
• Whenever we write a function that is case-specific and is not defined
in any header file, we need to declare and define our own functions
according to the syntax.
185
Program:
Output:
Explanation:
Function Declaration: The line void print(); is a function prototype that
declares the print function, indicating that it takes no parameters and does
not return any value.
Main Function: Inside the main() function:
• The print() function is called, which executes the code within the
print() function definition.
186
• The print() function prints "Welcome to Cranes Varsity" on the
screen.
• After calling the print() function, the program prints "let us learn C
Programming" on the screen.
OUTPUT:
187
We can pass arguments to the C function in two ways:
• Pass by Value
• Pass by Reference
1. Pass by Value:
• Parameter passing in this method copies values from actual
parameters into formal function parameters.
• As a result, any changes made inside the functions do not reflect in
the caller’s parameters.
Program:
Output:
188
Explanation:
Function Definition (modifyvalue):
• Takes an integer num, doubles it, prints the modified value, and
returns it.
Main Function:
• Prompts user for input and stores it in num.
• Prints the value of num before calling modifyvalue().
• Calls modifyvalue(num), which modifies a copy of num and prints the
doubled value, returning the modified value.
• Prints the original value of num after the function call (unchanged).
Pass by Reference
• Pass by reference is done by passing the address of the variable (using
pointers) to a function.
• This allows the function to directly modify the original value of the
argument, rather than working with a copy of it.
• The function gets the address (reference) of the variable, allowing it to
modify the original variable directly.
189
Program:
Output:
Scope of variable
A scope in any programming is a region of the program where a defined variable
can have its existence and beyond that variable, it cannot be accessed. There are
three places where variables can be declared in C programming language −
190
Global Variables
Global variables are defined outside a function, usually on top of the program.
Global variables hold their values throughout the lifetime of your program, and
they can be accessed inside any of the functions defined for the program. A global
variable can be accessed by any function. That is, a global variable is available for
use throughout your entire program after its declaration.
The following program shows how global and local variables are used in a
program.
191
Stores:
• Function calls
• Function arguments
• Local variables
• Return addresses
CPU Registers:
Small, high-speed memory locations within the CPU. Used to store temporary
data. Accessing data from registers is faster than accessing from RAM. Helps
improve execution speed.
• Storage: Stack
• Scope: Local to the block or function
• Lifetime: Created when the function is called, destroyed when the function
ends (along with the stack frame)
• Uninitialized Variables: Contain garbage values
• Access: Cannot be accessed outside the block
Syntax:
auto datatype var_name;
192
Output:
Syntax:
register datatype var_name;
Program
Output:
193
3. Static Storage Class Specifier
The static keyword modifies both the scope and lifetime of a variable. It retains
the value of the variable across multiple function calls.
• Limits Scope:
o If declared inside a function, the variable has local scope but retains
its value between calls.
o If declared outside a function, the variable’s access is restricted to the
file (i.e., file scope).
• Storage: Data Segment
• Lifetime: Entire program execution
• Scope: Depends on where the variable is declared
Explanation:
“Retain” means the variable does not lose its value when the function exits.
Useful when you need to preserve state between function calls.
194
Program
Output:
195
Program:
What is Recursion?
Recursion in C is a technique where a function calls itself to solve smaller
instances of the same problem. Recursion typically consists of two components:
• Base case: This is the condition where the recursion stops.
• Recursive case: This is the part where the function calls itself to break the
problem into smaller subproblems.
Recursion is typically used to solve problems that can be broken down into
smaller instances of the same problem, like factorial, Fibonacci numbers, tree
traversals, etc.
196
The recursive process involves:
• Recursive call: The function calls itself.
• Base case: A condition that stops further recursion and starts returning
values.
Output:
Code Explanation
AI can break down and explain C functions line by line in plain English,
making it easier to understand what a piece of code does.
Example:
You write this C function:
197
AI can explain:
"This function add takes two integers as input and returns their sum."
Debugging Help
AI can analyze C functions and:
• Spot logical or syntax errors
• Suggest corrections
• Explain why something is not working
198
Code Conversion
AI can convert functions between languages. Want to see how a C function
would look in Python or JavaScript? AI can translate that for you.
Concept Reinforcement
AI can quiz you or summarize topics like:
• Function prototypes
• Recursion
• Scope (local vs global)
• Call by value/reference
Summary
Functions are modular units of code designed to perform specific tasks. They help
organize programs logically, making code reusable, maintainable, and easier to
debug.
In C, functions are defined using a return type, a function name, and an optional
parameter list. Once defined, they can be called from the main() function or other
functions to perform specific operations.
This avoids code repetition and promotes a structured and efficient programming
approach.
Regarding scope, variables can either be local (declared inside functions and
accessible only there) or global (declared outside all functions and accessible
throughout the program).
Recursion in C
Recursion occurs when a function calls itself. It is commonly used for problems
that can be broken down into smaller, similar subproblems, such as calculating
factorials or performing tree traversals. A base condition is essential to stop the
recursive calls and prevent infinite loops.
199
Check Your Knowledge
• What are the different types of functions in C? Provide examples.
• Differentiate between call by value and call by reference. Which one does C
use by default?
• What is variable scope? Explain with examples (local, global, static).
• What is the lifetime of a static variable declared inside a function?
• What is the use of extern keyword in the context of function and variable
scope?
• Write a program in C to convert a decimal number to a binary number using
the function.
• Write a program in C to check whether a number is a prime number or not
using the function.
• Write a program with a global variable and a local variable with the same
name. Print their values inside and outside of a function.
• Write a program in C to find the sum of the series
1!/1+2!/2+3!/3+4!/4+5!/5 using the function.
Expected Output : The sum of the series is : 34
200
SESSION 10
STRINGS
SESSION OBJECTIVES
• By the end of this session, you should be able to:
• Understand the concept and structure of arrays and strings in C programming.
• Learn how to declare and initialize 1D and 2D arrays in C.
• Understand how strings are represented as character arrays in C.
• Perform basic operations on strings using built-in string functions from the C Standard
Library (<string.h>).
• Apply practical problem-solving techniques using arrays and strings in C.
• Write simple C programs involving arrays and string manipulation.
Introduction to Strings
What is a String in C?
In C programming, a string is a sequence of characters stored in a
character array and terminated by a special null character ('\0').
This null character marks the end of the string, since arrays in C do not
inherently store their own length.
Important:
A string is not just an array of characters — it’s a text data sequence ending
with '\0'. Without the null terminator, C cannot detect where the string
ends, which can lead to undefined behaviour or memory errors.
201
Think of a string like a series of boxes lined up in a row. Each box contains
one character, and the last box contains the null character ('\0'). The null
character acts like a flag to tell the program where the string ends, so it
knows where to stop reading the characters.
All of these lines are C declarations defining and initializing character arrays
(strings), but there are subtle differences in how they're written and what
they mean:
202
1. char c[] = "abcd";
• This declares an array c of length 5 (4 characters + 1 null terminator).
• The size is automatically determined by the compiler
• Equivalent to: char c[5] = {'a', 'b', 'c', 'd', '\0'};
Not using a string literal, but it still represents a valid C string because of
the '\0' terminator.
203
Assigning Values to Strings
Arrays and strings are second-class citizens in C; they do not support the
assignment operator once it is declared. For example,
This is because name is a char array, and we know that array names decay to
pointers in C. Thus, the name in scanf() already points to the address of the
first element in the string, which is why we don't need to use &.
Here, we have used fgets() function to read a string from the user.
fgets(name, sizeof(name), stdlin); // read string
The sizeof(name) results to 30. Hence, we can take a maximum of 30
characters as input which is the size of the name string. To print the string,
we have used puts(name);.
205
Note:
• The gets() function can also be to take input from the user. However,
it is removed from the C standard.
• It's because gets() allows you to input any length of characters.
Hence, there might be a buffer overflow.
Syntax:
strlen(const char *str);
Program:
Output:
Logic Breakdown:
1. What happens behind the scenes: strlen() works by iterating through
the string one character at a time and counting the characters until it
encounters the null terminator \0.
206
2. In this example, The string "Hello, World!" has 13 characters, so strlen()
returns 13.
Syntax: strcpy(dest,src)
1. dest: The destination string where the contents of the source string
will be copied.
2. src: The source string that is to be copied.
3. Return Value: It returns a pointer to the destination string (dest).
Program
Output:
Logic Breakdown:
• What happens behind the scenes: strcpy() copies each character from
the source string (src) to the destination string (dest), including the null
terminator \0.
• In this example, "Hello" is copied from source to destination, and the
output is Hello.
207
3. strcmp() - Compare Two Strings
Usage: The strcmp() function is used to compare two strings lexicographically
(in dictionary order).
Syntax:
int strcmp(const char *str1, const char *str2);
Program:
Logic Breakdown:
• What happens behind the scenes: strcmp() compares both strings
character by character until it finds a difference or reaches the null
terminator \0. It returns 0 if the strings are identical, or a non-zero
value based on the lexicographical order.
• In this example: Since "Hello" is compared with "Hello", strcmp()
returns 0, and the output is "Strings are equal.
208
4. STRCAT()- Concatenate Two Strings
Usage: The strcat() function concatenates (appends) one string to the end of
another.
Syntax:
Strcat(dest,src)
1. dest: The destination string to which the source string (src) will be
appended.
2. src: The source string that will be appended to dest.
3. Return Value: It returns a pointer to the destination string (dest).
Program:
Logic Breakdown:
1. What happens behind the scenes: strcat() appends the source string
(src) to the end of the destination string (dest). It also takes care of the
null terminator, ensuring the destination string remains properly
terminated after concatenation.
2. In this example: "Hello, " is concatenated with "World!", and the
output is "Hello, World!".
209
Syntax:
char *strchr(const char *str, int c);
1. str: The string to be searched.
2. c: The character to find.
3. Return Value: It returns a pointer to the first occurrence of the
character c in str, or NULL if the character is not found.
Program:
Logic Breakdown:
• What happens behind the scenes: strchr() searches the string for the
first occurrence of the specified character. If the character is found, it
returns a pointer to it; otherwise, it returns NULL.
• In this example, The first occurrence of the character 'o' is found at the
second position in the string "Hello, World!". The output will be "o,
World!"
210
Syntax:
char *strstr(const char *haystack, const char *needle);
• haystack: The string to be searched.
• needle: The substring to search for.
• Return Value: It returns a pointer to the first occurrence of the
substring needle in haystack, or NULL if the substring is not found
Program:
Output:
Logic Breakdown:
• What happens behind the scenes: strstr() searches for the first
occurrence of the substring needle in the string haystack. If the
substring is found, it returns a pointer to the substring's first character
in haystack; otherwise, it returns NULL.
• In this example, the substring "World" is found within "Hello, World!",
and the output will be "World!.
211
Summary
In C, a string is a character array terminated with a null character '\0'.
Declared as:
Strings can be read and printed using scanf(), gets(), printf(), or puts().
• Declaring and Initializing Strings
Declaration:
Initialization:
or directly:
212
Check Your Knowledge
• How are 1D and 2D arrays declared and accessed in C? Give practical use
cases for each.
• Explain memory allocation of arrays in C. What does it mean for array
elements to be stored in contiguous memory?
• What is the difference between a character array and a string in C?
• What will happen if you go out of bounds while accessing an array in C?
• How is a string represented in C? Why is the null character '\0' important?
• What are the differences between gets() and fgets() in C when reading
strings?
• How do built-in string functions like strlen(), strcpy(), strcat(), and strcmp()
work internally?
• Write a C program to reverse a string without using strrev().
• Count the number of vowels and consonants in a string using a C program.
• Write a function to manually concatenate two strings (without using
strcat()).
• Given a 2D array of integers, find the largest element and its position.
• Write a function in C to check whether a string is a palindrome.
213
SESSION 11
ADVANCED DATA TYPES (STRUCTURES) AND SORTING
SESSION OBJECTIVES
By the end of this session, students should be able to:
• Understand the purpose and use of structures in C/C++ (or other programming
languages, if applicable).
• Declare, initialize, and access data within a structure.
• Explain the basic concepts of sorting and their significance in programming.
• Describe how key sorting algorithms such as Bubble Sort, Selection Sort, and Insertion
Sort work.
• Write and implement sorting algorithms to sort data stored within structures.
214
• struct: Keyword used to define a structure.
• structure_name: Name given to the structure.
• member1, member2, ...: Members (variables) of the structure, each having a
specific data type.
Example:
Here, a derived type struct Person is defined. Now, you can create variables of this
type.
215
Another way of creating a struct variable is:
In both cases, person1 and person2 are struct Person variables p[] is a struct
Person array of size 20.
Example:
216
In this program, we have created a struct named Person. We have also created a
variable of Person named person1. In main(), we have assigned values to the
variables defined in Person for the person1 object.
Notice that we have used strcpy() function to assign the value to person1.name.
This is because the name is a char array (C-string) and we cannot use the
assignment operator = with it after we have declared the string.
Finally, we printed the data of person1.
Logic Breakdown:
1. Structure Definition: struct Student defines a structure with three members:
name (string), age (integer), and marks (float).
2. Structure Variable: student1 is declared as a variable of type struct Student.
217
3. Accessing Members: We access the members of the structure using the dot (.)
operator.
Nested Structures
A nested structure is a structure that contains another structure as a member. This
is useful when you need to model hierarchical or complex data.
Logic Breakdown:
1. Nested Structure: The Employee structure contains another structure Address
as a member.
2. Accessing Nested Members: The dot operator is used twice to access
members of the nested structure: emp.addr.street.
218
Array of Structures
An array of structures allows you to store multiple instances of a structure in an
array.
OUTPUT:
219
Logic Breakdown:
1. Array of Structures: An array of students of type struct Student is created with
3 elements.
2. Accessing Array Members: A loop is used to iterate through each student, and
the dot operator is used to access individual members of each structure.
Array of Structure
An array having a structure as its base type is known as an array of structure. To
create an array of structure, first structure is declared, and then an array of
structure is declared just like an ordinary array.
Explanation
In this example, the first structure employee is declared, then the array of
structures is created using a new type, i.e., struct employee. Using the above array
of structure, 10 sets of employee records can be stored and manipulated.
A similar array of structure can also be declared like:
220
Accessing Elements from an Array of Structure
To access any structure, index is used. For example, to read the emp_id of the first
structure, we use scanf(“%d”, emp[0].emp_id); as we know in C array indexing
starts from 0.
221
Pointers to struct
Here's how you can create pointers to structs.
222
In this example, the address of person1 is stored in the personPtr pointer using
personPtr = &person1;. Now, you can access the members of person1 using the
personPtr pointer.
By the way,
• personPtr->age is equivalent to (*personPtr).age
• personPtr->weight is equivalent to (*personPtr).weight
223
Sorting Concepts and Algorithms and Implementing Sorting Algorithms
Bubble Sort
Bubble Sort is a simple sorting algorithm that repeatedly steps through the
list to be sorted, compares adjacent elements, and swaps them if they are
in the wrong order. The process is repeated until the list is sorted. It is called
Bubble Sort because smaller elements "bubble" to the top of the list.
First pass:
Compare 4 and 2, swap to get [2, 4, 7, 1]
Compare 4 and 7, no swap
Compare 7 and 1, swap to get [2, 4, 1, 7]
Second pass:
Compare 2 and 4, no swap
Compare 4 and 1, swap to get [2, 1, 4, 7]
Third pass:
Compare 2 and 1, swap to get [1, 2, 4, 7]
Fourth pass:
List is already sorted, no swaps needed
Final sorted list: [1, 2, 4, 7].
224
Use Cases of Bubble Sorting
Used to teach the basics of sorting algorithms and algorithm analysis due to
its simplicity. Suitable for small datasets where its simplicity outweighs its
inefficiency. Performs well on data that is already partially sorted, as it can
quickly detect the order and terminate early
225
Selection Sort
226
Example: Consider the list [4, 2, 7, 1].
First pass:
Find the minimum element in [4, 2, 7, 1], which is 1
Swap 1 with 4 to get [1, 2, 7, 4]
Second pass:
Find the minimum element in [2, 7, 4], which is 2
Swap 2 with 2 to get [1, 2, 7, 4] (no change)
Third pass:
Find the minimum element in [7, 4], which is 4
Swap 4 with 7 to get [1, 2, 4, 7]
Fourth pass:
The last element 7 is already in place, no need to swap
Final sorted list: [1, 2, 4, 7].
227
Insertion Sort
Insertion Sort is a simple comparison-based sorting algorithm that builds
the final sorted list one element at a time. It works similarly to the way you
might sort playing cards in your hands.
The algorithm takes one element from the unsorted portion of the list and
inserts it into its correct position in the sorted portion. This process is
repeated until the entire list is sorted.
229
Summary
In this session, we introduced the concept of structures in programming—an
essential data type that allows grouping variables of different types under a single
name. We explored how to declare, initialize, and access members of a structure,
laying the groundwork for more complex data handling.
Following that, we discussed sorting concepts, explaining why sorting is important
in computer science and real-world applications. We covered basic sorting
algorithms like Bubble Sort, Selection Sort, and Insertion Sort, and explored how
they function through implementation examples. The session focused on
understanding the logic behind each algorithm and how to implement them
efficiently using structures.
• What is a structure in C and how does it differ from an array and a union?
• How is memory allocated for structures in C, and how does padding affect
structure size?
• Explain how you can pass a structure to a function in C. What are the
differences between passing by value and by reference?
• Can a structure contain a pointer to itself? Justify your answer with an
example.
230
• Describe how to initialize nested structures. What are the advantages of
nesting?
• What are the key differences between bubble sort, selection sort, and
insertion sort in terms of time complexity and use cases?
• Why is quicksort generally considered better than other O(n²) sorting
algorithms in practice?
• Explain stability in sorting algorithms. Which common sorting algorithms
are stable?
• How would you sort an array of structures based on one of the structure’s
fields? What challenges might arise?
• What are the benefits and limitations of using structures in sorting
algorithms, particularly when handling large datasets?
• Write a C program to define a structure Student with fields name, roll_no,
and marks. Take input for 5 students and display their details.
• Write a function in C to sort an array of integers using insertion sort. Also
write a main() to test it.
• Given a structure Employee with fields id, name, and salary, write a
program to sort the employees in descending order of salary using bubble
sort.
• Write a C function to swap two structure variables using pointers. Use it to
sort an array of structures.
• Implement quicksort in C to sort an array of integers. Include a function to
print the array before and after sorting.
231
SESSION 12
FILE HANDLING
SESSION OBJECTIVES
By the end of this session, learners will be able to:
• Understand the importance and purpose of file handling in programming.
• Describe different file operations such as creating, opening, reading, writing, and closing
files.
• Explain the concept of file pointers and how they are used to track the position in a file.
• Perform reading from and writing to text files using appropriate functions and modes.
• Work with binary files for storing and retrieving non-text data.
• Apply best practices in file handling to ensure safe, efficient, and error-free file
operations.
What is a File?
A file is a collection of data or information that has a name and is stored in a
storage location. Files can contain different types of data.
232
Types of Files
When dealing with files, there are two types of files you should know
about:
• Text files
• Binary files
Text files
Text files are the normal .txt files. You can easily create text files
using any simple text editors such as Notepad. When you open those
files, you'll see all the contents within the file as plain text. You can
easily edit or delete the contents. They take minimum effort to
maintain, are easily readable, and provide the least security and
takes bigger storage space.
Binary files
Binary files are mostly the .bin files in your computer. Instead of
storing data in plain text, they store it in the binary form (0's and 1's).
They can hold a higher amount of data, are not readable easily, and
provides better security than text files.
233
Below are some of the following explanations for file management’s
popularity:
• Reusability: helps to retain the data collected after the software is
run.
• Huge storage capacity: you don’t need to think about the issue of
mass storage using data.
• Save time: Unique applications need a lot of user feedback. You can
quickly open some aspect of the code using special commands.
• Portability: You can quickly move file material from one operating
device to another without thinking about data loss.
File Operations and Files Pointers, reading from and Writing to Files
234
File Operations and File Pointers in C
In C programming, file handling is done using functions from the stdio.h
header file. Files are used to store data permanently, and a file pointer is
used to keep track of the file being used.
235
FILE Pointer (File*)
While working with file handling, you need a file pointer to store the
reference of the FILE structure returned by the fopen() function. The file
pointer is required for all file-handling operations.
The fopen() function returns a pointer of the FILE type. FILE is a predefined
struct type in stdio.h and contains attributes such as the file descriptor,
size, and position, etc.
Opening a File
A file must be opened to perform any operation. The fopen() function is
used to create a new file or open an existing file. You need to specify the
mode in which you want to open. There are various file opening modes
explained below, any one of them can be used during creating/opening of a
file.
Opening a file is performed using the fopen() function defined in the stdio.h
header file. The fopen() function returns a FILE pointer which will be used
for other operations such as reading, writing, and closing the files.
236
Explanation:
fopen():
This is a standard library function defined in stdio.h. It is used to open a file
for reading, writing, or appending. It returns a pointer to a FILE object (of
type FILE *), which is then used to access the file.
"fileToOpen":
This is the name of the file you want to open. It should be a string literal
(enclosed in double quotes). It can be just a filename (e.g., "data.txt") or a
full path (e.g., "C:\\Users\\user\\data.txt"). If the file doesn't exist and
you’re opening in read mode ("r"), it will return NULL.
"mode":
This defines the mode in which the file is opened. It’s also a string (enclosed
in quotes). Some common file modes are:
Mode Meaning
"r" Open file for reading (file must exist)
"w" Open file for writing (creates or overwrites)
"a" Open file for appending
"r+" Open for reading and writing (file must exist)
"w+" Open for reading and writing (creates or overwrites)
"a+" Open for reading and appending
ptr:
This is a variable (typically of type FILE *) that holds the file pointer
returned by fopen().
Example:
FILE *ptr;
Return Value:
If the file is successfully opened, fopen() returns a valid file pointer. If the
file cannot be opened (e.g., doesn’t exist in read mode), it returns NULL.
Example Usage:
Use fopen() to open a file.
237
Reading and writing to a text file
For reading and writing to a text file, we use the functions fprintf() and
fscanf(). They are just the file versions of printf() and scanf(). The only
difference is that fprintf() and fscanf() expects a pointer to the structure
FILE.
238
provides input and output functions such as printf() and fopen(). Inside the
main() function, a file pointer named file is declared and used to open the
file in write mode ("w") using fopen(). If the file does not exist, it will be
created; if it already exists, its contents will be overwritten. The program
then checks whether the file was successfully created by verifying if the file
pointer is NULL. If it is NULL, an error message is displayed and the program
exits with a return value of 1, indicating failure. If the file is created
successfully, it prints "File created." to notify the user. The program then
terminates by returning 0, indicating successful execution. However, it’s a
good programming practice to close the file using fclose(file); before the
program ends, to properly release the file resource.
Example: Program to write the data to the file output.txt using fprintf()
Output
239
Example: Program to read the data from the file output.txt using fscanf()
240
Example: Program to append the data to the file output.txt using fprintf()
Closing a File
The file (both text and binary) should be closed after reading/writing.
241
Example: Writing and Reading a File
File I/O in C uses a special file pointer (FILE *), which acts as a connection
between the program and the file.
242
Common Functions for Binary File Handling
Function Purpose
Reads binary data from a file into
fread()
memory
Writes binary data from memory to a
fwrite()
file
Syntax:
fread()
fwrite()
size_t fwrite(const void *ptr, size_t size, size_t count, FILE
*stream);
243
• number of such type of data
• pointer to the file where you want to write.
244
Example: Reading from a Binary File
MODE DESCRIPTION
245
"rb", "wb", "ab" Same as above but in binary mode.
Best Practice: Always use the appropriate mode that matches your
intended operation to avoid unintended data loss or errors.
Best Practice: Even in error conditions or early returns, ensure that fclose()
is called.
246
Avoiding Incorrect Use of feof()
A common mistake is using feof() as a loop condition:
Correct Approach:
247
Summary
File handling in C allows programs to store and retrieve data from files, ensuring
data persists even after the program ends. It uses file pointers (FILE *) to manage
files, which need to be opened using fopen() and closed with fclose(). Files can be
opened in different modes like read ("r"), write ("w"), and append ("a"). C
provides functions such as fgetc(), fgets(), fputc(), fputs(), fprintf(), and fscanf() for
text file operations. For working with structured, non-text data, binary files are
used, accessed with fread() and fwrite(). Binary files are faster and more space-
efficient compared to text files as they store data in raw memory format.
Key Points:
Uses file pointers (FILE *) for file operations.
Open files using fopen() and close them with fclose().
248
Text files: fgetc(), fgets(), fputc(), fputs(), fprintf(), fscanf().
Binary files: fread(), fwrite() for faster, structured data storage.
Modes: "r" (read), "w" (write), "a" (append), and combinations like "r+", "w+".
Test Data:
249
Input the file name to be opened: test.txt
Expected Output:
The content of the file test.txt is:
This is the content of the file test.txt.
• Write a program in C to write multiple lines to a text file.
Test Data:
Input the number of lines to be written: 4
The lines are:
test line 1
test line 2
test line 3
test line 4
Expected Output:
test line 1
test line 2
test line 3
test line 4
250
251