0% found this document useful (0 votes)
2 views

BCA I Sem - C Programming-1

Uploaded by

Vaidya Kshitij
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

BCA I Sem - C Programming-1

Uploaded by

Vaidya Kshitij
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 72

BCA SEMESTER I

PROBLEM-SOLVING TECHNIQUES
(UNIT - I, II, III)
BOOKS:
1.​ The Art of programming through flowcharts & algorithm by Anil B. Chaudhari Firewall Media,
Laxmi publication, New Publication.
2. Programming in C by E. Balagurusamy TMH Publications

INTRODUCTION
A computer program is a sequential set of instructions written in some computer language that is
used to direct the computer to perform some specific tasks of computation.

UNIT I
PROGRAMMING STRUCTURES

Introduction:
In any programming language, the logical structure of a program is vital for ensuring clarity and
functionality. The four fundamental programming structures are:

1.​ Sequence
2.​ Selection
3.​ Iteration
4.​ Modular

These structures allow a program to handle various tasks, make decisions, repeat operations, and
break down complex tasks into smaller parts. Let’s go over each concept in detail with examples.

1. Sequence:

Sequence is the most basic structure in programming, where instructions are executed one after the
other in a specific order. Every statement in the program runs in the order they appear unless a
control structure alters this flow.

Example:

printf("Step 1: Start the program"); // Executes first


printf("Step 2: Read data from the file"); // Executes second
printf("Step 3: Process the data"); // Executes third
printf("Step 4: Display the output"); // Executes fourth
2. Selection (Conditional Statements):

Selection allows programs to make decisions and choose different paths based on conditions. It is
implemented using if, else, and elif statements (in Python). This allows the program to execute a
block of code only if a certain condition is true.

Example:

temperature = 30
if(temperature > 25)
printf("It's a hot day!");
else
printf("It's a cool day!");

3. Iteration (Looping):

Iteration allows a program to repeat a block of code multiple times until a specific condition is met.
Common looping structures include for loops and while loops.

for Loop Example:

for(i=1; i <= 5; i++)


printf("This is iteration number", i);

Loop Control Statements:

1.​ break: Terminates the loop prematurely.


2.​ continue: Skips the rest of the code inside the loop for the current iteration and jumps to the
next iteration.

4. Modular (Functions):

Modular programming is a way of organizing programs into smaller, manageable, and reusable
blocks of code known as functions or modules. Each function performs a specific task and can be
called upon when needed.
Function Example:

void greet_user(name) {
printf("Hello, %s", name)
}
greet_user("Alice");
greet_user("Bob");
Advantages of Modular Programming:
●​ Reusability: Functions can be reused in different parts of the program.
●​ Maintainability: Breaking the code into smaller parts makes it easier to maintain.
●​ Debugging: It simplifies debugging as you can test individual functions separately.

INTRODUCTION TO DEVELOPMENT TOOLS

When starting to program, we need a clear way to plan and organize our thoughts before writing
actual code. This is where development tools come into play. Three common tools used for planning
a program are:
●​ Pseudocode
●​ Flowcharts
●​ Algorithms

These tools help us design the structure of a program logically and systematically.

1. Pseudocode

Definition:
Pseudocode is a simple way to describe a program’s logic without using a specific programming
language. It uses plain, everyday language or a mix of English and common programming
constructs like loops or conditionals.

Characteristics of Pseudocode:

●​ Language-friendly: It doesn't follow any syntax rules of a programming language. It's easy
to understand for anyone, regardless of their technical knowledge.
●​ Easy to write and read: Focuses on the logic and steps rather than precise syntax.
●​ Helps transition to actual code: Developers can use pseudocode as a stepping stone to
writing code in any programming language.
●​ No strict formatting: Unlike code, pseudocode is flexible in formatting, as its main purpose
is clarity.
Example of Pseudocode:

START
INPUT two numbers (A and B)
IF A > B THEN
​ PRINT "A is greater than B"
ELSE
​ PRINT "B is greater than or equal to A"
ENDIF
END
Advantages:
●​ Clarifies thinking before coding.
●​ Provides a high-level view of the solution without worrying about syntax.

2. Flowcharts

Definition:
A flowchart is a visual diagram that represents the flow of a program or process. It uses different
symbols to represent different types of actions or decisions in a program.

Characteristics of Flowcharts:
●​ Visual representation: Uses shapes like rectangles, diamonds, and arrows to represent
processes, decisions, and the flow of control.
●​ Structured and clear: Helps illustrate complex processes in an easy-to-understand way.
●​ Widely used in problem-solving: Helps identify logical errors or inefficiencies in the
process early.

Common Flowchart Symbols:


Example of a Flowchart:

Advantages:
●​ Visual clarity: Flowcharts make it easy to see how different parts of a program are
connected.
●​ Detects issues early: Helps in identifying errors or logical gaps before coding begins.

3. Algorithms

Definition:
An algorithm is a step-by-step procedure or formula for solving a problem. In programming,
algorithms define how a program processes data to achieve a desired outcome.
Characteristics of Algorithms:
1.​ Finite: An algorithm must terminate after a finite number of steps.
2.​ Definite: Each step must be clearly defined without any ambiguity.
3.​ Input: The algorithm should take some input.
4.​ Output: It should produce at least one output.
5.​ Effectiveness: Every step of the algorithm should be basic enough to be performed, even by
hand.
6.​ Language-independent: Algorithms are not tied to any specific programming language.

Example of an Algorithm:

Problem: Find the Average of given numbers


Step-by-step Algorithm:
Step 1. INPUT TO A, B
Step 2. S ← A + B (Get sum of the values A & B and store in S)
Step 3. AVG ← S / 2 (Compute the average)
Step 4. PRINT AVG (Show the average)
Step 5. STOP
Advantages:
●​ Structured approach: Algorithms ensure the problem is solved systematically.
●​ Foundation of programming: They form the basis for writing efficient and correct programs.

Problem 2: Construct a flowchart to show how to obtain the volume of a rectangular box
Problem: Draw a flowchart to find the greatest among three numbers.

Step 1. INPUT TO A, B, C
Step 2. IF A > B
IF B > C
THEN PRINT B “is greater”
ELSE
PRINT C “is greater”
END-IF
ELSE
​ IF A > C
​ ​ THEN PRINT A “is greater”
​ ELSE
​ ​ PRINT “C is greater”
​ END-IF
END-IF
Step 3: STOP

Problem: Write an algorithm to find the smallest of three numbers.


Problem: Write an algorithm and flowchart to sum of given numbers;

Problem: Write an algorithm for the summation of 20 even numbers.


Problem: Write an algorithm to find the sum of even numbers from 1 to 100.
Problem: Write an algorithm to find the factorial of a number.
Problem: Write an algorithm for finding whether a number is a prime number.
Problem: Write an algorithm to find whether a given year is leap year or not.
UNIT II
C PROGRAMMING LANGUAGE

Sample Program

main()
{
/* printing begins */
printf(“Hello World!”);
/* printing begins */
}

C CHARACTER SET

The characters that can be used to form words, numbers and expressions depend upon the
computer on which the program is run. The characters in C are grouped into the following
categories:

1. Letters
2. Digits
3. Special characters
4. White spaces

The entire character set is given in the below table.

Letters Digits

Uppercase: A…Z All decimal digits: 0 … 9


Lowercase: a…z

Special Characters
& ampersand
, comma ^ caret
. period * asterisk
; semicolon - minus sign
: colon + plus sign
? question mark < opening angle bracket (or less than sign)
' apostrophe > closing angle bracket (or greater than sign)
" quotation mark ( left parenthesis
! exclamation mark ) right parenthesis
| vertical bar [ left bracket
/ slash ] right bracket
\ backslash { left brace
~ tilde } right brace
_ underscore # number sign
$ dollar sign
% percent sign

White Spaces

Blank space
Horizontal tab
Carriage return
New line
Form feed

C TOKENS

