Understanding Algorithms and C Programming
Understanding Algorithms and C Programming
1. Introduction to Algorithms. 1
------------------------------------------------------------------------------------------------------------
1.1 Definition of Algorithms. 1
1.2 Characteristics of Algorithms. 1
1.3 Role of Algorithms. 1
1.4 Algorithm Examples. 1
a) Addition of two number. 1
b) Given number is odd or even, 2
c) Largest of three numbers. 2
d) Factorial of a number . 2
e). Given number is prime or not. 2
f). Generate Fibonacci Series. 3
g). Roots of Quadratic equation. 3
h). Palindrome of a given number. 4
i). Search an element using linear search technique. 4
j). Search an element using Binary search technique. 4
2. Introduction to Flowcharts. 6
----------------------------------------------------------------------------------------------------------------
2.1 Importance of Flowchart. 6
2.2 Working of Flowcharts . 6
2.3 Common flowchart symbols. 7
2.4 Key uses of flowcharts. 7
2.5 Writing Flowchart. 8
3. Overview of C Language. 11
----------------------------------------------------------------------------------------------------------------
3.1 History of C Language. 11
3.2 Applications of C Language. 11
3.3 Structure of C Program. 12
3.4 Complete Program to understand C coding structure. 15
8. Decision Making. 41
----------------------------------------------------------------------------------------------------------------
8.1 if Statement. 41
8.2 if…else Statement. 42
8.3 Nested if Statements. 44
8.4 Switch Statement. 45
8.5 Conditional operator (:?). 47
9. Loops. 48
--------------------------------------------------------------------------------------------------------------------------
9.1 Purpose of Loops. 48
9.2 Benefits of Using Loops. 48
9.3 Types of Loops. 48
10. Arrays. 53
----------------------------------------------------------------------------------------------------------------
10.1 Characteristics of an array. 53
10.2 Applications of Arrays. 53
10.3 Declaring Arrays. 54
10.4 Initializing Arrays. 54
10.5 Reading and Printing Array Elements with for Loop. 54
10.6 Accessing Array Elements. 55
10.7 Linear Search. 56
10.8 Binary Search. 57
10.9 Bubble sort. 58
10.10 Two-dimensional Array. 59
10.11 Addition of Two Matrices. 61
10.12 Multiplication of two matrices. 62
11. Pointers. 65
----------------------------------------------------------------------------------------------------------------
11.1 Memory Organization. 65
11.2 Benefits of Using Pointers:. 66
11.3 Declaring a Pointer. 66
11.4 Initialize the Pointer. 67
11.5 Addition of two number using pointers. 68
11.6 Types of Pointers. 69
11.7 Using Pointers on Array. 71
11.8 Accessing Array Elements Using Pointers. 71
11.9 Modifying Array Values with Pointers. 71
12. Functions. 72
---------------------------------------------------------------------------------------------------------------------------
12.1 Benefits of Using Functions. 72
12.2 Types of functions . 72
12.3 Function Definition. 72
12.4 Function Call. 73
12.5 Function return type. 73
12.6 Passing Parameters to Function. 74
12.7 Factorial of number using function. 75
12.8 Recursion. 76
12.9 Passing arrays to Function. 77
12.10 Call by value and Call by Reference. 79
12.11 Passing Multidimensional Arrays. 81
13. Strings. 83
-----------------------------------------------------------------------------------------------------------------------
13.1 Declaration. 83
13.2 Initialization. 83
13.3 Accessing Characters. 84
13.4 Basic Operations on strings.. 85
14. Structures. 88
---------------------------------------------------------------------------------------------------------------------------
14.1 Key Characteristics. 88
14.2 Use Cases. 88
14.3 Defining Structures. 88
14.4 Creating Structure Variables. 89
14.5 Copying Structure. 90
14.6 Nested Structures. 92
14.7 Pointer to a structure. 93
15. Unions. 95
---------------------------------------------------------------------------------------------------------------------------
15.1 Key points of Union. 95
15.2 Key Differences from Structures. 95
15.3 Union Declaration. 95
15.4 Initialization and Accessing. 96
15.5 Comparison between structures and unions. 97
Step 1: Start
Step 2: Input first number as P
Step 3: Input second number as Q
Step 4: Set Sum=P+Q
Step 5: Print Sum
Step 6: End.
1
B). Given number is odd or even
Step 1: Start
Step 2: Read a number to N
Step 3: Divide the number by 2 and store the remainder in R.
Step 4: If R = O Then go to Step 6
Step 5: Print “N is odd” go to step 7
Step 6: Print “N is even”
Step 7: End
2
F). Generate Fibonacci Series
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144….
Step 1 : Start.
Step 2 : Declare variables i, a,b , show
Step 3 : start the loop from i= 2 to i=N-1
Step 4 : Initialize the variables, a=0, b=1, and show =0.
Step 5 : Enter the number of terms of Fibonacci series to be printed.
Step 6: Print First two terms of series
Step 7: Use loop for the following steps
show=a+b
a=b
b=show
increase value of i each time by 1
print the value of show
Step 8: End
Step 1 : Start.
Step 2 : Input Coefficients: Obtain the values of the coefficients a,b and c
Step 3 : Calculate Discriminant: Compute the discriminant, 𝐷=𝑏2−4𝑎
Step 4 : Determine Nature of Roots:
* If D>0 (Real and Distinct roots)
3
H). Palindrome of a Given number
Step1: Start.
Step2: Input the number n.
Step3: Store the original number in a variable original.
Step4 :Reverse the number:
Initialize rev = 0.
While n > 0:
o Get the last digit: digit = n % 10
o Update reverse: rev = rev * 10 + digit
o Remove last digit from n: n = n / 10
Step5: Compare the reversed number rev with the original.
Step6 : If rev == original:
Print It's a palindrome.
else
Print Not a palindrome.
Step 7. End
Step1: Start
Step2: An array/list A of size n
Step3: A value target to search for
Step4: Set i = 0 ← (initialize index)
Step5: Repeat while i < n:
If A[i] == target:
Return i ← (target found at index i)
Else:
Increment i by 1
Step6: End of loop: If target was not found in the array
Return -1
Stop7: End
4
Else:
Set high = mid - 1 ← (search in the left half)
Step 6: End of loop: If target not found
Return -1
Step7: Stop
5
1. Introduction to Flowcharts
Input and initialization: The process starts with a clearly defined beginning and an input of
data.
Steps and logic: The flow moves through a series of actions (represented by rectangles) and
decision points (diamonds) that determine the path forward.
Output and termination: The process concludes with a final output or result and a clearly
defined end.
6
2.3 Common flowchart symbols
Universal symbols, standardized by the International Organization for Standardization (ISO),
have specific meanings within a flowchart.
Diamond: Indicates a decision point, typically a question with a "yes" or "no" answer, which
leads to different paths.
Arrows (flowlines): Show the direction of flow and the order of steps.
Circle (on-page connector): Connects different parts of a flowchart on the same page.
Pentagon (off-page connector): Indicates that the process continues on another page.
Simplifying complex processes: They make it easy to understand and analyze complicated
workflows by providing a clear, visual overview.
7
Improving efficiency: By visualizing a process, you can identify and eliminate unnecessary or
redundant steps, or find bottlenecks that cause delays.
Debugging and documentation: In software development, flowcharts are used to plan program
logic and help developers find errors or document how a system works.
Training: They can be used as a step-by-step instructional guide for training new employees.
[Link].
[Link] two numbers N1 and N2.
[Link] them.
[Link] the result.
[Link].
8
Figure 2. Flow charts for Addition of Two numbers and Biggest of Two Numbers
Figure 3. Flow charts for Celcius to Farenheit and Inches to centimeter Conversion
9
Figure 4. Flow charts for Sum of N numbers and Reading a character until Z character
10
3. Overview of C Language
C is a general-purpose, high-level language that was originally developed by Dennis M. Ritchie
to develop the UNIX operating system at Bell Labs. C was origin
ally first implemented on the DEC PDP-11 computer in 1972. In 1978, Brian Kernighan and
Dennis Ritchie produced the first publicly available description of C, now known as the K&R
standard. The UNIX operating system, the C compiler, and essentially all UNIX application
programs have been written in C. C has now become a widely used professional language for
various reasons.
Easy to learn
Structured language
It can handle low-level activities
It can be compiled on a variety of computer platforms
Operating Systems
Language Compilers
Assemblers
Text Editors
Print Spoolers
Network Drivers
Databases
Language Interpreters
Utilities
11
3.3 Structure of C Program
The structure of a C program is the foundation of writing functional and efficient code.
Learning how a C program is organized helps new programmers grasp the flow and purpose of
each part, from including libraries to writing the main() function. Whether you're a beginner or
an experienced coder, knowing the structure of C program with example ensures that your
programs are not only correct but also well-organized. Here, we’ll break down the key
components of a C program and show how they come together to make it work smoothly. The
C program structure consists of the following sections or components shown in Table 1.1
Table 1.1 Sections or components of C
Component Description
Documentation Comments describing the program’s
purpose.
Preprocessor Directives Includes libraries and macros using #include
and #define.
Definition Section Defines constants or macros used in the
program.
Global Declarations Variables declared globally and accessible
by all functions.
main() Function The entry point of the program where
execution begins.
Variable Declarations Local variables declared inside functions.
Statements and Expression Code logic, including operations, loops, and
conditionals.
Sub Programs Additional user-defined sub-programs or
functions.
Return Statement Indicates the end of program execution, often
with a success code.
12
Example
#include <stdio.h> // Includes the standard input-output library
c. Definition Section
This section in the C program structure defines constants or macros that can be used throughout
the [Link] like #define are used to assign names to constant values, so if you need to
change the value later, you only update it in one place. For instance, #define MAX 10 assigns
MAX the value of 10, and this value remains the same throughout the program.
Example :
d. Global Declarations
Global variables are declared outside any function, usually at the top of the program. These
variables can be accessed and modified by any function in the program. However, global
variables in C should be used cautiously, as they can lead to errors if not handled properly.
Example :
e. main() Function
The main() function is the entry point of every C program. It defines where the program starts
executing and returns an integer value (0 means successful execution). Inside the main()
function, you declare variables, define the logic of the program, and call other functions if
necessary.
Example :
int main() {
int n; // Declare a local variable
printf("Enter a number: ");
scanf("%d", &n); // Get user input
printf("Factorial of %d is %d\n", n, factorial(n)); // Call the factorial function
return 0;
}
f. Variable Declarations
Variables in C are used to store data, and they must be declared before they are used. The data
type of the variable (e.g., int, float, char) tells the compiler what type of data the variable will
hold. For instance, declaring int age = 25; assigns the integer value 25 to the variable age.
Example :
13
int num = 5; // Declare and initialize a variable
14
Figure 3.1 Basic Structure of C Program
15
// Function to calculate factorial
int factorial(int n) {
int fact = 1; // Initialize factorial
for (int i = 1; i <= n; i++) { // Loop to calculate factorial
fact *= i;
}
return fact; // Return calculated factorial
}
Output :
Enter a number: 5
Factorial of 5 is 120
16
4. C Tokens and Data Types
You have seen the basic structure of a C program, so it will be easy to understand other basic
building blocks of the C programming language.
4.1 C Tokens
A C program consists of various tokens and a token is either a keyword, an identifier, a
constant, a string literal, or a symbol. For example, the following C statement consists of five
tokens:
printf("Hello, World! \n");
The individual tokens are:
printf
(
"Hello, World! \n"
)
;
Semicolons
In a C program, the semicolon is a statement terminator. That is, each individual statement
must be ended with a semicolon. It indicates the end of one logical entity.
Given below are two different statements:
printf("Hello, World! \n");
return 0;
Comments
Comments are like helping text in your C program and they are ignored by the compiler. They
start with /* and terminate with the characters */ as shown below:
/* my first program in C */
You cannot have comments within comments and they do not occur within a string or character
literals.
Identifiers
A C identifier is a name used to identify a variable, function, or any other userdefined item. An
identifier starts with a letter A to Z, a to z, or an underscore ‘_’ followed by zero or more letters,
underscores, and digits (0 to 9). C does not allow punctuation characters such as @, $, and %
within identifiers. C is a case-sensitive programming language. Thus, Manpower and
manpower are two different identifiers in C. Here are some examples of acceptable identifiers:
tngb raj abc move_name a_123
myname50 _temp j a23b9 retVal
17
Keywords
The following list shows the reserved words in C. These reserved words may not be used as
constants or variables or any other identifier names.
Auto else long switch
Break enum register typedef
case extern return union
char float short unsigned
const for signed void
continue goto sizeof volatile
default if static while
do int struct _Packed double
Whitespace in C
A line containing only whitespace, possibly with a comment, is known as a blank line, and a C
compiler totally ignores it. Whitespace is the term used in C to describe blanks, tabs, newline
characters and comments. Whitespace separates one part of a statement from another and
enables the compiler to identify where one element in a statement, such as int, ends and the
next element begins. Therefore, in the following statement:
int age;
there must be at least one whitespace character (usually a space) between int and age for the
compiler to be able to distinguish them. On the other hand, in the following statement:
fruit = apples + oranges; // get the total fruit
no whitespace characters are necessary between fruit and =, or between = and apples, although
you are free to include some if you wish to increase readability.
18
2. Derived Data Types: These are derived from basic data types and include arrays, pointers,
and functions.
3. User-Defined Data Types: These are created by the programmer and include structures
(struct), unions (union), and enumerations (enum).
Basic Data Types Derived Data Types User-Defined Data Types
int Arrays struct
char Pointers union
float Functions enum
double typedef
void
19
The void Type
The void type specifies that no value is available. It is used in three kinds of situations:
Function returns as void
There are various functions in C which do not return any value or you can say they return void.
A function with no return value has the return type as void. For example, void exit (int status).
Function arguments as void
There are various functions in C which do not accept any parameter. A function with no
parameter can accept a void. For example, int rand(void).
Pointers to void
A pointer of type void * represents the address of an object, but not its type. For example, a
memory allocation function void *malloc(size_t size); returns a pointer to void which can be
casted to any data type.
20
5. Variables. Constants and Literals
5.1 Variables
A variable is nothing but a name given to a storage area that our programs can manipulate.
Each variable in C has a specific type, which determines the size and layout of the variable's
memory; the range of values that can be stored within that memory; and the set of operations
that can be applied to the variable. The name of a variable can be composed of letters, digits,
and the underscore character. It must begin with either a letter or an underscore. Upper and
lowercase letters are distinct because C is case-sensitive. Based on the basic types explained in
the previous chapter, there will be the following basic variable types:
Type Description
char Typically a single octet (one byte). This is an integer type.
int The most natural size of integer for the machine.
float A single-precision floating point value
double A double-precision floating point value.
void Represents the absence of type.
Defining Variables
A variable definition tells the compiler where and how much storage to create for the variable.
A variable definition specifies a data type and contains a list of one or more variables of that
type as follows:
type variable_list;
Here, type must be a valid C data type including char, w_char, int, float, double, bool, or any
user-defined object; and variable_list may consist of one or more identifier names separated by
commas. Some valid declarations are shown here:
int i, j, k;
char c, ch;
float f, salary;
double d;
The line int i, j, k; declares and defines the variables i, j and k; which instruct the compiler to
create variables named i, j, and k of type int.
Variables can be initialized (assigned an initial value) in their declaration. The initializer
consists of an equal sign followed by a constant expression as follows:
type variable_name = value;
Some examples are:
extern int d = 3, f = 5; // declaration of d and f.
int d = 3, f = 5; // definition and initializing d and f.
21
byte z = 22; // definition and initializes z.
char x = 'x'; // the variable x has the value 'x'.
For definition without an initializer: variables with static storage duration are implicitly
initialized with NULL (all bytes have the value 0); the initial value of all other variables are
undefined.
Variable Declaration in C
A variable declaration provides assurance to the compiler that there exists a variable with the
given type and name so that the compiler can proceed for further compilation without requiring
the complete detail about the variable. A variable declaration has its meaning at the time of
compilation only, the compiler needs actual variable declaration at the time of linking the
program. A variable declaration is useful when you are using multiple files and you define your
variable in one of the files which will be available at the time of linking the program. You will
use the keyword extern to declare a variable at any place. Though you can declare a variable
multiple times in your C program, it can be defined only once in a file, a function, or a block
of code.
Example
Try the following example, where variables have been declared at the top, but they have been
defined and initialized inside the main function:
#include <stdio.h>
// Variable declaration:
extern int a, b;
extern int c;
extern float f;
int main ()
{
/* variable definition: */
int a, b;
int c;
float f;
/* actual initialization */
a = 10;
b = 20;
22
c = a + b;
23
also have a suffix that is a combination of U and L, for unsigned and long, respectively. The
suffix can be uppercase or lowercase and can be in any order.
Here are some examples of integer literals
212 /* Legal */
215u /* Legal */
0xFeeL /* Legal */
078 /* Illegal: 8 is not an octal digit */
032UU /* Illegal: cannot repeat a suffix */
Following are other examples of various types of integer literals:
85 /* decimal */
0213 /* octal */
0x4b /* hexadecimal */
30 /* int */
30u /* unsigned int */
30l /* long */
30ul /* unsigned long */
Floating-point Literals
A floating-point literal has an integer part, a decimal point, a fractional part, and an exponent
part. You can represent floating point literals either in decimal form or exponential form. While
representing decimal form, you must include the decimal point, the exponent, or both; and
while representing exponential form, you must include the integer part, the fractional part, or
both. The signed exponent is introduced by e or E.
Here are some examples of floating-point literals:
3.14159 /* Legal */
314159E-5L /* Legal */
510E /* Illegal: incomplete exponent */
210f /* Illegal: no decimal or exponent */
.e55 /* Illegal: missing integer or fraction */
Character Constants
Character literals are enclosed in single quotes, e.g., 'x' can be stored in a simple variable of
char type. A character literal can be a plain character (e.g., 'x'), an escape sequence (e.g., '\t'),
or a universal character (e.g., '\u02C0'). There are certain characters in C that represent special
meaning when preceded by a backslash, for example, newline (\n) or tab (\t). Here, you have a
list of such escape sequence codes:
24
Escape sequence Meaning
\\ \ character
\' ' character
\" " characte
\? ? character
\a Alert or bell
\b Backspace
\f Form feed
\n Newline
\r Carriage return
\t Horizontal tab
\v Vertical tab
\ooo Octal number of one to three digits
\xhh . . . Hexadecimal number of one or more digits
25
Defining Constants
There are two simple ways in C to define constants:
26
const char NEWLINE = '\n';
int area;
area = LENGTH * WIDTH;
printf("value of area : %d", area);
printf("%c", NEWLINE);
return 0;
}
When the above code is compiled and executed, it produces the following result:
value of area : 50
Note that it is a good programming practice to define constants in CAPITALS
27
6. Input and Output
In C programming, input refers to data a program receives, and output is the data a program
displays or generates. The standard library provides functions for both, with printf for
outputting formatted text and scanf for receiving formatted input. The following diagram
depicts the same.
6.1 Input
Purpose :
Input allows a program to interact with the user or external sources by receiving data.
Examples:
Reading data entered by the user through the keyboard.
Reading data from a file
Key Function:
scanf() is a primary function for reading formatted input from the standard input stream
(typically the keyboard).
6.2 Output
Purpose:
Output allows a program to communicate results, messages, or errors to the user or external
destinations.
Examples:
Displaying text on the console (screen).
Writing data to a file.
Key Function:
printf() is a primary function for displaying formatted output to the standard output stream
(typically the screen).
28
Programming Example :
#include <stdio.h>
int main() {
int age;
char name[50];
// Input (using scanf)
printf("Enter your age: ");
scanf("%d", &age);
printf("Enter your name: ");
scanf("%s", name); // Note: scanf("%s", name) reads only up to the first space
// Output (using printf)
printf("Your name is: %s\n", name);
printf("Your age is: %d\n", age);
return 0;
}
Explanation:
printf("Enter your age: ");: Prints a prompt message to the screen, asking the user to enter their
age.
scanf("%d", &age);: Reads an integer value from the standard input (keyboard) and stores it in
the age variable. The %d is a format specifier indicating an integer. The & (ampersand)
provides the memory address of the age variable, where the input value should be stored
printf("Enter your name: ");: Prints a prompt message to the console, asking the user to enter
their name
29
Explanation:
Purpose: Format specifies ensure that data is displayed or read correctly based on its
type. Without them, the compiler wouldn't know how to interpret the variable values.
Syntax: A format specifies starts with a % followed by a character indicating the data type.
Common Specifies:
%d or %i: Integer.
%f: Floating-point number.
%s: String.
%c: Character.
Example :
# include <stdio.h>
int main() {
int age = 30;
float price = 19.99;
char name[] = "Alice";
printf("My age is %d.\n", age); // Outputs: My age is 30.
printf("The price is %.2f.\n", price); // Outputs: The price is 19.99.
printf("My name is %s.\n", name); // Outputs: My name is Alice.
return 0;
}
30
7. Operators in C
In C programming, operators are symbols that instruct the compiler to perform specific
operations on variables and data. They are used to manipulate data, perform calculations, make
decisions, and control the flow of a program. C provides a wide variety of operators, including
arithmetic, relational, logical, bitwise, and more.
Example
// Working of arithmetic operators
#include <stdio.h>
int main()
{
int a = 9,b = 4, c;
c = a+b;
printf("a+b = %d \n",c);
c = a-b;
printf("a-b = %d \n",c);
c = a*b;
printf("a*b = %d \n",c);
c = a/b;
printf("a/b = %d \n",c);
c = a%b;
printf("Remainder when a divided by b = %d \n",c);
return 0;
}
31
Output :
a+b=13
a-b=5
a*b=36
a/b=2
Remainder when a divided by b =1
32
7.3 Assignment Operator (=)
An assignment operator is used for assigning a value to a variable. The most common
assignment operator is =
Operator Example Same as
= a=b a=b
+= a += b a = a+b
-= a -= b a -= b
*= a *= b a = a*b
/= a /= b a = a/b
%= a %= b a = a%b
Example :
// Working of assignment operators
#include <stdio.h>
int main()
{
int a = 5, c;
c = a; // c is 5
printf("c = %d\n", c);
c += a; // c is 10
printf("c = %d\n", c);
c -= a; // c is 5
printf("c = %d\n", c);
c *= a; // c is 25
printf("c = %d\n", c);
c /= a; // c is 5
printf("c = %d\n", c);
c %= a; // c = 0
printf("c = %d\n", c);
return 0;
}
Output :
c=5
c=10
c=5
33
c=25
c=5
c=0
Example :
// Working of relational operators
#include <stdio.h>
int main()
{
int a = 5, b = 5, c = 10;
printf("%d == %d is %d \n", a, b, a == b);
printf("%d == %d is %d \n", a, c, a == c);
printf("%d > %d is %d \n", a, b, a > b);
printf("%d > %d is %d \n", a, c, a > c);
printf("%d < %d is %d \n", a, b, a < b);
printf("%d < %d is %d \n", a, c, a < c);
printf("%d != %d is %d \n", a, b, a != b);
printf("%d != %d is %d \n", a, c, a != c);
return 0;
}
Output :
5==5 is 1
34
5==10 is 0
5>5 is 0
5>10 is 0
5<5 is 0
5<10 is 1
5!=5 is 0
5!=10 is 1
Example
// Working of logical operators
#include <stdio.h>
int main()
{
int a = 5, b = 5, c = 10, result;
result = (a == b) && (c > b);
printf("(a == b) && (c > b) is %d \n", result);
result = (a == b) && (c < b);
printf("(a == b) && (c < b) is %d \n", result);
result = (a == b) || (c < b);
printf("(a == b) || (c < b) is %d \n", result);
35
result = (a != b) || (c < b);
printf("(a != b) || (c < b) is %d \n", result);
result = !(a != b);
printf("!(a != b) is %d \n", result);
result = !(a == b);
printf("!(a == b) is %d \n", result);
return 0;
}
Output :
(a == b) && (c > b) is 1
(a == b) && (c < b) is 0
(a == b) || (c < b) is 1
(a != b) || (c < b) is 0
(a != b) is 1
!(a == b) is 0
Bitwise operators allow precise manipulation of bits, giving you control over hardware
operations. Let’s look at the truth table of the bitwise operators
X Y X&Y X|Y X^Y
0 0 0 0 0
0 1 0 1 0
1 0 0 1 1
1 1 1 1 0
36
Example
// C Program to demonstrate use of bitwise operators
#include <stdio.h>
int main()
{
// a = 5 (00000101 in 8-bit binary), b = 9 (00001001 in
// 8-bit binary)
unsigned int a = 5, b = 9;
// The result is 00000001
printf("a = %u, b = %u\n", a, b);
printf("a&b = %u\n", a & b);
// The result is 00001101
printf("a|b = %u\n", a | b);
// The result is 00001100
printf("a^b = %u\n", a ^ b);
// The result is 11111111111111111111111111111010
// (assuming 32-bit unsigned int)
printf("~a = %u\n", a = ~a);
// The result is 00010010
printf("b<<1 = %u\n", b << 1);
// The result is 00000100
printf("b>>1 = %u\n", b >> 1);
return 0;
}
Output :
a=5 ,b=9
a&b=1
a|b=13
a^b=12
37
~a=4294967290
b<<1=18
b>>1=4
Interesting Facts About Bitwise Operators
The left-shift and right-shift operators should not be used for negative numbers.
The bitwise OR of two numbers is simply the sum of those two numbers if there is no carry
involved; otherwise, you add their bitwise AND.
The Bitwise operators should not be used in place of logical operators.
The left-shift and right-shift operators are equivalent to multiplication and division by 2
respectively.
38
Size of float = 4 bytes
Size of double=8 bytes
Size of char= 1 byte
Example
The following example to understand operator precedence in C:
#include <stdio.h>
main()
{
int a = 20;
int b = 10;
int c = 15;
39
int d = 5;
int e;
e = (a + b) * c / d; // ( 30 * 15 ) / 5
printf("Value of (a + b) * c / d is : %d\n", e );
e = ((a + b) * c) / d; // (30 * 15 ) / 5
printf("Value of ((a + b) * c) / d is : %d\n" , e );
e = (a + b) * (c / d); // (30) * (15/5)
printf("Value of (a + b) * (c / d) is : %d\n", e );
e = a + (b * c) / d; // 20 + (150/5)
printf("Value of a + (b * c) / d is : %d\n" , e );
return 0;
}
Output :
Value of (a + b) * c / d is : 90
Value of ((a + b) * c) / d is : 90
Value of (a + b) * (c / d) is : 90
Value of a + (b * c) / d is : 50
40
8. Decision Making
Decision-making structures require that the programmer specifies one or more conditions to be
evaluated or tested by the program, along with a statement or statements to be executed if the
condition is determined to be true, and optionally, other statements to be executed if the
condition is determined to be false. C programming language assumes any non-zero and non-
null values as true, and if it is either zero or null, then it is assumed as false value.
C programming language provides the following types of decision-making statements.
Statement Description
if statement An if statement consists of a boolean
expression followed by one or more
statements.
if...else statement An if statement can be followed by an optional
else statement, which executes when the
Boolean expression is false.
nested if statement You can use one if or else if statement inside
another if or else if statement(s).
switch statement A switch statement allows a variable to be
tested for equality against a list of values.
nested switch statements You can use one switch statement inside
another switch statement(s).
8.1 if Statement
An if statement consists of a Boolean expression followed by one or more statements.
Syntax
The syntax of an ‘if’ statement in C programming language is
If the Boolean expression evaluates to true, then the block of code inside the ‘if’ statement will
be executed. If the Boolean expression evaluates to false, then the first set of code after the end
of the ‘if’ statement (after the closing curly brace) will be executed.C programming language
41
assumes any non-zero and non-null values as true and if it is either zero or null, then it is
assumed as false value.
Example :
#include <stdio.h>
int main ()
{
/* local variable definition */
int a = 10;
/* check the boolean condition using if statement */
if( a < 20 )
{
/* if condition is true then print the following */
printf("a is less than 20\n" );
}
printf("value of a is : %d\n", a);
return 0;
}
Output :
a is less than 20;
value of a is : 10
42
{
/* statement(s) will execute if the boolean expression is false */
}
If the Boolean expression evaluates to true, then the if block will be executed, otherwise, the
else block will be executed.
Example
#include <stdio.h>
int main ()
{
/* local variable definition */
int a = 100;
/* check the boolean condition */
if( a < 20 )
{
/* if condition is true then print the following */
printf("a is less than 20\n" );
}
else
{
/* if condition is false then print the following */
printf("a is not less than 20\n" );
}
printf("value of a is : %d\n", a);
return 0;
43
}
Output :
a is not less than 20;
value of a is : 100
Example
#include <stdio.h>
int main ()
{
/* local variable definition */
int a = 100;
int b = 200;
/* check the boolean condition */
if( a == 100 )
{
44
/* if condition is true then check the following */
if( b == 200 )
{
/* if condition is true then print the following */
printf("Value of a is 100 and b is 200\n" );
}
}
printf("Exact value of a is : %d\n", a );
printf("Exact value of b is : %d\n", b );
return 0;
}
Output
Value of a is 100 and b is 200
Exact value of a is : 100
Exact value of b is : 200
45
The expression is evaluated, and its value is compared against the constant-expression values
of each case. If a match is found, the code block associated with that case is
executed. The break statement is typically used to exit the switch statement after a
matching case is processed. If no break is present, execution continues to the next case, which
is known as "fall-through." The default case is optional and is executed if no
other case matches the expression's value.
Example :
// Output:
46
Wednesday
In this example, the switch statement checks the value of the day variable and prints the
corresponding day of the week. Since day is 3, the output is "Wednesday".
The conditional operator in C, also known as the ternary operator, provides a concise way to
express conditional logic. It serves as a shorthand for the if-else statement, allowing for more
compact code. The syntax of the conditional operator is as follows:
variable = (condition) ? expression1 : expression2;
The condition is evaluated first. It can be any expression that results in a boolean value (true
or false). If the condition is true, expression1 is evaluated and its result is returned. If
the condition is false, expression2 is evaluated and its result is returned.
Example :
int time = 20;
if (time < 18)
{
printf("Good day.");
}
else
{
printf("Good evening.");
}
The above program can be written using conditional operator as
int time = 20;
(time < 18) ? printf("Good day.") : printf("Good evening.");
47
9. Loops
Loops in programming are used to execute a block of code repeatedly until a specific condition
is met. This allows for efficient repetition of tasks, reducing code redundancy and improving
program organization. By using loops, programmers can automate repetitive actions without
having to write the same code multiple times
48
Syntax :
Example
Sum = 1+2+3+4+5+6+7+8+9+10+………………+n
#include <stdio.h>
int main() {
int i = 1,sum=0,n=5;
while (i <= n) {
sum=sum+i;
i++;
}
printf(“Sum of first n numbers is =%d”, sum);
return 0;
}
Output :
Sum of first n numbers is =15
do-while loop
49
The do while loop in C is a post-test loop, meaning that the loop's body is executed at least
once before the condition is checked. The syntax of the do while loop is as follows
Syntax
do
{
//true
Code to be executed when condition is true
//repeats
} while (condition); // true or false
Example
Sum = 1+2+3+4+5+6+7+8+9+10+………………+n
#include <stdio.h>
int main() {
int i = 1,sum=0,n=5;
do {
sum=sum+i;
i++;
} while (i <= n)
printf(“Sum of first n numbers is =%d”, sum);
return 0;
}
Output :
Sum of first n numbers is =15
for loop
In C, the for loop is a control flow statement that allows code to be executed repeatedly for a
predetermined number of times. It is particularly useful when the number of iterations is known
50
in advance. The for loop consists of three parts: initialization, condition, and
increment/decrement, all defined within the loop's parentheses.
Syntax
Initialization:
This statement is executed only once at the beginning of the loop. It is typically used to
declare and initialize a loop counter variable.
Condition:
This expression is evaluated before each iteration. If the condition is true, the loop body is
executed. If it is false, the loop terminates.
Increment/Decrement:
This statement is executed after each iteration. It is commonly used to update the loop counter
variable.
Example
Sum = 1+2+3+4+5+6+7+8+9+10+………………+n
#include <stdio.h>
int main() {
51
int i,n=5,sum=0;
for (i = 1; i <= n; i++)
{
sum=sum+i;
}
printf(“Sum of first n numbers is =%d”, sum);
return 0;
}
Output :
Sum of first n numbers is =15
52
10. Arrays
Arrays a kind of data structure that can store a fixed-size sequential collection of elements of
the same type. An array is used to store a collection of data, but it is often more useful to think
of an array as a collection of variables of the same type. Instead of declaring individual
variables, such as number0, number1, ..., and number99, you declare one array variable such
as numbers and use numbers[0], numbers[1], and ..., numbers[99] to represent individual
variables. A specific element in an array is accessed by an index.
53
10.3 Declaring Arrays
To declare an array in C, a programmer specifies the type of the elements and the number of
elements required by an array as follows:
type arrayName [ arraySize ];
This is called a single-dimensional array. The arraySize must be an integer constant greater
than zero and type can be any valid C data type. For example, to declare a 10-element array
called balance of type double, use this statement:
double balance[10];
Here, balance is a variable array which is sufficient to hold up to 10 double numbers.
printf("Enter 5 integers:\n");
for (int i = 0; i < size; i++) {
scanf("%d", &arr[i]); // Read input from the user and store it
}
printf("You entered:\n");
for (int i = 0; i < size; i++) {
printf("%d ", arr[i]); // Print the entered elements
54
}
printf("\n");
return 0;
}
}
/* output each array element's value */
for (j = 0; j < 10; j++ )
{
printf("Element[%d] = %d\n", j, n[j] );
}
return 0;
}
55
Output :
Element[0] = 100
Element[1] = 101
Element[2] = 102
Element[3] = 103
Element[4] = 104
Element[5] = 105
Element[6] = 106
Element[7] = 107
Element[8] = 108
Element[9] = 109
56
}
In this code, the program iterates through each element of the array arr. If the current
element arr[i] matches the key, the program prints the index i and sets the found flag to 1, then
exits the loop. If the loop completes without finding the key, it prints that the element is not
found.
57
} else if (arr[mid] < key) {
low = mid + 1;
} else {
high = mid - 1;
}
}
if (low > high) {
printf("Element not found.\n");
}
return 0;
}
58
a[i]=a[j];
a[j]=temp;
}
}
for(i=0; i<n; i++)
{
printf("%d\t",a[i]);
}
return 0;
}
Output :
data_type array_name[rows][columns];
Example
59
int matrix[3][4]; // A 3x4 matrix (3 rows and 4 columns)
Initializing a 2D Array
int matrix[2][3] = {
{1, 2, 3},
{4, 5, 6}
};
Accessing Elements
matrix[0][1]; // Accesses the element in the 1st row, 2nd column (value = 2)
60
}
printf("\n");
}
return 0;
}
61
scanf("%d", &matrix2[i][j]);
}
}
return 0;
}
62
int matrix1[ROW1][COL1] = {
{1, 2, 3},
{4, 5, 6}
};
int matrix2[ROW2][COL2] = {
{7, 8},
{9, 10},
{11, 12}
};
int result[ROW1][COL2];
63
}
printf("\n");
}
return 0;
}
11. Pointers
64
In C programming, a pointer is a variable that stores the memory address of another variable. It
allows you to directly access and manipulate the data stored at that memory location. Pointers
are used to access the memory of a variable and manipulate their addresses within a program.
Storing Addresses:
Pointers are designed to store the addresses of memory locations in hexadecimal integer.
Example : 0x00000004
Accessing Data:
Once a pointer holds the address of a variable, it can be used to access and modify the data
stored at that address.
65
Dereferencing:
Using the dereference operator (e.g., * in C/C++) to access the data at the memory address
stored in a pointer.
Address-of Operator:
Using the address-of operator (e.g., & in C/C++) to obtain the memory address of a
variable.
Pointers are fundamental for creating dynamic data structures like linked lists, trees, and
graphs.
data_type* name
Here, data_type defines the type of data that the pointer is pointing to. An integer type
pointer can only point to an integer. Similarly, a pointer of float type can point to a floating-
point data, and so on.
Example:
int *ptr; // ptr holds some address and *ptr means value at address ptr
In the above statement, pointer ptr can store the address of an integer. It is pronounced as
pointer to integer.
66
11.4 Initialize the Pointer
Pointer initialization means assigning some address to the pointer variable. In C, the (&)
addressof operator is used to get the memory address of any variable. This memory
address is then stored in a pointer variable.
Example:
int var = 10;
// Initializing ptr
int *ptr = &var;
In the above statement, pointer ptr store the address of variable x which was determined
using address-of operator (&).
Dereference a Pointer
#include <stdio.h>
int main() {
int var = 10;
// Store address of var variable
int* ptr = &var;
// Directly accessing ptr
printf("%d", ptr);
return 0;
}
Output :
0x00000004
This hexadecimal integer (starting with 0x) is the memory [Link] have to
first dereference the pointer to access the value present at the memory address. This is done
with the help of dereferencing operator(*) (same operator used in declaration).
#include <stdio.h>
int main() {
int var = 10;
67
int* ptr = &var;
// Dereferencing ptr to access the value
printf("%d", *ptr);
return 0;
}
Output : 10
68
ptr2 = &num2;
// Adding values using pointers
sum = *ptr1 +*ptr2;
printf("Sum = %d\n", sum);
return 0;
}
Void Pointer
The void pointers in C are the pointers of type void. It means that they do not have any
associated data type. They are also called generic pointers as they can point to any type and
can be typecasted to any type.
#include <stdio.h>
int main() {
// Void pointer
69
void *ptr;
return 0;
}
Wild Pointers
The wild pointers are pointers that have not been initialized with something yet. These types
of C-pointers can cause problems in our programs and can eventually cause them to crash. If
values are updated using wild pointers, they could cause data abort or data corruption.
#include <stdio.h>
int main() {
// Wild Pointer
int *ptr;
reurn 0;
}
Dangling Pointer
A pointer pointing to a memory location that has been deleted (or freed) is called a dangling
pointer. Such a situation can lead to unexpected behavior in the program and also serve as a
source of bugs in C programs.
#include <stdio.h>
#include <stdlib.h>
int main() {
int* ptr = (int*)malloc(sizeof(int));
// After below free call, ptr becomes a dangling pointer
free(ptr);
printf("Memory freed\n");
// removing Dangling Pointer
ptr = NULL;
return 0;
}
70
11.7 Using Pointers on Array
int arr[5] = {10, 20, 30, 40, 50}; // arr is initialized.
printf("%d\n", *arr); // Output: 10 (same as arr[0])
printf("%d\n", *(arr+1)); // Output: 20 (same as arr[1])
12. Functions
71
A function C is a set of statements that, when called, perform some specific tasks. It is the
basic building block of a C program that provides modularity and code reusability. They are
also called subroutines or procedures in other languages.
return_type name () {
// Body of function
};
where,
return_type: type of value the function return.
name: Name of the function
Body of function: Statements inside curly brackets { } are executed when function call.
Example:
72
void hello(){
printf("Hello AIET");
}
In the above code, hello is the name assigned to the function and its return type is void.
73
Output : 3
In this program, the getThree() function is of integer type, meaning that when you call this
function, it returns an integer value, which is 3.
74
12.7 Factorial of number using function
#include <stdio.h>
int main() {
int N = 5;
int fact = factorial(N);
printf("Factorial of %d is %d", N, fact);
return 0;
}
int factorial(int N) {
int fact = 1, i;
// Loop from 1 to N to get the factorial
for (i = 1; i <= N; i++) {
fact *= i;
}
return fact;
}
75
12.8 Recursion
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.
Key Concepts in Recursion
Base Case:
A crucial part of recursion is the base case, which is a condition that stops the function from
calling itself infinitely. Without a base case, a recursive function would result in a stack
overflow error.
Recursive Step:
This is the part where the function calls itself with a modified input, working towards the base
case.
Function Call Stack:
Each recursive call adds a new frame to the call stack, storing the function's local variables and
return address. When the base case is reached, the function returns, and the stack unwinds.
Advantages of Recursion
Can make code more concise and easier to read for certain problems.
Well-suited for problems that can be naturally expressed in terms of smaller, self-similar
subproblems (e.g., tree traversals, sorting algorithms).
Disadvantages of Recursion
Can be less efficient than iterative solutions due to the overhead of function calls and stack
management.
May lead to stack overflow errors if the recursion depth is too large.
Can sometimes be harder to debug and understand compared to iterative code.
Recursion Example
// Factorial of a number using recursion
#include <stdio.h>
long factorial(int n) {
if (n == 0) {
return 1;
76
} else {
return n * factorial(n - 1);
}
}
int main() {
int number;
printf("Enter a non-negative integer: ");
scanf("%d", &number);
if (number < 0) {
printf("Factorial is not defined for negative numbers.\n");
} else {
printf("Factorial of %d = %ld\n", number, factorial(number));
}
return 0;
}
Passing an array to a function allows the function to directly access and modify the original
array. In this article, we will learn how to pass arrays to functions in C.
In C, arrays are always passed to function as pointers. They cannot be passed by value
because of the array decay due to which, whenever array is passed to a function, it decays
into a pointer to its first element. However, there can be different syntax of passing the arrays
as pointers.
The easiest way to pass array to a function is by defining the parameter as the undefined
sized array. Let’s take a look at an example:
#include <stdio.h>
int main() {
printArr(arr, 5);
77
return 0;
In this example, we pass an integer array arr to the function printArr(). In the function
prototype, we define the array as the array of integers with no size [Link], you
may also notice that we have passed the size of the array as second parameter to the function.
It is recommended to pass the size of the array to the function as another parameter,
otherwise we won’t know how many elements to process.
Array passed as an array with the size of its dimension
#include <stdio.h>
int main() {
printArr(arr, 5);
return 0;
78
Passing Array as Pointer Notation
Instead of using array notation arr[] in the function parameter, we can directly use pointer
notation int *arr. All are equivalent, as arrays in C are treated as pointers to the first element
of the array. This method is more flexible when working with dynamically allocated arrays.
#include <stdio.h>
// dimension
int main() {
printArr(arr, 5);
return 0;
In "call by value," a copy of the argument's value is passed to a function, so any changes made
to the argument inside the function do not affect the original variable. In "call by reference,"
the address (or reference) of the argument is passed, so any modifications made to the argument
inside the function directly affect the original variable.
Call by Value
How it works: A copy of the variable's value is created and passed to the function.
Impact on the original variable: Changes made to the variable within the function do not affect
the original variable outside the function.
Example: If you pass a number (like 5) to a function, the function will receive a copy of that
number, and any changes made to that copy will not alter the original number.
79
#include <stdio.h>
int sum = a + b;
return sum;
int main() {
int num1 = 5;
int result;
return 0;
}
Call by Reference
How it works:
The function receives a reference (or pointer) to the original variable's memory location, not a
copy of its value.
Impact on the original variable:
Modifications made to the variable within the function directly impact the original variable.
Example:
If you pass a variable (like x = 5) to a function by reference, and the function changes x to 10,
then the original variable x outside the function will also be 10
#include <stdio.h>
int add(int &a, int &b) {
int sum = *a + * b;
return sum;
80
}
int main() {
int *num1 = 5;
int *num2 = 10;
int result;
result = add(&num1, &num2);
printf("Sum: %d\n", result);
printf("num1: %d\n", *num1);
printf("num2: %d\n", n*um2);
return 0;
}
#include <stdio.h>
int main() {
int arr[3][3] = {{1, 2, 3},
{4, 5, 6},
{7, 8, 9}};
// Passing the array along with the size of rows and columns
print(arr, 3, 3);
return 0;
81
void print(int arr[3][3], int n, int m) {
printf("\n");
82
13. Strings
A String in C programming is a sequence of characters terminated with a null character '\0'.
The C String is work as an array of characters. The difference between a character array and
a C string is that the string in C is terminated with a unique character '\0'.
13.1 Declaration
Declaring a string in C is as simple as declaring a one-dimensional array of character type.
Below is the syntax for declaring a string.
char string_name[size];
In the above syntax string_name is any name given to the string variable and size is used to
define the length of the string, i.e. the number of characters strings will store.
Like array, we can skip the size in the above statement:
char array_name[];
13.2 Initialization
We can initialize a string either by specifying the list of characters or string literal.
// Using character list
char str[] = {'H', 'e', 'l', 'l', 'o', '\0'};
// Using string literal
char str[] = "Hello";
83
13.3 Accessing Characters
We can access any character of the string by providing the position of the character, like in
array. We pass the index inside square brackets [] with the name of the string.
#include <stdio.h>
int main() {
char str[] = "Hello";
// Access first character of string
printf("%c", str[0]);
return 0;
}
Output : H
#include <stdio.h>
int main() {
char str[] = " Hello ";
// Update the first
// character of string
str[0] = 'R';
printf("%c", str[0]);
return 0;
}
Output : R
84
return 0;
}
Output : 3
Copy:
strcpy(dest, src) copies the string src to dest. strncpy(dest, src, n) copies at most n characters
of src to dest.
#include <stdio.h>
#include <string.h>
int main() {
char src[] = "Hello";
char dest[20];
// Copies "Hello" to dest
strcpy(dest, src);
printf("%s", dest);
return 0;
}
Output : Hello
Concatenation:
strcat(dest, src) appends the string src to the end of dest. strncat(dest, src, n) appends at
most n characters of src to dest.
#include <stdio.h>
#include <string.h>
int main() {
char s1[30] = "Hello, ";
char s2[] = "AIET!";
// Appends "AIET!" to "Hello, "
strcat(s1, s2);
printf("%s", s1);
return 0;
}
Output : Hello AIET1
85
Comparison:
strcmp(str1, str2) compares two strings lexicographically. It returns 0 if the strings are equal,
a negative value if str1 is less than str2, and a positive value if str1 is greater
than str2. strncmp(str1, str2, n) compares at most n characters of the strings.
#include <stdio.h>
#include <string.h>
int main() {
char s1[] = "Apple";
char s2[] = "Applet";
// Compare two strings and print result
int res = strcmp(s1, s2);
if (res == 0)
printf("s1 and s2 are same");
else if (res < 0)
printf("s1 is lexicographically smaller than s2");
else
printf("s1 is lexicographically "
"greater than s2");
return 0;
}
Output : s1 is lexicographically smaller than s2
Character Search:
strchr(str, ch) finds the first occurrence of character ch in str. strrchr(str, ch) finds the last
occurrence of character ch in str.
#include <stdio.h>
#include <string.h>
int main() {
char s[] = "Hello, World!";
// Finding the first occurence of 'o' in string s
86
char *res = strchr(s, 'o');
if (res != NULL)
printf("Character found at: %ld index", res - s);
else
printf("Character not found");
return 0;
}
strstr(str1, str2) finds the first occurrence of the substring str2 in str1.
#include <stdio.h>
#include <string.h>
int main() {
if (pos != NULL)
printf("Found");
else
printf("Not Found");
return 0;
Output : Found
87
14. Structures
Structures in C are user-defined data types that allow you to group together variables of
different data types under a single name. These variables are called members of the structure
and can be of any valid C data type, including other structures.
Example :
struct Student {
char name[50];
int rollNumber;
float gpa;
88
};
In this example, Student is the name of the structure, and it contains three
members: name, rollNumber, and gpa.
int main() {
89
printf("%s\t%d\t%.2f\n", [Link], [Link], [Link]);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
struct Student {
int id;
char grade;
};
int main() {
struct Student s1 = {1, 'A'};
// Create a copy of student s1 struct Student s1c = s1;
printf("Student 1 ID: %d\n", [Link]);
printf("Student 1 Grade: %c", [Link]);
return 0;
}
Output :
Student 1 ID : 1
Student 1 Grade: A
Passing Structure to Functions
90
Structure can be passed to a function in the same way as normal variables. Though, it is
recommended to pass it as a pointer to avoid copying a large amount of data.
#include <stdio.h>
// Structure definition
struct A {
int x;
};
int main() {
struct A a = { 10 };
struct A b = { 10 };
Output
a.x:10 b.x=13
91
14.6 Nested Structures
In C, a nested structure refers to a structure that contains another structure as one of its
members. This allows you to create more complex data types by grouping multiple structures
together, which is useful when dealing with related data that needs to be grouped within a larger
structure.
There are two ways in which we can nest one structure into another:
Embedded Structure Nesting: The structure being nested is also declared inside the parent
structure.
Separate Structure Nesting: Two structures are declared separately and then the member
structure is nested inside the parent structure.
Accessing Nested Members
We can access nested Members by using the same ( . ) dot operator two times as shown:
str_parent.[Link]
Example
#include <stdio.h>
92
int main() {
struct parent p = { 25, 195, 'A' };
p.a=25
p.b.x=195
p.b.c=A
In this code, the structure parent contains another structure child as a member.
The parent structure is then initialized with values, including the values for the child
structure's members.
#include <stdio.h>
// Structure declaration
struct Point {
int x, y;
};
int main() {
struct Point p = { 1, 2 };
93
// ptr is a pointer to structure p
struct Point* ptr = &p;
// Accessing structure members using structure pointer
printf("%d %d", ptr->x, ptr->y);
return 0;
}
Output
12
94
15. Unions
Unions in C are a user-defined data type that allows different data types to share the same
memory location. This means that only one member of a union can store a value at any given
time.
95
After declaration of a union then create a variable of union like below:
union_name variable_name
The value of a union variable can be accessed using the dot (.) operator. A value can be
assigned to the union variable using the assignment operator (=).
In a union, all the variables share the same memory, so only one variable can store a value at
a time. If we try to access the value of another variable, the behavior will be undefined.
Example
#include <stdio.h>
96
int main() {
// Declare a union variable
union Student data;
// Assign and print the roll number
[Link] = 21;
printf("%d\n", [Link]);
[Link] = 5.2;
printf("%.2f\n", [Link]);
[Link] = 'N';
printf("%c", [Link]);
return 0;
}
Output
21
5.20
N
97
Example
#include <stdio.h>
struct Student {
char name[50];
int age;
float grade;
};
int main() {
// Create a structure variable
struct Student s1 = {"Geek", 20, 85.5};
// Access structure members address
printf("%u\n", [Link]);
printf("%u\n", [Link]);
printf("%.u\n", [Link]);
return 0;
}
#include <stdio.h>
union Data {
int i;
double d;
char c;
};
int main() {
98
// Create a union variable
union Data data;
// Store an integer in the union
data.i = 100;
data.d=12.9909;
data.c=’G’;
printf("%u\n", data.i);
printf("%u\n", data.d);
printf("%.u\n", data.c);
return 0;
}
0x00001025
0x00001025
0x00001025
99
16. Dynamic Memory Allocation
Dynamic memory allocation is a technique that allows programs to allocate memory during
runtime, rather than at compile time. This flexibility is crucial for handling data structures like
linked lists or arrays where the size is not known beforehand, or when memory needs to be
adjusted as the program runs. It involves using functions like malloc(), calloc(), realloc(),
and free() to request and release memory blocks..
Flexibility: Programs can allocate memory only when they need it, avoiding unnecessary
memory usage.
Efficiency: Memory can be optimized by allocating only as much as is required.
Handles Data Structures: Dynamic memory allocation is essential for implementing data
structures like linked lists, stacks, queues, and trees.
Memory Leaks:
Failing to free() allocated memory can lead to memory leaks, where the memory is no longer
accessible to the program but is also not released for other use.
Fragmentation:
Repeated allocation and deallocation can lead to memory fragmentation, where the heap is
broken up into small, non-contiguous blocks, making it difficult to find large blocks of
contiguous memory.
100
Reallocation:
realloc() allows you to resize an existing memory block, either increasing or decreasing its
size.
Deallocation:
free() releases the allocated memory back to the heap, making it available for other
programs to use.
101
// Dynamically allocated memory is deallocated
delete ptr1;
delete [] ptr2;
}
malloc()
Purpose: Allocates a block of memory of a specified size.
Syntax: void* malloc(size_t size);
Behavior:
Takes the size of the memory block (in bytes) as an argument.
Returns a pointer to the beginning of the allocated memory.
The memory is not initialized; it contains garbage values.
Returns NULL if allocation fails.
Use Case: Allocating memory for a single object or a block of data when initial values are
not critical.
Example
#include <stdlib.h>
int *ptr = (int *)malloc(10 * sizeof(int)); // Allocates space for 10 integers
calloc()
Purpose: Allocates a block of memory for an array and initializes it to zero.
Syntax: void* calloc(size_t num, size_t size);
Behavior:
Takes the number of elements and the size of each element as
arguments.
Returns a pointer to the beginning of the allocated memory.
The allocated memory is initialized with all bits set to zero.
Returns NULL if allocation fails.
Use Case: Allocating memory for arrays or structures where initialization to zero is required.
Example
102
#include <stdlib.h>
int *ptr = (int *)calloc(10, sizeof(int)); // Allocates space for 10 integers and initializes to 0
realloc()
Purpose: Resizes a previously allocated memory block.
Syntax: void* realloc(void* ptr, size_t size);
Behavior:
Takes a pointer to an allocated memory block and a new size as
arguments.
Attempts to resize the memory block pointed to by ptr.
If the new size is smaller, the memory block is truncated; if larger,
additional memory is allocated.
The contents of the original memory block are preserved up to the
smaller of the old and new sizes.
If ptr is NULL, it behaves like malloc().
Returns a pointer to the beginning of the resized memory (may be a
different address).
Returns NULL if resizing fails.
Use Case: Dynamically adjusting the size of an allocated memory block as needed.
Example
#include <stdlib.h>
int *ptr = (int *)malloc(5 * sizeof(int)); // Initial allocation
ptr = (int *)realloc(ptr, 10 * sizeof(int)); // Resizes to 10 integers
free()
Purpose: Releases previously allocated memory, making it available for reuse.
Syntax: void free(void* ptr);
Behavior:
Takes a pointer to the beginning of a dynamically allocated memory
block.
Deallocates the memory block.
The pointer ptr becomes invalid after calling free().
Does not return a value.
103
Use Case
Releasing memory when it is no longer needed to avoid memory leaks.
Example
#include <stdlib.h>
int *ptr = (int *)malloc(10 * sizeof(int));
free(ptr); // Deallocates the memory
#include <stdio.h>
#include <stdlib.h>
int main() {
int n, i, *ptr, sum = 0;
printf("Enter number of elements: ");
scanf("%d", &n);
ptr = (int*) malloc(n * sizeof(int));
// if memory cannot be allocated
if(ptr == NULL) {
printf("Error! memory not allocated.");
exit(0);
}
printf("Enter elements: ");
for(i = 0; i < n; ++i) {
scanf("%d", ptr + i);
sum += *(ptr + i);
}
printf("Sum = %d", sum);
// deallocating the memory
104
free(ptr);
return 0;
}
// Program to calculate the sum of n numbers entered by the user
#include <stdio.h>
#include <stdlib.h>
int main() {
int n, i, *ptr, sum = 0;
printf("Enter number of elements: ");
scanf("%d", &n);
ptr = (int*) calloc(n, sizeof(int));
if(ptr == NULL) {
printf("Error! memory not allocated.");
exit(0);
}
printf("Enter elements: ");
for(i = 0; i < n; ++i) {
scanf("%d", ptr + i);
sum += *(ptr + i);
} printf("Sum = %d", sum);
free(ptr);
return 0;
}
105
17. Handling Files
Files in C are essential for storing data persistently. They allow programs to read from and
write to external storage, enabling data to be preserved even after program termination.
Modes Description
r Searches file. If the file is opened successfully fopen( ) loads it into
memory and sets up a pointer that points to the first character in it.
If the file cannot be opened fopen( ) returns NULL.
rb Open for reading in binary mode. If the file does not exist, fopen(
) returns NULL.
w Open for writing in text mode. If the file exists, its contents are
overwritten. If the file doesn’t exist, a new file is created. Returns
NULL, if unable to open the file.
wb Open for writing in binary mode. If the file exists, its contents are
overwritten. If the file does not exist, it will be created.
a Searches file. If the file is opened successfully fopen( ) loads it into
memory and sets up a pointer that points to the last character in it.
It opens only in the append mode. If the file doesn’t exist, a new
file is created. Returns NULL, if unable to open the file.
106
ab Open for append in binary mode. Data is added to the end of the
file. If the file does not exist, it will be created.
r+ Searches file. It is opened successfully fopen( ) loads it into
memory and sets up a pointer that points to the first character in it.
Returns NULL, if unable to open the file.
w+ Searches file. If the file exists, its contents are overwritten. If the
file doesn’t exist a new file is created. Returns NULL, if unable to
open the file.
wb+ Open for both reading and writing in binary mode. If the file exists,
its contents are overwritten. If the file does not exist, it will be
created.
a+ Searches file. If the file is opened successfully fopen( ) loads it into
memory and sets up a pointer that points to the last character in it.
It opens the file in both reading and append mode. If the file doesn’t
exist, a new file is created. Returns NULL, if unable to open the
file.
ab+ Open for both reading and appending in binary mode. If the file
does not exist, it will be created.
#include <stdio.h>
#include <stdlib.h>
int main() {
// File pointer
FILE* fptr;
107
printf("The file is not opened.");
else
printf("The file is created Successfully.");
return 0;
}
Function Description
fprintf() Similar to printf(), this function uses formatted string and variable
arguments list to print output to the file
fputs() Prints the whole line in the file and a newline at the end.
fputc() Prints a single character into the file.
fputw() Prints a number to the file.
fwrite() This function writes the specified number of bytes to the binary file.
Example :
#include <stdio.h>
#include <stdlib.h>
int main() {
// File pointer
FILE* fptr;
108
// with access mode "w"
fptr = fopen("[Link]", "w");
Output :
The file is now opened
Data successfully written in file [Link]
The file is now closed
The file read operation in C can be performed using functions fscanf() or fgets(). Both the
functions performed the same operations as that of scanf() and gets but with an additional
parameter, the file pointer. There are also other functions we can use to read from a file. Such
functions are listed below
109
Function Description
fscanf() Use formatted string and variable arguments list to take input from a file.
fgets() Input the whole line from the file.
fgetc() Reads a single character from the file.
fgetw() Reads a number from a file.
fread() Reads the specified bytes of data from a binary file.
Example
#include <stdio.h>
#include <string.h>
int main() {
FILE* fptr;
// Declare the character array for the data to be read from file
char data[50];
fptr = fopen("[Link]", "r");
if (fptr == NULL) {
printf("[Link] file failed to open.");
}
else {
printf("The file is now opened.\n");
110
fclose(fptr);
}
return 0;
}
Output :
The fclose() function is used to close the file. After successful file operations, you must
always close a file to remove it from the memory.
Syntax:
Fclose(file_pointer);
Syntax:
where, pos is the position from where offset is counted and offset is the number of positions
to shift from pos (it can be negative or positive).
111
Example:
While writing to a file opened in rw+ mode, the file pointer moves to the end of the file. In
case where we want to replace a word, then first we have to move the file pointer to the
position where that word starts.
#include <stdio.h>
#include <stdlib.h>
int main() {
// File pointer
FILE* fptr;
fputs("Hello", fptr);
112
// Closing the file using fclose()
fclose(fptr);
printf("Data successfully written in file "
"[Link]\n");
printf("The file is now closed.");
}
return 0;
}
Output :
The file is now opened
Data successfully written in file [Link]
The file is now closed
113
File modes in C specify the type of operations allowed on an opened file, such as reading, writing, or appending data. These modes guide how the file is accessed or modified. For instance, 'r' opens a file for reading, while 'w' opens it for writing. The significance of file modes lies in their ability to dictate the interaction with files, ensuring the correct type of file access and preventing erroneous operations, such as editing a non-existent file .
The role of a for loop in a C program is to repeat a block of code a known number of times, providing an efficient way to automate repetitive tasks like summing a series of numbers. It consists of three parts: initialization, condition, and increment/decrement, which together control the loop's execution. The initialization sets up the loop variable, the condition tests whether the loop should continue, and the increment/decrement updates the loop variable. In the context of summing a series, the for loop iterates through each number, accumulating the sum in a variable until the condition is no longer met .
Arrays in C differ from individual variable declarations in that they allow the storage of multiple values of the same data type using a single identifier. Syntax-wise, arrays are declared with a type, a name, and a size, while variables are declared with just a type and a name. Usage-wise, arrays enable efficient management of collections of data, facilitating operations across all elements with indexed access, whereas variables represent single data items, limiting their use to single-value scenarios .
Defining a function in C involves specifying the function's return type, name, parameters, and body. The body contains statements that execute when the function is called. To call a function, you use its name followed by parentheses, optionally passing arguments. One advantage of using functions is improved code reusability; functions encapsulate specific tasks, which can be reused in different parts of a program or shared across different projects, reducing duplication .
Modularity, achieved through user-defined functions in C, is crucial because it breaks down a program into smaller, manageable chunks. This facilitates easier debugging, testing, and maintenance. Each function performs a specific task, making the code more readable and reducing redundancy. Functions enhance reusability, allowing the same code to be used multiple times in a program or across different projects, which streamlines development and ensures consistency .
File operations in C enhance data persistence by allowing programs to read from and write to external storage media, ensuring data is available even after the program terminates. The key operations involved in file handling include creating files, opening existing files, reading data from files, writing data to files, and closing files. These operations utilize a FILE pointer to interact with files, enabling efficient data management and long-term storage of program output or user input .
Pointers can be used to modify values in an array by directly accessing memory locations. By obtaining the address of an array element, a pointer can be used to change the value stored in that memory location. This approach has several advantages: it allows for more efficient memory usage as it avoids the need to copy data, facilitates the implementation of dynamic data structures, and enables complex operations like pointer arithmetic, which can lead to more concise and faster code execution .
In a for loop, initialization sets the starting point by establishing the initial value of the loop counter. The condition checks before each iteration to determine if the loop should continue, ensuring the loop executes only as long as the condition is true. Increment/decrement updates the loop counter after each iteration, moving the loop closer to termination. Together, these components control the iteration process, providing a structured way to repeat actions until a specific condition is met .
Arrays in C provide efficient data storage and access by storing elements in contiguous memory locations, which allows direct access to any element using its index. This contiguous memory allocation enhances performance by making access times predictable and fast. However, one trade-off is the fixed size of arrays; once declared, the size cannot be dynamically adjusted, which can lead to inefficient memory usage if the allocated array size is not fully utilized .
The return statement in C signifies the end of a function and can be used to return a value to the calling function. In the main function, return 0 typically indicates successful execution of the program. In other functions, the return statement is used to send a specific value back to the caller, enabling functions to produce output based on their logical operations. This facilitates data flow between functions and enhances modularity .