C Programming History and Fundamentals
C Programming History and Fundamentals
1
UNIT I
OVERVIEW OF C LANGUAGE
HISTORY OF C
1. Pre-C Programming
2
3. C's Early Impact
4. Standardization of C
1983: ANSI C
o As C became widely adopted, it was important to standardize the language to
ensure consistency across different compilers and platforms. In 1983, the
American National Standards Institute (ANSI) began work on
standardizing C.
o The ANSI C standard was finalized in 1989, known as C89. This version
added clearer rules for function declarations, the inclusion of function
prototypes, and stricter syntax rules.
3
1990: ISO C
o Following ANSI C, the International Organization for Standardization
(ISO) also adopted the ANSI standard in 1990, making the C language more
universally accepted across the globe.
6. C Today
C17/C18 (2017):
o The C17 (sometimes referred to as C18) standard, introduced in 2017, was a
bug-fix release that made minor improvements but didn't introduce any major
new features. It was a stabilization of C11.
C's Ongoing Influence
o Despite the rise of other programming languages, C remains one of the most
important languages in modern computing. It continues to be used in:
Embedded systems (e.g., microcontrollers)
4
Operating systems (e.g., UNIX, Linux, and BSD)
Compilers and system software
Low-level hardware interfaces
o Languages like C++, C#, and Objective-C are all influenced by C, and the
basic structure and syntax of C continue to influence newer languages such as
Java, Python, and JavaScript.
7. C's Legacy
CHARACTER SET
In C programming, a character set refers to the collection of characters that can be used in
the source code. These characters are used for defining variables, writing instructions, and
creating programs. The C language defines a standard character set, which includes letters,
digits, punctuation, and special characters. These are classified into several categories.
The C programming language uses the ASCII (American Standard Code for Information
Interchange) character set as its basic character set. The standard ASCII character set contains
128 characters (values 0 to 127). However, modern systems often use extended ASCII or
other encoding schemes (like Unicode) to support additional characters.
5
2. Types of Characters in C
Digits: 0, 1, 2, 3, ..., 9
These are used for forming numeric constants and performing arithmetic operations.
3. Special Characters
Special characters have specific meanings and functions in C. Some examples include:
Whitespace characters: These include space (' '), horizontal tab (\t), newline (\n),
carriage return (\r), and form feed (\f). These characters are used for formatting and
separating code but are not directly used for computation.
Punctuation characters:
o Comma (,), period (.), semicolon (;), colon (:), question mark (?), exclamation
mark (!), etc.
Operators and symbols:
o Arithmetic operators: +, -, *, /, %
o Relational operators: ==, !=, <, >, <=, >=
o Logical operators: &&, ||, !
o Bitwise operators: &, |, ^, ~, <<, >>
o Assignment operator: =
o Others: =, ?, :, [], {}
4. Escape Sequences
Escape sequences are special combinations of characters that represent specific actions or
characters, particularly those that can't be directly typed in the code. Examples include:
6
\t : Horizontal tab
\\ : Backslash
\' : Single quote
\" : Double quote
\0 : Null character (marks the end of a string)
\r : Carriage return
5. Comments
Multi-line comments: Enclosed between /* and */, used for commenting multiple
lines.
/* This is a multi-line
comment that spans multiple lines */
In C, the char data type is used to store individual characters. A char variable can hold one
character at a time and takes up 1 byte of memory (typically).
Example:
The char type can also store ASCII values, which represent characters. For example,
'A' has the ASCII value of 65.
4. String Literals
7
Example:
In this example, str is an array of characters with the following values: {'H', 'e', 'l', 'l', 'o', ',', ' ',
'W', 'o', 'r', 'l', 'd', '!', '\0'}.
While the standard ASCII character set includes 128 characters (0-127), many modern
systems use extended ASCII or Unicode encoding to represent characters beyond the
standard ASCII range (values 128–255 for extended ASCII). Unicode can represent a much
wider variety of characters, including characters from non-Latin alphabets, special symbols,
and emojis.
Category Characters
Digits 0-9
Whitespace Space (' '), Tab (\t), Newline (\n), Carriage Return (\r)
Escape Sequences \n, \t, \\, \r, \", \', \0, etc.
C TOKENS
8
9
IDENTIFIERS, KEYWORDS,
DATATYPES,VARIABLES,CONSTANTS,SYMBOLIC CONSTANTS
10
11
12
13
14
15
16
17
Symbolic Constants in C are constants that are defined using a name (identifier) rather than
a direct value. These constants are useful because they make the code more readable and
maintainable. In C, symbolic constants are typically defined using the #define pre processor
directive.
18
Syntax:
Example:
#include <stdio.h>
int main() {
float area;
float radius = 5.0;
return 0;
}
19
20
21
22
23
24
In C programming, type conversions and library functions are essential tools for
manipulating data types and performing various operations. Below is an overview of both
concepts:
1. Type Conversions in C
Type conversion refers to converting one data type to another. There are two types of type
conversion in C:
Example:
int i = 10;
float f = i; // Implicit conversion from int to float
printf("%f", f); // Output: 10.000000
o In this case, the integer i is automatically converted into a float when assigned
to f.
Explicit conversion (also called type casting) is done manually by the programmer.
You need to specify the target type in parentheses.
Example:
float f = 10.5;
int i = (int)f; // Explicit conversion (casting) from float to int
printf("%d", i); // Output: 10
o In this case, the float value 10.5 is cast to an integer, resulting in 10.
25
2. Library Functions in C
C provides a wide range of library functions that you can use for various tasks such as
mathematical operations, input/output handling, string manipulation, memory management,
etc.
Example Functions:
#include <math.h>
double result;
result = sqrt(16); // Square root
result = pow(2, 3); // Power (2^3)
result = fabs(-4.5); // Absolute value
result = sin(3.14); // Sine function
result = cos(3.14); // Cosine function
b) Input/Output Functions (stdio.h)
The stdio.h library provides functions for input and output operations.
Example Functions:
#include <stdio.h>
int main() {
printf("Hello, World!"); // Output a message
int num;
scanf("%d", &num); // Take user input for an integer
printf("You entered: %d", num);
return 0;
}
26
c) String Handling Functions (string.h)
Example Functions:
#include <string.h>
char str1[] = "Hello";
char str2[20];
The stdlib.h library provides functions for memory allocation and deallocation.
Example Functions:
#include <stdlib.h>
int *ptr = (int*)malloc(sizeof(int)); // Dynamically allocate memory
*ptr = 5; // Assign value to allocated memory
free(ptr); // Free the allocated memory
e) Character Handling Functions (ctype.h)
The ctype.h library provides functions for checking and manipulating individual characters.
Example Functions:
#include <ctype.h>
char ch = 'A';
if (isupper(ch)) { // Check if character is uppercase
printf("Uppercase\n");
}
27
ch = tolower(ch); // Convert to lowercase
f) Time Handling Functions (time.h)
Example Functions:
#include <time.h>
time_t t = time(NULL); // Get current time
struct tm *tm_info = localtime(&t); // Convert to local time
Example Functions:
#include <errno.h>
#include <stdio.h>
FILE *file = fopen("[Link]", "r");
if (file == NULL) {
perror("Error opening file"); // Prints the error message
printf("Error number: %d\n", errno); // Prints the error code
28
From Type To Type Implicit Conversion Explicit Conversion
These functions and type conversions provide powerful tools to handle data and perform a
wide range of operations in C programs.
In C, managing input and output is done using functions provided by the stdio.h library.
These functions allow you to read data from the user (input) and display results (output).
Below is an explanation of the most commonly used input and output functions in C.
Output functions are used to display data to the user. The most commonly used output
function is printf(), which provides formatted output.
a) printf() Function
29
Syntax
Example
#include <stdio.h>
int main() {
int age = 25;
float salary = 35000.75;
char grade = 'A';
return 0;
}
Explanation:
b) puts() Function
Syntax:
puts("string");
Example:
#include <stdio.h>
30
int main() {
puts("Hello, World!"); // Automatically adds a newline after the string
return 0;
}
c) putchar() Function
Syntax:
putchar(character);
Example
#include <stdio.h>
int main() {
putchar('A'); // Prints 'A'
return 0;
}
Input functions are used to read data from the user. The most common input functions are
scanf(), getchar(), and gets(). However, gets() is unsafe, and it's better to avoid it in modern C
programming.
a) scanf() Function
Syntax:
31
Example:
#include <stdio.h>
int main() {
int age;
float salary;
return 0;
}
Explanation:
b) getchar() Function
Syntax:
getchar();
32
Example:
#include <stdio.h>
int main() {
char ch;
printf("Enter a character: ");
ch = getchar(); // Reads a single character
printf("You entered: %c\n", ch);
return 0;
}
c) gets() Function (Deprecated, Not Recommended)
Syntax
gets(string);
Warning: The gets() function is unsafe because it can cause buffer overflow. It is
recommended to use fgets() instead.
Example:
#include <stdio.h>
int main() {
char name[50];
return 0;
}
33
d) fgets() Function
Purpose: Reads a line of text from a file or standard input (safer alternative to gets()).
Syntax:
Example:
#include <stdio.h>
int main() {
char name[50];
return 0;
}
Explanation:
o fgets() reads a string from the standard input (stdin), but you must specify the
buffer size to avoid buffer overflow.
o It includes the newline character \n in the string, so you may need to handle it
when processing the input.
34
o %X: Unsigned hexadecimal integer (uppercase).
Floating-Point Format Specifiers:
o %f: Decimal floating-point number.
o %.2f: Floating-point number with 2 decimal places.
o %e: Scientific notation (e.g., 1.234000e+02).
o %g: Shorter of %f or %e format.
In some cases, you might want to flush the output buffer to ensure all data is printed
immediately, especially in interactive applications.
a) fflush(stdout)
Syntax:
fflush(stdout);
Example:
#include <stdio.h>
35
int main() {
printf("Please wait...");
fflush(stdout); // Forces the output to be displayed immediately
// Simulate a delay
for (int i = 0; i < 1000000000; i++) {} // Some computation
printf(" Done\n");
return 0;
}
Summary
Output Functions:
o printf(): Formatted output to standard output (console).
o puts(): Output a string followed by a newline.
o putchar(): Output a single character.
Input Functions:
o scanf(): Formatted input from standard input (keyboard).
o getchar(): Input a single character.
o fgets(): Safe function to input a string.
o gets(): Unsafe and deprecated function (avoid using it).
Managing input and output in C is fundamental for interacting with users and processing
data. Understanding these functions allows you to build more effective and interactive
programs.
In C programming, Formatted and Unformatted I/O Functions are used to handle input
and output operations. Let’s explore both types with explanations and examples.
These functions allow input and output operations in a specific format. They enable you to
control how data is read or displayed, including specifying data types and layout.
36
Function Description
#include <stdio.h>
int main() {
int age;
char name[50];
return 0;
}
Output:
37
Enter your name: John
Enter your age: 25
Hello John, you are 25 years old.
These functions perform input and output operations without any specific format. They
handle data as raw bytes and are faster than formatted I/O functions because they don’t
perform format checks.
Function Description
#include <stdio.h>
int main() {
char ch;
char str[50];
38
printf("You entered: ");
putchar(ch);
printf("\n");
return 0;
}
Output:
Enter a character: A
You entered: A
Enter a string: Hello, World!
You entered:
Hello, World!
Control Provides control over data type and format No control over data type or format
Speed Slower due to format checking Faster due to raw data handling
Use Case Used for user-friendly I/O Used for faster, raw I/O
UNIT II
39
Decision Making in C
if Statement
if-else Statement
Nested if Statement
if-else-if Ladder
switch Statement
Conditional Operator
Jump Statements:
break
continue
goto
return
Let’s discuss each of them one by one.
1. if in C
The if statement is the most simple 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.
Syntax of if Statement
if(condition)
{
// Statements to execute if
// condition is true
}
Here, the condition after evaluation will be either true or false. C if statement accepts
boolean values – if the value is true then it will execute the block of statements below it
otherwise not. If we do not provide the curly braces ‘{‘ and ‘}’ after if(condition) then by
40
default if statement will consider the first immediately below statement to be inside its
block.
Flowchart of if Statement
1. if Statement
✅ Syntax:
if (condition) {
// Code to execute if condition is true
}
🔧 Example:
#include <stdio.h>
int main() {
int num = 10;
if (num > 0) {
printf("The number is positive.\n");
}
return 0;
}
41
2. if-else in C
The if statement alone tells us that if a condition is true it will execute a block of statements
and if the condition is false it won’t. But what if we want to do something else when the
condition is false? Here comes the C else statement. We can use the else statement with
the if statement to execute a block of code when the condition is false. The if-else
statement consists of two blocks, one for false expression and one for true expression.
Syntax of if else in C
✅ Syntax:
if (condition) {
// Code to execute if condition is true
} else {
// Code to execute if condition is false
}
🔧 Example:
#include <stdio.h>
int main() {
42
int num = -5;
if (num > 0) {
printf("The number is positive.\n");
} else {
printf("The number is not positive.\n");
}
return 0;
}
Output
i is greater than 15
The block of code following the else statement is executed as the condition present in
the if statement is false.
3. Nested if-else in C
A nested if in C is an if statement that is the target of another if statement. Nested if
statements mean an if statement inside another if statement. Yes, C allow us to nested if
statements within if statements, i.e, we can place an if statement inside another if statement.
✅ Syntax:
if (condition1) {
if (condition2) {
// Code to execute if both conditions are true
}
}
🔧 Example:
#include <stdio.h>
int main() {
int num = 15;
if (num > 0) {
43
if (num % 2 == 0) {
printf("The number is even.\n");
} else {
printf("The number is odd.\n");
}
}
return 0;
}
FLOW CHART:
✅ Syntax:
if (condition1) {
if (condition2) {
// Code to execute if both conditions are true
}
}
🔧 Example:
#include <stdio.h>
int main() {
int num = 15;
44
if (num > 0) {
if (num % 2 == 0) {
printf("The number is even.\n");
} else {
printf("The number is odd.\n");
}
}
return 0;
}
4. if-else-if Ladder in C
The if else if statements are used when the user has to decide among multiple options. The
C if statements are executed from the top down. As soon as one of the conditions
controlling the if is true, the statement associated with that if is executed, and the rest of the
C else-if ladder is bypassed. If none of the conditions is true, then the final else statement
will be executed. if-else-if ladder is similar to the switch statement.
45
Flow Diagram of if-else-if
✅ Syntax:
if (condition1) {
// Code to execute if condition1 is true
} else if (condition2) {
// Code to execute if condition2 is true
} else {
// Code to execute if none of the conditions are true
}
🔧 Example:
#include <stdio.h>
int main() {
int num = 0;
if (num > 0) {
printf("The number is positive.\n");
} else if (num < 0) {
printf("The number is negative.\n");
} else {
printf("The number is zero.\n");
}
return 0;}
46
5. switch Statement in C
The switch case statement is an alternative to the if else if ladder that can be used to execute
the conditional code based on the value of the variable specified in the switch statement.
The switch block consists of cases to be executed based on the value of the switch variable.
Syntax of switch
switch (expression) {
case value1:
statements;
case value2:
statements;
....
....
....
default:
statements;
}
Flowchart of switch
47
🔧 Example:
#include <stdio.h>
int main() {
int day = 3;
switch (day) {
case 1:
printf("Monday\n");
break;
case 2:
printf("Tuesday\n");
break;
case 3:
printf("Wednesday\n");
break;
default:
printf("Invalid day\n");
}
return 0;
}
6. Conditional Operator in C
The conditional operator is used to add conditional code in our program. It is similar to the
if-else statement. It is also known as the ternary operator as it works on three operands.
48
Flowchart of Conditional Operator
🔧 Example:
#include <stdio.h>
int main() {
int num = 5;
// Using conditional operator
num > 0 ? printf("Positive number\n") : printf("Non-positive number\n");
return 0;
}
7. Jump Statements in C
These statements are used in C for the unconditional flow of control throughout the
functions in a program. They support four types of jump statements:
In C programming, the keywords break, continue, goto, and return are control flow
statements used to manage the flow of a program. Here's a detailed explanation of each:
1. break
49
Example:
2. continue
The continue statement is used to skip the current iteration of a loop and proceed to
the next iteration.
When encountered, it skips the remaining code in the current loop body and moves to
the next iteration, if any.
Example:
3. goto
The goto statement provides a way to transfer control unconditionally to another part
of the program.
It is typically used with labels to create loops or jump over certain sections of code.
Note: The use of goto is generally discouraged, as it can make code harder to
understand and maintain.
50
Example:
int i = 0;
start: // Label
if (i < 5) {
printf("%d\n", i);
i++;
goto start; // Jumps to 'start' label, continuing the loop
}
// Output: 0 1 2 3 4
4. return
The return statement is used to exit a function and optionally return a value to the
caller.
If the function has a return type (e.g., int, float), return can return a value of that type;
otherwise, it simply terminates the function.
In main(), return 0; is commonly used to indicate successful execution.
Example:
int main()
{
int result = add(3, 4); // Calls add() function
printf("%d\n", result); // Output: 7
return 0; // Exits the main function and returns control to the OS
}
51
LOOPING
In C, loops are used to repeat a block of code multiple times. The main types of loops in C
are:
1. for Loop
The for loop is used when you know in advance how many times you want to repeat a
block of code.
It has three parts: initialization, condition, and increment/decrement.
Syntax:
for (initialization; condition; increment/decrement) {
// Code to be executed
}
Example:
printf("%d\n", i);
}
// Output: 0 1 2 3 4
Explanation:
Initialization: Sets the initial value of the loop variable (e.g., int i = 0).
Condition: Specifies the condition that must be true for the loop to continue (e.g., i <
5).
Increment/Decrement: Increases or decreases the loop variable (e.g., i++).
52
for loop Equivalent Flow Diagram:
2. while Loop
The while loop is used when the number of iterations is not known in advance, and
the loop should run as long as a specified condition is true.
The condition is checked before each iteration.
Syntax:
while (condition) {
// Code to be executed
Example:
int i = 0;
while (i < 5) {
printf("%d\n", i);
i++;
}
53
// Output: 0 1 2 3 4
Explanation:
The loop continues as long as the condition (i < 5) is true. After each iteration, the
value of i is incremented.
3. do-while Loop
The do-while loop is similar to the while loop, except that the condition is checked
after each iteration. This guarantees that the loop runs at least once.
Syntax:
do {
// Code to be executed
} while (condition);
Example:
int i = 0;
do {
printf("%d\n", i);
i++;
54
} while (i < 5);
// Output: 0 1 2 3 4
Explanation:
The code block inside the do part is executed once, then the condition (i < 5) is
checked. If the condition is true, the loop continues.
Key Differences:
for loop: Best when the number of iterations is known in advance. Initialization,
condition, and increment/decrement are all in one line.
while loop: Ideal when the number of iterations is not known and depends on some
dynamic condition.
do-while loop: Ensures the loop executes at least once, since the condition is checked
after the loop body.
55
FUNCTIONS
FUNCTION DEFINITION:
In C, a function is a block of code that performs a specific task. Functions are used to break
down complex programs into smaller, manageable parts. Defining and using functions in C
follows a specific syntax. Here’s a detailed explanation:
1. Function Definition
Return type: The type of data the function will return (e.g., int, float, void).
Function name: The name by which the function is called.
Parameters (optional): Input values passed to the function.
Function body: A block of statements that define what the function does.
Syntax:
return_type function_name(parameter_list) {
// Function body
// Code to be executed
}
Before you define a function, you can declare it to let the compiler know its name, return
type, and parameters. The declaration can be placed at the beginning of the program or before
the function is called.
Syntax:
return_type function_name(parameter_list);
Example:
56
3. Function Definition Example
Example:
#include <stdio.h>
// Function declaration
int add(int, int); // Declares that a function named 'add' returns an int and takes two int
parameters
// Function definition
int add(int a, int b) {
return a + b; // Returns the sum of a and b
}
int main() {
int result = add(3, 4); // Calls the add function
printf("Sum: %d\n", result); // Output: Sum: 7
return 0;
}
1. Function Declaration:
o The prototype int add(int, int); informs the compiler that a function named add
exists, returns an int, and takes two int parameters. This declaration can be
used before the main function if the function definition is written later in the
program.
2. Function Definition:
o The function int add(int a, int b) is defined to take two integer parameters and
return their sum.
3. Function Call:
o Inside main(), the add(3, 4) function call invokes the function and passes 3 and
4 as arguments. The result is stored in the variable result, which is then
printed.
57
4. Function with void Return Type
If a function does not return a value, you use void as the return type.
EXAMPLE
#include <stdio.h>
// Function declaration
void printMessage();
// Function definition
void printMessage() {
printf("Hello, World!\n");
}
int main()
{
printMessage(); // Calls the function to print the message
return 0;
}
In this example, the printMessage() function has a void return type because it does not
return any value. It simply prints a message to the screen.
void modifyValue(int a) {
a = 10; // This modification only affects the local copy of a
58
}
int main() {
int num = 5;
modifyValue(num);
printf("num = %d\n", num); // Output: num = 5
return 0;
}
Recursive function
Recursion is the process of a function calling itself repeatedly till the given condition is
satisfied. A function that calls itself directly or indirectly is called a recursive function and
such kind of function calls are called recursive calls.
59
return 1;
}
return n * factorial(n - 1);
}
int main() {
int result = factorial(5);
printf("Factorial of 5: %d\n", result); // Output: Factorial of 5: 120
return 0;
}
60
UNIT III
ARRAYS
DEFINITION
Declaring an Array in C
data_type array_name[array_size];
Here, the array numbers can hold 5 integer values, and the index range will be from 0 to 4.
Initializing Arrays
1. Static Initialization:
2. Partial Initialization: If you initialize fewer elements, the remaining ones are set to
zero.
3. Implicit Size: You can omit the size, and the compiler will determine it based on the
number of elements.
61
int numbers[] = {1, 2, 3, 4, 5}; // Array size will be automatically set to 5
In C, an array is a collection of elements of the same type stored in contiguous memory
locations. This organization allows efficient access to elements using their index. Arrays
can also be of different types depending upon the direction/dimension they can store the
elements. It can be 1D, 2D, 3D, and more. We generally use only one-dimensional, two-
dimensional, and three-dimensional arrays.
In this article, we will learn all about one-dimensional (1D) arrays in C, and see how to use
them in our C program.
Only a single row exists in the one-dimensional array and every element within the array is
accessible by the index. In C, array indexing starts zero-indexing i.e. the first element is at
index 0, the second at index 1, and so on up to n-1 for an array of size n.
In declaration, we specify then name and the size of the 1d array.
elements_type array_name[array_size];
62
1D Array Element Accessing/Updating Syntax
After the declaration, we can use the index of the element along with the array name to
access it.
array_name [index]; // accessing the element
Then, we can also assign the new value to the element using assignment operator.
Example:
#include <stdio.h>
int main()
int arr[5] = { 1, 2, 4, 8, 16 };
// printing it
63
printf("\n");
// updating elements
arr[3] = 9721;
// printing again
return 0;
Output
1 2 4 8 16
1 2 4 9721 16
A multi-dimensional array can be defined as an array that has more than one dimension.
Having more than one dimension means that it can grow in multiple directions. Some
popular multidimensional arrays are 2D arrays and 3D arrays. In this article, we will learn
about multidimensional arrays in C programming language.
Syntax
64
Types of Multidimensional Arrays
In C, there can be many types of arrays depending on their dimensions but two of them are
most commonly used:
1. Two-Dimensional Array (2D Array)
2. Three-Dimensional Array (3D Array)
65
In list initialization, we can skip specifying the size of the row. The compiler will
automatically deduce it in this case. So, the below declaration is valid.
type arr_name[][n] = {…values…};
#include <stdio.h>
int main() {
// and 2 columns
int arr[3][2] = { { 0, 1 }, { 2, 3 }, { 4, 5 } };
printf("\n");
return 0;
}
Output
arr[0][0]: 0 arr[0][1]: 1
arr[1][0]: 2 arr[1][1]: 3
arr[2][0]: 4 arr[2][1]: 5
66
Three-Dimensional (3D) Array in C
A Three-Dimensional Array or 3D array in C is a collection of two-dimensional arrays. It
can be visualized as multiple 2D arrays stacked on top of each other.
Declaration of 3D Array in C
We can declare a 3D array with x 2D arrays each having m rows and n columns using
Initialization of 3D Array in C
Initialization in a 3D array is the same as that of 2D arrays. The difference is as the number
of dimensions increases so the number of nested braces will also increase.
int arr[2][3][2] = {0, 1, 2, 3, 4, 5, 6, 7 , 8, 9, 10, 11}
or
int arr[2][3][2] = { { { 1, 1 }, { 2, 3 }, { 4, 5 } },
{ { 6, 7 }, { 8, 9 }, { 10, 11 } } };
Example
#include <stdio.h>
int main() {
int arr[2][3][2] = { { { 1, 1 }, { 2, 3 }, { 4, 5 } },
{ { 6, 7 }, { 8, 9 }, { 10, 11 } } };
67
for (int i = 0; i < 2; ++i) {
printf("arr[%i][%i][%i] = %d ", i, j, k,
arr[i][j][k]);
printf("\n");
printf("\n\n");
return 0;
Output
arr[0][0][0] = 1 arr[0][0][1] = 1
arr[0][1][0] = 2 arr[0][1][1] = 3
arr[0][2][0] = 4 arr[0][2][1] = 5
arr[1][0][0] = 6 arr[1][0][1] = 7
arr[1][1][0] = 8 arr[1][1][1] = 9
arr[1][2][0] = 10 arr[1][2][1] = 11
68
Passing Arrays to Functions in C
In C, when you pass an array to a function, you are actually passing a pointer to the first
element of the array. This allows the function to modify the original array.
#include <stdio.h>
int main() {
int myArray[] = {10, 20, 30, 40, 50};
int size = sizeof(myArray) / sizeof(myArray[0]);
return 0;
}
69
💻 Output
Array elements: 10 20 30 40 50
Definition of a String
In C, strings are essentially arrays of characters, and the '\0' character is automatically added
at the end to mark the string's termination.
✅ String Syntax in C
#include <stdio.h>
int main() {
70
char str[] = "Hello, World!";
printf("%s\n", str); // %s is the format specifier for strings
return 0;
}
💻 Output:
Hello, World!
Use the scanf() and printf() functions for string input and output.
#include <stdio.h>
int main() {
char name[50]; // Allocate memory for the string
return 0;
}
💻 Output:
Enter your name: John
Hello, John!
📚 Operations on Strings in C
71
🔧 Common String Operations:
Operation Function Description
The strlen() function calculates the number of characters in a string, excluding the null
terminator ('\0').
Example:
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "Hello, World!";
int length = strlen(str);
72
✅ 2. Copying a String (strcpy)
Example:
#include <stdio.h>
#include <string.h>
int main() {
char source[] = "Hello, World!";
char destination[50];
strcpy(destination, source);
The strcat() function joins two strings by appending the second string to the first.
Example:
#include <stdio.h>
#include <string.h>
int main() {
char str1[50] = "Hello, ";
char str2[] = "World!";
strcat(str1, str2);
73
printf("Concatenated string: %s\n", str1);
return 0;
}
💻 Output:
Example:
#include <stdio.h>
#include <string.h>
int main() {
char str1[] = "Hello";
char str2[] = "World";
if (result == 0) {
printf("Strings are equal.\n");
} else if (result < 0) {
printf("String 1 is less than String 2.\n");
} else {
printf("String 1 is greater than String 2.\n");
}
74
return 0;
}
💻 Output:
String 1 is less than String 2.
The strchr() function returns a pointer to the first occurrence of a character in a string.
Example:
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "Hello, World!";
char *ptr = strchr(str, 'W');
if (ptr != NULL) {
printf("Character found: %c\n", *ptr);
} else {
printf("Character not found.\n");
}
return 0;
}
💻 Output:
Character found: W
The strstr() function returns a pointer to the first occurrence of a substring in a string.
Example:
#include <stdio.h>
75
#include <string.h>
int main() {
char str[] = "Hello, World!";
char *ptr = strstr(str, "World");
if (ptr != NULL) {
printf("Substring found: %s\n", ptr);
} else {
printf("Substring not found.\n");
}
return 0;
}
💻 Output:
Substring found: World!
✅ 7. Reversing a String (Custom Function)
There is no built-in function to reverse a string in C, but you can create a custom function.
Example:
#include <stdio.h>
#include <string.h>
// Function to reverse a string
void reverseString(char str[]) {
int length = strlen(str);
for (int i = 0; i < length / 2; i++) {
char temp = str[i];
str[i] = str[length - i - 1];
str[length - i - 1] = temp;
}
}
int main() {
char str[] = "Hello, World!";
reverseString(str);
76
printf("Reversed string: %s\n", str);
return 0;
}
💻 Output:
Reversed string: !dlroW ,olleH
These functions are not part of the standard C library but are available in some compilers.
Example:
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "hello, world!";
toUpperCase(str);
77
📚 Arrays of Strings in C
For example, an array of strings can store a list of names, words, or sentences.
char names[3][20] = {
"Alice",
"Bob",
"Charlie"
};
char *names[] = {
"Alice",
"Bob",
"Charlie"
};
Example:
#include <stdio.h>
int main() {
78
// Array of 3 strings, each with a maximum length of 19 characters
char names[3][20] = {
"Alice",
"Bob",
"Charlie"
};
printf("Names are:\n");
for (int i = 0; i < 3; i++) {
printf("%s\n", names[i]);
}
return 0;
}
💻 Output:
Names are:
Alice
Bob
Charlie
Both methods allow you to manipulate or process the string inside the function. Since strings
are arrays in C, they are always passed by reference, meaning any changes made to the string
inside the function will affect the original string.
You can pass a string to a function by declaring the parameter as a character array.
Example:
#include <stdio.h>
79
// Function to print a string
void printString(char str[]) {
printf("The string is: %s\n", str);
}
int main() {
char myString[] = "Hello, World!";
printString(myString); // Passing the string to the function
return 0;
}
💻 Output:
The string is: Hello, World!
✅ Method 2: Passing a String as a Pointer
You can also pass a string to a function using a pointer to a character array.
Example:
#include <stdio.h>
// Function to print a string using a pointer
void printString(char *str) {
printf("The string is: %s\n", str);
}
int main() {
char myString[] = "Hello, World!";
printString(myString); // Passing the string to the function
return 0;
}
💻 Output:
The string is: Hello, World!
📚 Storage Classes in C
A storage class in C defines the scope, visibility, lifetime, and default initial value of a
variable. There are four types of storage classes in C:
80
1. Automatic (auto)
2. External (extern)
3. Static (static)
4. Register (register)
✅ Example:
#include <stdio.h>
void display() {
auto int x = 10; // `auto` keyword is optional
printf("x = %d\n", x);
}
int main() {
display();
return 0;
}
2. extern (External Storage Class)
✅ Example:
#include <stdio.h>
81
int count = 10; // Global variable
void display() {
printf("Count = %d\n", count);
}
3. static (Static Storage Class)
✅ Example:
#include <stdio.h>
void countCalls() {
static int count = 0; // Static variable
count++;
printf("Function called %d times\n", count);
}
int main() {
countCalls();
countCalls();
countCalls();
return 0;
}
Output:
82
4. register (Register Storage Class)
Suggests that the variable be stored in the CPU register for faster access.
Used for frequently accessed variables.
Scope: Local to the block in which it is defined.
Lifetime: Exists only during the function execution.
Default Value: Garbage (uninitialized).
Cannot be used with the & operator (because it may not have a memory address).
✅ Example:
#include <stdio.h>
int main() {
register int i;
for (i = 0; i < 5; i++) {
printf("%d ", i);
}
return 0;
}
Output:
01234
Storage Classes in C
Storage Class Scope Lifetime Default Value Keyword
83
Stuctures
📚 Definition of Structures in C
A structure in C is a user-defined data type that allows you to group different types of
variables under a single name. It is used to represent a record or complex data that requires
multiple attributes, like storing information about a student, employee, or product.
Syntax of Structure
struct structure_name {
data_type member1;
data_type member2;
...
};
#include <stdio.h>
// Defining a structure
struct Student {
int id;
char name[50];
float marks;
};
int main() {
// Declaring a structure variable
struct Student s1;
// Assigning values to the structure members
[Link] = 101;
strcpy([Link], "Alice");
[Link] = 95.5;
// Printing structure members
printf("ID: %d\n", [Link]);
84
printf("Name: %s\n", [Link]);
printf("Marks: %.2f\n", [Link]);
return 0;
}
📚 Nested Structures in C
A nested structure is a structure within another structure. It allows you to group related data
together, even if the data has a more complex relationship. This is useful when representing
struct Outer {
data_type member1;
struct Inner {
data_type member2;
data_type member3;
} inner_var;
};
#include <stdio.h>
85
// Declaring and initializing a structure variable
struct Student s1 = {101, "Alice", {"New York", 10001}};
// Accessing members of the nested structure
printf("ID: %d\n", [Link]);
printf("Name: %s\n", [Link]);
printf("City: %s\n", [Link]);
printf("ZIP: %d\n", [Link]);
return 0;
}
💻 Output:
ID: 101
Name: Alice
City: New York
ZIP: 10001
📚 Array of Structures in C
An array of structures allows you to store multiple structures of the same type in a
contiguous block of memory. This is useful when you want to manage a collection of similar
data, such as a list of students, employees, or products.
struct StructureName {
data_type member1;
data_type member2;
...
};
86
#include <stdio.h>
students[2].id = 103;
strcpy(students[2].name, "Charlie");
students[2].marks = 78.9;
// Printing the details of each student
for (int i = 0; i < 3; i++) {
printf("Student %d: ID = %d, Name = %s, Marks = %.2f\n",
i + 1, students[i].id, students[i].name, students[i].marks);
}
return 0;
}
💻 Output:
Student 1: ID = 101, Name = Alice, Marks = 85.50
Student 2: ID = 102, Name = Bob, Marks = 92.30
Student 3: ID = 103, Name = Charlie, Marks = 78.90
87
📚 Passing Structures to Functions in C
When you pass a structure by value, the function works with a copy of the structure, so any
changes made inside the function won't affect the original structure.
Example:
#include <stdio.h>
// Define a structure
struct Student {
int id;
char name[50];
};
88
Student Name: Alice
In this example, the structure s1 is passed to the display function, but it is not modified
within the function.
📚 Unions in C
A union is a user-defined data type in C that allows you to store different types of data in
the same memory location. Unlike structures, where each member has its own memory
space, all members of a union share the same memory. This means that a union can only
hold one value at a time, and the memory size is determined by the largest member.
🔧 Syntax of a Union
union UnionName {
data_type member1;
data_type member2;
...
};
member1, member2, ...: Members of the union, which can have different data types.
✅ Example of Union
#include <stdio.h>
// Defining a union
union Data {
int i;
float f;
char c;
};
int main() {
// Declaring a variable of union type
union Data data;
89
// Assigning value to an integer member
data.i = 10;
printf("Data (int): %d\n", data.i);
// Assigning value to a float member (overwrites the previous value)
data.f = 3.14;
printf("Data (float): %.2f\n", data.f);
// Assigning value to a char member (overwrites the previous value)
data.c = 'A';
printf("Data (char): %c\n", data.c);
return 0;}
💻 Output:
Data (int): 10
Data (float): 3.14
Data (char): A
typedef in C
The typedef keyword in C is used to create type aliases. It allows you to define a new name
for an existing data type, making code more readable and easier to maintain. This is
particularly useful for complex data types like structures, pointers, or function pointers.
🔧 Syntax of typedef
new_type_name: The alias name you want to use for the existing type.
Example:
#include <stdio.h>
int main() {
90
Integer num1 = 10; // Using 'Integer' as alias for 'int'
Float num2 = 3.14; // Using 'Float' as alias for 'float'
return 0;
}
💻 Output
Integer: 10
Float: 3.14
📚 enum in C
An enum (short for "enumeration") is a user-defined data type in C that allows you to
assign names to integral constants, making your code more readable and easier to maintain. It
defines a set of named integer constants.
🔧 Syntax of enum
enum EnumName {
Name1 = value1,
Name2 = value2,
...
};
value1, value2, ...: The values assigned to each enumerator (optional). By default, the first
enumerator gets 0, the next gets 1, and so on.
91
#include <stdio.h>
// Defining an enum
enum Weekday {
Sunday, // 0
Monday, // 1
Tuesday, // 2
Wednesday, // 3
Thursday, // 4
Friday, // 5
Saturday // 6
};
int main() {
enum Weekday today = Wednesday; // Assigning an enum value
Here, Wednesday is automatically assigned the value 3, because enums are assigned values
starting from 0 by default.
Bit Fields in C
A bit field is a feature in C that allows you to specify the exact number of bits used to store a
variable within a structure. This can be useful for saving memory, especially when dealing
with flags or small numbers, where you don't need the full range of an int or char.
struct {
type member_name : bit_count;
};
92
type: The data type of the field (usually int or unsigned).
#include <stdio.h>
struct Employee {
unsigned int id : 4; // 4 bits for ID (0-15)
unsigned int age : 7; // 7 bits for age (0-127)
unsigned int salary : 10; // 10 bits for salary (0-1023)
};
int main() {
struct Employee emp1;
// Assigning values to bit fields
[Link] = 5;
[Link] = 30;
[Link] = 500;
// Printing the values of the bit fields
printf("ID: %u\n", [Link]); // Output: 5
printf("Age: %u\n", [Link]); // Output: 30
printf("Salary: %u\n", [Link]); // Output: 500
return 0;
}
💻 Output:
ID: 5
Age: 30
Salary: 500
In this example:
93
id is allocated 4 bits (max value 15),
age is allocated 7 bits (max value 127),
salary is allocated 10 bits (max value 1023).
94
UNIT IV
📚 Pointers in C
A pointer is a variable that stores the memory address of another variable. Pointers are a
powerful feature in C that allow for dynamic memory management, direct memory access,
and more flexible data structures like linked lists.
🔧 Syntax of Pointers
type *pointer_name;
type: The type of data the pointer is pointing to (e.g., int, float, etc.).
#include <stdio.h>
int main() {
int num = 10; // Declare an integer variable
int *ptr = # // Declare a pointer that stores the address of 'num'
95
printf("Value of num: %d\n", num); // Output the value of num
printf("Address of num: %p\n", &num); // Output the memory address of num
printf("Pointer value (address stored in ptr): %p\n", ptr); // Address stored in ptr
printf("Dereferenced pointer value: %d\n", *ptr); // Dereferencing the pointer to get the
value of num
return 0;
}
💻 Output:
Value of num: 10
Address of num: 0x7ffee6f93d8c
Pointer value (address stored in ptr): 0x7ffee6f93d8c
Dereferenced pointer value: 10
In this example:
A pointer can also point to another pointer. This is called a pointer to a pointer, or double
pointer.
#include <stdio.h>
int main() {
int num = 5;
int *ptr = # // Pointer to num
int **ptr2 = &ptr; // Pointer to pointer (double pointer)
96
return 0;
}
💻 Output:
Value of num: 5
Value using *ptr: 5
Value using **ptr2: 5
Here, ptr2 points to ptr, and ptr points to num. Using **ptr2 dereferences twice to access the
value of num.
✅ Pointer Arithmetic
Pointers support arithmetic operations like addition, subtraction, and comparison. This is
often used to navigate through arrays.
In this example, ptr + 1 moves the pointer to the next memory location (which corresponds to
the next element in the array).
97
1. Call by Value
In call by value, a copy of the actual argument is passed to the function. Changes made to the
parameter inside the function do not affect the original argument.
How it works: The function gets a copy of the value passed to it.
Effect: The original variable remains unchanged outside the function.
In call by reference, the address (reference) of the actual argument is passed to the function.
Changes made to the parameter inside the function affect the original argument.
How it works: The function gets the memory address of the argument.
Effect: The original variable is modified directly.
98
int main() {
int n = 5;
addTen(&n); // Passes the address of n
printf("Value of n after function: %d\n", n); // Output: 15 (value modified)
return 0;
}
💻 Output:
Value of n after function: 15
Key Differences:
Parameter Passes a copy of the argument to the Passes the address of the argument
Passing function. (reference).
More memory used as a copy of the More efficient since no copy is made,
Memory Usage
argument is made. only a reference.
In C, pointers and arrays are closely related, as arrays can be accessed through pointers, and
pointers can be used to manipulate arrays efficiently.
Pointer to an Array
An array name is essentially a pointer to the first element of the array. You can use pointers
to access and manipulate array elements.
99
// Accessing array elements using pointer
printf("First element: %d\n", *ptr); // Output: 10
printf("Second element: %d\n", *(ptr + 1)); // Output: 20
printf("Third element: %d\n", *(ptr + 2)); // Output: 30
return 0;
}
💻 Output:
First element: 10
Second element: 20
Third element: 30
ARRAYS OF POINTERS
Arrays of Pointers in C
An array of pointers is an array where each element is a pointer to a specific variable or data
type. This concept is commonly used when dealing with arrays of strings or when you need
to store the addresses of multiple variables in an array.
How It Works:
#include <stdio.h>
int main() {
int a = 10, b = 20, c = 30;
// Array of pointers to integers
int *arr[] = {&a, &b, &c};
// Accessing elements through the pointers
printf("a: %d\n", *arr[0]); // Dereferencing pointer to access value
printf("b: %d\n", *arr[1]); // Dereferencing pointer to access value
printf("c: %d\n", *arr[2]); // Dereferencing pointer to access value
100
return 0;
}
💻 Output:
a: 10
b: 20
c: 30
In C, pointers and structures are often used together to create flexible and dynamic
programs. Pointers to structures allow for dynamic memory management, efficient passing of
large structures to functions, and handling complex data types like linked lists.
Pointer to a Structure
A pointer to a structure is used to refer to a structure variable indirectly. The pointer holds
the address of the structure and can access its members using the -> operator.
101
}
💻 Output:
Name: Alice
Age: 25
In this example:
When you pass a structure to a function using a pointer, the function works with the actual
structure (not a copy), which is more efficient.
102
In this example:
Key Points:
1. Pointer to Structure: A pointer can point to a structure and access its members using
the -> operator.
2. Efficient Function Passing: Passing structures by pointer avoids copying the entire
structure, which is more efficient.
3. Dynamic Memory Allocation: Pointers to structures are often used with functions
like malloc() to dynamically allocate memory for structures.
In C, memory allocation refers to the process of reserving space in memory to store data.
There are two main types of memory allocation:
In static memory allocation, memory is allocated at compile time, before the program starts
running. The size and type of memory needed must be known in advance.
Fixed Memory Size: The amount of memory is decided when the program is
compiled and cannot be changed during runtime.
Automatic/Global Variables: Variables that are declared outside functions (global
variables) or with the static keyword (local static variables) are statically allocated.
103
}
// Print the array
for (int i = 0; i < 5; i++) {
printf("%d ", arr[i]);
}
return 0;
}
💻 Output:0 10 20 30 40
Here, arr[5] is statically allocated with memory for 5 integers at compile time.
Flexible Memory Size: The size of the memory can be decided at runtime and can
change.
Heap Memory: Dynamically allocated memory is taken from the heap, which is a
region of memory that is managed during program execution.
104
int main() {
int *arr;
int n = 5;
// Dynamically allocate memory for 5 integers
arr = (int*)malloc(n * sizeof(int));
// Check if memory allocation is successful
if (arr == NULL) {
printf("Memory allocation failed\n");
return 1;
}
// Initialize the array
for (int i = 0; i < n; i++) {
arr[i] = i * 10;
}
// Print the array
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
// Free the dynamically allocated memory
free(arr);
return 0;
}
💻 Output:0 10 20 30 40
Here, memory for the array arr is dynamically allocated using malloc(), and the size is
determined at runtime.
Memory size can be adjusted during runtime based on the program's needs.
Efficient use of memory since you can allocate just the required amount.
105
Requires manual management (malloc to allocate, free to release) to avoid memory
leaks.
Summary of Differences:
Memory Allocation
At compile time. At runtime.
Time
Definition: Memory is allocated at compile time before the program starts executing.
Fixed Size: The size of the memory must be known in advance, and it cannot change
during runtime.
Memory Allocation: Done automatically by the compiler for variables (e.g., arrays,
global/static variables).
Types of Variables:
o Global Variables: Memory is allocated at compile time and stays for the
lifetime of the program.
o Local Variables: Memory is allocated for the function's duration.
o Static Variables: Retain their value across function calls.
Access: Fast memory access since memory allocation is done at compile time.
Example:int arr[5]; // Array of size 5, memory is allocated at compile time
106
Advantages:
Disadvantages:
107
Disadvantages:
1. malloc():
o Allocates a block of memory of the specified size.
o Returns a pointer to the allocated memory.
o Example:int *ptr = (int*)malloc(sizeof(int) * 10);
2. calloc():
o Allocates memory for an array of n elements, each of a specified size, and
initializes all bytes to 0.
o Example:int *arr = (int*)calloc(5, sizeof(int));
3. realloc():
o Resizes previously allocated memory to a new size.
o Example:arr = (int*)realloc(arr, 10 * sizeof(int)); // Resize to store 10
elements
4. free():
o Deallocates previously allocated memory, releasing it back to the system.
o Example:free(arr);
Key Differences:
Memory Region Stack (for local variables) or Data Heap (dynamically allocated
108
Aspect Static Memory Allocation Dynamic Memory Allocation
Less flexible, cannot change size More flexible, size can be changed
Flexibility
after allocation. during runtime.
Example Comparison:
Files in C: Definition
In C, a file is a collection of data stored in a specific format, usually on a storage device (like
a hard drive). Files are used to read, write, and store data for later use. C provides built-in
functions to work with files, allowing you to interact with external data easily.
1. File Operations in C
109
2. File Types
1. Text Files: Files that contain data in readable text format. Each line ends with a
newline character.
2. Binary Files: Files that store data in binary format, typically used for storing data
other than text (e.g., images, audio).
1. fopen():
o Opens a file for reading or writing.
o Syntax: FILE *fopen(const char *filename, const char *mode);
o Modes:
"r": Read (file must exist).
"w": Write (creates a new file or truncates an existing file).
"a": Append (writes data at the end of the file).
"rb", "wb", etc.: Binary mode.
2. fclose():
o Closes the file after the operation is completed.
o Syntax: int fclose(FILE *file);
o Always close files after operations to avoid memory leaks.
Example:fclose(file);
3. fgetc():
o Reads a single character from the file.
o Syntax: int fgetc(FILE *file);
o Returns the character read or EOF on error.
Example:char c = fgetc(file);
110
4. fgets():
o Reads a string from the file.
o Syntax: char *fgets(char *str, int n, FILE *file);
o Reads up to n-1 characters or until a newline is encountered.
Example:char buffer[100];
5. fputc():
o Writes a single character to the file.
o Syntax: int fputc(int c, FILE *file);
6. fputs():
o Writes a string to the file.
o Syntax: int fputs(const char *str, FILE *file);
7. fread():
o Reads a block of data from the file.
o Syntax: size_t fread(void *ptr, size_t size, size_t count, FILE *file);
Example:char buffer[50];
8. fwrite():
o Writes a block of data to the file.
o Syntax: size_t fwrite(const void *ptr, size_t size, size_t count, FILE *file);
111
Example:fwrite(buffer, sizeof(char), 50, file);
4. File Modes
When opening a file, you specify the mode which defines how you want to interact with the
file:
5. Error Handling
if (file == NULL) {
printf("Error opening file!\n");
}
if (feof(file)) {
printf("End of file reached.\n");
}
#include <stdio.h>
112
int main() {
FILE *file;
char content[100];
In C, files are primarily classified into text files and binary files. These two types of files
differ in how data is stored and processed.
1. Text Files
113
Definition: Text files store data in a human-readable format. Each line of text is
typically terminated with a newline (\n) character.
Data Representation: Data is stored as a sequence of characters (ASCII or Unicode),
making it easy to read and edit using text editors.
File Operations: You can open text files with modes like "r", "w", "a", and "r+".
2. Binary Files
Definition: Binary files store data in its raw binary format (i.e., 0s and 1s), typically
used for non-text data like images, audio, and executable programs.
Data Representation: Data is stored as bytes (8 bits) rather than characters. The
structure of the data is more complex and specific to the application.
File Operations: You can open binary files with modes like "rb", "wb", and "r+".
A binary file could contain bytes representing an image or a serialized data structure (not
human-readable).
Common Functions:
Key Characteristics:
Not Readable: Cannot be opened and edited in a text editor, as it's not meant to be
human-readable.
Byte-Based: Stores data as raw bytes, which could represent any type of data.
114
No Line Terminators: Unlike text files, binary files do not have specific line-ending
characters.
Key Differences:
Data
Human-readable characters (ASCII). Raw binary data (0s and 1s).
Representation
115
Command-Line Arguments in C:
In C, command-line arguments allow you to pass data to your program when it is executed
from the terminal or command prompt. These arguments can be used to provide input values,
configurations, or other parameters to influence the behavior of the program.
1. Definition
Command-line arguments are inputs provided after the program's name in the
terminal/command prompt when running a C program. They are passed to the main()
function as parameters.
Syntax:
116
3. Example Usage
4. Important Points
Error Handling:
o Always check argc to make sure the correct number of arguments is passed.
o Handle errors if insufficient arguments are provided.
117
5. Example with Integer Argument Parsing
To convert command-line arguments into integers, use atoi() (or strtol() for more control).
#include <stdio.h>
#include <stdlib.h>
Syntax:
int main(int argc, char *argv[])
o argc: Total count of arguments (including program name).
o argv[]: Array of strings holding each argument passed.
Common Usage:
o Configuring program behavior.
o Passing user input to a program without interactive prompts.
Error Handling:
o Check argc to ensure the required number of arguments.
o Use atoi() or strtol() to convert strings to integers.
118
Preprocessor Directives in C: Short Notes
Preprocessor directives in C are commands that are processed by the preprocessor before the
actual compilation of the program begins. They are used to include files, define constants,
and conditionally compile parts of the code.
1. Definition
Preprocessor directives are lines in the program that start with a # symbol. They provide
instructions to the preprocessor which modifies the code before it is compiled.
1. #include
Purpose: Includes the contents of a file (usually a header file) in the program.
Usage:
o #include <file>: Includes system/library header files.
o #include "file": Includes user-defined header files.
Example:
2. #define
Syntax:
Example:
119
#define PI 3.14159 // Defines a constant PI
#define SQUARE(x) ((x) * (x)) // Defines a macro for squaring a number
3. #undef
Example:
Syntax:
#if CONDITION
// Code if condition is true
#elif ANOTHER_CONDITION
// Code if the second condition is true
#else
// Code if none of the conditions are true
#endif
Example:
#define DEBUG
#if defined(DEBUG)
120
printf("Debugging is enabled.\n");
#else
printf("Debugging is disabled.\n");
#endif
5. #ifdef and #ifndef
Example:
#define PI 3.14
#ifdef PI
printf("PI is defined.\n");
#endif
#ifndef MAX_SIZE
printf("MAX_SIZE is not defined.\n");
#endif
6. #pragma
Modular Code: Use #include to include header files and split the code into multiple
files.
Constants and Macros: Use #define to define constants and macros for reusable
code.
Conditional Compilation: Use #if, #ifdef, etc., to include/exclude parts of code
depending on the conditions, such as debugging or platform-specific code.
121
#include <stdio.h>
#define MAX 100
int main() {
int arr[MAX];
#ifdef MAX
printf("MAX is defined as %d\n", MAX);
#endif
#if MAX > 50
printf("MAX is greater than 50\n");
#else
printf("MAX is less than or equal to 50\n");
#endif
return 0;
}
Output:
MAX is defined as 100
MAX is greater than 50
122
Directive Purpose Example
In C, macros are a type of preprocessor directive that allows you to define reusable code or
values. Macros are processed by the preprocessor before the actual compilation starts, making
them powerful tools for simplifying complex code, enhancing readability, and improving
maintainability.
1. Definition of Macros
A macro is a name that represents a code fragment. When the preprocessor encounters the
macro name in the code, it replaces it with the defined code.
Syntax:
Example:
2. Types of Macros
123
1. Object-like Macros
Syntax:
Example:
Usage: The preprocessor replaces MAX_SIZE with 100 and PI with 3.14159
wherever they appear in the code.
Example in Code:
#include <stdio.h>
#define MAX_SIZE 100
int main() {
int arr[MAX_SIZE];
printf("Array size: %d\n", MAX_SIZE);
return 0;
}
2. Function-like Macros
Syntax:
124
#define MACRO_NAME(arg1, arg2, ...)
replacement_expression
Example:
Example in Code:
#include <stdio.h>
#define SQUARE(x) ((x) * (x))
int main() {
int result = SQUARE(5);
printf("Square of 5: %d\n", result); // Output: Square of 5: 25
return 0;
}
3. Advantages of Macros
Efficiency: Macros are processed at compile time, making them faster than functions.
Code Reusability: Macros allow you to reuse code with minimal redundancy.
Flexibility: They can be used for constants, expressions, and even code snippets.
Conditionally include code: Macros can be used to include or exclude code based on
conditions (e.g., using #ifdef).
4. Disadvantages of Macros
Example:
125
printf("%d\n", SQUARE(2 + 3)); // Expands to ((2 + 3) * (2 + 3)) => 5 * 5 = 25
Debugging Difficulty: Since macros are expanded at compile time, debugging can be
tricky.
Example Usage:
#define TO_STRING(x) #x
Example Usage:
Example Usage:
int xy = 10;
printf("%d\n", CONCAT(x, y)); // Output: 10
126
Type Description Example
Function-like Macro that behaves like a function with #define SQUARE(x) ((x) *
Macro arguments. (x))
In C, header files are used to declare function prototypes, constants, and types, which can be
shared between multiple source files. You can create your own header files to organize code
and improve reusability.
A header file is a file that contains definitions or declarations that are shared across multiple
source files. It usually has a .h extension and is included at the top of C source files using the
#include directive.
Create a .h file that contains function prototypes, constants, and type definitions. This file
doesn't contain function definitions or logic; it only contains declarations.
Example: myheader.h
127
#ifndef MYHEADER_H // Include guard to prevent double inclusion
#define MYHEADER_H
#endif
In the source file (.c), include the header file using #include to access the declarations.
Example
#include <stdio.h>
#include "myheader.h" // Including the user-defined header file
void printMessage() {
printf("Hello from the header file!\n");
}
int main() {
printf("Value of PI: %f\n", PI);
printf("Square of 5: %d\n", SQUARE(5));
printMessage();
return 0;
}
128
#include "myheader.h": Includes the header file in your source file, making its
contents available for use.
Function printMessage() is defined in main.c, while its prototype is declared in the
header file.
3. Compilation Process
Code Reusability: Declare functions, constants, and structures in the header file, and
reuse them across different .c files.
Modularity: Separate function declarations and definitions, making code easier to
maintain.
Encapsulation: Hide implementation details and expose only the necessary functions
through the header file.
Avoid Redundancy: Use #ifndef and #define to avoid multiple inclusions of the same
header file.
project/
│
├── myheader.h // User-defined header file
├── main.c // Source file using the header file
└── Makefile // Makefile for compiling the program (optional)
129
130