The blog post continues to introduce the very basics of C.

Bear with me for a little bit. Learning about these basics carefully is instrumental for the future.
If Statements
Let's say we are trying to give comments to students depending on the letter grade. We can do so using if statements as follows:
char grade = 'A';
if (grade == 'A') {
printf("Perfect!");
} else if (grade == 'B') {
printf("Great!");
} else if (grade == 'C') {
printf("Great. ");
} else if (grade == 'D') {
printf("Great. ");
} else if (grade == 'E') {
printf("You survived. ");
} else if (grade == 'F') {
printf("You failed. ");
} else {
printf("Grade is invalid.");
}
However, the above is not ideal because we have three conditions that print the same thing.
This can be simplified using the AND logical operator &&
.
char grade = 'C';
if (grade == 'A') {
printf("Perfect!");
} else if ('B' <= grade && grade <= 'D') {
printf("Great!");
} else if (grade == 'E') {
printf("You survived. ");
} else if (grade == 'F') {
printf("You failed. ");
} else {
printf("Grade is invalid.");
}
In addition to the AND operator, we have the OR operator ||
and the NOT operator !
. Inside the if statement, we can use
<
and >
for greater than or less than, ==
for equal to, and !=
for not equal to.
Switch Statements
However, having many else if
is regarded as bad coding practice. When there are many conditions we need to check,
we use a switch
statement.
switch (grade) {
case 'A':
printf("Perfect!");
break;
case 'B':
printf("Great!");
break;
case 'C':
printf("Nice. ");
break;
case 'D':
printf("OK. ");
break;
case 'E':
printf("You survived. ");
break;
case 'F':
printf("You failed. ");
break;
default:
printf("Grade is invalid. ");
}
We need to use break
to stop the execution of the switch
statement. Otherwise, the programs in the
following cases will also get triggered.
Ternary Operators
The following is a valid code, but writing this all the time is quite tedious.
int a = 4;
int b = 3;
int min;
if (a < b) {
min = a;
} else {
min = b;
}
printf("Minimum: %d", min);
Instead, we can use ternary operator to refactor the code as follows.
int a = 4;
int b = 3;
// Ternary Operator (condition) ? value if true : value if false;
int min = (a < b) ? a : b;
printf("Minimum: %d", min);
This can simplify the code in many scenarios.
For Loops
When we want to have for loops in C, we can do so as follows.
// For Loop
// for (starting index; condition to continue; how to increment index) { operation }
for (int i = 1; i <= 10; i++) {
printf("%d ", i);
}
// => 1 2 3 4 5 6 7 8 9 10
We can also decrement as well.
// For Loop, Decrement
for (int i = 10; i >= 1; i--) {
printf("%d ", i);
}
// => 10 9 8 7 6 5 4 3 2 1
// For Loop, Decrement by 2
for (int i = 10; i >= 1; i-=2) {
printf("%d ", i);
}
// => 10 8 6 4 2
While Loops
When we want to run a program indefinitely until a condition is met, we can do so with while loop.
int i = 1;
while (i <= 10) {
printf("%d ", i);
i++;
}
// => 1 2 3 4 5 6 7 8 9 10
There are some situations where we want to perform an operation first and decide whether to iterate it again. In such scenario, we use a do-while loop.
int age;
do {
printf("What is your age?: ");
scanf("%d", &age);
} while (age < 0);
printf("Your age is %d", age);
We can ask for age first and decide whether we continue asking depending on the user input.
Break vs Continue
A lot of beginners seem to get very confused about the difference between break
and continue
, so
here is the explanation. While break
breaks out of the loop or terminates the loop that it is in, continue
skip one iteration of the loop. Let's see some examples to understand what I mean by that.
// Break
for (int i = 1; i <= 5; i++) {
if (i == 3) {
break;
} else {
printf("%d ", i);
}
}
// => 1 2
// Continue
for (int i = 1; i <= 5; i++) {
if (i == 3) {
continue;
} else {
printf("%d ", i);
}
}
// => 1 2 4 5
In the above example, when break
is used, the output is 1 2
because break
terminated the loop it is in.
On the other hand, when continue
is used, the output is 1 2 4 5
because continue
just skipped 3. Both the
break
and continue
only work on the loop on the same level even when the loop is nested.
// Break (exit the inner loop when i == j)
for (int i = 1; i <= 5; i++) {
for (int j = 1; j <= 5; j++) {
if (i == j) {
break;
} else {
printf("%d ", j);
}
}
printf("\n");
}
// => 1
// 1 2
// 1 2 3
// 1 2 3 4
// Continue (skip when i == j but continue the inner loop)
for (int i = 1; i <= 5; i++) {
for (int j = 1; j <= 5; j++) {
if (i == j) {
continue;
} else {
printf("%d ", j);
}
}
printf("\n");
}
// => 2 3 4 5
// 1 3 4 5
// 1 2 4 5
// 1 2 3 5
// 1 2 3 4
Arrays
You have seen how strings, arrays of chars, can be initialized. How can we do that for other datatypes? We can do that like the following.
int grades[] = {1,2,3,4,5};
When we want to access the elements of an array, we can do so as follows.
grades[0]; // => 1
grades[1]; // => 2
grades[2]; // => 3
When we want to iterate over an array, we can calculate the number of elements with sizeof
.
// Getting the number of elements
// We are dividing the size of the whole list by the size of the first element
// It works because the datatype of elements in an array is consistent
int size = sizeof(grades)/sizeof(grades[0]);
for (int i = 0; i < size; i++) {
printf("Grade: %d\n", grades[i]);
}
You have to use <
instead of <=
because an array is 0 indexed in C.
Functions
having all the code in main
function is a bad idea when the code is long and contains repetition. To simplify the code,
we can define other functions before main
like the following.
// Functions outputType functionName (Inputs) { Operations }
void happyBirthday (char name[], int age) {
printf("Happy Birthday, %s!\n", name);
printf("You just turned %d years old!\n", age)
}
int square (int x) {
return x*x;
}
int main () {
char name[] = "Micheal Jordan";
int age = 24;
happyBirthday(name, age);
int ageSquared = square(age);
printf("Your age squared is %d",ageSquared);
return 0;
}
When we want to define other functions after main
for readability, we need to be careful that many C compilers do not
check parameter matching when functions are not defined before they are invoked, which can result in unexpected
behavior. Hence, we want to add function prototypes at the beginning for compilers to properly check parameter matching.
// Function prototypes
void happyBirthday (char[], int);
int square (int);
int main () {
char name[] = "Micheal Jordan";
int age = 24;
happyBirthday(name);
int ageSquared = square(age);
printf("Your age squared is %d",ageSquared);
return 0;
}
void happyBirthday (char name[], int age) {
printf("Happy Birthday, %s!\n", name);
printf("You just turned %d years old!\n", age)
}
int square (int x) {
return x*x;
}
Exercises
From this article, there will be an exercise section where you can test your understanding of the material introduced in the article. I highly recommend solving these questions by yourself after reading the main part of the article. You can click on each question to see its answer.
Resources
- Bro Code. 2022. C if statements βοΈ. YouTube.
- Bro Code. 2022. C switch statements π½. YouTube.
- Bro Code. 2022. C functions π. YouTube.
- Bro Code. 2022. C arguments π§. YouTube.
- Bro Code. 2022. C return statement π. YouTube.
- Bro Code. 2022. C function prototypes π€. YouTube.
- Bro Code. 2022. C for loops π. YouTube.
- Bro Code. 2022. C while loops βΎοΈ. YouTube.
- Bro Code. 2022. C do while loop π€ΈββοΈ. YouTube.
- Bro Code. 2022. C break vs continue π₯. YouTube.
- Bro Code. 2022. C arrays ποΈ. YouTube.