In a passage of text, individual words and punctuation marks are called tokens. Similarly, in a C
program, the smallest individual units are known as C tokens. C has six types of tokens as shown in
below figure. C programs are written using these tokens and the syntax of the language.

KEYWORDS

Every C word is classified as either a keyword or an identifier. All keywords have fixed meanings
and these meanings cannot be changed. Keywords serve as basic building blocks for program
statements. The list of all keywords of ANSI C are listed in below table. All keywords must be written
in lowercase.
auto break case char
const continue default do
double else enum extern
float for goto if
int long register return
short signed sizeof static
struct switch typedef union
unsigned void volatile while

IDENTIFIER

Identifiers refer to the names of variables, functions and arrays. These are user-defined names and
consist of a sequence of letters and digits, with a letter as a first character.
Both uppercase and lowercase letters are permitted. The underscore character is also permitted in
identifiers. It is usually used as a link between two words in long identifiers.

Rules for Identifier


1.​ The first character must be an alphabet (or underscore).
2.​ Must consist of only letters, digits or underscore.
3.​ Only the first 31 characters are significant.
4.​ Cannot use a keyword.
5.​ Must not contain white space.

VARIABLES

A variable is a data name that may be used to store a data value. A variable may take different
values at different times during execution.

A variable name can be chosen by the programmer in a meaningful way so as to reflect its function
or nature in the program.

Some examples of such names are:


​ Average
height
Total
Counter_1
class strength
Variable names may consist of letters, digits, and the underscore(_) character, subject to the
following conditions:

1. They must begin with a letter.


2. It should not have more than 31 characters.
3. Uppercase and lowercase are different. So total and TOTAL is different.
4. It should not be a keyword.
5. White space is not allowed.

DATA TYPES

Data types are the foundation of any programming language, and in C, they allow you to define the
type of data you’re working with. They help the compiler understand the size and format of data
stored in variables.

C supports three classes of data types:

1. Primary (or fundamental) data types


2. Derived data types
3. User-defined data types

1. Primary (or Fundamental) Data Types

The basic data types in C are used to store simple values, such as integers and characters. They
include:
1.​ integer (int),
2.​ floating point (float),
3.​ double-precision floating point (double)
4.​ character (char),
5.​ void.

Many of them also offer extended data types such as long int and long double.

Data Type Description

int Integer values

float Single-precision floating-point

double Double-precision floating-point


char Single characters

void

Data Type Typical Range Size (bits)

int -32,768 to 32,767 16

float 3.4E-38 to 3.4E+38 32

double 1.7E-308 to 1.7E+308 64


Table: Range Of Basic Data Types in 16 Bit Machines

1.1. Integer Types


●​ Used for whole numbers (like 5, -3).
●​ Size: Typically 2 or 4 bytes, depending on the system.
●​ Example: int age = 21;
We declare long and unsigned integers to increase the range of values

Example:
long int total;
unsigned int marks;

1.2. Floating Point Types

●​ Used for decimal numbers (like 3.14).


●​ Size: 4 bytes, accurate up to 6 decimal places.
●​ Example: float price = 10.99;

1.3. Double-Precision Floating Point

●​ Used when higher precision is needed (like 3.141592).


●​ Size: 8 bytes, accurate up to 15 decimal places.
●​ Example: double pi = 3.1415926535;

1.4. Character Types

●​ Stores single characters (like 'A' or 'z').


●​ Size: 1 byte.
●​ char grade = 'A';
1.5. Void Types

●​ Represents no data; often used in functions that do not return a value.


●​ Example: void greet() { printf("Hello!"); }

2. User-Defined Type Declaration

In C programming, user-defined data types are types created by the programmer, building on C’s
basic types.
These types allow for more complex data structures to be represented within a program. The main
user-defined data types in C are:

typedef
●​ Simplifies complex data types by giving them custom names, making code more readable.
●​ Use typedef to create an alias for existing data types, so you can use shorter names.

Example:
typedef unsigned long int ULI;
ULI number = 1000000;

QUALIFIERS

Qualifiers in C modify the behavior or storage of a variable. They don’t change the data type
itself but instead add certain characteristics. The main qualifiers are:

1. const

●​ Declares a variable as constant, meaning its value cannot be changed after


initialization.
●​ Example: const int maxSize = 100; maxSize = 200;
2. volatile

●​ Tells the compiler that the value of a variable may change at any time.
●​ Example: volatile int sensorValue;
OPERATORS AND EXPRESSIONS

OPERATORS

Operators are symbols that perform operations on variables and values. In C, operators are
grouped into several categories:

1. Arithmetic Operators: Perform basic math operations:


●​ + (Addition)
●​ - (Subtraction)
●​ * (Multiplication)
●​ / (Division)
●​ % (Modulus – gives the remainder

Examples:
​ ​ int a = 10, b = 3;
​ ​ int sum = a + b; // Addition: 13
int diff = a - b; // Subtraction: 7
int prod = a * b; // Multiplication: 30
int quot = a / b; // Division: 3
int rem = a % b; // Modulus: 1

2. Relational Operators: Compare two values and return a Boolean result:


●​ == (Equal to)
●​ != (Not equal to)
●​ > (Greater than)
●​ < (Less than)
●​ >= (Greater than or equal to)
●​ <= (Less than or equal to)

Examples:
​ ​ int x = 5, y = 8;
int isEqual = (x == y); // Equal to: 0 (false)
int isNotEqual = (x != y;// Not equal to: 1 (true)
int isGreater = (x > y);// Greater than: 0 (false)
int isLess = (x < y);// Less than: 1 (true)
int isGreaterEqual = (x >= y);// Greater than or equal to: 0
(false)
int isLessEqual = (x <= y); // Less than or equal to: 1 (true)
3. Logical Operators: Used to combine multiple conditions:
●​ && (Logical AND)
●​ || (Logical OR)
●​ ! (Logical NOT)

Examples:
​ ​ int p = 1, q = 0;
​ ​ int andResult = (p && q); // Logical AND: 0(false)
​ ​ int orResult = (p || q); // Logical OR: 1 (true)
​ ​ int notResult = (!p); // Logical NOT: 0 (false)

4. Assignment Operators: Assign values to variables:


●​ = (Simple assignment)
●​ += (Add and assign)
●​ -= (Subtract and assign)
●​ *= (Multiply and assign)
●​ /= (Divide and assign)
●​ %= (Modulus and assign)

Examples:
​ ​ int a = 5;
​ ​ a += 3; // Add and assign: a = 8
​ ​ a -= 2; // Subtract and assign: a = 6
​ ​ a *= 4; // Multiply and assign: a = 24
​ ​ a /= 6; // Divide and assign: a = 4
​ ​ a %= 3; // Modulus and assign: a = 1

5. Increment and Decrement Operators: Increase or decrease the value of a variable by 1:


●​ ++ (Increment)
●​ -- (Decrement)
Examples:
​ ​ int num = 7;
​ ​ num++; // Increment: num becomes 8
​ ​ num--; // Decrement: num becomes 7

Pre-Increment ++num;
Post-Increment: num++

6. Bitwise Operators: Perform bit-level operations:


●​ & (Bitwise AND)
●​ | (Bitwise OR)
●​ ^ (Bitwise XOR)
●​ ~ (Bitwise NOT)
●​ << (Left shift)
●​ >> (Right shift)

Examples:
​ int m = 5, n = 3; // In binary: m = 0101, n = 0011
​ int andOp = m & n; // Bitwise AND: 0001 (1 in decimal)
​ int orOp = m | n; // Bitwise OR: 0111 (7 in decimal)
​ int xorOp = m ^ n; // Bitwise XOR: 0110 (6 in decimal)
int notOp = ~m; // Bitwise NOT: 1010 (-6 in decimal for 2's complement)
int leftShift = m << 1; // Left shift: 1010 (10 in decimal)
int rightShift = m >> 1; // Right shift: 0010 (2 in decimal)

EXPRESSIONS

An expression is a combination of variables, constants, and operators that produces a value. For
example:
​ int a = 10, b = 5;
int sum = a + b; // sum is an expression
int result = (a * b) + (a - b); // complex expression

CONSTANTS

In C programming, constants are fixed values that cannot be altered by the program during
execution. They are classified into various types, including numeric constants and character
constants.
1. Numeric Constants
Numeric constants represent numbers that remain constant throughout the program. They are
further divided into two categories:

i. Integer Constants
Integer constants are whole numbers without any fractional part or decimal point.

Rules for Integer Constants:


●​ Must contain at least one digit (0–9).
●​ Should not contain a decimal point.
●​ Can be written in decimal, octal, or hexadecimal format.
●​ Can have a sign (+ or -), but it is optional.
●​ Range depends on the data type (e.g., int, long).

Types of Integer Constants:


1.​ Decimal Constants: Numbers in base-10 (e.g., 123, -45).
2.​ Octal Constants: Numbers prefixed with 0 (e.g., 012 represents 10 in decimal).
3.​ Hexadecimal Constants: Numbers prefixed with 0x or 0X (e.g., 0xA represents 10 in
decimal).

#include <stdio.h>

int main() {
int decimal = 100; // Decimal constant
int octal = 012; // Octal constant (12 in octal is 10 in
decimal)
int hexadecimal = 0x1A; // Hexadecimal constant (1A in hexadecimal is
26 in decimal)

printf("Decimal: %d\n", decimal);


printf("Octal: %d\n", octal);
printf("Hexadecimal: %d\n", hexadecimal);

return 0;
}

