AIo C programming
AIo C programming
○ #ifdef, #ifndef, #else, #endif: Conditional compilation directives that allow you to
include or exclude sections of code based on whether a certain macro is defined.
3. Global Declarations (Optional):
● Variables and function declarations (prototypes) declared outside any function are
considered global.
● Global variables: Can be accessed from any function in the program. While convenient,
excessive use of global variables can make code harder to manage and debug.
● Function prototypes (declarations): Declare the function's name, return type, and
parameter types before its actual definition. This allows you to call the function before its
full definition appears in the code. It's generally good practice to declare functions before
main() if their definitions appear after main().
4. The main() Function (Mandatory):
● This is the entry point of every C program. Execution of the program begins from the
main() function.
● It is a special function with a fixed name main.
● It typically returns an integer value to the operating system to indicate the program's exit
status. A return value of 0 usually indicates successful execution.
● The main() function can optionally accept command-line arguments, which are passed as
parameters argc (argument count) and argv (argument vector - an array of strings).
● The body of the main() function contains:
○ Local variable declarations: Variables declared within main() are local to this
function and cannot be directly accessed from other functions.
○ Executable statements: Instructions that perform the actual work of the program
(e.g., input/output operations, calculations, function calls).
5. Function Definitions:
● These are the actual implementations of the functions that are declared (either implicitly if
defined before being called or explicitly through prototypes).
● A function definition includes:
○ Return type: The data type of the value the function returns (e.g., int, void, float).
void indicates that the function does not return any value.
○ Function name: A unique identifier for the function.
○ Parameter list (optional): A comma-separated list of parameters (with their data
types) that the function accepts as input.
○ Function body: Enclosed in curly braces {} and contains the local variable
declarations and executable statements that define what the function does.
Order of Sections:
While the order shown above is a common and recommended practice, the compiler is
generally flexible. However, adhering to this structure improves code readability and
organization.
Key Principles of C Program Structure:
● Modularity: Breaking down the program into smaller, manageable functions.
● Top-down approach: Starting with the main() function and then defining the supporting
functions.
● Clarity: Using comments and meaningful variable and function names to make the code
easy to understand.
● Organization: Following a consistent structure to improve maintainability.
Understanding this fundamental structure is crucial for writing well-organized and effective C
programs. It helps in managing the complexity of larger projects and makes collaboration easier.
The execution process in C programming involves several distinct stages, transforming the
human-readable source code into a program that the computer's central processing unit (CPU)
can understand and execute. Here's a breakdown of these stages:
1. Preprocessing:
● Input: The C source code file(s) (e.g., main.c, utils.c).
● Processor: The C preprocessor (often integrated with the compiler).
● Actions: The preprocessor performs several operations based on directives (lines
starting with #) in the source code:
○ Include Header Files (#include): The content of the specified header files (e.g.,
stdio.h, stdlib.h) is literally inserted into the source code at the location of the
#include directive. This provides declarations of standard library functions and other
definitions.
○ Macro Substitution (#define): Symbolic constants (macros) defined using #define
are replaced with their corresponding values throughout the code. For example, if
#define PI 3.14159 is present, all occurrences of PI will be replaced by 3.14159.
○ Conditional Compilation (#ifdef, #ifndef, #else, #endif): Sections of code are
included or excluded from compilation based on the evaluation of preprocessor
conditions. This allows for creating different versions of the code for different
environments or debugging purposes.
○ Other Directives: The preprocessor handles other directives like #undef, #pragma,
etc.
● Output: One or more modified source code files (often in a temporary directory) that no
longer contain preprocessor directives. These files are ready for the next stage.
2. Compilation:
● Input: The preprocessed source code file(s).
● Processor: The C compiler (e.g., GCC, Clang).
● Actions: The compiler translates the preprocessed C code into assembly language,
which is a low-level programming language specific to the target processor architecture.
This involves:
○ Lexical Analysis: Breaking down the source code into tokens (keywords,
identifiers, operators, etc.).
○ Syntax Analysis (Parsing): Checking if the sequence of tokens adheres to the
grammar rules of the C language. If there are syntax errors, the compiler will report
them and the compilation process will likely stop.
○ Semantic Analysis: Checking the meaning and consistency of the code, such as
type checking, ensuring that variables are declared before use, and verifying the
correctness of operations. Semantic errors will also be reported by the compiler.
○ Intermediate Code Generation (Optional): Some compilers generate an
intermediate representation of the code before producing assembly language. This
can help in optimization.
○ Assembly Code Generation: Translating the intermediate code (or directly from
the parsed structure) into assembly language instructions specific to the target
CPU.
● Output: One or more assembly language files (e.g., main.s, utils.s).
3. Assembly:
● Input: The assembly language file(s).
● Processor: The assembler (often invoked by the compiler driver).
● Actions: The assembler converts the assembly language code into machine code, which
consists of binary instructions that the CPU can directly execute. Each assembly
instruction typically corresponds to one or a few machine code instructions.
● Output: One or more object files (e.g., main.o, utils.o). These files contain the machine
code for each source code file, along with some metadata needed for the next stage (like
relocation information). Object files are usually not directly executable.
4. Linking:
● Input: One or more object files (generated in the assembly stage) and potentially libraries
(both static and dynamic).
● Processor: The linker (often invoked by the compiler driver).
● Actions: The linker combines the object files into a single executable program. This
involves:
○ Symbol Resolution: Resolving references between different object files. For
example, if a function defined in utils.c is called from main.c, the linker finds the
machine code for that function in utils.o and connects the call in main.o to it.
○ Relocation: Adjusting memory addresses in the machine code. The compiler and
assembler often don't know the final memory locations of functions and variables.
The linker assigns these addresses and updates the code accordingly.
○ Library Linking: Incorporating code from libraries.
■ Static Linking: The code from the required static libraries (e.g., libc.a on
Linux) is copied directly into the executable file, making it self-contained.
■ Dynamic Linking: The executable file only contains references to the
dynamic libraries (e.g., libc.so or .dll). These libraries are loaded into memory
at runtime when the program is executed. This reduces the size of the
executable and allows multiple programs to share the same library in
memory.
● Output: A single executable file (e.g., a.out on Unix-like systems, main.exe on Windows).
5. Loading:
● Input: The executable file.
● Processor: The operating system's loader.
● Actions: When you run the executable, the operating system's loader:
○ Allocates memory: Assigns memory space for the program's code, data, stack,
and heap.
○ Loads code and data: Copies the instructions and initial data from the executable
file into the allocated memory.
○ Sets up the execution environment: Initializes registers, sets the program
counter to the starting address of the main() function, and prepares the program for
execution.
○ For dynamically linked libraries: If the program uses dynamic libraries, the loader
also loads these libraries into memory and resolves the necessary function calls
and data references.
● Output: The program is now loaded into memory and ready to be executed.
6. Execution:
● Input: The loaded program in memory.
● Processor: The CPU.
● Actions: The CPU fetches and executes the machine code instructions of the program
sequentially (or as directed by control flow statements like loops and conditional
statements). This involves performing arithmetic and logical operations, accessing
memory, interacting with input/output devices, and calling functions.
● Output: The program produces output (to the console, files, network, etc.) and may
interact with the user or other parts of the system. The program continues to execute until
it finishes its tasks or encounters an error that causes it to terminate.
In summary, the execution process of a C program involves a series of transformations:
1. Preprocessing: Handling preprocessor directives.
2. Compilation: Translating C code to assembly language.
3. Assembly: Converting assembly language to machine code (object files).
4. Linking: Combining object files and libraries into an executable.
5. Loading: Loading the executable into memory.
6. Execution: The CPU running the program's instructions.
Understanding these stages is crucial for debugging, optimizing, and comprehending how C
programs interact with the underlying system. The compiler driver (like gcc) often automates
most of these steps, making the compilation and linking process appear as a single command to
the user. However, knowing what's happening behind the scenes is essential for more advanced
programming tasks.
In C programming, a constant is a value that cannot be changed by the program during its
execution. Once a constant is defined and initialized, its value remains the same throughout the
entire lifetime of the program. Constants are used to represent fixed values like mathematical
constants (e.g., pi), physical constants, or fixed configuration values.
C provides several ways to define constants:
1. Using the const Keyword:
● The const keyword is a type qualifier that can be applied to a variable declaration. When a
variable is declared with const, the compiler prevents any subsequent modification of its
value.
const int MAX_VALUE = 100;
const float PI = 3.14159;
const char MESSAGE[] = "Hello";
● Characteristics:
○ const variables are still technically variables, but the compiler enforces their
immutability.
○ They follow the scope rules of regular variables (local or global).
○ It's a good practice to initialize const variables at the time of declaration. While you
can declare a const variable without immediate initialization, you won't be able to
assign a value to it later.
2. Using #define Preprocessor Directive (Symbolic Constants or Macros):
● The #define preprocessor directive is used to create symbolic constants (often called
macros). The preprocessor replaces all occurrences of the defined name with the
specified value before the actual compilation begins.
#define GRAVITY 9.8
#define BUFFER_SIZE 512
#define GREETING "Welcome"
● Characteristics:
○ #define creates a textual substitution. The preprocessor simply replaces the macro
name with its value throughout the code.
○ Macros do not have a specific data type associated with them (the type is
determined by the context where they are used).
○ Macros have global scope within the file where they are defined (from the point of
definition onwards).
○ They are often written in uppercase by convention to distinguish them from regular
variables.
○ #define can also be used to create simple function-like macros, but this can
sometimes lead to unexpected behavior due to the textual substitution nature.
3. Enumerations (enum):
● Enumerations provide a way to create a set of named integer constants. They are useful
for representing a set of related values.
enum Days {
SUNDAY,
MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY
};
enum Status {
OK = 200,
ERROR = 404,
PENDING
};
● Characteristics:
○ By default, the enumerators are assigned integer values starting from 0 (SUNDAY =
0, MONDAY = 1, etc.).
○ You can explicitly assign values to the enumerators, and subsequent uninitialized
enumerators will automatically increment from the last assigned value (as seen in
the Status example).
○ Enumerations improve code readability by using meaningful names instead of raw
integer values.
○ Variables of an enumeration type can only be assigned one of the defined
enumerator values.
Types of Constants in C:
C supports various types of constants, just like it supports different data types:
● Integer Constants: Whole numbers (e.g., 10, -5, 0). They can be decimal, octal (prefixed
with 0, e.g., 012), or hexadecimal (prefixed with 0x or 0X, e.g., 0xFF). They can also have
suffixes to indicate their type (e.g., 10L for long, 15U for unsigned).
● Floating-Point Constants: Numbers with a decimal point (e.g., 3.14, -2.5, 0.0). They can
also be expressed in exponential notation (e.g., 1.2e-3). By default, they are of type
double. You can use suffixes f or F for float (e.g., 3.14f) and l or L for long double (e.g.,
2.71828L).
● Character Constants: Single characters enclosed in single quotes (e.g., 'a', '5', ' '). They
represent the ASCII value of the character. Escape sequences (preceded by a backslash
\) are used for special characters (e.g., '\n' for newline, '\t' for tab, '\\' for backslash, '\'' for
single quote).
● String Literals: Sequences of characters enclosed in double quotes (e.g., "Hello, world!",
"This is a string"). String literals are stored as arrays of characters terminated by a null
character (\0).
Why Use Constants?
● Readability: Using meaningful names for constants (e.g., MAX_SIZE instead of 100)
makes the code easier to understand.
● Maintainability: If a fixed value needs to be changed, you only need to modify the
constant's definition in one place, rather than searching and replacing all occurrences in
the code. This reduces the risk of errors.
● Preventing Accidental Modification: The compiler enforces the immutability of const
variables, preventing accidental changes that could lead to bugs.
● Safety: Using constants can make the code safer by ensuring that certain values remain
fixed as intended.
Choosing Between const and #define:
● const:
○ Provides type checking by the compiler.
○ Follows scope rules, which can be beneficial for local constants.
○ Is generally preferred for defining named constants that have a specific data type.
○ Easier for debuggers to handle (can see the value and type of const variables).
● #define:
○ Performs simple textual substitution by the preprocessor.
○ Does not have type checking.
○ Has global scope within the file (from the point of definition).
○ Can be useful for simple constants and macro definitions.
○ Might not be as visible to debuggers (the preprocessor has already done the
substitution).
In modern C programming, const is generally preferred over #define for defining named
constants due to its type safety and better integration with the language's scope rules and
debugging tools. #define is still commonly used for simple macros and conditional compilation.
Enumerations are specifically useful for representing sets of related integer constants.
Okay, let's discuss keywords and identifiers in C programming, keeping in mind our current
context (Tuesday, April 15, 2025, 11:34 AM IST, Bhubaneswar, Odisha, India). These are
fundamental building blocks of the C language's vocabulary.
1. Keywords:
● Definition: Keywords (also known as reserved words) are predefined words in the C
language that have special meanings to the compiler. They form the core syntax of the
language and are used to instruct the compiler on how to interpret the code.
● Characteristics:
○ Reserved: You cannot use keywords as names for your own variables, functions,
or other identifiers. The compiler would get confused if you tried to use a word with
a predefined meaning in a different context.
○ Lowercase: All C keywords are written in lowercase.
○ Essential for Syntax: Keywords are used to define data types, control program
flow (loops, conditions), declare storage classes, and perform other fundamental
operations.
● Examples of C Keywords:Here's a list of some common C keywords. The exact number
might vary slightly depending on the specific C standard (e.g., C89/90, C99, C11), but
these are the most frequently encountered:
○ Data Types: int, char, float, double, void, short, long, unsigned, signed, struct,
union, enum, typedef, const, volatile, _Bool, _Complex, _Imaginary (some of the
underscore-prefixed ones were introduced in later standards).
○ Control Flow: if, else, switch, case, default, break, continue, for, while, do, goto,
return.
○ Storage Class Specifiers: auto, static, extern, register, thread_local (introduced in
C11).
○ Other Keywords: sizeof, typedef, enum, struct, union, const, volatile, restrict
(introduced in C99), inline (introduced in C99), _Alignas (C11), _Alignof (C11),
_Noreturn (C11), _Static_assert (C11).
● Usage: Keywords are used in various contexts to structure your C programs:
int main() { // 'int' is a data type, 'main' is a function name
(not a keyword), 'return' is a keyword
int count = 0; // 'int' is a data type
if (count < 5) { // 'if' is a keyword for conditional
execution
printf("Count is less than 5\n");
count++;
} else { // 'else' is a keyword for the alternative branch of
'if'
for (int i = 0; i < 3; i++) { // 'for' is a keyword for
loop, 'int' is a data type
printf("Loop iteration: %d\n", i);
}
}
return 0;
}
2. Identifiers:
● Definition: Identifiers are the names given to various program elements such as
variables, functions, structures, unions, enumerations, and labels. They are the names
you, as the programmer, choose to refer to these entities in your code.
● Characteristics:
○ User-Defined: Unlike keywords, you create identifiers according to specific rules.
○ Naming Rules:
■ Must start with a letter (a-z, A-Z) or an underscore (_).
■ Can be followed by letters, digits (0-9), or underscores.
■ Cannot be the same as any C keyword.
■ Are case-sensitive (e.g., myVariable and MyVariable are different identifiers).
■ There's no strict limit on the length of an identifier, but compilers might have
practical limitations. It's good practice to keep them reasonably concise and
descriptive.
● Examples of Valid and Invalid Identifiers:Valid Identifiers:
count
totalSum
average_value
_index
studentName
MAX_SIZE
Invalid Identifiers (will cause compiler errors):
2ndValue // Cannot start with a digit
my-variable // Hyphens are not allowed
int // Cannot be a keyword
space in name // Spaces are not allowed
$amount // Special characters (except underscore) are
generally not allowed
● float (Floating-Point):
○ Used to store single-precision floating-point numbers (numbers with a decimal
point).
○ Typically occupies 4 bytes.
○ Has a limited precision compared to double.
float pi = 3.14159f; // 'f' suffix indicates a float literal
float temperature = 25.5f;
● char (Character):
○ Used to store single characters (e.g., 'a', 'X', '7', '$').
○ Typically occupies 1 byte.
○ Internally, characters are stored as their ASCII (or other encoding) values.
○ Modifiers:
■ signed char: Can store both positive and negative small integer values
(representing character codes).
■ unsigned char: Can store only non-negative small integer values
(representing character codes).
char initial = 'J';
char digit = '9';
signed char ascii_value = 65; // Represents 'A' in ASCII
unsigned char byte_value = 200;
● void:
○ Represents the absence of a type or a generic type.
○ Has several uses:
■ As the return type of a function that doesn't return a value (e.g., void
printMessage()).
■ As a pointer to a value of unknown type (e.g., void *ptr). You need to cast a
void pointer to a specific type before dereferencing it.
■ In function parameter lists to indicate that the function takes no arguments
(e.g., int main(void)).
void display(); // Function that doesn't return a value
void *generic_pointer;
● Pointers:
○ Variables that store the memory address of other variables.
○ Essential for dynamic memory allocation, passing arguments by reference, and
working with data structures.
int x = 10;
int *ptr_x = &x; // 'ptr_x' stores the memory address of 'x'
● Structures (struct):
○ A composite data type that groups together variables of different data types under a
single name.
○ Useful for representing records or entities with multiple attributes.
struct Student {
char name[50];
int roll_no;
float marks;
};
struct Student s1;
● Unions (union):
○ Similar to structures, but all members share the same memory location.
○ The size of a union is the size of its largest member.
○ Used when you need to store different types of data in the same memory location at
different times.
union Data {
int i;
float f;
char str[20];
};
union Data d;
● Enumerations (enum):
○ A user-defined data type that consists of a set of named integer constants.
○ Improves code readability by using meaningful names instead of raw integer
values.
enum Days { SUN, MON, TUE, WED, THU, FRI, SAT };
enum Days today = WED;
○ Relational Operators: These compare two operands and return a boolean value
(true or false), represented as 1 (true) or 0 (false) in C.
■ == (Equal to)
■ != (Not equal to)
■ > (Greater than)
■ < (Less than)
■ >= (Greater than or equal to)
■ <= (Less than or equal to)
int x = 7, y = 12;
int isEqual = (x == y); // isEqual is 0 (false)
int isNotEqual = (x != y); // isNotEqual is 1 (true)
int isGreater = (y > x); // isGreater is 1 (true)
int isLessOrEqual = (x <= 7); // isLessOrEqual is 1 (true)
○ Special Operators:
■ sizeof(): Returns the size (in bytes) of a variable or data type.
■ & (Address-of operator): Returns the memory address of a variable.
■ * (Dereference operator): Accesses the value at a memory address (used
with pointers).
■ . (Member access operator): Accesses members of a structure or union.
■ -> (Pointer to member access operator): Accesses members of a structure or
union through a pointer.
■ , (Comma operator): Separates expressions in a list (the value of the entire
expression is the value of the rightmost expression).
2. Expressions in C:
● Definition: An expression is a combination of operands (variables, constants, function
calls) and operators that evaluates to a single value.
● Types of Expressions:
○ Constant Expressions: Consist only of constant values (literals) and constant
operators. Their value is determined at compile time.
5 + 3 // Evaluates to 8
'A' // Evaluates to the ASCII value of 'A'
3.14 * 2 // Evaluates to 6.28
○ Function Call Expressions: Invoke a function and evaluate to the value returned
by the function.
sqrt(25.0) // Evaluates to 5.0
printf("Hello") // Evaluates to the number of characters
printed (though often the return value is ignored)
Understanding operators and expressions is crucial for writing C programs that can perform
calculations, make comparisons, and manipulate data effectively right here in Bhubaneswar, or
anywhere your C code might run! They are the building blocks of the logic and functionality of
your programs.
Alright, let's delve into the precedence of operators in C programming, keeping in mind our
current context (Tuesday, April 15, 2025, 11:44 AM IST, Bhubaneswar, Odisha, India). Operator
precedence dictates the order in which different operators are evaluated within a single
expression. It's crucial for understanding how C interprets and calculates the result of complex
expressions.
Think of it like the order of operations you learned in mathematics (PEMDAS/BODMAS). In C,
different operators have different levels of "priority." Operators with higher precedence are
evaluated before operators with lower precedence.
Here's a table summarizing the precedence of common C operators, from highest to lowest.
Operators on the same row have the same precedence and their associativity determines the
evaluation order.
Precedence Operator(s) Associativity
1 () (Function call, Parentheses), Left-to-right
[] (Array subscript), . (Member
access), -> (Pointer to member
access)
2 ! (Logical NOT), ~ (Bitwise Right-to-left
NOT), ++ (Prefix increment), --
(Prefix decrement), + (Unary
plus), - (Unary minus), *
(Dereference), & (Address-of),
sizeof, _Alignof (C11), _Generic
(C11)
3 * (Multiplication), / (Division), % Left-to-right
(Modulo)
4 + (Addition), - (Subtraction) Left-to-right
5 << (Left shift), >> (Right shift) Left-to-right
6 < (Less than), <= (Less than or Left-to-right
equal to), > (Greater than), >=
(Greater than or equal to)
7 == (Equal to), != (Not equal to) Left-to-right
8 & (Bitwise AND) Left-to-right
9 ^ (Bitwise XOR) Left-to-right
10 ` ` (Bitwise OR)
11 && (Logical AND) Left-to-right
12 `
13 ? : (Conditional operator) Right-to-left
14 = (Assignment), +=, -=, *=, /=, =`
%=, <<=, >>=, &=, ^=, `
15 , (Comma operator) Left-to-right
Explanation of the Table:
● Higher Precedence (Top of the Table): Operators at the top of the table have higher
precedence and are evaluated first.
● Lower Precedence (Bottom of the Table): Operators at the bottom have lower
precedence and are evaluated later.
● Associativity: When operators have the same precedence, associativity determines the
order of evaluation:
○ Left-to-right: Operators are evaluated from left to right (e.g., a - b + c is evaluated
as (a - b) + c).
○ Right-to-left: Operators are evaluated from right to left (e.g., a = b = 5 is evaluated
as a = (b = 5)).
Examples to Illustrate Precedence:
1. int result = 2 + 3 * 4;
○ Multiplication (*) has higher precedence than addition (+).
○ So, 3 * 4 is evaluated first, resulting in 12.
○ Then, 2 + 12 is evaluated, and result becomes 14.
2. int value = (5 - 2) * 3;
○ Parentheses () have the highest precedence.
○ So, (5 - 2) is evaluated first, resulting in 3.
○ Then, 3 * 3 is evaluated, and value becomes 9.
3. int flag = 1 && 0 || 1;
○ Logical AND (&&) has higher precedence than logical OR (||).
○ So, 1 && 0 is evaluated first, resulting in 0 (false).
○ Then, 0 || 1 is evaluated, and flag becomes 1 (true).
4. int x = 10; int y = ++x * 2;
○ Prefix increment (++x) has higher precedence than multiplication (*).
○ First, x is incremented to 11.
○ Then, 11 * 2 is evaluated, and y becomes 22.
5. int a = 5; int b = a++; int c = ++a;
○ Postfix increment (a++) has lower precedence than prefix increment (++a) in terms
of when the increment happens relative to the rest of the expression.
○ In int b = a++;: b is assigned the current value of a (which is 5), and then a is
incremented to 6. So, b becomes 5.
○ In int c = ++a;: a is first incremented to 7, and then this new value (7) is assigned to
c. So, c becomes 7.
Importance of Understanding Precedence:
● Predictable Evaluation: Knowing the precedence rules ensures that expressions are
evaluated in the intended order, leading to correct program behavior.
● Avoiding Errors: Misunderstanding precedence can lead to unexpected results and
logical errors in your code.
● Code Readability: While the rules exist, using parentheses to explicitly group operations
can significantly improve the readability of complex expressions, even if the default
precedence would yield the desired result. It makes your code easier to understand and
maintain.
Best Practice: Use Parentheses for Clarity:
Even though C has well-defined precedence rules, it's often a good practice to use parentheses
to make the order of evaluation explicit, especially in complex expressions. This reduces
ambiguity and makes your code easier to read and understand, both for yourself and for others
who might work with your code here in Bhubaneswar or elsewhere. For instance, instead of
relying on the precedence of && over ||, you might write (condition1 && condition2) || condition3
to clearly indicate your intent.
Okay, let's discuss built-in functions and user-defined functions in C programming, keeping
in mind our current context (Tuesday, April 15, 2025, 11:47 AM IST, Bhubaneswar, Odisha,
India). Functions are fundamental building blocks of modular and reusable code in C. They
allow you to break down complex tasks into smaller, manageable units.
1. Built-in Functions (Library Functions):
● Definition: Built-in functions are functions that are pre-defined and provided by the C
standard library. These functions perform common and essential tasks that are frequently
needed in programming.
● Characteristics:
○ Part of the Standard Library: They are part of the C standard library, which is a
collection of header files containing declarations and definitions of various
functions.
○ Ready to Use: You don't need to write the code for these functions yourself. You
can directly call them in your program after including the appropriate header file.
○ Wide Range of Functionality: The standard library provides functions for
input/output operations, string manipulation, mathematical calculations, memory
management, and much more.
○ Portability: Because they are part of the standard, these functions generally
behave consistently across different C compilers and operating systems,
contributing to the portability of C programs.
● How to Use Built-in Functions:
1. Include the Header File: You need to include the header file that declares the
function you want to use. Header files typically have a .h extension and contain
function prototypes (declarations) and other necessary definitions. You use the
#include preprocessor directive for this.
2. Call the Function: Once the header file is included, you can call the function by its
name, followed by parentheses (). If the function expects arguments (input values),
you provide them inside the parentheses, separated by commas. If the function
returns a value, you can store it in a variable or use it directly in an expression.
● Examples of Built-in Functions and Their Header Files:
○ Input/Output (stdio.h):
■ printf(): Prints formatted output to the standard output (usually the console).
■ scanf(): Reads formatted input from the standard input (usually the
keyboard).
■ fopen(), fclose(), fprintf(), fscanf(): Functions for file input and output.
#include <stdio.h>
int main() {
int num;
printf("Enter a number: ");
scanf("%d", &num);
printf("You entered: %d\n", num);
return 0;
}
2. User-Defined Functions:
● Definition: User-defined functions are functions that are written by the programmer to
perform specific tasks that are not directly provided by the standard library. They allow
you to modularize your code, make it more organized, and reuse blocks of code as
needed.
● Characteristics:
○ Programmer Created: You define the function's name, parameters (inputs), return
type (output), and the code that it executes.
○ Tailored to Specific Needs: They are designed to solve particular problems or
perform specific operations within your program.
○ Promote Code Reusability: Once defined, a user-defined function can be called
multiple times from different parts of your program, reducing code duplication.
○ Improve Code Organization: Breaking down a large program into smaller
functions makes it easier to understand, debug, and maintain.
● Syntax for Defining a User-Defined Function:
return_type function_name(parameter_list) {
// Function body: code to be executed
// ...
return value; // If return_type is not void
}
○ return_type: The data type of the value the function will return. If the function
doesn't return a value, the return type is void.
○ function_name: The name you choose for your function (must follow identifier
naming rules).
○ parameter_list: A comma-separated list of parameters (input values) that the
function accepts. Each parameter has a data type and a name (e.g., int x, float y). If
the function takes no parameters, you can leave the parentheses empty or use
void.
○ function body: The block of code enclosed in curly braces {} that contains the
statements to be executed when the function is called.
○ return value;: A return statement is used to send a value back from the function to
the caller (if the return type is not void).
● Example of a User-Defined Function:
#include <stdio.h>
// Function to add two integers
int add(int num1, int num2) {
int sum = num1 + num2;
return sum;
}
// Function to print a greeting message
void greet(char name[]) {
printf("Hello, %s!\n", name);
}
int main() {
int a = 5, b = 10;
int result = add(a, b); // Calling the 'add' function
printf("The sum is: %d\n", result); // Output: The sum is: 15
greet("Alice"); // Calling the 'greet' function
return 0;
}