Code With Harry C
Code With Harry C
01 2025 18:33
C Overview
What is C?
• Since the late 19th century, C has been a popular programming language for general-
purpose use.
• C language was developed by Dennis M. Ritchie at Bell Laboratories in the early 1970s.
• Its applications are very diverse. It ranges from developing operating systems to databases
and more. It is a system programming language used to do low-level programming (e.g.,
driver or kernel).
• Even if it’s old, it is still a very popular programming language.
• As the whole UNIX operating system was written in C, it has a strong association with
operating systems.
• C has also been used widely while creating iOS and Android kernels.
• MySQL database is written using C.
• Ruby and Perl are mostly written using C.
• Most parts of Apache and NGINX are written using C.
• Embedded Systems are created using C.
Why should we learn C/ Features of C?
• As mentioned above, it is one of the most popular programming languages in the world.
• Learning any other popular programming language such as Python or C++ becomes much
easier if you know C.
• C is a flexible language, proven by the fact that it can be used in a variety of applications as
well as technologies.
• C is very fast when compared to other programming languages, be it Java or Python.
• C takes only significant CPU time for interpretation. That is why a lot of Python libraries such
as NumPy, pandas, Scikit-learn, etc., are built using C.
• Being close to machine language, some of its functions include direct access to machine-
level hardware APIs.
• It is a structural language (follows a specific structure) and a compiled language.
• It is a procedural programming language (POP). Procedural programming is the use of code
in a step-wise procedure to develop applications.
How is it different from C++?
• The syntax of C++ is almost identical to that of C, as C++ was developed as an extension of
C.
• In contrast to C, C++ supports classes and objects, while C does not.
• C gives most of the control to the hands of users. Things like memory allocation and
manipulation are totally in the hands of the programmer. Being a flexible language, it
provides more access to the programmer, making it more efficient.
• C is POP (procedure-oriented programming), whereas C++ is OOP (object-oriented
programming).
From <https://www.codewithharry.com/tutorial/c>
From <https://www.codewithharry.com/tutorial/getting-started-with-c>
From <https://www.codewithharry.com/tutorial/basic-structure-and-syntax>
C Comments
Comments can be used to insert any informative piece which a programmer does not wish
to be executed. It could be either to explain a piece of code or to make it more readable. In
addition, it can be used to prevent the execution of alternative code when the process of
debugging is done.
Comments can be single-lined or multi-lined.
Single Line Comments
• Single-line comments start with two forward slashes (//).
From <https://www.codewithharry.com/tutorial/c-comments>
C Variables
Variables are containers for storing data values.
In C, there are different types of variables.
For example:
• An integer variable defined with the keyword int stores integers (whole numbers), without
decimals, such as 91 or -13.
• A floating point variable defined with the keyword float stores floating point numbers, with
decimals, such as 99.98 or -1.23.
• A character variable defined with the keyword char stores single characters, such as 'A' or 'z'.
Char values are bound to be surrounded by single quotes.
Declaration
We cannot declare a variable without specifying its data type. The data type of a variable
depends on what we want to store in the variable and how much space we want it to hold.
The syntax for declaring a variable is simple:
data_type variable_name;
OR
data_type variable_name = value;
Naming a Variable
There is no limit to what we can call a variable. Yet there are specific rules we must follow
while naming a variable:
• A variable name can only contain alphabets, digits, and underscores (_).
• A variable cannot start with a digit.
• A variable cannot include any white space in its name.
• The name should not be a reserved keyword or any special character.
A variable, as its name is defined, can be altered, or its value can be changed, but the same
is not true for its type. If a variable is of integer type, then it will only store an integer value
through a program. We cannot assign a character type value to an integer variable. We
cannot even store a decimal value into an integer variable.
From <https://www.codewithharry.com/tutorial/c-variables>
From <https://www.codewithharry.com/tutorial/c-data-types-operators-and-user-input-ouput>
C Operators
Special symbols that are used to perform actions or operations are known as operators.
They could be both unary or binary.
For example, the symbol asterisk (*) is used to perform multiplication in C so it is an operator
and it is a binary operator.
This section covers all types of operators.
Arithmetic Operators
Arithmetic operators are used to perform mathematical operations such as addition,
subtraction, etc. A few of the simple arithmetic operators are:
Operator Description
+ Addition
- Subtraction
* Multiplication
/ Division
% Modulus
We all must already know their purpose and how they are used in simple mathematics. Their
purpose and functionality are the same.
Modulus(%) operator - this operator returns the remainder of two operands when they are
been divided
#include<stdio.h>int main(){ int x; x = 5 % 2; printf("remainder is %d", x);}
From <https://www.codewithharry.com/tutorial/c-operators>
From <https://www.codewithharry.com/tutorial/c-format-specifiers-and-escape-sequences>
User Input/Output
We have already learned how the printf() function is used to output values in C. Another
method, which goes by the name, scanf(), is used to get user input.
The scanf() function takes two arguments:
• the format specifier of the variable (as shown in the example below)
• the reference operator (&myNum), which stores the memory address of the variable. This is
where the input data goes to.
Syntax
scanf("format specifier", &variable_name);
& - specifies the address of the variable.
One such example demonstrates how a program takes input from the user.
#include <stdio.h> int main(){ int marks; char name[30]; printf("Enter student's name: ");
scanf("%s", name); printf("Enter marks in Maths: "); scanf("%d", &marks); printf("Hello %s! You
have scored %d in Maths!", name, marks); return 0;}
Input
Enter student's name: Rohan
Enter marks in Maths: 98
Output
Hello Rohan! You have scored 98 in Maths!
You must note that we didn’t have to specify the reference operator (&) in cases of strings if
we have specified the size of the strings already. This is an exception.
From <https://www.codewithharry.com/tutorial/c-user-input-output>
C if...else statements
Sometimes, we wish to execute one set of instructions if a particular condition is met, and
another set of instructions if it is not. This kind of situation is dealt with in C language using a
decision control system.
The condition for the if statement is always enclosed within a pair of parentheses. If the
condition is true, then the set of statements following the if statement will execute. And if the
condition evaluates to false, then the statement will not execute, instead, the program skips
that enclosed part of the code.
An expression in if statements is defined using relational operators. Comparing two values
using relational operators allows us to determine whether they are equal, unequal, greater
than, or less than.
If we want to execute a particular code in some situation and its vice versa/opposite/different
code if that situation doesn’t occur, then if..else statements can be used. It all depends on
the condition. If the condition returns a true value, the situation has occurred, and the true
part of the code will be executed. If the condition returns a false value, the false part of the
code will be executed.
Conditions Meaning
a==b a is equal to b
From <https://www.codewithharry.com/tutorial/c-if-else-statements>
From <https://www.codewithharry.com/tutorial/c-switch-case-statements>
C Loops
In programming, we often have to perform an action repeatedly, with little or no variations in
the details each time they are executed. This need is met by a mechanism known as a loop.
The versatility of the computer lies in its ability to perform a set of instructions repeatedly.
This involves repeating some code in the program, either a specified number of times or until
a particular condition is satisfied. Loop-controlled instructions are used to perform this
repetitive operation efficiently, ensuring the program doesn’t look redundant at the same
time due to the repetitions.
Following are the three types of loops in C programming:
• For loop
• While loop
• Do-while loop
Types of Loops
Entry Controlled loops
In entry controlled loops, the test condition is evaluated before entering the loop body.
The for loop and the while loop are examples of entry-controlled loops.
Exit Controlled Loops
In exit-controlled loops, the test condition is tested at the end of the loop. Regardless of
whether the test condition is true or false, the loop body will execute at least once. The do-
while loop is an example of an exit-controlled loop.
For Loop
A for loop is a repetition control structure that allows us to efficiently write a loop that will
execute a specific number of times. The for loop working is as follows:
• The initialization statement is executed only once; in this statement, we initialize a variable to
some value.
• In the second step, the test expression is evaluated. Suppose the test expression is
evaluated to be true. In that case, the for loop keeps running, and the test expression is re-
evaluated, but if the test expression is evaluated to false, then the for loop terminates.
From <https://www.codewithharry.com/tutorial/c-loops>
while Loop
A While loop is also called a pre-tested loop. A while loop allows a piece of code in a
program to be executed multiple times, depending upon a given test condition which
evaluates to either true or false. The while loop is mostly used in cases where the number of
iterations is not known. If the number of iterations is known, then we could also use a for
loop.
The syntax for using a while loop:
while (condition test){ // Set of statements}
The body of a while loop can contain a single statement or a block of statements. The test
condition may be any expression that should evaluate as either true or false. The loop
iterates while the test condition evaluates to true. When the condition becomes false, the
program control passes to the line immediately following the loop, which means it
terminates.
One such example to demonstrate how a while loop works is:
#include <stdio.h> int main(){ int i = 0; while (i <= 5) { printf("%d ", i); i++; } return 0;}
Output
012345
Properties of the while loop:
Following are some of the properties of the while loop.
• A conditional expression written in the brackets of while is used to check the condition. The
set of statements defined inside the while loop will execute until the given condition returns
false.
• The condition will return 0 if it is true. The condition will be false if it returns any nonzero
number.
• In the while loop, we cannot execute the loop until we do not specify the condition
expression.
• It is possible to execute a while loop without any statements. This will give no error.
• We can have multiple conditional expressions in a while loop.
• Braces are optional if the loop body contains only one statement.
do-while Loop
A do-while loop is a little different from a normal while loop. A do-while loop, unlike what
happens in a while loop, executes the statements inside the body of the loop before
checking the test condition.
So even if a condition is false in the first place, the do-while loop would have already run
once. A do-while loop is very much similar to a while loop, except for the fact that it is
guaranteed to execute the body at least once.
Unlike for and while loops, which test the loop condition first, then execute the code written
inside the body of the loop, the do-while loop checks its condition at the end of the loop.
Following is the syntax of the do-while loop.
do{ statements;} while (test condition);
If the test condition returns true, the flow of control jumps back up to the do part, and the set
of statements in the loop executes again. This process repeats until the given test condition
becomes false.
How does the do-while loop work?
• First, the body of the do-while loop is executed once. Only then, the test condition is
evaluated.
• If the test condition returns true, the set of instructions inside the body of the loop is
executed again, and the test condition is evaluated.
• The same process goes on until the test condition becomes false.
• If the test condition returns false, then the loop terminates.
One such example to demonstrate how a do-while loop works is:
#include <stdio.h> int main(){ int i = 5; do { printf("%d ", i); i++; } while (i < 5); return
0;}
Output
5
As it was already mentioned at the beginning of this tutorial, a do-while loop runs for at least
once even if the test condition returns false, because the test condition is evaluated only
after the first execution of the instructions in the body of the loop.
Difference between a while and a do-while loop
A While loop is executed every time the given test condition returns true, whereas, a do-
while loop is executed for the first time irrespective of the test condition being true or false
because the test condition is checked only after executing the loop for the first time.
From <https://www.codewithharry.com/tutorial/c-do-while-loop>
for Loop
The "For" loop is used to repeat a specific piece of code in a program until a specific
condition is satisfied. The for loop statement is very specialized. We use a for loop when we
already know the number of iterations of that particular piece of code we wish to execute.
Although, when we do not know about the number of iterations, we use a while loop.
Here is the syntax of a for loop in C programming.
for (initialise counter; test counter; increment / decrement counter){ //set of statements}
Here,
• initialize counter: It will initialize the loop counter value. It is usually i=0.
• test counter: This is the test condition, which if found true, the loop continues, otherwise
terminates.
• Increment/decrement counter: Incrementing or decrementing the counter.
• Set of statements: This is the body or the executable part of the for loop or the set of
statements that has to repeat itself.
One such example to demonstrate how a for loop works is,
#include <stdio.h> int main(){ int num = 10; int i; for (i = 0; i < num; i++) { printf("%d ",
From <https://www.codewithharry.com/tutorial/c-for-loop>
C Break/Continue
Break Statement
• Break statement is used to break the loop or switch case statements execution and brings
the control to the next block of code after that particular loop or switch case it was used in.
• Break statements are used to bring the program control out of the loop it was encountered
in.
• The break statement is used inside loops or switch statements in C Language.
One such example to demonstrate how a break statement works is:
#include <stdio.h> int main(){ int i = 0; while (1) { if (i > 5) { break; }
printf("%d ", i); i++; } return 0;}
Output
012345
Here, when i became 6, the break statement got executed and the program came out of the
while loop.
Continue Statement
• The continue statement is used inside loops in C Language. When a continue statement is
encountered inside the loop, the control jumps to the beginning of the loop for the next
iteration, skipping the execution of statements inside the body of the loop after the continue
statement.
• It is used to bring the control to the next iteration of the loop.
• Typically, the continue statement skips some code inside the loop and lets the program
move on with the next iteration.
• It is mainly used for a condition so that we can skip some lines of code for a particular
condition.
• It forces the next iteration to follow in the loop unlike a break statement, which terminates the
loop itself the moment it is encountered.
One such example to demonstrate how a continue statement works is:
#include <stdio.h> int main(){ for (int i = 0; i <= 10; i++) { if (i < 6) { continue; }
printf("%d ", i); } return 0;}
Output
6 7 8 9 10
Here, the continue statement was continuously executing while i remained less than 6. For
all the other values of i, we got the print statement working.
From <https://www.codewithharry.com/tutorial/c-break-continue-statement>
From <https://www.codewithharry.com/tutorial/c-array-basics>
Array Operations
Defining an array
1. Without specifying the size of the array
int arr[] = {1, 2, 3};
Here, we can leave the square brackets empty, although the array cannot be left empty in
this case. It must have elements in it.
2. With specifying the size of the array
int arr[3];arr[0] = 1, arr[1] = 2, arr[2] = 3;
Here, we can specify the size of the array in its definition itself. We can then put array
elements later as well.
Accessing an array element
An element in an array can easily be accessed through its index number. This must be
remembered that the index number starts from 0 and not one.
Example:
#include <stdio.h> int main() { int arr[] = {1, 5, 7, 2}; printf("%d ", arr[2]); //printing element on
index 2 }
Output:
7
Changing an array element
An element in an array can be overwritten using its index number.
From <https://www.codewithharry.com/tutorial/c-array-operations>
String Basics
What are Strings?
A string is an array of characters. Data of the same type are stored in an array, for example,
integers can be stored in an integer array, similarly, a group of characters can be stored in a
character array. This character array is also known as strings. A string is a one-dimensional
array of characters that is terminated by a null ('\0').
Declaration of Strings:
Declaring a string is very simple, the same as declaring a one-dimensional array. It’s just
that we are considering it as an array of characters.
Below is the syntax for declaring a string.
char string_name[string_size];
In the above syntax, string_name is any name given to the string variable, and string_size is
used to define the length of the string, i.e., the number of characters that the strings will
store. Keep in mind that there is an extra terminating character which is the null character
('\0') that is used to indicate the termination of the string.
Example of string:
#include <stdio.h>int main(){ // declare and initialise string char str[] = "CodeWithHarry";
printf("%s", str); return 0;}
Output:
CodeWithHarry
From <https://www.codewithharry.com/tutorial/c-string-basics>
String Functions
We can use C's string handling library functions to handle strings. The string.h library is used
to perform string operations. It provides several functions for manipulating strings.
Following are some commonly used string handling functions:
1. strcat():
This function is used to concatenate the source string to the end of the target string. This
function expects two parameters, first, the base address of the source string and then the
base address of the target string. For example, “Hello” and “World” on concatenation would
result in a string “HelloWorld”.
Here is how we can use the strcat() function:
#include <stdio.h>#include <string.h>int main(){ char s[] = "Hello"; char t[] = "World"; strcat(s, t);
printf("String = %s", s);}
Output:
String = HelloWorld
2. strlen():
This function is used to count the number of characters present in a string.
Here is how we can use the strlen() function:
#include <stdio.h>#include <string.h>int main(){ char s[] = "Hello"; int len = strlen(s);
printf("Length = %d", len);}
Output:
Length = 5
3. strcpy():
This function is used to copy the contents of one string into the other. This function expects
two parameters, first, the base address of the source string and then the base address of the
From <https://www.codewithharry.com/tutorial/c-string-functions>
Function Basics
Functions:
• Functions are used to divide a large C program into smaller and less complex pieces.
• A function can be called multiple or several times to provide reusability and modularity to the
C program.
• Functions are also called procedures, subroutines, or methods.
• A function is also a piece of code that performs a specific task.
A function is nothing but a group of code put together and given a name, and it can be called
anytime without writing the whole code again and again in a program.
I know its syntax is a bit difficult to understand, but don’t worry; after reading this whole
information about Functions, you will know each and every term or thing related to
Functions.
Advantages of Functions
• The use of functions allows us to avoid re-writing the same logic or code over and over
again.
• With the help of functions, we can divide the work among the programmers.
• We can easily debug or find bugs in any program using functions.
• They make code readable and less complex.
Aspects of a Function
7. Declaration
This is where a function is declared to tell the compiler about its existence.
8. Definition
A function is defined to get some task executed. (It means when we define a function, we
write the whole code of that function, and this is where the actual implementation of the
function is done.)
9. Call
This is where a function is called in order to be used.
Types of Functions
10. Library functions:
From <https://www.codewithharry.com/tutorial/c-function-basics>
Function Parameters
A parameter or an argument of a function is the information we wish to pass to the function
when it is called to be executed. Parameters act as variables inside the function.
Parameters are specified after the function name, inside the parentheses. You can add as
many parameters as you want, just separate them with a comma.
Here’s the basic syntax of a function
return_type functionName(parameter1, parameter2) { // body of the function}
What is the return_type?
Return type specifies the data type the function should return after its execution. It could also
be a void where the function is required to return nothing.
Different ways to define a function
12. Without arguments and without return value
In this function, we don’t have to give any value to the function (argument/parameters) and
even don’t have to take any value from it in return.
One example of such functions could be:
#include <stdio.h> void func() { printf("This function doesn't return anything.");} int main() { func();}
Output:
This function doesn’t return anything.
Output:
11
The function func when called, asks for two integer inputs and returns the sum of them. The
function’s return type is an integer.
14. With arguments and without a return value.
In this type of function, we give arguments or parameters to the function but we don’t get any
value from it in return.
One example of such functions could be:
#include <stdio.h> void func(int a, int b) { printf("%d", a * b);} int main() { func(2, 3);}
Output:
6
The function’s return type is void. And it takes two integers as its parameters and prints the
product of them while returning nothing.
15. With arguments and with the return value
In these functions, we give arguments to a function and in return, we also get some value
from it.
One example of such functions could be:
The function func takes two integers as its parameters and returns an integer which is their
sum.
Make sure the return statement and the return_type of the functions are the same.
From <https://www.codewithharry.com/tutorial/c-function-parameters>
Functions Declaration
A function consists of two parts:
• Declaration, where we specify the function's name, its return type, and required parameters
(if any).
• Definition, which is nothing but the body of the function (code to be executed).
The basic structure of a function is:
return_type functionName() { // declaration // body of the function (definition)}
For code optimization and readability, it is often recommended to separate the declaration
and the definition of the function.
And this is the reason why you will often see C programs that have function declarations
above the main() function, and function definitions below the main() function. This will make
the code better organized and easier to read.
This is how it is done:
#include <stdio.h> // Function declarationvoid func(); int main(){ func(); // calling the function return
0;} // Function definitionvoid func(){ printf("This is the definition part.");}
Output:
This is the definition part.
From <https://www.codewithharry.com/tutorial/c-functions-declaration>
Recursive Functions
What are recursive functions?
Recursive functions or recursion is a process when a function calls a copy of itself to work
on smaller problems.
Recursion is the process in which a function calls itself directly or indirectly. The
corresponding function which calls itself is called a recursive function.
• Any function which calls itself is called a recursive function.
• This makes the life of a programmer easy by dividing a complex problem into simple or
easier problems.
• A termination condition is imposed on such functions to stop them from executing copies of
themselves forever or infinitely. This is also known as the base condition.
• Any problem which can be solved recursively can also be solved iteratively.
• Recursions are used to solve tougher problems like Tower Of Hanoi, Fibonacci Series,
Factorial finding, etc., and many more, where solving by intuition becomes tough.
What is a base condition?
The case in which the function doesn’t recur is called the base case.
For example, when we try to find the factorial of a number using recursion, the case when
our number becomes smaller than 1 is the base case.
Recursive Case
The instances where the function keeps calling itself to perform a subtask, which is generally
the same problem with the problem size reduced to many smaller parts, is called the
recursive case.
Example of recursion:
From <https://www.codewithharry.com/tutorial/c-recursive-functions>
C Pointers
When we initialize an array, we usually come to know about the:
• Memory block which is the space a variable gets in RAM. We can think of that space as a
block.
• Name of the memory block which is the variable’s name itself.
• Content of that block that is the value stored in that variable.
• Address of the memory block assigned to the variable which is a unique address that allows
us to access that variable.
What is a Pointer?
• A pointer is a variable that contains the address of another variable. It means it is a variable
that points to any other variable.
• Although this is itself a variable, it contains the address or memory address of any other
variable.
• It can be of type int, char, array, function, or even any other pointer.
• Its size depends on the architecture.
• Pointers in C Language can be declared using the * (asterisk symbol).
So, pointers are nothing but variables that store addresses of other variables, and by using
pointers, we can access other variables too and can even manipulate them.
Applications of Pointers
• Pointers are used to dynamically allocate or deallocate memory using methods such
as malloc(), realloc(), calloc(), and free().
• Pointers are used to point to several containers such as arrays, or structs, and also for
passing addresses of containers to functions.
• Return multiple values from a function.
• Rather than passing a copy of a container to a function, we can simply pass its pointer. This
helps reduce the memory usage of the program.
• Pointers reduce the code and improve the performance.
From <https://www.codewithharry.com/tutorial/C-pointers>
Operations on Pointers
Address of Operator (&):
• It is a unary operator.
• Operand must be the name of an already defined variable.
• & operator gives the address number of the variable.
• & is also known as the “Referencing Operator”.
Here’s one example to demonstrate the use of the address of the operator.
#include <stdio.h> int main(){ int a = 100; printf("%d\n", a); printf("Address of variable a is %d",
&a); return 0;}
Output:
100
Address of variable a is 6422220
Indirection Operator (*):
• * is an indirection operator.
• It is also known as the “Dereferencing Operator”.
From <https://www.codewithharry.com/tutorial/c-operations-on-pointers>
C VOID Pointer
After a brief discussion about pointers, it’s time to start with a very important type of pointers:
void pointers and their functionalities. We already know that a void function has no return
type, i.e., functions that are not returning anything are given the type void. Now, in the case
of pointers that are given the datatype of a void, they can be typecasted into any other data
type according to the necessity. This means we do not have to decide on a data type for the
pointer initially.
Void pointers can also be addressed as general-purpose pointer variables.
Let’s see a few examples that will demonstrate the functionalities of a void pointer.
Example:
int var = 1;void *voidPointer = &var;
Here, the data type of the void pointer gets typecasted into int as we have stored the
address of an integer value in it.
char x = 'a';void *voidPointer = &x;
In this example, the void pointer’s data type gets typecasted to char as we have stored the
address of a character value in it.
Type casting a void pointer must also remind you of the way we used to type cast a void
pointer returned by the functions malloc() and calloc() for dynamic memory allocation. There
also, the heap returns a void pointer to the memory requested. We could type cast it to any
other data type, and that is where a void pointer comes in handy.
Two important features of a VOID pointer are:
Void pointers cannot be dereferenced.
This can be demonstrated with the help of an example.
int a = 10;void *voidPointer;voidPointer = &a;printf("%d", *voidPointer);
Output:
Compiler Error!
This program will throw a compile-time error, as we cannot dereference a void pointer,
meaning that we would compulsorily have to typecast the pointer every time it is being used.
Here’s how it should be done.
int a = 10;void *voidPointer;voidPointer = &a;printf("%d", *(int *)voidPointer);
Output:
10
The compiler will not throw any error and will directly output the result because we are using
the type along with the pointer.
Pointer arithmetics cannot be used with void pointers since it is not holding any address to
be able to increment or decrement its value.
From <https://www.codewithharry.com/tutorial/c-void-pointer>
C NULL Pointer
A pointer that is not assigned any value or memory address but NULL is known as a NULL
pointer. A NULL pointer does not point to any object, variable, or function. NULL pointers are
often used to initialize a pointer variable, where we wish to represent that the pointer
variable isn’t currently assigned to any valid memory address yet.
From <https://www.codewithharry.com/tutorial/c-null-pointer>
Dangling Pointer
Dangling pointers are pointers that are pointing to a memory location that has been already
freed or deleted.
Dangling pointers often come into existence during object destruction. It happens when an
object with an incoming reference is deleted or de-allocated, without modifying the value of
the pointer. The pointer still points to the memory location of the deallocated memory.
The system may itself reallocate the previously deleted memory and several unpredicted
results may occur as the memory may now contain different data.
Dangling pointers are caused by the following factors:
De-allocating or free variable memory
When memory is deallocated, the pointer keeps pointing to freed space. An example to
demonstrate how that happens is:
#include <stdio.h>int main(){ int a = 80; int *ptr = (int *)malloc(sizeof(int)); ptr = &a; free(ptr);
return 0;}
The above code demonstrates how a variable pointer *ptr and an integer
variable a containing a value 80 was created. The pointer variable *ptr is created with the
help of the malloc() function. As we know that malloc() function returns a void pointer, so we
use int * for type conversion to convert the void pointer into an int pointer.
Function Call
Now, we will see how the pointer becomes dangling with the function call.
From <https://www.codewithharry.com/tutorial/c-dangling-pointer>
Wild Pointer
Uninitialized pointers are known as wild pointers because they point to some arbitrary
memory location while they are not assigned to any other memory location. This may even
cause a program to crash or behave unpredictably at times.
For example:
int *ptr;
Here, a pointer named ptr is created but was not given any value. This makes the
pointer ptr a wild pointer.
Declaring a pointer and not initializing it has its own disadvantages. One such disadvantage
is that it will store any garbage value in it. A random location in memory will be held in it
arbitrarily. This random allocation often becomes tough for a programmer to debug, causing
a lot of problems in the execution of the program.
A. Avoiding problems due to WILD pointers
Dereferencing a wild pointer becomes problematic at times, and to avoid them, we often
prefer to convert a wild pointer to a NULL pointer. By doing so, our pointer will not point to
any garbage memory location; rather, it will point to a NULL location. We can convert a wild
pointer to a NULL pointer by merely setting it equal to NULL.
B. Dereferencing
We cannot dereference a wild pointer as we are not sure about the data in the memory it is
pointing towards. In addition to causing a lot of bugs, dereferencing a wild pointer can also
cause the program to crash.
From <https://www.codewithharry.com/tutorial/c-wild-pointer>
C Static Variables
A. Local Variables
Local variables are variables that are declared inside a function or a block of code. These
variables cannot be accessed outside the function they are declared in. Local variables can
be accessed only by statements that are inside that function or block of code, which means
the scope of these variables will be within the function only.
From <https://www.codewithharry.com/tutorial/c-static-variables>
C Memory Layout
What is Dynamic Memory?
Any allocation of memory space during the runtime of the program is called dynamic
memory allocation. The concept of dynamic memory allocation is used to reduce the
wastage of memory, and it is the optimal way of memory allocation.
Memory Allocation in C
Memory allocation in C can be divided into four segments.
1. Code:
Code composes of all the text segments of our program. Everything we do as a programmer
to build a program falls into this category.
2. Variables:
Declarations of both global and static variables come into this segment. Global variables can
be used anywhere in the program, while static has its limitations inside the function.
3. Stack:
A stack is a data structure. Initially, the stack looks like an empty bucket in which the last
entry to be inserted will be the first one to get out. It is also known as a LIFO data structure,
i.e., last in first out.
Suppose the program starts executing a function named A, then this function A gets pushed
into the stack. Now, if function A calls another function B during its execution, then function
B will also get pushed into the stack, and the program will start executing B. Now, if B calls
another function C, then the program will push C into the stack and will start with its
execution. After the program gets done with the execution of C, the program will pop C from
the stack as it was the last one to get pushed and start executing B. When B gets executed
completely, it will get popped and A will start executing further until the stack becomes
empty.
4. Heap:
From <https://www.codewithharry.com/tutorial/c-memory-layout>
C Memory Allocation
There are ways in which we can allocate memories dynamically in a heap. We use these
four standard library functions often:
1. malloc():
malloc stands for memory allocation. This inbuilt function requests memory from the heap
and returns a pointer to the memory. The pointer is of the void type and we can typecast it to
any other data type of our choice. All the values at the allocation time are initialized to
garbage values. The function expects the memory space along with the size we want in
bytes at the time it is used.
Syntax:
ptr = (ptr - type *)malloc(size_in_bytes)
Example:
int *ptr;ptr = (int *)malloc(5 * sizeof(int));
2. calloc():
calloc stands for contiguous memory allocation. Similar to malloc, this function also requests
memory from the heap and returns a pointer to the memory. Differences lie in the way we
have to call it. First, we have to send as parameters the number of blocks needed along with
their size in bytes. Second, in calloc(), the values at the allocation time are initialized to 0
instead of garbage value unlike what happens in malloc().
Syntax:
ptr = (ptr - type *)calloc(n, size_in_bytes)
Example:
int *ptr;ptr = (int *)calloc(5, sizeof(int));
3. realloc():
realloc stands for reallocation of memory. It is used in cases where the dynamic memory
allocated previously is insufficient and there is a need of increasing the already allocated
memory to store more data. We also pass the previously declared memory address, and the
new size of the memory in bytes while calling the function.
Syntax:
ptr = (ptr - type *)realloc(ptr, new_size_in_bytes)
Example:
ptr = (int *)realloc(ptr, 10 * sizeof(int));
4. free():
While discussing the disadvantages of dynamic memory allocation, it was mentioned that
there is no automatic deletion of dynamically allocated memory when the pointer gets
overwritten. So, to manually do it, we use the free() function to free up the allocated memory
space. Therefore, free() is used to free up the space occupied by the allocated memory. We
just have to pass the pointer as a parameter inside the function and the address being
pointed gets freed.
Syntax:
free(ptr);
From <https://www.codewithharry.com/tutorial/c-memory-allocation>
From <https://www.codewithharry.com/tutorial/c-structures>
C Unions
Quick Notes Page 25
C Unions
Just like Structures, the union is a user-defined data type. All the members in unions share
the same memory location. The union is a data type that allows different data belonging to
different data types to be stored in the same memory locations. One of the advantages of
using a union is that it provides an efficient way of reusing the memory location, as only one
of its members can be accessed at a time. A union is used in the same way we declare and
use a structure. The difference lies just in the way memory is allocated to their members.
Defining a Union
We use the union keyword to define the union.
The syntax for defining a union is:
union union_name{ // union_elements} structure_variable;
Here’s one example of how a union is defined and used in main as a user-defined data type.
#include <stdio.h> union Books{ char title[20]; char author[100]; float price; int pages;}; int
main(){ union Books book1; return 0;}
Initialising and accessing union elements
Different from how we used to initialise a struct in one single statement, union elements are
initialised one at a time.
And also, one can access only one union element at a time. Altering one union element
disturbs the value stored in other union elements.
#include <stdio.h>#include <string.h> union Books{ char title[20]; char author[100]; float price;
int pages;}; int main(){ union Books book1; strcpy(book1.title, "C Programming"); printf("%s\n",
book1.title); strcpy(book1.author, "ABC"); printf("%s\n", book1.author); book1.price = 123.99;
printf("%f\n", book1.price); book1.pages = 300; printf("%d\n", book1.pages); return 0;}
Output:
C Programming
ABC
123.989998
300
How are Structs and Unions similar?
30. Structures and unions, both are user-defined data types used to store data of different types.
31. The members of structures and unions can be objects of any type, including even other
structures and unions or arrays.
32. A union or a structure can be passed by value to functions and can be returned by value by
functions.
33. The . operator is used for accessing both union and structure members.
How are Structs and Unions different?
34. The keyword union is used to define a union and a keyword struct is used to define the
structure.
35. Within a structure, each member is allocated a unique storage area of location whereas
memory allocated to a union is shared by individual members of the union.
36. Individual members can be accessed at a time in structures whereas only one member can
be accessed at a time in unions.
37. Changing the value of one of the members of a structure will not affect the values of the
other members of the structure, whereas changing the value of one of the members of a
union will affect the values of other members in a union.
38. Several members of a structure can be initialised at once, whereas only one member can be
initialised in the union.
From <https://www.codewithharry.com/tutorial/c-unions>
C Typedef
In C programming, a typedef declaration is used to create shorter, more meaningful, and
convenient names for keywords already defined by C like int, float, and char.
What is a typedef in C?
A typedef is a keyword that is used to assign alternative names to existing datatypes. We
use typedef with user-defined datatypes when the names of the datatypes become slightly
complicated to use in programs. Typedefs can be used to:
• Make a more complex definition reusable by abbreviating it to something less complex.
• Provide more clarity to the code.
From <https://www.codewithharry.com/tutorial/C-typedef>
From <https://www.codewithharry.com/tutorial/c-file-handling-basics>
Operations on Files
There are basically four operations we can perform on files in C:
• Creating a File:
We can create a file using C language, in any directory, without even leaving our compiler.
We can select the name or type we want our file to have, along with its location.
• Opening a File:
We can open an existing file and create a new file and open it using our program. We can
perform different operations on a file after it has been opened.
• Closing a File:
When we are done with the file, meaning that we have performed whatever we want to
perform on our file, we can close the file using the close function.
• Read/Write to a file:
After opening a file, we can access its contents and read, write, or update them.
From <https://www.codewithharry.com/tutorial/c-operations-on-files>
Files I/O
The first and foremost thing we should know when working with files in C is that we have to
declare a pointer of the file type to work with files. The syntax for declaring a pointer of file
type is:
FILE *ptr;
Modes
Functions and their modes of declarations are two important factors of file handling. We
have to learn about different modes used along with these functions as a parameter. The
following are the modes:
• r: opens a file for reading.
• w: opens a file for writing. It can also create a new file.
• a: opens a file for appending.
• r+: opens a file for both reading and writing but cannot create a new file.
• w+: opens a file for both reading and writing.
There are many other modes, but these are the basic and most used ones.
Closing a file
When working with C, closing open files is an essential step. A programmer often makes a
mistake of not closing an open file. This becomes crucial because files do not automatically
get closed after a program uses them. The closing has to be done manually.
To close a file, we have to use the fclose() function. We only need to pass the pointer as a
parameter to the function.
Syntax:
fclose(ptr);
Reading a file
Reading from a file is as easy as reading any other stuff as an input in C. We just use a file
version of scanf(). In order to read from a file, we use the function fscanf(). Like scanf() used to
get input from the keyboard, it gets its input from a file and prints it onto the screen.
We have to send the file pointer as an argument for the program to be able to read it. The
file has to be opened in r mode, i.e., read mode, to work properly for fscanf().
Example:
#include <stdio.h> int main(){ FILE *ptr; ptr = fopen("example.txt", "r"); char str[128]; fscanf(ptr,
"%s", str); printf("%s", str);}
The file example.txt had “Welcome_To_CodeWithHarry!” as its content, hence the output:
From <https://www.codewithharry.com/tutorial/c-files-input-output>