C Language Notes
C Language Notes
C is a general-purpose programming language created by Dennis Ritchie at the Bell Laboratories in 1972.
It is a very popular language, despite being old. The main reason for its popularity is because it is a
fundamental language in the field of computer science.
C is strongly associated with UNIX, as it was developed to write the UNIX operating system.
Why Learn C?
It is one of the most popular programming languages in the world
If you know C, you will have no problem learning other popular programming languages such as Java, Python,
C++, C#, etc, as the syntax is similar
If you know C, you will understand how computer memory works
C is very fast, compared to other programming languages, like Java and Python
C is very versatile; it can be used in both applications and technologies
Example explained
Line 1: #include <stdio.h> is a header file library that lets us work with input and output functions, such
as printf() (used in line 4). Header files add functionality to C programs.
Line 2: A blank line. C ignores white space. But we use it to make the code more readable.
Line 3: Another thing that always appear in a C program is main(). This is called a function. Any code inside its
curly brackets {} will be executed.
Line 4: printf() is a function used to output/print text to the screen. In our example, it will output "Hello
World!".
Note: Every C statement ends with a semicolon ;
Note: The body of int main() could also been written as:
int main(){printf("Hello World!");return 0;}
Remember: The compiler ignores white spaces. However, multiple lines makes the code more readable.
Line 5: return 0 ends the main() function.
Line 6: Do not forget to add the closing curly bracket } to actually end the main function.
C Statements
Statements
A computer program is a list of "instructions" to be "executed" by a computer.
In a programming language, these programming instructions are called statements.
The following statement "instructs" the compiler to print the text "Hello World" to the screen:
printf("Hello World!");
It is important that you end the statement with a semicolon ;
If you forget the semicolon (;), an error will occur and the program will not run:
Many printf Functions
You can use as many printf() functions as you want. However, note that it does not insert a new line at the
end of the output:
#include <stdio.h>
int main() {
printf("Hello World!");
printf("I am learning C.");
printf("And it is awesome!");
return 0;
}
C New Lines
To insert a new line, you can use the \n character:
#include <stdio.h>
int main() {
printf("Hello World!\n");
printf("I am learning C.");
return 0;
}
You can also output multiple lines with a single printf() function. However, this could make the code harder
to read:
Example
#include <stdio.h>
int main() {
printf("Hello World!\nI am learning C.\nAnd it is awesome!");
return 0;
}
Tip: Two \n characters after each other will create a blank line:
Example
#include <stdio.h>
int main() {
printf("Hello World!\n\n");
printf("I am learning C.");
return 0;
}
What is \n exactly?
The newline character (\n) is called an escape sequence, and it forces the cursor to change its position to the
beginning of the next line on the screen. This results in a new line.
Examples of other valid escape sequences are:
Escape Sequence Description Try it
\t Creates a horizontal tab
\\ Inserts a backslash character (\)
\" Inserts a double quote character
Comments in C
Comments can be used to explain code, and to make it more readable. It can also be used to prevent
execution when testing alternative code.
Comments can be singled-lined or multi-lined.
Single-line Comments
Single-line comments start with two forward slashes (//).
Any text between // and the end of the line is ignored by the compiler (will not be executed).
This example uses a single-line comment before a line of code:
// This is a comment
printf("Hello World!");
C Variables
Variables
Variables are containers for storing data values, like numbers and characters.
In C, there are different types of variables (defined with different keywords), for example:
int - stores integers (whole numbers), without decimals, such as 123 or -123
float - stores floating point numbers, with decimals, such as 19.99 or -19.99
char - stores single characters, such as 'a' or 'B'. Characters are surrounded by single quotes
Declaring (Creating) Variables
To create a variable, specify the type and assign it a value:
Syntax
type variableName = value;
Where type is one of C types (such as int), and variableName is the name of the variable (such
as x or myName). The equal sign is used to assign a value to the variable.
So, to create a variable that should store a number, look at the following example:
Create a variable called myNum of type int and assign the value 15 to it:
int myNum = 15;
You can also declare a variable without assigning the value, and assign the value later:
Example
// Declare a variable
int myNum;
C Format Specifiers
Format Specifiers
Format specifiers are used together with the printf() function to tell the compiler what type of data the
variable is storing. It is basically a placeholder for the variable value.
A format specifier starts with a percentage sign %, followed by a character.
For example, to output the value of an int variable, use the format specifier %d surrounded by double quotes
(""), inside the printf() function:
Example
int myNum = 15;
printf("%d", myNum); // Outputs 15
To print other types, use %c for char and %f for float
// Create variables
int myNum = 15; // Integer (whole number)
float myFloatNum = 5.99; // Floating point number
char myLetter = 'D'; // Character
// Print variables
printf("%d\n", myNum);
printf("%f\n", myFloatNum);
printf("%c\n", myLetter);
To combine both text and a variable, separate them with a comma inside the printf() function:
Example
int myNum = 15;
printf("My favorite number is: %d", myNum);
To print different types in a single printf() function, you can use the following:
Example
int myNum = 15;
char myLetter = 'D';
printf("My number is %d and my letter is %c", myNum, myLetter);
Print Values Without Variables
You can also just print a value without storing it in a variable, as long as you use the correct format specifier:
Example
printf("My favorite number is: %d", 15);
printf("My favorite letter is: %c", 'D');
However, it is more sustainable to use variables as they are saved for later and can be re-used whenever.
C Variable Values
Change Variable Values
If you assign a new value to an existing variable, it will overwrite the previous value:
Example
int myNum = 15; // myNum is 15
myNum = 10; // Now myNum is 10
You can also assign the value of one variable to another:
Example
int myNum = 15;
// Print variables
printf("Student id: %d\n", studentID);
printf("Student age: %d\n", studentAge);
printf("Student fee: %f\n", studentFee);
printf("Student grade: %c", studentGrade);
Data Types
As explained in the Variables chapter, a variable in C must be a specified data type, and you must use
a format specifier inside the printf() function to display it
Example
// Create variables
int myNum = 5; // Integer (whole number)
float myFloatNum = 5.99; // Floating point number
char myLetter = 'D'; // Character
// Print variables
printf("%d\n", myNum);
printf("%f\n", myFloatNum);
printf("%c\n", myLetter);
Notes on Characters
If you try to store more than a single character, it will only print the last character:
Example
char myText = 'Hello';
printf("%c", myText);
Try it Yourself »
Note: Don't use the char type for storing multiple characters, as it may produce errors.
To store multiple characters (or whole words), use strings (which you will learn more about in a later
chapter):
Example
char myText[] = "Hello";
printf("%s", myText);
Try it Yourself »
For now, just know that we use strings for storing multiple characters/text, and the char type for single
characters.
C Numeric Data Types
Numeric Types
Use int when you need to store a whole number without decimals, like 35 or 1000, and float or double when
you need a floating point number (with decimals), like 9.99 or 3.14515.
int
int myNum = 1000;
printf("%d", myNum);
float
float myNum = 5.75;
printf("%f", myNum);
double
double myNum = 19.99;
printf("%lf", myNum);
float vs. double
The precision of a floating point value indicates how many digits the value can have after the decimal point.
The precision of float is six or seven decimal digits, while double variables have a precision of about 15 digits.
Therefore, it is often safer to use double for most calculations - but note that it takes up twice as
much memory as float (8 bytes vs. 4 bytes).
Scientific Numbers
In C, you can write very large or very small floating-point numbers using scientific notation.
This is done using the letter e (or E), which stands for "times 10 to the power of".
For example, 35e3 means 35 × 10³ = 35000.
This is useful for writing numbers in a shorter way. Especially when working with scientific values or large-
scale data.
Example
float f1 = 35e3; // 35 * 10^3 = 35000
double d1 = 12E4; // 12 * 10^4 = 120000
printf("%f\n", f1);
printf("%lf", d1);
printf("%zu\n", sizeof(myInt));
printf("%zu\n", sizeof(myFloat));
printf("%zu\n", sizeof(myDouble));
printf("%zu\n", sizeof(myChar));
return 0;
}
// Print variables
printf("Number of items: %d\n", items);
printf("Cost per item: %.2f %c\n", cost_per_item, currency);
printf("Total cost = %.2f %c\n", total_cost, currency);
return 0;
}
Type Conversion
Sometimes, you have to convert the value of one data type to another type. This is known as type
conversion.
For example, if you try to divide two integers, 5 by 2, you would expect the result to be 2.5. But since we are
working with integers (and not floating-point values), the following example will just output 2:
Example
int x = 5;
int y = 2;
int sum = 5 / 2;
Implicit Conversion
Implicit conversion is done automatically by the compiler when you assign a value of one type to another.
For example, if you assign an int value to a float type:
Example
// Automatic conversion: int to float
float myFloat = 9;
printf("%d", myInt); // 9
What happened to .99? We might want that data in our program! So be careful. It is important that you
know how the compiler work in these situations, to avoid unexpected results.
As another example, if you divide two integers: 5 by 2, you know that the sum is 2.5. And as you know from
the beginning of this page, if you store the sum as an integer, the result will only display the number 2.
Therefore, it would be better to store the sum as a float or a double, right?
Example
float sum = 5 / 2;
And since you learned about "decimal precision" in the previous chapter, you could make the output even
cleaner by removing the extra zeros (if you like):
Example
int num1 = 5;
int num2 = 2;
float sum = (float) num1 / num2;
Real-Life Example
Here's a real-life example of data types and type conversion where we create a program to calculate the
percentage of a user's score in relation to the maximum score in a game:
Example
// Set the maximum possible score in the game to 500
int maxScore = 500;
/* Calculate the percantage of the user's score in relation to the maximum available score.
Convert userScore to float to make sure that the division is accurate */
float percentage = (float) userScore / maxScore * 100.0;
C Constants
Constants
If you don't want others (or yourself) to change existing variable values, you can use the const keyword.
This will declare the variable as "constant", which means unchangeable and read-only:
const int myNum = 15; // myNum will always be 15
myNum = 10; // error: assignment of read-only variable 'myNum'
You should always declare the variable as constant when you have values that are unlikely to change:
const int minutesPerHour = 60;
example
int main() {
const int BIRTHYEAR = 1980;
printf("%d", BIRTHYEAR);
return 0;
}
C Operators
Operators are used to perform operations on variables and values.
Arithmetic Operators
Arithmetic operators are used to perform common mathematical operations.
int main() {
int x = 10;
int y = 3;
printf("%d\n", x + y); // 13
printf("%d\n", x - y); // 7
printf("%d\n", x * y); // 30
printf("%d\n", x / y); // 3
printf("%d\n", x % y); // 1
int z = 5;
++z;
printf("%d\n", z); // 6
--z;
printf("%d\n", z); // 5
return 0;
}
Assignment operators can also be used in real-life scenarios. For example, you can use the += operator to
keep track of savings when you add money to an account:
int main() {
// Create an integer variable that will store the number we get from the user
int myNum;
// Get and save the number AND character the user types
scanf("%d %c", &myNum, &myChar);
return 0;
}
#include <stdio.h>
int main() {
// Create a string
char firstName[30];
return 0;
}
#include <stdio.h>
int main() {
int length, width;
int area, perimeter;
return 0;
}
Operators in C
Operators are the basic components of C programming. They are symbols that represent some kind of
operation, such as mathematical, relational, bitwise, conditional, or logical computations, which are to be
performed on values or variables. The values and variables used with operators are called operands.
C
#include <stdio.h>
int main() {
printf("%d", sum);
return 0;
}
Output
30
Types of Operators in C
C language provides a wide range of built in operators that can be classified into 6 types based on their
functionality:
Arithmetic Operators
The arithmetic operators are used to perform arithmetic/mathematical operations on operands. There
are nine arithmetic operators in C language:
C
#include <stdio.h>
int main() {
int a = 25, b = 5;
return 0;
}
Output
a + b = 30
a - b = 20
a * b = 125
a/b=5
a%b=0
+a = 25
-a = -25
a++ = 25
a-- = 26
Relational Operators
The relational operators in C are used for the comparison of the two operands. All these operators are binary
operators that return true or false values as the result of comparison.
C
#include <stdio.h>
int main() {
int a = 25, b = 5;
return 0;
}
Output
a<b :0
a>b :1
a <= b: 0
a >= b: 1
a == b: 0
a != b : 1
Here, 0 means false and 1 means true.
Logical Operator
Logical Operators are used to combine two or more conditions/constraints or to complement the evaluation
of the original condition in consideration. The result of the operation of a logical operator is a Boolean value
either true or false.
Symbol Operator Description Syntax
&& Logical AND Returns true if both the operands are true. a && b
C
#include <stdio.h>
int main() {
int a = 25, b = 5;
return 0;
}
Output
a && b : 1
a || b : 1
!a: 0
Bitwise Operators
The Bitwise operators are used to perform bit-level operations on the operands. The operators are first
converted to bit-level and then the calculation is performed on the operands.
Note: Mathematical operations such as addition, subtraction, multiplication, etc. can be performed at the bit
level for faster processing.
Symbol Operator Description Syntax
C
#include <stdio.h>
int main() {
int a = 25, b = 5;
// using operators and printing results
printf("a & b: %d\n", a & b);
printf("a | b: %d\n", a | b);
printf("a ^ b: %d\n", a ^ b);
printf("~a: %d\n", ~a);
printf("a >> b: %d\n", a >> b);
printf("a << b: %d\n", a << b);
return 0;
}
Output
a & b: 1
a | b: 29
a ^ b: 28
~a: -26
a >> b: 0
a << b: 800
Assignment Operators
Assignment operators are used to assign value to a variable. The left side operand of the assignment
operator is a variable and the right side operand of the assignment operator is a value. The value on the right
side must be of the same data type as the variable on the left side otherwise the compiler will raise an error.
The assignment operators can be combined with some other operators in C to provide multiple operations
using single operator. These operators are called compound operators.
C
#include <stdio.h>
int main() {
int a = 25, b = 5;
return 0;
}
Output
a = b: 5
a += b: 10
a -= b: 5
a *= b: 25
a /= b: 5
a %= b: 0
a &= b: 0
a |= b: 5
a ^= b: 0
a >>= b: 0
a <<= b: 0
Other Operators
Apart from the above operators, there are some other operators available in C used to perform some specific
tasks. Some of them are discussed here:
sizeof Operator
sizeof is much used in the C programming language.
It is a compile-time unary operator which can be used to compute the size of its operand.
The result of sizeof is of the unsigned integral type which is usually denoted by size_t.
Basically, the sizeof the operator is used to compute the size of the variable or datatype.
Syntax
C
sizeof (operand)
Comma Operator ( , )
The comma operator (represented by the token) is a binary operator that evaluates its first operand and
discards the result, it then evaluates the second operand and returns this value (and type).
The comma operator has the lowest precedence of any C operator. It can act as both operator and
separator.
Syntax
C
operand1 , operand2
Conditional Operator ( ? : )
The conditional operator is the only ternary operator in C++. It is a conditional operator that we can use in
place of if..else statements.
Syntax
C
expression1 ? Expression2 : Expression3;
Here, Expression1 is the condition to be evaluated. If the condition(Expression1) is True then we will execute
and return the result of Expression2 otherwise if the condition(Expression1) is false then we will execute and
return the result of Expression3.
dot (.) and arrow (->) Operators
Member operators are used to reference individual members of classes, structures, and unions.
The dot operator is applied to the actual object.
The arrow operator is used with a pointer to an object.
Syntax
C
structure_variable . member;
structure_pointer -> member;
Cast Operators
Casting operators convert one data type to another. For example, int(2.2000) would return 2.
A cast is a special operator that forces one data type to be converted into another.
Syntax
C
(new_type) operand;
addressof (&) and Dereference (*) Operators
Addressof operator & returns the address of a variable and the dereference operator * is a pointer to a
variable. For example *var; will pointer to a variable var.
Example of Other C Operators
C
// C Program to demonstrate the use of Misc operators
#include <stdio.h>
int main()
{
// integer variable
int num = 10;
int* add_of_num = #
return 0;
}
Output
sizeof(num) = 4 bytes
&num = 0x7ffdb58c037c
*add_of_num = 10
(10 < 5) ? 10 : 20 = 20
(float)num = 10.000000
It is strongly recommended to learn Operator Precedence and Associativity after reading about operators.
int main() {
int x = 5;
++x; // Increment x by 1
printf("%d\n", x); // 6
--x; // Decrement x by 1
printf("%d\n", x); // 5
return 0;
}
In C programming, storage classes define the scope, lifetime, and storage location of variables and
functions. There are four primary storage classes:
auto
Scope: Local to the block or function in which it is declared.
Lifetime: Exists only while the block or function is active.
Storage Location: Stored in the stack memory.
Key Feature: This is the default storage class for local variables. They are temporary and reinitialized each
time their scope is entered.
register
Scope: Local to the block or function in which it is declared.
Lifetime: Exists only while the block or function is active.
Storage Location: Stored in CPU registers for faster access, if available. Otherwise, stored in RAM.
Key Feature: Used for variables that are frequently accessed, like loop counters, to potentially improve
performance. The & operator cannot be applied to register variables as they might not have a memory
address.
static
Scope:
Local static: Local to the function or block where it's declared.
Global static: Limited to the file where it's declared.
Lifetime: Persists throughout the entire program execution.
Storage Location: Stored in the data segment of RAM.
Key Feature:
Local static: Retains its value across multiple function calls.
Global static: Prevents the variable from being accessed by other files, ensuring file-level encapsulation.
extern
Scope: Global, accessible throughout the entire program (potentially across multiple files).
Lifetime: Persists throughout the entire program execution.
Storage Location: Stored in the data segment of RAM.
Key Feature: Used to declare a variable or function that is defined in another file or later in the current
file. It informs the compiler that the definition exists elsewhere, enabling sharing of global variables and
functions.
Example Program Illustrating Storage Classes:
C
#include <stdio.h>
void func() {
// Local auto variable
auto int autoVar = 1;
printf("Inside func():\n");
printf(" autoVar: %d\n", autoVar);
printf(" staticFuncVar (before increment): %d\n", staticFuncVar);
printf(" regVar: %d\n", regVar);
autoVar++;
staticFuncVar++;
int main() {
extern int globalVar; // Declaration of external globalVar
printf("In main():\n");
printf(" globalStaticVar: %d\n", globalStaticVar);
printf(" globalVar: %d\n", globalVar);
printf("\n");
return 0;
}
In C programming, functions can be categorized based on whether they accept arguments and whether they
return a value.
// Function declaration
int add(int a, int b);
int main() {
int num1 = 5, num2 = 10;
int sum = add(num1, num2); // Function call with arguments, storing return value
printf("Sum: %d\n", sum);
return 0;
}
// Function definition
int add(int a, int b) {
return a + b; // Returns the sum of a and b
}
// Function declaration
void printMessage(char message[]);
int main() {
char greeting[] = "Hello from a function!";
printMessage(greeting); // Function call with argument
return 0;
}
// Function definition
void printMessage(char message[]) {
printf("%s\n", message); // Prints the message, no value returned
}
// Function declaration
int generateRandomNumber();
int main() {
int randomNum = generateRandomNumber(); // Function call, storing return value
printf("Random Number: %d\n", randomNum);
return 0;
}
// Function definition
int generateRandomNumber() {
// In a real scenario, you'd use a proper random number generator
return 42; // Returns a fixed value for demonstration
}
C Storage Classes
Storage classes define the lifetime, visibility, and memory location of variables.
There are four main storage class specifiers in C:
auto
static
register
extern
Difference Between Scope and Storage Classes
Scope defines where a variable can be used, and storage classes define how long it lasts and where it's
stored. This chapter continues from the C Scope chapter.
auto
The auto keyword is used for local variables. It is default for variables declared inside functions, so it's rarely
used explicitly.
Example
int main() {
auto int x = 50; // Same as just: int x = 50;
printf("%d\n", x);
return 0;
}
static
The static keyword changes how a variable or function behaves in terms of lifetime and visibility:
Static local variables keep their value between function calls.
Static global variables/functions are not visible outside their file.
Example
void count() {
static int myNum = 0; // Keeps its value between calls
myNum++;
printf("num = %d\n", myNum);
}
int main() {
count();
count();
count();
return 0;
}
Result:
num = 1
num = 2
num = 3
Try to remove the static keyword from the example to see the difference.
register
The register keyword suggests that the variable should be stored in a CPU register (for faster access).
You cannot take the address of a register variable using &.
Note: The register keyword is mostly obsolete - modern compilers automatically choose the best variables to
keep in registers, so you usually don't need to use it.
Example
int main() {
register int counter = 0;
printf("Counter: %d\n", counter);
return 0;
}
extern
The extern keyword tells the compiler that a variable or function is defined in another file.
It is commonly used when working with multiple source files.
File 1: main.c
#include <stdio.h>
int main() {
printf("shared = %d\n", shared);
return 0;
}
File 2: data.c