FEBRUARY 19, 2025
UNDERSTANDING
LOOPS, QUALIFIERS AND MODIFIERS IN C LANGUAGE
VAMSI KRISHNA VAKA
What is a Loop?
A loop in C is a control structure that allows repetitive execution of a block of code as long as a
specified condition is met. Loops help reduce redundancy and make the program more efficient.
Why Do We Use Loops?
• To avoid code repetition.
• To execute a block of code multiple times based on a condition.
• To iterate through arrays, lists, or perform calculations.
• To implement logic such as searching, sorting, and mathematical operations.
Types of Loops in C
C provides three types of loops:
1. for Loop (Entry-controlled loop)
2. while Loop (Entry-controlled loop)
3. do-while Loop (Exit-controlled loop)
1. for Loop
The for loop is an entry-controlled loop, meaning the condition is checked before execution.
Syntax:
for(initialization; condition; update)
// Code to be executed
• Initialization: Executed once before the loop starts.
• Condition: The loop executes as long as this condition is true.
• Update: Executed after each iteration.
Example: Print numbers from 1 to 5
#include <stdio.h>
int main()
{
for(int i = 1; i <= 5; i++)
{
printf("%d\n", i);
}
return 0;
}
Output:
2. while Loop
The while loop is an entry-controlled loop that executes as long as the condition is true.
Syntax:
while(condition)
// Code to be executed
• The loop starts only if the condition is true.
• If the condition is false initially, the loop does not execute.
Example: Print numbers from 1 to 5
#include <stdio.h>
int main()
{
int i = 1;
while(i <= 5)
{
printf("%d\n", i);
i++;
}
return 0;
}
Output:
5
3. do-while Loop
The do-while loop is an exit-controlled loop, meaning the loop body executes at least once, even if
the condition is false.
Syntax:
do
// Code to be executed
} while(condition);
Example: Print numbers from 1 to 5
#include <stdio.h>
int main()
{
int i = 1;
do
{
printf("%d\n", i);
i++;
} while(i <= 5);
return 0;
}
Output:
Loop Variations
1. Infinite Loops
o A loop runs indefinitely if the condition is always true.
o Example:
while(1)
printf("This is an infinite loop\n");
}
2. Nested Loops
o A loop inside another loop.
o Example:
for(int i = 1; i <= 3; i++)
for(int j = 1; j <= 2; j++)
printf("i = %d, j = %d\n", i, j);
o Output:
i = 1, j = 1
i = 1, j = 2
i = 2, j = 1
i = 2, j = 2
i = 3, j = 1
i = 3, j = 2
Jumping Statements:
Jumping statements in C are used to transfer control from one part of the program to another. These
include:
1. break
2. continue
3. goto
4. return
1. break Statement
The break statement is used to exit a loop or switch statement prematurely.
Syntax:
break;
Example 1: Breaking a Loop
#include <stdio.h>
int main()
{
for(int i = 1; i <= 10; i++)
{
if(i == 5)
{
break; // Exits the loop when i == 5
}
printf("%d ", i);
}
return 0;
}
Output:
1234
Explanation:
• The loop runs from 1 to 10, but when i == 5, the break statement terminates the loop.
Problem 1: Stop Printing at a Certain Value
Code:
#include <stdio.h>
int main()
{
for (int i = 1; i <= 10; i++)
{
if (i == 6)
{
break; // Exit loop when i == 6
}
printf("%d ", i);
}
return 0;
}
Output:
12345
Explanation:
• The loop runs from 1 to 10, but when i == 6, break terminates the loop.
Problem 2: Find the First Even Number
Code:
#include <stdio.h>
int main()
{
int arr[] = {1, 3, 5, 7, 8, 9, 11};
int size = sizeof(arr) / sizeof(arr[0]);
for (int i = 0; i < size; i++)
{
if (arr[i] % 2 == 0)
{
printf("First even number: %d\n", arr[i]);
break; // Stop after finding the first even number
}
}
return 0;
}
Output:
First even number: 8
Problem 3: Printing Stars but Stopping at a Certain Row
Code:
#include <stdio.h>
int main()
{
for (int i = 1; i <= 5; i++)
{
for (int j = 1; j <= i; j++)
{
printf("* ");
if (j == 3)
break; // Stop printing stars when 3rd column is reached
}
printf("\n");
}
return 0;
}
Output:
**
***
***
***
2. continue Statement
The continue statement is used to skip the current iteration and move to the next iteration of the
loop.
Syntax:
continue;
Example 2: Skipping a Number
#include <stdio.h>
int main()
{
for(int i = 1; i <= 10; i++)
{
if(i == 5)
{
continue; // Skips iteration when i == 5
}
printf("%d ", i);
}
return 0;
}
Output:
1 2 3 4 6 7 8 9 10
Explanation:
• When i == 5, the continue statement skips printing 5 and continues with the next iteration.
Problem 1: Skip Multiples of 3
Code:
#include <stdio.h>
int main()
{
for (int i = 1; i <= 10; i++)
{
if (i % 3 == 0)
{
continue; // Skip multiples of 3
}
printf("%d ", i);
}
return 0;
}
Output:
1 2 4 5 7 8 10
Problem 2: Skip 5 in a Pattern
Code:
#include <stdio.h>
int main()
{
for (int i = 1; i <= 10; i++)
{
if (i == 5)
{
continue; // Skip number 5
}
printf("%d ", i);
}
return 0;
}
Output:
1 2 3 4 6 7 8 9 10
Problem 3: Print Odd Numbers Only
Code:
#include <stdio.h>
int main()
{
for (int i = 1; i <= 10; i++)
{
if (i % 2 == 0)
{
continue; // Skip even numbers
}
printf("%d ", i);
}
return 0;
}
Output:
13579
3. Goto Statement
The goto statement allows jumping to a labeled statement anywhere in the program. It is generally
discouraged as it makes code hard to debug, but sometimes useful for breaking deeply nested loops.
Syntax:
goto label;
...
label:
// Code to execute
1. Using goto to Exit a Loop
#include <stdio.h>
int main()
{
int i = 1;
while(i <= 10)
{
printf("%d ", i);
if(i == 5)
{
goto end; // Jump to the "end" label
}
i++;
}
end: // Label
printf("\nLoop terminated early using goto.\n");
return 0;
}
Output:
12345
Loop terminated early using goto.
Explanation:
• The loop runs normally but exits early when i == 5 using goto.
2. Using goto to Repeat a Block of Code
#include <stdio.h>
int main()
{
int num;
retry: // Label for re-entering the input step
printf("Enter a positive number: ");
scanf("%d", &num);
if(num < 0)
{
printf("Invalid input! Try again.\n");
goto retry; // Jump to "retry" label
}
printf("You entered: %d\n", num);
return 0;
}
Output:
Enter a positive number: -3
Invalid input! Try again.
Enter a positive number: 5
You entered: 5
Explanation:
• If the user enters a negative number, the program jumps back to the retry label and asks for
input again.
Problem 1: Simple Jump
Code:
#include <stdio.h>
int main()
{
printf("Before goto\n");
goto jump;
printf("This won't be printed\n");
jump:
printf("After goto\n");
return 0;
}
Output:
Before goto
After goto
Problem 2: Retry Input Until Valid
Code:
#include <stdio.h>
int main()
{
int num;
retry:
printf("Enter a positive number: ");
scanf("%d", &num);
if (num < 0)
{
printf("Invalid! Try again.\n");
goto retry;
}
printf("You entered: %d\n", num);
return 0;
}
Problem 3: Loop Simulation Using goto
Code:
#include <stdio.h>
int main()
{
int i = 1;
loop:
if (i > 5) return 0;
printf("%d ", i);
i++;
goto loop;
}
Output:
12345
4. return Statement
The return statement exits the function and optionally returns a value.
Example: Using return
#include <stdio.h>
void greet()
{
printf("Hello, ");
return; // Exits the function early
printf("World!"); // This line is never executed
}
int main()
{
greet();
return 0;
}
Output:
Hello,
Explanation: The return statement exits the function early, skipping the second printf.
Pattern Programs
1. Right-Angled Triangle
#include <stdio.h>
int main()
int n = 5;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= i; j++)
printf("* ");
}
printf("\n");
return 0;
Output:
**
***
****
*****
2. Inverted Right-Angled Triangle
#include <stdio.h>
int main()
int n = 5;
for(int i = n; i >= 1; i--)
for(int j = 1; j <= i; j++)
printf("* ");
printf("\n");
return 0;
Output:
*****
****
***
**
3. Pyramid Pattern
#include <stdio.h>
int main()
int n = 5;
for(int i = 1; i <= n; i++)
for(int j = i; j < n; j++)
printf(" ");
for(int k = 1; k <= (2*i - 1); k++)
printf("*");
printf("\n");
return 0;
Output:
***
*****
*******
*********
4. Number Triangle Pattern
#include <stdio.h>
int main()
int n = 5;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= i; j++)
printf("%d ", j);
printf("\n");
return 0;
Output:
12
123
1234
12345
Explanation:
• Outer loop (i) runs from 1 to n (5).
• Inner loop (j) prints numbers from 1 to i, forming the increasing triangle pattern.
5. Reverse Number Triangle
#include <stdio.h>
int main()
int n = 5;
for(int i = n; i >= 1; i--)
{
for(int j = 1; j <= i; j++)
printf("%d ", j);
printf("\n");
return 0;
Output:
12345
1234
123
12
Explanation:
• Outer loop starts from n (5) and decreases.
• Inner loop prints numbers from 1 to i, creating a decreasing pattern.
6. Hollow Square Pattern
#include <stdio.h>
int main()
int n = 5;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
if(i == 1 || i == n || j == 1 || j == n)
printf("* ");
}
else
printf(" ");
printf("\n");
return 0;
Output:
*****
* *
* *
* *
*****
Explanation:
• Print * if on the first/last row or first/last column.
• Print space otherwise.
7. Diamond Pattern
#include <stdio.h>
int main()
int n = 5;
// Upper half of the diamond
for(int i = 1; i <= n; i++)
for(int j = i; j < n; j++)
printf(" ");
}
for(int k = 1; k <= (2*i - 1); k++)
printf("*");
printf("\n");
// Lower half of the diamond
for(int i = n - 1; i >= 1; i--)
for(int j = n; j > i; j--)
printf(" ");
for(int k = 1; k <= (2*i - 1); k++)
printf("*");
printf("\n");
return 0;
output:
***
*****
*******
*********
*******
*****
***
*
Explanation:
• The first loop prints the upper pyramid.
• The second loop prints the lower pyramid by reducing the row count.
Qualifiers and Modifiers
1. Type Qualifiers in C
Type qualifiers in C specify how a variable should be stored or accessed. They do not change the
data type but modify the behaviour of variables.
Types of Type Qualifiers
1. const - Declares a variable as read-only.
2. volatile - Prevents compiler optimizations on a variable.
1.1 const Qualifier
• The const qualifier makes a variable read-only.
• It must be initialized at the time of declaration.
• Syntax:
const int x = 10;
x = 20; // Error: assignment of read-only variable
1. const with Basic Variables
Example 1: Trying to Modify const Variable
#include <stdio.h>
int main()
const int x = 10;
x = 20; // Error: Cannot modify a const variable
printf("%d", x);
return 0;
Explanation: Since x is declared as const, modifying it is not allowed.
2. const with Pointers
Example 2: Pointer to const Integer
#include <stdio.h>
int main()
const int a = 5;
const int *ptr = &a; // Pointer to a constant integer
*ptr = 10; // Error: Cannot modify a const value through a pointer
printf("%d", a);
return 0;
Explanation: The pointer ptr can point to another integer, but cannot modify the value it points to.
Example 3: const Pointer to Integer (Constant Pointer)
#include <stdio.h>
int main()
int a = 10;
int b = 20;
int *const ptr = &a; // Constant pointer to an integer
ptr = &b; // Error: Cannot change the address of a constant pointer
*ptr = 30; // Allowed: Can modify the value at the address
printf("%d", a);
return 0;
Explanation: ptr is a constant pointer, so its address cannot be changed, but the value it points to
can be modified.
Example 4: const Pointer to const Integer
#include <stdio.h>
int main()
const int a = 10;
const int *const ptr = &a; // Constant pointer to a constant integer
*ptr = 20; // Error: Cannot modify the value
ptr = &b; // Error: Cannot change the address
printf("%d", a);
return 0;
Explanation:
• const int *const ptr → Cannot modify value, cannot change pointer.
3. const with Function Parameters
Example 5: Passing const to a Function
#include <stdio.h>
void modify(const int x)
{
x = 20; // Error: Cannot modify a const parameter
}
int main()
{
int num = 10;
modify(num);
return 0;
}
Explanation: A const parameter cannot be modified inside the function.
Example 6: Using const Pointer as Function Parameter
#include <stdio.h>
void printValue(const int *ptr)
{
*ptr = 100; // Error: Cannot modify a const value
printf("%d", *ptr);
}
int main()
{
int num = 10;
printValue(&num);
return 0;
}
Explanation: ptr is a pointer to const int, so the function cannot modify the value of num.
4. const with Arrays
Example 7: const Array Elements
#include <stdio.h>
int main()
const int arr[] = {1, 2, 3, 4};
arr[0] = 10; // Error: Cannot modify a `const` array element
printf("%d", arr[0]);
return 0;
Explanation: Since arr is const, we cannot change its elements.
Example 8: const Pointer to Array
#include <stdio.h>
int main()
int arr[] = {1, 2, 3, 4};
const int *ptr = arr; // Pointer to `const` array
ptr[0] = 100; // Error: Cannot modify a `const` value
printf("%d", ptr[0]);
return 0;
Explanation: The pointer ptr cannot modify array elements.
5. const with Global Variables
Example 9: Global const Variable
#include <stdio.h>
const int x = 50; // Global const variable
void changeValue()
{
x = 100; // Error: Cannot modify a global `const` variable
int main()
changeValue();
return 0;
Explanation: A const global variable cannot be modified inside or outside of main().
6. const in Structs
Example 11: const Struct Members
#include <stdio.h>
struct Data
{
const int value;
};
int main()
{
struct Data d1 = {100};
d1.value = 200; // Error: Cannot modify a `const` struct member
printf("%d", d1.value);
return 0;
}
Explanation: A const struct member cannot be modified.
1.2. volatile Qualifier
What is volatile in C?
The volatile keyword informs the compiler that a variable’s value can change at any time, preventing
the compiler from applying certain optimizations.
Why volatile is Needed?
When a variable is declared as volatile, the compiler must always read its value from memory instead
of optimizing it by storing it in a register.
Situations Where volatile is Necessary
1. Memory-Mapped Registers in Embedded Systems
2. Global Variables Modified by Interrupts
3. Shared Variables in Multi-Threading
• Used in: Embedded systems, hardware registers, interrupt handlers, multi-threading.
• Syntax:
volatile int flag = 0;
Compiler Optimizations:
Compilers use various optimization techniques to improve performance and reduce code size by
eliminating unnecessary computations. However, these optimizations can sometimes change the
intended behavior of the program, especially when working with hardware registers, multi-threaded
applications, or memory-mapped devices.
Example 1:
#include <stdio.h>
volatile int flag = 0; // Can be modified by hardware
void check()
{
while (flag == 0)
{
// Loop will not be optimized
}
printf("Flag changed!\n");
}
int main()
{
check();
return 0;
}
• Example Problem:
// Why do we need volatile for hardware registers?
volatile int *status_register = (int *)0x40021000;
while ((*status_register & 0x01) == 0) {
// Wait for hardware event (without optimization)
2. Type Modifiers in C
Type modifiers are used to change the storage size and sign of basic data types.
Types of Type Modifiers
1. signed - Allows both positive and negative values (default for int).
2. unsigned - Allows only positive values.
3. short - Reduces memory size.
4. long - Increases memory size.
2.1 signed and unsigned Modifiers
• Signed Variables store positive and negative values.
• Unsigned Variables store only positive values (0 and above).
• Syntax:
signed int a = -5; // Default signed integer
unsigned int b = 10; // Only positive values
• Example:
#include <stdio.h>
int main()
signed int x = -10;
unsigned int y = 10;
printf("x = %d\n", x);
printf("y = %u\n", y);
return 0;
• Example Problem:
int main()
unsigned int x = -5; // Overflow: Interpreted as large positive number
printf("%u\n", x);
return 0;
2.2 short and long Modifiers
• short reduces memory usage, while long increases it.
• Syntax:
short int s = 100; // Uses 2 bytes
long int l = 100000; // Uses 4 or 8 bytes
Example:
#include <stdio.h>
int main()
short int s = 100;
long int l = 1000000;
printf("Short: %hd, Long: %ld\n", s, l);
return 0;
• Example Problem:
long int x = 2147483648; // Error: Out of range for int
Summary Table
Qualifier/Modifier Purpose Example
const Makes a variable read-only const int x = 5;
volatile Prevents compiler optimizations volatile int flag;
signed Allows negative and positive values signed int a = -5;
unsigned Only positive values unsigned int a = 10;
short Uses less memory short int a = 10;
long Uses more memory long int a = 100000;
Practice Problems
1. What is the output of this code?
int main()
const int x = 10;
int *ptr = (int *)&x;
*ptr = 20;
printf("x = %d\n", x);
return 0;
o Will this compile? What happens?
2. Why is volatile important in embedded systems?
volatile int *status = (int *)0x4000;
while ((*status & 0x01) == 0) { }
o What happens if volatile is removed?
3. What is wrong with this code?
void modify(int *restrict p, int *q)
*p = *q; // May cause undefined behavior