Lecture 7: Interactive Guide to Types, Precedence & Applications
Work on single operand
int a = 5; ++a; // Pre-increment: a becomes 6 a--; // Post-decrement: a becomes 5 !a; // Logical NOT ~a; // Bitwise NOT sizeof(a); // Size operator
Work on two operands
int a = 10, b = 5; a + b; // Addition: 15 a - b; // Subtraction: 5 a * b; // Multiplication: 50 a / b; // Division: 2 a % b; // Modulus: 0
Works on three operands
int a = 10, b = 5; int max = (a > b) ? a : b; // max = 10 // Conditional operator syntax: // condition ? value_if_true : value_if_false
| Operator | Name | Example | Result (a=10, b=3) |
|---|---|---|---|
| + | Addition | a + b | 13 |
| - | Subtraction | a - b | 7 |
| * | Multiplication | a * b | 30 |
| / | Division | a / b | 3 (integer division) |
| % | Modulus | a % b | 1 |
| ++ | Increment | ++a or a++ | 11 |
| -- | Decrement | --a or a-- | 9 |
| + (unary) | Unary Plus | +a | 10 |
| - (unary) | Unary Minus | -a | -10 |
#include <stdio.h>
int main() {
int a = 10, b = 3;
printf("Arithmetic Operations:\n");
printf("a + b = %d\n", a + b); // 13
printf("a - b = %d\n", a - b); // 7
printf("a * b = %d\n", a * b); // 30
printf("a / b = %d\n", a / b); // 3
printf("a %% b = %d\n", a % b); // 1
printf("Pre-increment: %d\n", ++a); // 11
printf("Post-increment: %d\n", a++); // 11, then a becomes 12
printf("Current a: %d\n", a); // 12
return 0;
}Note: Relational operators return 1 for true and 0 for false
| Operator | Name | Example | Result (a=10, b=5) |
|---|---|---|---|
| == | Equal to | a == b | 0 (false) |
| != | Not equal to | a != b | 1 (true) |
| > | Greater than | a > b | 1 (true) |
| < | Less than | a < b | 0 (false) |
| >= | Greater than or equal | a >= b | 1 (true) |
| <= | Less than or equal | a <= b | 0 (false) |
int a = 5, b = 10, c = 0;
// Logical AND (&&) - Both conditions must be true
if (a > 0 && b > 0) {
printf("Both a and b are positive\n"); // This executes
}
// Logical OR (||) - At least one condition must be true
if (a > 0 || c > 0) {
printf("At least one is positive\n"); // This executes
}
// Logical NOT (!) - Reverses the logical state
if (!c) {
printf("c is zero\n"); // This executes
}Important: Bitwise operators work on individual bits of operands. Mathematical operations at bit level are faster!
| Operator | Name | Example | Binary Operation |
|---|---|---|---|
| & | Bitwise AND | 5 & 3 | 0101 & 0011 = 0001 (1) |
| | | Bitwise OR | 5 | 3 | 0101 | 0011 = 0111 (7) |
| ^ | Bitwise XOR | 5 ^ 3 | 0101 ^ 0011 = 0110 (6) |
| ~ | Bitwise NOT | ~5 | ~0101 = 1010 (-6) |
| << | Left Shift | 5 << 1 | 0101 << 1 = 1010 (10) |
| >> | Right Shift | 5 >> 1 | 0101 >> 1 = 0010 (2) |
int a = 10; // Simple assignment a += 5; // Compound assignment: a = a + 5 (a = 15) a -= 3; // a = a - 3 (a = 12) a *= 2; // a = a * 2 (a = 24) a /= 4; // a = a / 4 (a = 6) a %= 4; // a = a % 4 (a = 2) // Bitwise compound assignments a &= 3; // a = a & 3 a |= 1; // a = a | 1 a ^= 5; // a = a ^ 5 a <<= 2; // a = a << 2 a >>= 1; // a = a >> 1
#include <stdio.h>
int main() {
int arr[10];
double x = 3.14;
printf("Size of int: %zu bytes\n", sizeof(int)); // Usually 4
printf("Size of double: %zu bytes\n", sizeof(double)); // Usually 8
printf("Size of array: %zu bytes\n", sizeof(arr)); // 40 (10*4)
printf("Size of variable x: %zu bytes\n", sizeof(x)); // 8
// Calculate array length
int length = sizeof(arr) / sizeof(arr[0]);
printf("Array length: %d\n", length); // 10
return 0;
}// Basic ternary operator
int a = 10, b = 20;
int max = (a > b) ? a : b; // max = 20
// Nested ternary
int num = 15;
char* result = (num > 0) ? "Positive" :
(num < 0) ? "Negative" : "Zero";
// Grade calculation
int marks = 85;
char grade = (marks >= 90) ? 'A' :
(marks >= 80) ? 'B' :
(marks >= 70) ? 'C' :
(marks >= 60) ? 'D' : 'F';// Comma operator
int a = 1, b = 2, c = 3; // Multiple declarations
int result = (a++, b++, c++); // result = 3 (last expression)
// Address-of operator (&)
int x = 10;
int* ptr = &x; // ptr stores address of x
// Dereference operator (*)
int value = *ptr; // value = 10 (value at address stored in ptr)
// Dot operator (.)
struct Point {
int x, y;
};
struct Point p;
p.x = 5; // Access member using dot
// Arrow operator (->)
struct Point* pPtr = &p;
pPtr->y = 10; // Access member through pointerKey Concept: Precedence determines which operator is evaluated first when multiple operators are present in an expression. Associativity determines the order when operators have the same precedence.
| Priority | Operators | Associativity | Example |
|---|---|---|---|
| 1 (Highest) | () [] -> . | Left to Right | func(), arr[0], ptr->member |
| 2 | ! ~ ++ -- + - * & sizeof | Right to Left | !x, ~x, ++x, --x, +x, -x |
| 3 | * / % | Left to Right | a * b / c |
| 4 | + - | Left to Right | a + b - c |
| 5 | << >> | Left to Right | a << 2 >> 1 |
| 6 | < <= > >= | Left to Right | a < b <= c |
| 7 | == != | Left to Right | a == b != c |
| 8 | & | Left to Right | a & b & c |
| 9 | ^ | Left to Right | a ^ b ^ c |
| 10 | | | Left to Right | a | b | c |
| 11 | && | Left to Right | a && b && c |
| 12 | || | Left to Right | a || b || c |
| 13 | ? : | Right to Left | a ? b : c ? d : e |
| 14 | = += -= *= /= %= <<= >>= &= ^= |= | Right to Left | a = b = c |
| 15 | , | Left to Right | a, b, c |
Tip: When in doubt, use parentheses to make the order of evaluation explicit and improve code readability.
What is the value of the following expression? (Try to solve it manually first, then verify with a C program)
int x = 5, y = 10, z = 2;
int result = ++x * y-- / z + y % z;
Solution: The result is 31. Here's the step-by-step evaluation:
Write a C program to check if a number is a power of 2 using bitwise operators.
#include
int isPowerOfTwo(int num) {
// A number is a power of 2 if it has exactly one bit set to 1
// For example: 4 (100), 8 (1000), 16 (10000)
return (num > 0) && ((num & (num - 1)) == 0);
}
int main() {
int num;
printf("Enter a number: ");
scanf("%d", &num);
if (isPowerOfTwo(num)) {
printf("%d is a power of 2\n", num);
} else {
printf("%d is not a power of 2\n", num);
}
return 0;
}
In this lecture, we've explored the rich set of operators available in C programming. Understanding operator precedence and associativity is crucial for writing correct and efficient code. Remember that while C provides many powerful operators, clarity should never be sacrificed for cleverness. When in doubt, use parentheses to make your intentions clear.