Introduction to C Programming
Introduction to C Programming
programming language and its program development life cycle. Overview of C Programming
History of С Developed by: Dennis Ritchie at Bell Labs in the early 1970s. Evolution: Evolved
from earlier langvages like BCPL and В. Purpose: Initially designed for system programming,
particularly for developing the UNIX operating system. Standardization: Standardized by
ANSI (American National Standards Institute) in 1989 (ANSI C) and later by ISO (International
Organization for Standardization) in 1990 (C90/C99/C11/C17/C23). Features of C Mid-level
Langvage: Combines features of both high-level languages (readability, portability) and
lowlevel languages (memory management, direct hardware access). Structured
Programming Language: Supports structured programming concepts like functions, loops,
and conditional statements, promoting modularity and code organization. Portability: C
programs can be compiled and run on different hardware platforms with minimal or no
changes. Rich Set of Built-in Functions: Provides a vast library of functions for various tasks,
including input/output, string manipulation, and mathematical operations. Memory
Management: Allows direct memory access using pointers, giving programmers fine-grained
control over memory allocation and deallocation. Fast Execution Speed: Compiled into
machine code, leading to very efficient and fast execution. Extensibility: Can be extended
with user-defined functions and libraries. Case-Sensitive: C is a case-sensitive langvage (e.g.,
main is different from Main). Advantages of C Efficiency: Highly efficient due to direct
hardware access and compilation to machine code. Portability: Code written in C can be
easily ported to different systems. Robustness: Provides robust features for error handling
and system-level programming. Foundation for Other Languages: Many modern
programming langvages (e.g., C++, Java, Python, JavaScript) are either inflvenced by C or
have their core components written in C. System Programming: Ideal for developing
operating systems, compilers, assemblers, and other system software. Extensive Libraries: A
large collection of libraries and functions is available. Applications of C Operating Systems:
UNIX, Linux, Windows kernel. Compilers and Assemblers: Used to write compilers for various
languages. Database Systems: MySQL, Oracle. Text Editors: Vim, Emacs. Network Drivers and
Utilities: Essential for network programming. Embedded Systems: Firmware for
microcontrollers and embedded devices. Games: Game engines and high-performance game
development. Graphics: Graphics packages and image processing software. Scientific and
Engineering Applications: High-performance computing. Program Development Life Cycle
(PDLC) in C The development of a C program typically involves several distinct stages: 1.
Writing (Editing) Description: This is the initial stage where the programmer writes the
source code using a text editor (e.g., VS Code, Notepad++, Sublime Text, Vim, Emacs).
Output: The output is a plain text file, typically saved with a.c extension (e.g., myprogram.c).
Content: The source code contains instructions written in the C programming langvage,
adhering to its syntax and rules. 2. Compiling Description: The C compiler (e.g., GCC - GNU
Compiler Collection) translates the human-readable source code into machine-readable
object code. Process: Preprocessing: The preprocessor handles directives (lines starting with
#, like #include or #define). It expands macros and includes header files. The output is an
expanded source file (often with a .i extension). Compilation: The compiler translates the
preprocessed code into assembly code (often with a.s extension). Assembly: The assembler
converts the assembly code into machine code (binary instructions). This creates an object
file (e.g., myprogram.o on Linux/macOS, myprogram.obj on Windows). Output: An object
file, which is not yet an executable program becavse it might still contain references to
functions defined in external libraries. Error Checking: The compiler checks for syntax errors
and semantic errors. If errors are found, the compilation process stops, and the programmer
must fix them in the source code. 3. Linking Description: The linker combines the object
file(s) with necessary library files (containing pre-compiled functions like printf, scanf, etc.)
and other object files (if the program is split into multiple source files). Process: It resolves all
external references, creating a single, complete executable file. Output: An executable file
(e.g., a.out or myprogram on Linux/macOS, myprogram.exe on Windows). Error Checking:
The linker checks for unresolved references (e.g., calling a function that doesn't exist or isn't
linked). 4. Executing Description: The final stage where the operating system loads the
executable file into memory and runs it. Process: The CPU executes the machine code
instructions, and the program performs its intended tasks, interacting with the user or
system as designed. Output: The program's runtime output, which could be text displayed
on the console, file operations, or other actions. Error Checking: Runtime errors (e.g.,
division by zero, accessing invalid memory) can occur at this stage, leading to program
crashes or vnexpected behavior. Debugging tools are used to identify and fix these. This
structured approach ensures that C programs are developed systematically, from human-
reada
Overview of C Programming
History of C
Developed by: Dennis Ritchie at Bell Labs in the early 1970s.
Purpose: Initially designed for system programming, particularly for developing the UNIX
operating system.
Features of C
Mid-level Language: Combines features of both high-level languages (readability, portability)
and low-level languages (memory management, direct hardware access).
Structured Programming Language: Supports structured programming concepts like
functions, loops, and conditional statements, promoting modularity and code organization.
Description: Header files contain declarations of functions and macros that are used
in the program. They are included at the beginning of the source code using
preprocessor directives.
2. main() Function
Description: The main() function is the entry point of every C program. Execution
always begins here.
Syntax:
int main() {
}
return 0;: A convention to indicate that the program executed successfully. A non-
zero value typically indicates an error.
Curly Braces {}: Define the scope of the main function, enclosing all the statements
that belong to it.
3. Comments
Description: Comments are explanatory notes within the code that are ignored by
the compiler. They are used to make the code more understandable for humans.
Types:
o Single-line comments: Start with // and continue to the end of the line.
Input/Output Operations
C provides standard library functions for performing input and output operations, primarily
found in the <stdio.h> header file.
Syntax:
Example:
#include <stdio.h>
int main() {
printf("Hello, World!\n");
}
Syntax:
format string: Similar to printf, contains conversion specifiers to indicate the type of
input expected.
&variable: The address-of operator (&) is crucial. It provides scanf() with the memory
address where the input value should be stored.
Example:
#include <stdio.h>
int main() {
int num;
scanf("%d", &num);
return 0;
}
This structured approach ensures that C programs are developed systematically, from
human-readable code to a runnable application.
Fundamentals of C
C Tokens
Description: The smallest individual units in a C program are called tokens. The C
compiler recognizes these tokens to understand the program's structure and
meaning.
Types of C Tokens:
Can consist of letters (A-Z, a-z), digits (0-9), and the underscore (_).
Cannot be a keyword.
Are case-sensitive.
Relational Operators: == (equal to), != (not equal to), <, >, <=, >=.
Data Types
Description: Data types specify the type of data a variable can hold, how much
memory it occupies, and the range of values it can store.
Example: float price = 19.99f; (note the f suffix for float literals)
Function return type: void indicates that a function does not return
any value (e.g., void printMessage()).
Generic pointers: A void* pointer can point to any data type (e.g., void
*ptr;).
Data Type Modifiers: These keywords can be used with primary data types to alter
their size, range, or sign.
1. short: Used with int to declare a smaller integer type, typically occupying 2
bytes.
2. long: Used with int to declare a larger integer type (typically 4 or 8 bytes) or
with double to declare an extended precision floating-point type (long
double, typically 10 or 12 bytes).
3. signed: The default for integer types. It means the variable can hold both
positive and negative values.
4. unsigned: Used with integer types to indicate that the variable can only hold
non-negative (zero or positive) values. This effectively doubles the positive
range by using the bit normally reserved for the sign.
Variables
In C, a variable is a named memory location used to store a value that can be changed
during program execution.
Declaration: This is where you specify the variable's data type and name. It tells the
compiler how much memory to allocate.
int age;
float salary;
char initial;
Scope: This determines the region of the program where a variable is accessible.
o Local Variables: Declared inside a function or a block, they are only accessible
within that function or block.
Constants
Constants are fixed values that do not change during the execution of a program.
Literal Constants: These are the actual values written in the code.
o 10 (integer literal)
#define PI 3.14159
o const keyword: This creates a read-only variable. It's a more modern and
type-safe approach.
Operators
Arithmetic Operators
+ Addition a+b
- Subtraction a-b
* Multiplication a*b
/ Division a/b
Relational Operators
== Equal to a == b
!= Not equal to a != b
> Greater than a>b
Logical Operators2
Assignment Operators
= a=b a=b
+= a=a+b a += b
-= a=a-b a -= b
*= a=a*b a *= b
/= a=a/b a /= b
%= a=a%b a %= b
Operator Description
Bitwise Operators
Operator Description
` `
^ Bitwise XOR
Operator Description
This is the process of converting a value from one data type to another.
int i = 10;
float f = 3.14;
Explicit Type Conversion (Casting): Manually done by the programmer using the
(type) syntax.
double d = 100.56;
Control flow statements are used to alter the sequence of execution in a program. They
allow you to make decisions and repeat blocks of code.
These statements allow the program to choose different paths of execution based on certain
conditions.
if statement:
o Syntax:
o if (condition) {
o }
o Example:
o }
if-else statement:
o Executes one block of code if the condition is true and another block if the
condition is false.
o Syntax:
o if (condition) {
o } else {
o }
o Example:
o int number = 7;
o if (number % 2 == 0) {
o } else {
o }
o Syntax:
o if (condition1) {
o // statements
o if (condition2) {
o // statements
o } else {
o // statements
o }
o } else {
o // statements
o }
o Example:
o if (a > b) {
o if (a > c) {
o } else {
o }
o } else {
o if (b > c) {
o } else {
o }
o }
else-if ladder:
o Syntax:
o if (condition1) {
o // statements
o } else if (condition2) {
o // statements
o } else if (condition3) {
o // statements
o } else {
o Example:
o printf("Grade A\n");
o printf("Grade B\n");
o printf("Grade C\n");
o } else {
o printf("Grade D\n");
o }
switch statement:
o The expression is evaluated, and its value is compared with the values of case
labels.
o The break statement is crucial to exit the switch block after a match;
otherwise, execution "falls through" to subsequent cases.
o Syntax:
o switch (expression) {
o case constant_value1:
o // statements
o break;
o case constant_value2:
o // statements
o break;
o default:
o }
o Example:
o switch (grade) {
o case 'A':
o printf("Excellent!\n");
o break;
o case 'B':
o printf("Good!\n");
o break;
o case 'C':
o printf("Fair.\n");
o break;
o default:
o printf("Needs improvement.\n");
o }
Looping Statements
Looping statements (or iterative statements) are used to execute a block of code repeatedly
as long as a certain condition is true.
for loop:
o Syntax:
o for (initialization; condition; increment/decrement) {
o // statements to execute
o }
o Example:
o }
o printf("\n");
while loop:
o Used when the number of iterations is not known beforehand, but the loop
continues as long as a condition is true.
o Syntax:
o while (condition) {
o // statements to execute
o }
o Example:
o int i = 1;
o while (i <= 5) {
o }
o printf("\n");
do-while loop:
o Similar to a while loop, but the condition is checked after executing the loop
body (exit-controlled loop).
o This means the loop body will always execute at least once.
o Syntax:
o do {
o // statements to execute
o } while (condition);
o Example:
o int i = 1;
o do {
o i++;
o printf("\n");
o do {
o printf("This will print once: %d\n", j); // Output: This will print once: 6
o j++;
o printf("* ");
o }
o }
o /* Output:
o ***
o ***
o ***
o */
Jump Statements
break:
o if (i == 5) {
o }
o }
o printf("\n");
continue:
o Skips the remaining statements in the current iteration of a loop (for, while,
do-while) and proceeds to the next iteration.
o Example:
o if (i == 3) {
o }
o }
o printf("\n");
o Overuse of goto can lead to "spaghetti code," making programs hard to read
and maintain. It's generally avoided in modern programming practices in
favor of structured control flow statements.
o Syntax:
o // ...
o goto label;
o // ...
o label:
o // statements
o Example (often used for breaking out of deeply nested loops, though
alternatives are preferred):
o if (i == 1 && j == 1) {
o }
o }
o }
o end_loops:
o printf("\nLoops terminated.\n");
return:
o Terminates the execution of the current function and returns control to the
caller function.
o Syntax:
4. Functions
Functions are self-contained blocks of code that perform a specific task. They are
fundamental to C programming for creating modular, reusable, and organized code.
Introduction to Functions
o Reusability: Write a function once and use it multiple times in different parts
of the program or even in different programs.
Function Definition:
o Provides the actual body of the function (the code that performs the task).
o Syntax:
o return_type function_name(parameter_list) {
o // statements
o }
return_type: The data type of the value the function returns (e.g., int,
float, void if it returns nothing).
o Tells the compiler about the function's name, return type, and the types of its
parameters before the function is actually defined or called.
o This is essential if you define a function after its first call, or if the function
definition is in a different file.
o Syntax:
o return_type function_name(parameter_type_list);
o Example:
o int add(int a, int b); // Function prototype
o // or
Function Call:
o Syntax:
o function_name(argument_list);
o Example:
o #include <stdio.h>
o int main() {
o int sum;
o // Function call
o return 0;
o }
o // Function definition
o return x + y;
o }
Function Parameters
Formal Parameters:
o They act as placeholders for the values that will be passed to the function
when it is called.
o In sum = add(num1, num2);, num1 and num2 (or their values) are actual
parameters.
Return Values
A function can return a single value to the calling code using the return statement.
The return_type in the function definition and declaration specifies the data type of
the value being returned.
o If a function does not need to return a value, its return type is specified as
void.
o A void function can still use return; (without a value) to exit the function
early.
o Example:
o void greet() {
o printf("Hello, World!\n");
o // return; // Optional here, as it's the end of the function
o }
o Functions can return any valid C data type (e.g., int, float, char, pointers,
structures).
o Example:
o }
Call by Value:
o Copies of the actual parameters' values are passed to the formal parameters
of the function.
o Changes made to the formal parameters inside the function do not affect the
actual parameters in the calling code.
o Example:
o #include <stdio.h>
o }
o int main() {
o int num = 5;
o printf("Before function call, num = %d\n", num);
o return 0;
o }
o /* Output:
o */
o Instead of passing values, the memory addresses of the actual parameters are
passed to the function.
o The formal parameters in the function become pointers that hold these
addresses.
o Example:
o #include <stdio.h>
o *ptr = *ptr + 10; // Changes the value at the address 'ptr' points to
o }
o int main() {
o int num = 5;
o printf("Before function call, num = %d\n", num);
o return 0;
o }
o /* Output:
o */
Recursion
1. Base Case: A condition that stops the recursion (prevents infinite loops).
2. Recursive Step: The part of the function where it calls itself, usually with
modified arguments that move closer to the base case.
Examples:
o Factorial:
o #include <stdio.h>
o if (n == 0 || n == 1) { // Base case
o return 1;
o }
o }
o int main() {
o int num = 5;
o return 0;
o }
o #include <stdio.h>
o int fibonacci(int n) {
o if (n == 0) { // Base case 1
o return 0;
o return 1;
o }
o }
o int main() {
o int count = 7;
o printf("\n"); // Output: 0 1 1 2 3 5 8
o return 0;
o }
(Note: Recursive Fibonacci is elegant but inefficient for large n due to repeated calculations.
Iterative solutions are often preferred for performance.)
Storage Classes
Storage classes in C determine the scope (visibility), lifetime (duration), and initial value of
variables and functions.
auto:
o The default storage class for local variables (variables declared inside a
function or block).
o Lifetime: Exists only while the block or function is being executed. Created
when the block is entered, destroyed when exited.
o Example:
o void myFunction() {
o }
extern (External):
o Scope: Global (can be accessed from any function in any file where it's
declared, provided the definition exists).
o Lifetime: Exists for the entire duration of the program.
o For variables: extern int globalVar; declares globalVar but doesn't allocate
memory for it (definition does).
o Example:
o // File1.c
o #include <stdio.h>
o int main() {
o display();
o return 0;
o }
o // File2.c
o #include <stdio.h>
o void display() {
o }
static:
Example:
void counterFunc() {
count++;
}
3. Static Functions:
register:
o A hint to the compiler to store the variable in a CPU register instead of RAM
for faster access.
o You cannot get the address of a register variable (using &) because registers
don't have memory addresses in the same way RAM does.
o Example:
o void processData() {
o }
o }