ii. Real Constants


Real constants represent numbers with fractional parts. They are also known as floating-point
constants.

Rules for Real Constants:

●​ Must include at least one digit.


●​ Must have a decimal point.
●​ Can include an exponent part (scientific notation using e or E).
Types of Real Constants:
1.​ Fixed-Point Notation: Numbers with a simple decimal (e.g., 3.14, -0.567).
2.​ Scientific Notation: Numbers with an exponent part (e.g., 1.2e3 represents 1.2 × 10³).

Examples:

#include <stdio.h>

int main() {
float pi = 3.14; // Fixed-point notation
double large = 2.5e6; // Scientific notation (2.5 × 10^6)

printf("Pi: %.2f\n", pi);


printf("Large: %.2e\n", large);

return 0;
}

2. Character Constants

Character constants represent single characters or sequences of characters enclosed in quotes.


These constants are categorized into single character constants and string constants.

i. Single Character Constants


A single character constant contains exactly one character enclosed in single quotes (' ').

Rules for Single Character Constants:


●​ Enclosed in single quotes.
●​ Represent a single ASCII character.
●​ Internally, it is stored as an integer (ASCII value).

Examples of Single Character Constants:

#include <stdio.h>

int main() {
char letter = 'A'; // Single character constant
char digit = '5'; // Single digit constant
char special = '$'; // Special character constant
printf("Letter: %c\n", letter);
printf("Digit: %c\n", digit);
printf("Special: %c\n", special);

// ASCII value of 'A'


printf("ASCII value of %c: %d\n", letter, letter);

return 0;
}

ii. String Constants

String constants are sequences of characters enclosed in double quotes (" ").

Rules for String Constants:


●​ Enclosed in double quotes.
●​ Can include multiple characters, spaces, or escape sequences.
●​ Stored as a null-terminated array of characters (ends with \0).

Examples of String Constants:

#include <stdio.h>

int main() {
char name[] = "John Doe"; // String constant
char greeting[] = "Hello, World!";

printf("Name: %s\n", name);


printf("Greeting: %s\n", greeting);

return 0;
}

Escape Sequences in Character Constants


Escape sequences represent special characters using a backslash (\). Examples include:

Escape Sequence Meaning


\n Newline
\t Horizontal Tab
\\ Backslash
\' Single Quote
\" Double Quote
Escape Sequence Meaning
\a Audible alert (bell)
\b Back space
\? Question mark
\0 null

#include <stdio.h>

int main() {
printf("Hello\nWorld!\tTabbed\n");
printf("Path: C:\\Program Files\\MyApp\n");

return 0;
}

DECLARING SYMBOLIC CONSTANTS IN C

In C programming, symbolic constants are identifiers that represent constant values. Symbolic
constants are defined with meaningful names, improving code readability and maintainability. Once
defined, their values cannot be altered throughout the program.

Why Use Symbolic Constants?

●​ Readability: Descriptive names make the code easier to understand.


●​ Maintainability: Changing a constant's value only requires modifying it in one place.
●​ Avoids Errors: Prevents accidental modification of fixed values.

Methods for Declaring Symbolic Constants

C provides two primary ways to define symbolic constants:


1.​ Using the #define Preprocessor Directive
2.​ Using the const Keyword

1. Using #define Preprocessor Directive


The #define directive is used to define symbolic constants at the preprocessor level. It replaces
occurrences of the constant's name with its value during compilation.
Syntax
#define CONSTANT_NAME value

Features of #define:
●​ No memory is allocated.
●​ Can define both numbers and strings.
●​ Typically written in uppercase for clarity.
●​ Does not terminate with a semicolon.

Example 1: Numeric Constant


#include <stdio.h>
#define PI 3.14159 // Define a symbolic constant for Pi

int main() {
float radius = 5.0;
float area = PI * radius * radius;

printf("Area of the circle: %.2f\n", area);

return 0;
}

Example 2: String Constant


#include <stdio.h>

#define GREETING "Hello, World!" // Define a symbolic constant for a string

int main() {
printf("%s\n", GREETING);

return 0;
}

Advantages of #define:
●​ No additional memory usage.
●​ Ideal for defining global constants.

Limitations of #define:
●​ No type checking (e.g., treating numbers as integers or floats).
●​ Difficult to debug if errors occur in preprocessor substitution.
2. Using const Keyword

The const keyword allows you to declare typed constants. These are variables whose values cannot
be modified after initialization.

Syntax
const data_type variable_name = value;

Features of const:
●​ Provides type safety (e.g., distinguishing between int and float).
●​ Allows memory allocation, enabling pointer and scope usage.
●​ Can be local or global.

Example 1: Numeric Constant


#include <stdio.h>

int main() {
const float GRAVITY = 9.8; // Define a constant using const
float weight = 75.0; // Mass in kg
float force = weight * GRAVITY;

printf("Force: %.2f N\n", force);

return 0;
}

Example 2: String Constant


#include <stdio.h>

int main() {
const char MESSAGE[] = "Welcome to C Programming!"; // String constant

printf("%s\n", MESSAGE);

return 0;
}

Advantages of const:
●​ Enforces type checking, reducing errors.
●​ Scopes can be limited (local or global).

