Introduction To Computer Programming Notes
Introduction To Computer Programming Notes
1. Structure of a C Program
int main() {
return 0;
#include <stdio.h>: This is a preprocessor directive that includes the standard input-output
library.
int main(): This is the main function, where execution starts.
{ : start of program execution.
return 0;: It indicates that the program ran successfully.
VARIABLES IN C
In C programming, variables are used to store data values. Each variable has a specific data type
that defines the type of data it can hold, such as integers, floating-point numbers, or characters.
A variable declaration specifies the type of data the variable will hold and its name. And the syntax is:
data_type variable_name
Type of variable in c
Int – for storing integers (whole number) eg 0, 36, 213, 10000000004, etc example: int age =23;
Float – for storing single precision floating point number ie 3.14. example: float pi = 3.14;
double = 3.145628277
Char – For storing individual characters ie a, A etc. example char grade = ‘A’;
Variable names are case sensitive ie name Name and NAME are different variable names.
Variable names cannot be key words ie int, float, char, double, switch, case, return etc.
Scope of variables
The scope of a variable determines where it can be accessed in a program. We have two types:
1. Local variables – these are declared inside a function and can only be accessed from within
that function.
Example:
void My_Function(){
}
2. Global Variables - are declared outside all functions and can be accessed by any function in
the program.
Example:
void My_Function(){
Data Types in C
Example:
struct Person {
char name[50];
int age;
};
Unions: Similar to structures, but all members share the same memory location.
o Example:
union Data {
int i;
float f;
};
Control Structures in C
Control structures allow the flow of a program to change, based on conditions or loops. They can
be grouped into:
1. Conditional Statements:
if (x > 0) {
printf("x is positive");
}
if-else: Executes one block of code if a condition is true, otherwise executes another.
o Example:
if (x > 0) {
printf("x is positive");
} else {
printf("x is not positive");
}
if (x > 0) {
printf("x is positive");
} else if (x == 0) {
printf("x is zero");
} else {
printf("x is negative");
}
switch (choice) {
case 1:
printf("Choice is 1");
break;
case 2:
printf("Choice is 2");
break;
default:
printf("Invalid choice");
}
2. Loops:
int i = 0;
while (i < 10) {
printf("%d ", i);
i++;
}
do-while loop: Executes a block of code at least once, then continues if the condition is
true.
o Example:
int i = 0;
do {
printf("%d ", i);
i++;
} while (i < 10);
continue: Skips the current iteration of the loop and proceeds to the next iteration.
o Example:
c
Copy code
int sum(int a, int b) {
return a + b;
}
bash
gcc hello.c -o hello
./hello
o On Windows, you can use MinGW or Visual Studio's compiler to compile and
run programs.
C Fundamentals
1. Arrays
An array is a collection of elements of the same type stored in contiguous memory locations.
Arrays in C are indexed from 0. Multidimensional arrays, like 2D arrays, are also supported.
int x = 10;
int *ptr = &x; // Pointer to an integer that holds the address of x
printf("%d", *ptr); // Dereferencing a pointer to get the value stored at the address
int *arr = (int*) malloc(5 * sizeof(int)); // Dynamically allocate memory for 5 integers
if (arr == NULL) {
printf("Memory allocation failed");
}
free(arr); // Deallocates the memory
Functions are reusable blocks of code that perform specific tasks. There are two ways to pass
arguments to functions:
You can return values from functions, and functions can also return pointers.
int num;
char ch;
ch = getchar(); // Reads a single character from input
putchar(ch); // Outputs the character
Structures:
A structure (struct) is a user-defined data type that groups variables of different data types under
a single name. It allows you to create complex data types that represent real-world entities.
Example of a Structure:
#include <stdio.h>
struct Person {
char name[50];
int age;
float height;
};
int main() {
struct Person person1; // Declare a structure variable
return 0;
}
Unions:
A union is similar to a structure, but its members share the same memory location. At any given
time, only one member can hold a value. This is useful for memory optimization when you only
need one of the members at a time.
Example of a Union:
#include <stdio.h>
union Data {
int i;
float f;
char str[20];
};
int main() {
union Data data;
return 0;
}
Key Differences:
Structures: Each member has its own memory, and all members can store values
simultaneously.
Unions: All members share the same memory space, and only one member can hold a
value at any given time.
2. Dynamic Memory Allocation and Deallocation
Dynamic memory allocation is the process of allocating memory during runtime using pointers.
The four key functions used for dynamic memory management in C are:
1. malloc(): Allocates a specified number of bytes and returns a pointer to the allocated
memory. The memory is not initialized.
2. calloc(): Allocates memory for an array of elements, initializing all bytes to zero.
int *ptr = (int*) calloc(5, sizeof(int)); // Allocate and initialize memory for 5 integers
int main() {
int *arr;
int n = 5;
if (arr == NULL) {
printf("Memory allocation failed!\n");
return 1;
}
// Deallocate memory
free(arr);
return 0;
}
Best Practices:
File handling in C allows you to read from and write to files on disk. C provides a set of
functions for performing input/output (I/O) operations on files, which are included in the stdio.h
library.
Opening and Closing Files:
Writing to a File:
char buffer[100];
fgets(buffer, 100, fp); // Read up to 100 characters from a file
int main() {
FILE *fp;
In this section, we'll dive into some more advanced C programming techniques, such as
preprocessor directives, bitwise manipulation, function pointers, and the use of popular C
libraries.
Preprocessor Directives:
Preprocessor directives are commands given to the C preprocessor, which runs before the actual
compilation of code begins. Common preprocessor directives include:
#define: Defines macros, which are constants or functions replaced by the preprocessor.
#if, #ifdef, #ifndef, #else, #endif: Conditional compilation, allowing certain parts of code
to be compiled based on conditions.
#ifdef DEBUG
printf("Debug mode is on.\n");
#endif
Macros:
Macros are typically used to define constants and inline functions. They help in avoiding
repetitive code.
Constant Macro:
Function-like Macros: You can define a macro that behaves like a function, which
avoids the overhead of a function call.
Bitwise operators perform operations at the bit level, which is useful for tasks such as low-level
hardware programming, optimizing memory usage, and encryption.
Bitwise Operators:
& (AND): Sets each bit to 1 if both bits are 1.
<< (Left Shift): Shifts bits to the left, adding 0s on the right.
>> (Right Shift): Shifts bits to the right, adding 0s on the left for unsigned integers.
bool isSet = x & (1 << n); // Checks if the nth bit is set
A function pointer is a pointer that points to a function. You can use it to call a function or pass it
as an argument to another function. This is useful for implementing callbacks, function dispatch
tables, and more.
// Function to be pointed to
int add(int a, int b) {
return a + b;
}
Function pointers can be passed as arguments to other functions, enabling more flexible and
reusable code.
void execute(int (*func)(int, int), int x, int y) {
printf("Result: %d\n", func(x, y));
}
int main() {
execute(add, 10, 5); // Output: 15
execute(subtract, 10, 5); // Output: 5
return 0;
}
4. Libraries in C
The C Standard Library provides a collection of built-in functions and header files that simplify
common programming tasks.
The math library contains functions for performing mathematical operations like square roots,
power, and trigonometric functions.
#include <math.h>
The string library provides functions for handling and manipulating C-style strings.
#include <string.h>
// Copy a string
strcpy(str2, str1);
// Concatenate strings
strcat(str1, " World!");
Variables are containers that store data, and C++ supports various data types to store different
kinds of information. A data type defines the type of data a variable can hold, such as integers,
floating-point numbers, characters, etc.
Example:
#include <iostream>
#include <string>
int main() {
int age = 25;
float height = 5.9;
char grade = 'A';
bool isStudent = true;
std::string name = "Alice";
return 0;
}
Control Structures:
Control structures direct the flow of a program. In C++, control structures include:
If-else statement:
int x = 10;
if (x > 5) {
std::cout << "x is greater than 5" << std::endl;
} else {
std::cout << "x is less than or equal to 5" << std::endl;
}
Loops:
o For loop:
o While loop:
int j = 0;
while (j < 5) {
std::cout << "j: " << j << std::endl;
j++;
}
o Do-while loop:
int k = 0;
do {
std::cout << "k: " << k << std::endl;
k++;
} while (k < 5);
C++ has a syntax similar to C but with added features for object-oriented programming (OOP)
and other advanced concepts.
Basic Syntax:
Every C++ program must have a main() function, which is the entry point of the program.
Code is written inside functions and blocks are defined by {} brackets.
Statements must end with a semicolon (;).
Input/output operations are done using cin and cout.
int main() {
std::cout << "Hello, World!" << std::endl; // Output a string
return 0; // Return 0 to indicate successful execution
}
You can use any text editor like VS Code, Sublime Text, or a full-fledged Integrated
Development Environment (IDE) like Code::Blocks, CLion, or Visual Studio.
2. Compiler:
You need a compiler that converts your C++ code into machine code. Popular C++ compilers
include:
After installing an IDE or text editor and compiler, write a simple "Hello, World!" program to
ensure everything is set up correctly.
4. C++ Fundamentals
Arrays:
An array is a collection of elements of the same type stored in contiguous memory locations.
Arrays are zero-indexed in C++.
Example:
#include <iostream>
int main() {
int arr[5] = {1, 2, 3, 4, 5}; // Declare and initialize an array
return 0;
}
Pointers:
Pointers store the memory address of another variable. They are a powerful feature in C++ for
dynamic memory allocation and managing memory more efficiently.
Example:
#include <iostream>
int main() {
int x = 10;
int *ptr = &x; // Pointer to x
return 0;
}
Memory Management:
In C++, dynamic memory can be allocated and deallocated using new and delete.
Memory Deallocation:
Functions in C++ allow you to encapsulate reusable code. Functions can pass parameters by
value, by reference, or by pointer.
void myFunction(int x) {
x = 10; // This change won't affect the original variable
}
C++ uses cin for input and cout for output, both of which are part of the iostream library.
int age;
std::cin >> age;
std::cout << "You entered: " << age << std::endl;
Example:
#include <iostream>
int main() {
int age;
std::cout << "Enter your age: ";
std::cin >> age;
std::cout << "You are " << age << " years old!" << std::endl;
return 0;
}
Objects: Real-world entities that have attributes (data) and behaviors (methods). Objects
are instances of classes.
Classes: Templates or blueprints used to create objects. They define the attributes and
behaviors that objects of that class will have.
OOP Principles:
Encapsulation: Bundling data (attributes) and methods (functions) that operate on the
data into a single unit (class), and restricting access to some of the object's components.
Inheritance: Creating new classes (derived classes) based on existing ones (base
classes), allowing reuse of code and extension of functionalities.
Polymorphism: The ability of different classes to be treated as instances of the same
class through interfaces or inheritance, typically through method overloading and
overriding.
Classes:
A class is a user-defined type that describes what attributes (data members) and methods
(member functions) its objects will have. The syntax for creating a class involves specifying the
class name and the body of the class.
#include <iostream>
class Person {
public:
// Data members (attributes)
std::string name;
int age;
int main() {
// Create an object (instance) of class Person
Person person1;
return 0;
}
Objects:
Objects are instances of a class. You can create objects using the class name and then use the dot
operator (.) to access the class members (data and functions).
Member functions are functions defined inside a class that operate on objects of that class. They
have access to the data members of the class.
3. Encapsulation
Encapsulation refers to the bundling of data and functions that manipulate the data within a
single unit or class. It also involves controlling the access to the data by making it private and
exposing it through public methods.
#include <iostream>
class Car {
private:
int speed; // Private member
public:
// Public setter method to set the value of speed
void setSpeed(int s) {
if (s > 0) {
speed = s;
}
}
int main() {
Car car1;
[Link](120); // Access through public methods
std::cout << "Car speed: " << [Link]() << std::endl;
return 0;
}
In this example, speed is encapsulated as a private member, and it can only be accessed or
modified through the public methods setSpeed() and getSpeed().
4. Inheritance
Inheritance allows one class (child or derived class) to inherit properties and behaviors from
another class (parent or base class). It enables code reuse and the creation of a class hierarchy.
Example:
#include <iostream>
int main() {
Dog dog1;
[Link](); // Inherited from the Animal class
[Link](); // Defined in the Dog class
return 0;
}
Types of Inheritance:
5. Polymorphism
Polymorphism means "many forms" and allows objects of different classes to be treated as
objects of a common base class. It is achieved through:
Function Overloading: Defining multiple functions with the same name but different
parameters.
Function Overriding: Redefining a function in a derived class that was already defined
in the base class.
Function Overloading:
#include <iostream>
class Calculator {
public:
// Overloading the add function to handle different parameter types
int add(int a, int b) {
return a + b;
}
double add(double a, double b) {
return a + b;
}
};
int main() {
Calculator calc;
std::cout << "Sum of integers: " << [Link](3, 5) << std::endl;
std::cout << "Sum of doubles: " << [Link](2.5, 4.1) << std::endl;
return 0;
}
Overriding allows a derived class to provide its own implementation of a function that is defined
in its base class. To achieve runtime polymorphism, C++ uses virtual functions.
Example:
#include <iostream>
// Base class
class Animal {
public:
virtual void sound() {
std::cout << "Some animal sound." << std::endl;
}
};
// Derived class
class Dog : public Animal {
public:
void sound() override { // Function overriding
std::cout << "The dog barks." << std::endl;
}
};
int main() {
Animal* animalPtr;
Dog dog1;
return 0;
}
In this example, the base class Animal has a virtual function sound(), and the derived class Dog
overrides this function. When using a base class pointer to refer to a derived class object, the
overridden method in the derived class is called, achieving runtime polymorphism.
6. Abstraction
Hiding the complex details of a system from the user and only exposing the essential features.
1. Abstract Classes: An abstract class is a class that cannot be instantiated on its own and
typically contains at least one pure virtual function. This allows you to define a common
interface for derived classes while enforcing that certain methods must be implemented.
class Shape {
public:
// Pure virtual function
virtual void draw() = 0; // No implementation in the base class
};
In this example, Shape is an abstract class with a pure virtual function draw(). The
derived classes Circle and Rectangle provide specific implementations for the draw()
function.
2. Interfaces: In C++, an interface is essentially a class with only pure virtual functions. It
defines a contract that derived classes must fulfill.
class Drawable {
public:
virtual void draw() = 0; // Interface method
};
Any class that implements this interface must provide an implementation for the draw()
method.
Advantages of Abstraction:
Intermediate C++ programming encompasses several advanced topics that enhance code
reusability, error management, and data manipulation. Here’s a detailed overview of templates
and generic programming, exceptions and error handling, and the Standard Template
Library (STL).
Templates are a powerful feature in C++ that allows you to write generic and reusable code.
With templates, you can create functions and classes that operate on any data type.
Function Templates
Function templates enable you to define a function without specifying the exact type of the
parameters. The type is determined when the function is called.
Example:
#include <iostream>
// Function template
template <typename T>
T add(T a, T b) {
return a + b;
}
int main() {
std::cout << "Integer sum: " << add(3, 4) << std::endl; // Calls
add<int>
std::cout << "Double sum: " << add(2.5, 3.5) << std::endl; // Calls
add<double>
return 0;
}
In this example, the add function is defined as a template that can take any type T. When called
with specific types, the compiler generates the appropriate function.
Class Templates
Class templates allow you to create a class that can operate on any data type.
Example:
#include <iostream>
// Class template
template <typename T>
class Pair {
private:
T first, second;
public:
Pair(T a, T b) : first(a), second(b) {}
int main() {
Pair<int> intPair(1, 2);
Pair<double> doublePair(1.5, 2.5);
return 0;
}
Here, Pair is a class template that can hold two values of the same type T.
Throwing Exceptions
Example:
#include <iostream>
#include <stdexcept> // For std::runtime_error
int main() {
try {
divide(10, 0); // This will throw an exception
} catch (const std::runtime_error& e) {
std::cerr << "Error: " << [Link]() << std::endl; // Catching and
handling the exception
}
return 0;
}
In this example, if b is zero, an exception is thrown, which is then caught and handled in the
catch block.
Catch Blocks
You can have multiple catch blocks to handle different types of exceptions:
try {
// Code that might throw exceptions
} catch (const std::invalid_argument& e) {
// Handle invalid argument exception
} catch (const std::runtime_error& e) {
// Handle runtime error exception
}
The Standard Template Library (STL) is a powerful library in C++ that provides a collection
of template classes and functions, including various containers and algorithms.
STL Containers
STL containers are data structures that store collections of objects. Common containers include:
#include <vector>
std::vector<int> numbers = {1, 2, 3, 4, 5};
List: A doubly linked list that allows efficient insertion and deletion.
#include <list>
std::list<int> myList = {1, 2, 3};
#include <map>
std::map<std::string, int> ageMap = {{"Alice", 30}, {"Bob", 25}};
STL Algorithms
The STL provides a variety of algorithms that operate on containers, including sorting,
searching, and manipulating data.
Example:
#include <iostream>
#include <vector>
#include <algorithm> // For std::sort
int main() {
std::vector<int> numbers = {4, 2, 5, 1, 3};
return 0;
}
1. Advanced Language Features
Operator Overloading
Operator overloading allows you to define custom behavior for operators (like +, -, *, etc.) for
user-defined types (classes). This enables intuitive syntax for operations on objects.
Example:
#include <iostream>
class Complex {
private:
double real, imag;
public:
Complex(double r, double i) : real(r), imag(i) {}
int main() {
Complex c1(3.0, 4.0);
Complex c2(1.0, 2.0);
Complex c3 = c1 + c2; // Using overloaded + operator
[Link](); // Output: 4.0 + 6.0i
return 0;
}
Type Conversions
Type conversions in C++ can be implicit or explicit. Implicit conversions happen automatically,
while explicit conversions require a cast.
int a = 5;
double b = a; // Implicit conversion from int to double
double d = 9.7;
int i = static_cast<int>(d); // Explicit conversion from double to int
Creating Threads
Example:
#include <iostream>
#include <thread>
void printHello() {
std::cout << "Hello from thread!" << std::endl;
}
int main() {
std::thread t(printHello); // Create a thread
[Link](); // Wait for the thread to finish
return 0;
}
Example:
#include <iostream>
#include <thread>
#include <mutex>
void increment() {
for (int i = 0; i < 1000; ++i) {
std::lock_guard<std::mutex> lock(mtx); // Lock the mutex
++sharedCounter; // Increment shared counter
}
}
int main() {
std::thread t1(increment);
std::thread t2(increment);
[Link]();
[Link]();
std::cout << "Final counter: " << sharedCounter << std::endl; // Output: 2000
return 0;
}
Here, std::lock_guard automatically locks the mutex when it is created and releases it when it
goes out of scope, ensuring safe access to the shared resource.
The C++ standards introduced several important features that enhance the language's
capabilities:
C++11 Features
C++14 Features
Generic Lambdas: Lambda expressions can now use auto in their parameter lists.
Return Type Deduction: Functions can deduce their return type automatically.
C++17 Features
Optional and Variant: Provides types that represent optional values or values that can
take on several types.
Inline Variables: Allows the definition of variables that can be initialized in header files
without violating the one-definition rule.