Limitations of const:
●​ Uses memory (unlike #define).

Best Practices for Using Symbolic Constants


1.​ Use Uppercase Names: It is conventional to write symbolic constant names in uppercase,
e.g., MAX_SIZE, to differentiate them from variables.
2.​ Prefer const for Typed Constants: Use const when type safety or memory allocation is
required.
3.​ Limit #define to Global Constants: Use #define for global and frequently reused constants
to avoid memory allocation.

ENUMERATED DATA TYPES IN C

In C, the enumerated data type (enum) is a user-defined data type that assigns names to integral
constants. It is used to represent a set of related constants, making code more readable and easier
to manage.

Why Use Enumerated Data Types?


1.​ Improves Code Readability: Use meaningful names instead of numbers.
2.​ Groups Related Constants: Logical grouping of constants simplifies management.
3.​ Enhances Type Safety: Ensures the variable can only hold predefined constant values.

Declaring Enumerated Data Types


The enum keyword is used to declare an enumerated type.

enum EnumName {
CONSTANT1,
CONSTANT2,
CONSTANT3,
...
};

Example:
#include <stdio.h>

// Declare an enumeration
enum Color {
RED, // 0
GREEN, // 1
BLUE // 2
};

int main() {
enum Color myColor = GREEN; // Assign the constant GREEN
printf("My color value: %d\n", myColor); // Output: 1
return 0;
}
Specifying Values for Constants
You can assign specific integer values to constants. Constants without assigned values increment
from the last specified value.

#include <stdio.h>

enum Weekday {
MONDAY = 1, // Start from 1
TUESDAY, // 2 (incremented automatically)
WEDNESDAY = 5, // Set specific value
THURSDAY, // 6 (incremented automatically)
FRIDAY // 7
};

int main() {
printf("Monday: %d\n", MONDAY); // Output: 1
printf("Wednesday: %d\n", WEDNESDAY); // Output: 5
printf("Friday: %d\n", FRIDAY); // Output: 7

return 0;
}

OPERATOR PRECEDENCE AND ASSOCIATIVITY

Operator precedence and associativity determine how expressions are evaluated. This is essential
for understanding the behavior of complex expressions involving multiple operators.

What is Operator Precedence?


Operator precedence defines the order in which operators are evaluated in an expression. For
instance, in the expression:

int result = 10 + 5 * 2;

The multiplication (*) operator has higher precedence than addition (+), so 5 * 2 is evaluated first,
and then 10 + 10 is computed.

What is Operator Associativity?


When two or more operators of the same precedence appear in an expression, associativity
determines the order of evaluation. Associativity can either be:

●​ Left-to-right (e.g., +, -, *, /)
●​ Right-to-left (e.g., assignment operators like =, +=, and -=)

How Precedence and Associativity Work


Example 1: Precedence

#include <stdio.h>

int main() {
int x = 5, y = 10, z = 20;
int result = x + y * z; // Multiplication (*) has higher precedence than
addition (+).
printf("Result: %d\n", result); // Output: 205
return 0;
}

Example 2: Associativity
#include <stdio.h>

int main() {
int a = 10, b = 20, c = 30;
int result = a = b = c; // Assignment (=) is right-to-left associative.
printf("Result: a=%d, b=%d, c=%d\n", a, b, c); // Output: a=30, b=30,
c=30
return 0;
}

LIBRARY FUNCTIONS: MATHEMATICS IN C

The C programming language provides a comprehensive set of mathematical functions to perform


common mathematical operations. These functions are defined in the <math.h> header file and
allow developers to perform calculations such as square roots, trigonometric operations, logarithmic
operations, and more.

Including the <math.h> Library


To use the mathematical functions in your program, include the <math.h> header at the beginning of
your program:

#include <math.h>
List of Common Math Functions in <math.h>
Function Description Syntax
abs() Returns the absolute value of an integer int abs(int x)

fabs() Returns the absolute value of a float/double double fabs(double x)

ceil() Rounds up to the nearest integer double ceil(double x)

floor() Rounds down to the nearest integer double floor(double x)

sqrt() Returns the square root of a number double sqrt(double x)

pow() Returns a number raised to a power double pow(double base,


double exp)

log() Returns the natural logarithm (base e) double log(double x)

log10() Returns the logarithm (base 10) double log10(double x)

exp() Returns the value of e raised to a power double exp(double x)

sin() Returns the sine of an angle in radians double sin(double x)

cos() Returns the cosine of an angle in radians double cos(double x)

tan() Returns the tangent of an angle in radians double tan(double x)

asin() Returns the arcsine of a value in radians double asin(double x)

acos() Returns the arccosine of a value in radians double acos(double x)

atan() Returns the arctangent of a value in radians double atan(double x)

atan2() Returns the arctangent of y/x in radians double atan2(double y,


double x)

Example 1: Calculating the Square Root


#include <stdio.h>
#include <math.h>

int main() {
double number = 16.0;
double result = sqrt(number);

printf("Square root of %.2f is %.2f\n", number, result); // Output: 4.00

double base = 2.0, exponent = 3.0;


double result = pow(base, exponent);

printf("%.2f raised to the power of %.2f is %.2f\n", base, exponent,


result); // Output: 8.00
return 0;
}
Mathematical Constants in <math.h>
Constant Description Value

M_PI The value of π 3.141592653589793

M_E The value of e (Euler’s number) 2.718281828459045

LIBRARY FUNCTIONS: STRING HANDLING FUNCTIONS IN C

The C programming language provides a variety of string-handling functions through the <string.h>
header file. These functions are used to manipulate and process strings, such as copying,
concatenating, comparing, and finding the length of strings.

What is a String in C?

In C, a string is an array of characters terminated by a null character \0. For example:

char str[] = "Hello"; // A string


char str[6] = {'H', 'e', 'l', 'l', 'o', '\0'}; // Equivalent way

Including the <string.h> Library

Include the <string.h> header at the beginning of your program to access string-handling functions:

#include <string.h>

Common String-Handling Functions

Function Description Syntax

strlen() Returns the length of a string size_t strlen(const char


*str)

strcpy() Copies one string into another char *strcpy(char *dest,


const char *src)
strncpy() Copies up to n characters from one string char *strncpy(char *dest,
to another const char *src, size_t n)

strcat() Concatenates two strings char *strcat(char *dest,


const char *src)

strncat() Concatenates up to n characters of one char *strncat(char *dest,


string to another const char *src, size_t n)

strcmp() Compares two strings int strcmp(const char


*str1, const char *str2)

strncmp() Compares up to n characters of two strings int strncmp(const char


*str1, const char *str2,
size_t n)

strstr() Finds the first occurrence of a substring in char *strstr(const char


a string *haystack, const char
*needle)

Example: Finding the Length of a String (strlen)

#include <stdio.h>
#include <string.h>

int main() {
char str[] = "Hello, World!";
printf("Length of the string: %zu\n", strlen(str)); // Output: 13
return 0;
}

Example: Copying Strings (strcpy and strncpy)


#include <stdio.h>
#include <string.h>

int main() {
char src[] = "Hello, C!";
char dest[20];

strcpy(dest, src); // Copy the entire string


printf("Copied string: %s\n", dest); // Output: Hello, C!

strncpy(dest, src, 5); // Copy the first 5 characters


dest[5] = '\0'; // Add null terminator
printf("Partial copy: %s\n", dest); // Output: Hello

return 0;
}
Example: Concatenating Strings (strcat and strncat)
#include <stdio.h>
#include <string.h>

int main() {
char str1[20] = "Hello, ";
char str2[] = "World!";

strcat(str1, str2); // Concatenate str2 to str1


printf("Concatenated string: %s\n", str1); // Output: Hello, World!

strncat(str1, " C Programming", 2); // Add first 2 chars of another


string
printf("Partial concatenation: %s\n", str1); // Output: Hello, World! C

return 0;
}

Example: Comparing Strings (strcmp and strncmp)


#include <stdio.h>
#include <string.h>

int main() {
char str1[] = "Apple";
char str2[] = "Banana";

int result = strcmp(str1, str2); // Compare the entire strings


if (result < 0)
printf("str1 is less than str2\n"); // Output
else if (result > 0)
printf("str1 is greater than str2\n");
else
printf("str1 is equal to str2\n");

result = strncmp(str1, str2, 3); // Compare first 3 characters


printf("Comparison of first 3 characters: %d\n", result);

return 0;
}

Example: Finding Substrings (strstr)


#include <stdio.h>
#include <string.h>

int main() {
char str[] = "Learning C is fun!";
char *ptr = strstr(str, "C");
if (ptr)
printf("Substring found: %s\n", ptr); // Output: C is fun!
else
printf("Substring not found\n");

return 0;
}

COMPOUND STATEMENTS

A compound statement in C programming, also known as a block, is a way to group multiple


statements together so they are treated as a single unit. Compound statements are fundamental in
writing control structures like loops and conditional statements.

What is a Compound Statement?


In C, a compound statement is a collection of one or more individual statements enclosed within
curly braces {}. These statements are executed sequentially.

The use of compound statements is essential when you need to execute multiple instructions where
only one is allowed syntactically, such as within an if statement, for loop, or while loop.

Syntax
{
statement1;
statement2;
...
statementN;
}

Why Use Compound Statements?


●​ Grouping Statements: Allows multiple operations to be executed in situations where only
one is expected.
●​ Readability: Improves clarity and maintains logical grouping of related operations.
●​ Flexibility: Used within control structures to define a block of code that should execute
together.

Scoping in Compound Statements


Variables declared inside a compound statement are local to that block and are not accessible
outside it.
#include <stdio.h>

int main()
{
int a = 5;

printf("Value of a: %d\n", a);

{
int b = 10;
printf("Value of b: %d", b);
}

// printf("Value of b: %d", b); // Error: b is not defined here

return 0;
}

SELECTION STATEMENTS IN C

fSelection statements in C control the flow of execution based on certain conditions. These
conditions evaluate to either true (non-zero) or false (zero).

1. if Statement
The if statement executes a block of code only if a specified condition is true.

Syntax:
if (condition) {
// Block of code to execute if the condition is true
}

Example:
#include <stdio.h>

int main() {
int number = 10;

if (number > 0) {
printf("The number is positive.\n");
}

return 0;
}
2. if-else Statement
The if-else statement provides an alternative block of code if the condition evaluates to false.

Syntax:
if (condition) {
// Block of code to execute if the condition is true
} else {
// Block of code to execute if the condition is false
}

Example:
#include <stdio.h>

int main() {
int number = -5;

if (number >= 0) {
printf("The number is non-negative.\n");
} else {
printf("The number is negative.\n");
}

return 0;
}

Example:
#include <stdio.h>

int main() {
int age = 25;
int hasLicense = 1; // 1 = true, 0 = false

if (age >= 18 && hasLicense) {


printf("You are eligible to drive.\n");
} else {
printf("You are not eligible to drive.\n");
}

return 0;
}

3. Nested if
if else if ladder in C programming is used to test a series of conditions sequentially.
Furthermore, if a condition is tested only when all previous if conditions in the if-else ladder are
false. If any of the conditional expressions are evaluated to be true, the appropriate code block will
be executed, and the entire if-else ladder will be terminated.

Syntax:
if (condition1) {
if (condition2) {
// Block of code if both condition1 and condition2 are true
}
}

Example:
#include <stdio.h>

int main() {
int age = 20;
int hasID = 1; // 1 means true, 0 means false

if (age >= 18) {


if (hasID) {
printf("You are allowed to enter.\n");
} else {
printf("You need an ID to enter.\n");
}
} else {
printf("You are not old enough to enter.\n");
}

return 0;
}

Example: Grading System


#include <stdio.h>

int main() {
int marks;

printf("Enter your marks: ");


scanf("%d", &marks);

if (marks >= 90) {


printf("Grade: A\n");
} else if (marks >= 80 && marks < 90) {
printf("Grade: B\n");
} else if (marks >= 70 && marks < 80) {
printf("Grade: C\n");
} else if (marks >= 60 && marks < 70) {
printf("Grade: D\n");
} else {
printf("Grade: F\n");
}

return 0;
}

4. switch Statement
The switch statement allows you to test a variable against multiple values (cases) and execute the
corresponding block of code.

In C, the switch case statement is used for executing one condition from multiple conditions. It is
similar to an if-else-if ladder.

Syntax:
switch (expression) {
case value1:
// Block of code for value1
break;
case value2:
// Block of code for value2
break;
...
default:
// Block of code if no case matches
}

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;
case 4:
printf("Thursday\n");
break;
case 5:
printf("Friday\n");
break;
default:
printf("Invalid day\n");
}
return 0;
}

Example:
#include <stdio.h>

int main() {
int grade = 2;

switch (grade) {
case 1:
case 2:
case 3:
printf("You are in primary school.\n");
break;
case 4:
case 5:
printf("You are in middle school.\n");
break;
default:
printf("Invalid grade.\n");
}

return 0;
}

ITERATION STATEMENTS IN C
Iteration statements in C, also known as loops, are used to execute a block of code repeatedly as
long as a specified condition is true. C provides three main types of loops:

●​ for loop
●​ while loop
●​ do-while loop

Each loop serves a distinct purpose and is chosen based on the specific requirement of the
program. Let's explore each of these in detail.
1. for Loop

The for loop is used when the number of iterations is known beforehand. It is commonly used for
counting iterations.

Syntax:

for (initialization; condition; increment/decrement) {


// Body of the loop
}

Components:

1.​ Initialization: Initializes a loop control variable.


2.​ Condition: The loop continues as long as this evaluates to true.
3.​ Increment/Decrement: Updates the loop control variable after each iteration.

Example:

#include <stdio.h>

int main() {
for (int i = 1; i <= 5; i++) {
printf("Iteration %d\n", i);
}
return 0;
}

Output:
Iteration 1
Iteration 2
Iteration 3
Iteration 4
Iteration 5

2. while Loop

The while loop is used when the number of iterations is not known in advance and depends on a
condition being true.

Syntax:

while (condition) {
// Body of the loop
}

How It Works:

●​ The condition is evaluated before entering the loop body.


●​ If the condition is true, the body of the loop executes.
●​ The condition is checked again after each iteration.
●​ The loop exits when the condition becomes false.

Example:

#include <stdio.h>

int main() {
int count = 1;
while (count <= 5) {
printf("Count: %d\n", count);
count++;
}
return 0;
}

Output:
Count: 1
Count: 2
Count: 3
Count: 4
Count: 5

3. do-while Loop

The do-while loop is similar to the while loop, but it guarantees that the loop body executes at least
once because the condition is evaluated after the loop body.

Syntax:

do {
// Body of the loop
} while (condition);
Example:

#include <stdio.h>

int main() {
int num = 1;
do {
printf("Number: %d\n", num);
num++;
} while (num <= 5);
return 0;
}

Output:
Number: 1
Number: 2
Number: 3
Number: 4
Number: 5

4. Infinite Loops

An infinite loop runs indefinitely because the terminating condition is never met. They are commonly
used in event-driven programs or where the program needs to wait for user input.

Example:
#include <stdio.h>

int main() {
while (1) {
printf("This will run forever. Press Ctrl+C to stop.\n");
}
return 0;
}
5. Controlling Loops

break Statement:

The break statement is used to terminate the loop immediately and transfer control to the
statement following the loop.

Example:

#include <stdio.h>

int main() {
for (int i = 1; i <= 10; i++) {
if (i == 5) {
break;
}
printf("%d\n", i);
}
return 0;
}

Output:
1
2
3
4

continue Statement:

The continue statement skips the current iteration of the loop and moves to the next iteration.

Example:

#include <stdio.h>

int main() {
for (int i = 1; i <= 5; i++) {
if (i == 3) {
continue;
}
printf("%d\n", i);
}
return 0;
}
Output:
1
2
4
5

6. Nested Loops

Loops can be nested, meaning one loop inside another. This is often used for working with
multidimensional data like matrices.

Example:

#include <stdio.h>

int main() {
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 3; j++) {
printf("(%d, %d)\n", i, j);
}
}
return 0;
}

Output:

(1, 1)
(1, 2)
(1, 3)
(2, 1)
(2, 2)
(2, 3)
(3, 1)
(3, 2)
(3, 3)

goto in C

The goto statement in C is a control flow statement that allows you to transfer control to a labeled
statement within the same function. While it can simplify certain tasks, improper use can lead to
difficult-to-maintain code.
Syntax of goto
The syntax of goto consists of two parts:

1.​ Declaring a label: A label is an identifier followed by a colon (:).

label_name:
// code to execute

2.​ Using goto: The goto statement uses the label name to transfer control.

goto label_name;

Example:
#include <stdio.h>

int main() {
printf("Start of program.\n");
goto skip;
printf("This line will be skipped.\n");

skip:
printf("This line is executed after the goto.\n");
return 0;
}

Output:
Start of program.
This line is executed after the goto.

Advantages of goto
1.​ Simplifies certain control flows: When used judiciously, goto can simplify breaking out of
complex structures like nested loops.

2.​ Improves error handling in legacy code: It can be used for cleanups in older C programs
without modern exception handling.

Disadvantages of goto
1.​ Readability issues: Code with multiple goto statements can become hard to follow, often
called "spaghetti code."

2.​ Debugging complexity: Debugging becomes harder because the control flow is less
predictable.
3.​ Structured alternatives: Modern languages and practices provide alternatives like break,
continue, and functions, making goto less relevant.
UNIT III

ARRAYS
Arrays are one of the most fundamental and commonly used data structures in C programming.
They allow the storage and management of multiple values of the same data type in a single
variable, enabling efficient handling of large datasets.

Why Do We Need Arrays in C?


When programming, you often need to manage multiple related values. Without arrays, you would
need to declare separate variables for each value, which is both inefficient and impractical.

Challenges Without Arrays:

1.​ Large Number of Variables: Suppose you need to store marks of 100 students. Without
arrays:

int mark1, mark2, mark3, ..., mark100; // Inefficient

2.​ Difficult to Process Data: Iterating through these variables for calculations (e.g., finding the
average) requires individual handling for each variable, leading to long and error-prone code.
3.​ Dynamic Operations Are Tedious: Without arrays, performing operations like sorting,
searching, or modifying elements in bulk is cumbersome.

Arrays provide a systematic way to handle multiple elements of the same type. With arrays:

●​ All elements are stored in contiguous memory locations.


●​ You can access any element using an index.
●​ Operations on large datasets become manageable.

What is an Array?
An array is a collection of elements of the same data type, stored in contiguous memory locations
and accessed using an index.

Key Characteristics of Arrays:


1.​ Fixed Size: The size of an array is specified during its declaration and cannot be changed
later.
2.​ Homogeneous Elements: All elements in an array must be of the same data type.
3.​ Random Access: Any element can be accessed directly using its index.

Declaration and Initialization of Arrays

1. Declaring an Array:

data_type array_name[size];

●​ data_type: The type of data stored in the array (e.g., int, float, char).
●​ array_name: The name of the array.
●​ size: The number of elements the array can hold.

Example:

int marks[5]; // Declares an array to store 5 integers

2. Initializing an Array:

You can initialize an array during declaration:


int marks[5] = {90, 85, 88, 92, 87}; // Initializes the array with
values

You can also initialize only some elements:


int marks[5] = {90, 85}; // Remaining elements are set to 0

Alternatively, you can omit the size if you provide values during initialization:
int marks[] = {90, 85, 88, 92, 87};

Accessing Array Elements

Array elements are accessed using their index, starting from 0. The syntax is:

array_name[index]
Example:

int marks[5] = {90, 85, 88, 92, 87};


printf("First mark: %d\n", marks[0]); // Output: 90
printf("Third mark: %d\n", marks[2]); // Output: 88

Traversing an Array

You can iterate through an array using loops.

Example:

#include <stdio.h>
int main() {
int marks[5] = {90, 85, 88, 92, 87};

for (int i = 0; i < 5; i++) {


printf("Mark %d: %d\n", i + 1, marks[i]);
}
return 0;
}

Output:
Mark 1: 90
Mark 2: 85
Mark 3: 88
Mark 4: 92
Mark 5: 87

TYPES OF ARRAYS
1. One-Dimensional Arrays:
A one-dimensional array is like a list.

Declaration:
int arr[10]; // An array of 10 integers
2. Two-Dimensional Arrays:

A Two-dimensional array is like a table or a matrix where we can access element by two indices.

Declaration:

int matrix[3][3]; // A 3x3 matrix

Initialization:
int matrix[2][2] = {{1, 2}, {3, 4}};

Accessing elements:
We can access elements from two dimensions array by givingan index.

printf("%d", matrix[1][0]); // Accesses the element in the second row,


first column

3. Character Arrays (Strings):

Character arrays are used to store strings where each element has a single character.

Example:

char name[6] = "Alice";


char name2[] = {'A', 'm', 'i', 't', '\0'};

Common Operations on Arrays


Searching: Find an element in the array. Suppose we have given key to search in given array. We
can find the element by traversing each element one by one and exit loop if we get the element.

int search(int arr[], int size, int key) {


for (int i = 0; i < size; i++) {
if (arr[i] == key) return i;
}
return -1; // Key not found
}

Advantages of Arrays

1.​ Efficient Data Access: Allows direct access to elements using their index.
2.​ Compact Memory Storage: Stores data contiguously in memory.
3.​ Ease of Iteration: Loop constructs make it simple to process array elements.

Limitations of Arrays

1.​ Fixed Size: Arrays have a fixed size, which must be declared at compile time.
2.​ Homogeneous Data: Only stores elements of the same data type.
3.​ No Built-In Operations: Requires manual implementation for tasks like resizing or inserting.

Functions in C
1. Function Components
A function in C is a self-contained block of code that performs a specific task. Functions provide
modularity and reusability, allowing programmers to break down complex problems into smaller,
manageable parts.

Key Components of a Function

1.​ Function Declaration (Prototype):


○​ Specifies the function's name, return type, and parameters.
○​ It tells the compiler what to expect from the function.
○​ Syntax: return_type function_name(parameter_list);
○​ Example: int add(int a, int b);
2.​ Function Definition:
○​ Contains the actual implementation of the function.
○​ Syntax:
​ ​
return_type function_name(parameter_list) {
// Function body
}
Example:

int add(int a, int b) {


return a + b;
}

3. Function Call:

○​ Invokes the function to execute its code.


○​ Syntax: function_name(arguments);
○​ Example: result = add(5, 10);

4. Return Statement:

○​ Used to return a value from the function to the caller.


○​ Syntax: return expression;
○​ Example: return a + b;

Advantages of Functions:

●​ Code Reusability: Functions can be reused across programs.


●​ Modularity: Breaks code into logical chunks.
●​ Improved Readability: Makes code easier to understand and maintain.
●​ Easier Debugging: Errors can be isolated within a function.

2. Return Data Type


The return data type defines the type of value a function returns to the caller. If no value is returned,
the function uses the void keyword.

Types of Return Values:

1.​ Void:
○​ Indicates the function does not return any value.
○​ Syntax: void display();

Example:

void display() {
printf("Hello, World!\n");
}
2.​ Basic Data Types:
○​ Functions can return data types like int, float, char, etc.

Example:
int getNumber() {
return 42;
}


3. Rules for Return Values:

●​ The return type must match the data type specified in the function prototype.
●​ A function returning a non-void type must use a return statement.
●​ If no return type is specified, int is assumed by default (not recommended).

3. Parameter Passing
Parameters allow functions to accept input values, which influence the function's behavior. In C,
there are two primary ways to pass parameters:

1. Pass by Value:

●​ A copy of the argument is passed to the function.


●​ Changes made to the parameter inside the function do not affect the original variable.

Example:​

void increment(int x) {
x = x + 1;
}

int main() {
int a = 10;
increment(a);
printf("a = %d", a); // Output: a = 10

2. Pass by Reference:

●​ The address of the variable is passed, allowing the function to modify the original value.
●​ Uses pointers to achieve this behavior.

Example:

void increment(int *x) {


*x = *x + 1;
}
int main() {
int a = 10;
increment(&a);
printf("a = %d", a); // Output: a = 11
}

4. Recursive Functions
A recursive function is a function that calls itself to solve smaller instances of a problem. Recursion
is commonly used for problems that can be divided into smaller, similar sub-problems.

Structure of a Recursive Function:

1.​ Base Case:


○​ Terminates the recursion.
○​ Prevents infinite recursion.
2.​ Recursive Case:
○​ Calls the function itself with a smaller or simpler input.

Example: Factorial Calculation

int factorial(int n) {
if (n == 0) { // Base case
return 1;
} else {
return n * factorial(n - 1); // Recursive case
}
}

int main() {
printf("Factorial of 5 = %d", factorial(5));
return 0;
}
Advantages of Recursion:

●​ Simplifies code for problems like tree traversal, factorial calculation, and Fibonacci series.

Disadvantages of Recursion:

●​ Higher memory usage due to function call stack.


●​ Slower execution compared to iterative solutions in some cases.

Arrays with Functions in C


Arrays and functions are fundamental features of C that allow efficient data processing. Arrays can
be passed to functions for modular and reusable code. Understanding how arrays interact with
functions is essential for effective programming.

Passing Arrays to Functions

When an array is passed to a function, a pointer to the first element of the array is passed. This
allows the function to access and modify the original array elements.

Syntax for Passing Arrays:

void function_name(data_type array_name[], int size);

Example: Passing an Array to a Function

void printArray(int arr[], int size) {


for (int i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}

int main() {
int numbers[] = {1, 2, 3, 4, 5};
printArray(numbers, 5);
return 0;
}
Modifying Arrays in Functions

Since arrays are passed by reference, modifications made to the array within the function affect the
original array.

Example: Modifying an Array

void doubleArray(int arr[], int size) {


for (int i = 0; i < size; i++) {
arr[i] *= 2;
}
}

int main() {
int numbers[] = {1, 2, 3, 4, 5};
doubleArray(numbers, 5);
for (int i = 0; i < 5; i++) {
printf("%d ", numbers[i]);
}
return 0;
}

Multidimensional Arrays

Multidimensional arrays, such as matrices, can also be passed to functions. However, the size of all
dimensions except the first must be specified.

Syntax:

void function_name(data_type array_name[][columns], int rows);

Example: Passing a 2D Array

void printMatrix(int matrix[][3], int rows) {


for (int i = 0; i < rows; i++) {
for (int j = 0; j < 3; j++) {
printf("%d ", matrix[i][j]);
}
printf("\n");
}
}

int main() {
int matrix[2][3] = {{1, 2, 3}, {4, 5, 6}};
printMatrix(matrix, 2);
return 0;
}

Advantages of Using Arrays with Functions

●​ Efficiency: Functions can process large datasets without copying the entire array.
●​ Modularity: Simplifies complex tasks by breaking them into reusable functions.

Common Mistakes to Avoid

1.​ Passing the Array Size: Always pass the size of the array to avoid out-of-bounds errors.
2.​ Returning Local Arrays: Avoid returning local arrays as their memory is deallocated after
the function ends.

STORAGE CLASSES IN C
Storage classes in C determine the scope, visibility, lifetime, and default initial value of
variables. They control where a variable is stored, how long it persists in memory, and who can
access it during program execution.

C provides four main storage classes:

1.​ Automatic (auto)


2.​ External (extern)
3.​ Static (static)
4.​ Register (register)

Let’s explore each storage class in detail with examples.

1. Automatic Storage Class (auto)

Characteristics:

●​ Scope: Local to the block or function in which the variable is defined.


●​ Lifetime: Exists only while the block or function is executing.
●​ Default Initial Value: Garbage (undefined value).
●​ Storage: Stored in the stack memory.
Key Points:

●​ The auto keyword explicitly specifies an automatic variable.


●​ By default, variables declared inside a function without any storage class specifier are
considered auto.

Syntax:

auto int x;

Example:

#include <stdio.h>

void autoExample() {
auto int a = 10; // Explicit use of 'auto' (optional)
int b = 20; // Implicitly 'auto'
printf("a = %d, b = %d\n", a, b);
}

int main() {
autoExample();
return 0;
}

// Output:
// a = 10, b = 20

2. External Storage Class (extern)

Characteristics:

●​ Scope: Global across all files.


●​ Lifetime: Exists throughout the program's lifetime.
●​ Default Initial Value: Zero.
●​ Storage: Stored in global memory.

Key Points:
●​ The extern keyword allows access to a global variable or function defined in another file.
●​ Useful for sharing variables between multiple files in a project.

Syntax:

extern int x;

Example (Multiple File Example):

File1.c:

#include <stdio.h>

int x = 42; // Global variable

void printX() {
printf("Value of x: %d\n", x);
}

File2.c:

#include <stdio.h>

extern int x; // Declaration of 'x' defined in File1.c


void printX();

int main() {
printX(); // Accesses 'x' from File1.c
return 0;
}

Compilation:

gcc File1.c File2.c -o output


./output

// Value of x: 42
3. Static Storage Class (static)

Characteristics:

●​ Scope:
○​ Local static variables: Scope is limited to the block in which it is declared.
○​ Global static variables: Scope is limited to the file in which it is defined.
●​ Lifetime: Exists throughout the program's lifetime but retains the value between function
calls.
●​ Default Initial Value: Zero.
●​ Storage: Stored in global memory.

Key Points:

●​ Local Static Variables: Retain their value between function calls.


●​ Global Static Variables: Accessible only within the file in which they are declared.

Syntax:

static int x;

Example 1: Local Static Variables

#include <stdio.h>

void staticExample() {
static int counter = 0; // Retains value between calls
counter++;
printf("Counter = %d\n", counter);
}

int main() {
staticExample();
staticExample();
staticExample();
return 0;
}

// Output
Counter = 1
Counter = 2
Counter = 3
4. Register Storage Class (register)
Characteristics:

●​ Scope: Local to the block or function in which the variable is defined.


●​ Lifetime: Exists only while the block or function is executing.
●​ Default Initial Value: Garbage (undefined value).
●​ Storage: Stored in CPU registers instead of RAM for faster access.

Key Points:

●​ The register keyword suggests that the variable be stored in a CPU register.
●​ Used for frequently accessed variables, such as counters in loops.
●​ Cannot take the address of a register variable using the & operator.

Syntax:

register int x;

Example:

#include <stdio.h>

void registerExample() {
register int i;
for (i = 0; i < 5; i++) {
printf("i = %d\n", i);
}
}

int main() {
registerExample();
return 0;
}

// Output
i = 0
i = 1
i = 2
i = 3
i = 4
UNIT IV
STRUCTURE
What is a Structure in C?

A structure in C is a user-defined data type that allows grouping of variables of different types under
a single name. It is especially useful when dealing with complex data where grouping related
information together makes the code more readable and manageable.
Unlike arrays, which can only store multiple elements of the same type, structures enable you to
combine variables of various data types, making it possible to represent real-world entities like a
student, an employee, or a book.

Declaration of a Structure
To define a structure, the struct keyword is used. The declaration defines the structure's blueprint
but does not allocate memory for any variables.

Syntax:

struct StructureName {
data_type member1;
data_type member2;
...
};

Here, StructureName is the name of the structure, and member1, member2, etc., are the
variables (or members) inside the structure.

Example:

struct Student {
int id;
char name[50];
float marks;
};

This declares a structure named Student with three members: an integer id, a string (character
array) name, and a float marks.
Definition of Structure Variables
After declaring a structure, you can create variables of that structure type. These variables hold the
actual data.

Syntax:

struct StructureName variable_name;

Example:

struct Student s1, s2;

This defines two structure variables s1 and s2 of type Student.

Alternatively, you can declare and define structure variables simultaneously:

struct Student {
int id;
char name[50];
float marks;
} s1, s2;

Accessing Structure Members


The members of a structure can be accessed using the dot (.) operator for regular variables and
the arrow (->) operator for pointers.

Syntax:

variable_name.member_name;

Example:

#include <stdio.h>

struct Student {
int id;
char name[50];
float marks;
};

int main() {
struct Student s1;

// Assigning values to structure members


s1.id = 101;
s1.marks = 95.5;
strcpy(s1.name, "John Doe");

// Accessing and printing structure members


printf("ID: %d\n", s1.id);
printf("Name: %s\n", s1.name);
printf("Marks: %.2f\n", s1.marks);

return 0;
}

Output:

ID: 101
Name: John Doe
Marks: 95.50

Initialization of Structures
You can initialize a structure variable at the time of definition by assigning values in a
comma-separated list inside curly braces.

Syntax:

struct StructureName variable_name = {value1, value2, ...};

Example:

struct Student s1 = {101, "John Doe", 95.5};

printf("ID: %d\n", s1.id);


printf("Name: %s\n", s1.name);
printf("Marks: %.2f\n", s1.marks);

If you initialize fewer members than declared, the remaining members will be initialized to zero (for
numeric types) or NULL (for pointers).
Nesting of Structures
Structures can be nested, meaning one structure can contain another structure as a member. This
allows you to model complex data relationships.
Example:

#include <stdio.h>

struct Address {
char city[50];
char state[50];
int zip;
};
struct Student {
int id;
char name[50];
float marks;
struct Address addr; // Nested structure
};
int main() {
struct Student s1;

// Assigning values to nested structure members


s1.id = 101;
s1.marks = 95.5;
strcpy(s1.name, "John Doe");
strcpy(s1.addr.city, "New York");
strcpy(s1.addr.state, "NY");
s1.addr.zip = 10001;

// Accessing nested structure members


printf("ID: %d\n", s1.id);
printf("Name: %s\n", s1.name);
printf("Marks: %.2f\n", s1.marks);
printf("City: %s\n", s1.addr.city);
printf("State: %s\n", s1.addr.state);
printf("ZIP: %d\n", s1.addr.zip);

return 0;
}

Output:

ID: 101
Name: John Doe
Marks: 95.50
City: New York
State: NY
ZIP: 10001
What is a Union in C?

A union in C is a user-defined data type, similar to a structure, but with a key difference: all
members of a union share the same memory location. This means that while multiple members can
be defined, only one member can store a value at any given time. A union is useful when you need
to work with different types of data in the same memory space, optimizing memory usage.

Declaration of a Union

A union is declared using the union keyword. The declaration defines the blueprint of the union but
does not allocate memory for any variables.

Syntax:

union UnionName {
data_type member1;
data_type member2;
...
};

Here, UnionName is the name of the union, and member1, member2, etc., are the members inside
the union.

Example:

union Data {
int i;
float f;
char str[20];
};

This declares a union named Data with three members: an integer i, a float f, and a string
(character array) str.

Definition of Union Variables

To use a union, you need to define variables of the union type. Memory is allocated only for the
largest member of the union, ensuring efficient memory usage.

Syntax:

union UnionName variable_name;


Example:

union Data d1, d2;

This defines two variables, d1 and d2, of type Data.

Alternatively, you can declare and define union variables simultaneously:

union Data {
int i;
float f;
char str[20];
} d1, d2;

Accessing Union Members

Union members are accessed using the dot (.) operator for regular variables and the arrow (->)
operator for pointers. Since all members share the same memory, modifying one member affects
the values of other members.

Syntax:

variable_name.member_name;

Example:

#include <stdio.h>

union Data {
int i;
float f;
char str[20];
};

int main() {
union Data d1;

// Assigning and accessing integer member


d1.i = 10;
printf("Integer: %d\n", d1.i);

// Assigning and accessing float member


d1.f = 220.5;
printf("Float: %.2f\n", d1.f);

// Assigning and accessing string member


strcpy(d1.str, "Hello, Union");
printf("String: %s\n", d1.str);

return 0;
}

Output:

Integer: 10
Float: 220.50
String: Hello, Union

Note: Assigning a new value to one member overwrites the memory, so the previous value
becomes invalid.

Initialization of Unions

Unions can be initialized at the time of definition, but only one member can be initialized.

Syntax:

union UnionName variable_name = {value};

Example:

union Data d1 = {10};

printf("Integer: %d\n", d1.i);

If you initialize more than one member, only the first member's value will be considered, as all
members share the same memory.

Differences Between Structures and Unions

While structures and unions seem similar in syntax and usage, they differ significantly in how they
allocate and use memory.
Feature Structure Union

Memory Allocates separate memory for Allocates shared memory for all
Allocation each member. members.

Size Size is the sum of the sizes of Size is equal to the size of the
all members. largest member.

Access All members can hold Only one member can hold a value
independent values at a time.
simultaneously.

Usage Used when you need to store Used when you need to store and
and access all data members access one member at a time to
simultaneously. save memory.

Example Representing a student record Representing a variable that can


Use Case with fields like ID, name, and hold different types of data at
marks. different times, like a variant.

Pointers
Pointers are one of the most powerful and versatile features of the C programming language. They
allow developers to directly manipulate memory, making them essential for dynamic memory
allocation, efficient array handling, and building data structures like linked lists. In this tutorial, we
will explore pointers in detail, covering their concepts, operators, and advanced usage.

1. Introduction to Pointers

A pointer is a variable that stores the memory address of another variable. Instead of holding a
value directly, pointers "point" to the location in memory where the value is stored. Understanding
pointers is crucial because:

●​ They provide a way to directly access and manipulate memory.


●​ They enable dynamic memory allocation.
●​ They are essential for efficient array handling and function argument passing.

For example:

int x = 10; // A variable with a value of 10


int *p = &x; // A pointer that holds the address of x
Here, p is a pointer to the integer variable x.

2. The Address Operator (&)

The address operator (&) is used to retrieve the memory address of a variable. It is the foundation
for working with pointers.

Example:

int x = 5;
int *p;
p = &x; // `p` now holds the address of `x`

●​ x is a variable that stores the value 5.


●​ &x returns the memory address of x.
●​ p is a pointer variable that stores this address.

Key Points:

●​ The & operator can only be applied to variables, not constants or expressions.
●​ It is often used to pass arguments by reference to functions.

3. Pointer Variables

A pointer variable is a variable designed to hold the address of another variable. When declaring a
pointer, you must specify the type of data it points to.

Syntax:

data_type *pointer_name;

●​ data_type specifies the type of the variable the pointer will point to.
●​ * indicates that the variable is a pointer.

Example:

int x = 42;
int *p = &x; // Declare a pointer to an integer and assign it the
address of `x`
Explanation:

●​ int *p declares a pointer p that points to an integer.


●​ p = &x assigns the address of x to p.

Dereferencing:

To access the value stored at the memory address a pointer holds, you use the dereference
operator (*).

printf("Value of x: %d\n", *p); // Outputs 42

4. Void Pointers

A void pointer is a special type of pointer that can store the address of any data type. Since it has
no associated data type, you cannot dereference it directly.

Syntax:

void *ptr;

Example:

int x = 10;
float y = 20.5;
void *ptr;

ptr = &x; // Store the address of an integer


printf("Value of x: %d\n", *(int *)ptr);

ptr = &y; // Store the address of a float


printf("Value of y: %.2f\n", *(float *)ptr);

Key Points:

●​ Void pointers are often used in generic functions like malloc and free.
●​ To dereference a void pointer, you must cast it to the appropriate type.
5. Pointer Arithmetic

Pointer arithmetic allows you to perform operations on pointers to traverse arrays and manipulate
memory. These operations depend on the size of the data type the pointer is pointing to.

Operations:

1.​ Increment (ptr++): Moves the pointer to the next memory location based on the size of the
data type.
2.​ Decrement (ptr--): Moves the pointer to the previous memory location.
3.​ Addition (ptr + n): Moves the pointer n elements forward.
4.​ Subtraction (ptr - n): Moves the pointer n elements backward.

Example:

int arr[] = {10, 20, 30, 40};


int *p = arr; // Point to the first element of the array

printf("Value at p: %d\n", *p); // 10


p++; // Move to the next element
printf("Value at p: %d\n", *p); // 20

p += 2; // Move two elements forward


printf("Value at p: %d\n", *p); // 40

Key Points:

●​ Pointer arithmetic respects the size of the data type.


●​ It is especially useful when working with arrays.

6. Pointers to Pointers

A pointer to a pointer is a pointer that stores the address of another pointer. This is useful in
scenarios where you need to modify a pointer's value indirectly or work with multi-level data
structures.

Syntax:

data_type **ptr;
Example:

int x = 5;
int *p = &x; // Pointer to x
int **pp = &p; // Pointer to the pointer `p`

printf("Value of x: %d\n", x); // 5


printf("Value of x using *p: %d\n", *p); // 5
printf("Value of x using **pp: %d\n", **pp); // 5

Explanation:

●​ pp is a pointer to p, which in turn points to x.


●​ **pp dereferences twice to access the value of x.

Applications:

●​ Dynamic memory allocation for multi-dimensional arrays.


●​ Managing pointers in complex data structures like linked lists.

You might also like