Fundamentals of Conditional Execution
Branching mechanisms enable programs to diverge execution paths based on runtime evaluations. In C, decision-making relies on relational operators (e.g., <, >, ==) combined with logical operators (&&, ||). Proper handling of these expressions is critical for building reliable control flows.
Binary Branching with if-else
The if-else construct handles two possible outcomes. When evaluating multiple conditions simultaneously, all relationships must be explicitly stated. For instance, verifying geometric properties requires checking equality across all dimensions.
#include <stdio.h>
int main(void) {
int dimA, dimB, dimC;
printf("Enter three integer dimensions (A B C): ");
if (scanf("%d %d %d", &dimA, &dimB, &dimC) != 3) {
printf("Invalid input.\n");
return 1;
}
if (dimA == dimB && dimB == dimC) {
printf("Shape classification: Cube\n");
} else {
printf("Shape classification: Rectangular Prism\n");
}
return 0;
}
Multi-Way Selection Using switch-case
When a single variable dictates one of several distinct execution paths, switch-case offers a cleaner alternative to chained if-else statements. It is particularly effective for tiered calculations, such as applying discount brackets based on a total amount.
#include <stdio.h>
int main(void) {
float qtyPaper, qtyInk, qtyDisk;
printf("Enter quantities for paper, ink, and disk: ");
if (scanf("%f %f %f", &qtyPaper, &qtyInk, &qtyDisk) != 3) return 1;
float rawTotal = (qtyPaper * 18.0f) + (qtyInk * 132.0f) + (qtyDisk * 4.5f);
float discountRate = 0.0f;
int tier = (int)(rawTotal / 100.0f);
switch (tier) {
case 0: discountRate = 0.00f; break;
case 1: discountRate = 0.05f; break;
case 2: discountRate = 0.06f; break;
case 3: discountRate = 0.07f; break;
case 4: discountRate = 0.08f; break;
default:
if (rawTotal >= 500.0f) discountRate = 0.10f;
break;
}
float finalPrice = rawTotal * (1.0f - discountRate);
printf("Base cost: %.2f\nDiscount applied: %.0f%%\nFinal payable: %.2f\n",
rawTotal, discountRate * 100, finalPrice);
return 0;
}
Nesting Control Structures
Complex decision trees often require combining control statements. Nesting if inside switch is useful for secondary validations, while nested switch blocks efficiently manage hierarchical menus.
Secondary Validation: Days in a Month
Determining the number of days in February requires an additional leap year check. The switch statement routes to month 2, where an if block evaluates the calendar rule.
#include <stdio.h>
int main(void) {
int yr, mn;
printf("Input year and month (e.g., 2023 10): ");
if (scanf("%d %d", &yr, &mn) != 2) return 1;
int daysInMonth;
switch (mn) {
case 2:
if ((yr % 4 == 0 && yr % 100 != 0) || (yr % 400 == 0))
daysInMonth = 29;
else
daysInMonth = 28;
break;
case 1: case 3: case 5: case 7:
case 8: case 10: case 12:
daysInMonth = 31;
break;
case 4: case 6: case 9: case 11:
daysInMonth = 30;
break;
default:
printf("Invalid month provided.\n");
return 1;
}
printf("Month %d in year %d contains %d days.\n", mn, yr, daysInMonth);
return 0;
}
Hierarchical Routing: Tiered Menu System
A two-level selection process can be modeled by placing a switch block inside another. The outer block selects a product category, while the inner block calculates costs based on the specific item and quantity.
#include <stdio.h>
int main(void) {
int category, item, quantity;
float totalPrice = 0.0f;
printf("Select category: 1 for Household, 2 for Stationery, 3 for Snacks\n");
if (scanf("%d", &category) != 1) return 1;
switch (category) {
case 1:
printf("1: Toothbrush (3.50) 2: Toothpaste (6.20)\n");
printf("3: Soap (2.00) 4: Towel (8.60)\n");
scanf("%d", &item);
printf("Quantity: ");
scanf("%d", &quantity);
switch (item) {
case 1: totalPrice = 3.50f * quantity; break;
case 2: totalPrice = 6.20f * quantity; break;
case 3: totalPrice = 2.00f * quantity; break;
case 4: totalPrice = 8.60f * quantity; break;
default: printf("Invalid item.\n"); return 1;
}
break;
case 2:
printf("1: Pen (3.00) 2: Notebook (1.20)\n");
printf("3: Binder (12.00) 4: Pencil Case (8.60)\n");
scanf("%d", &item);
printf("Quantity: ");
scanf("%d", &quantity);
switch (item) {
case 1: totalPrice = 3.00f * quantity; break;
case 2: totalPrice = 1.20f * quantity; break;
case 3: totalPrice = 12.00f * quantity; break;
case 4: totalPrice = 8.60f * quantity; break;
default: printf("Invalid item.\n"); return 1;
}
break;
case 3:
printf("1: Sugar Pack (3.60) 2: Salt Pack (1.00)\n");
printf("3: Biscuit (2.00) 4: Noodle Pack (3.60)\n");
scanf("%d", &item);
printf("Quantity: ");
scanf("%d", &quantity);
switch (item) {
case 1: totalPrice = 3.60f * quantity; break;
case 2: totalPrice = 1.00f * quantity; break;
case 3: totalPrice = 2.00f * quantity; break;
case 4: totalPrice = 3.60f * quantity; break;
default: printf("Invalid item.\n"); return 1;
}
break;
default:
printf("Invalid category.\n");
return 1;
}
printf("Total amount due: %.2f\n", totalPrice);
return 0;
}
Pitfalls in Relational and Logical Expressions
Two common sources of logical errors involve floating-point comparisons and chained relational operators.
Floating-Point Precision
Direct equality checks with double or float types often fail due to binary representation limits. Instead of if (z == 0), an epsilon tolerance should be used.
#include <stdio.h>
#include <math.h>
int main(void) {
double x = 1000.0 / 3.0;
double y = x - 333.0;
double z = 3.0 * y - 1.0;
printf("x = %.6f\ny = %.6f\nz = %.6f\n", x, y, z);
if (fabs(z) < 1e-9) {
printf("Result is effectively zero.\n");
} else {
printf("Result deviates from zero.\n");
}
return 0;
}
Chained Comparisons vs Logical Conjunction
Mathematical notation like 5 < num < 10 is invalid in C. The compiler evaluatse left-to-right: (5 < num) yields 1 (true) or 0 (false), which is then compared to 10. This always evaluates to true. The correct approach explicitly combines two separate relational checks.
#include <stdio.h>
int main(void) {
int num = 20;
// Incorrect: 5 < num < 10 (compiles but yields wrong logic)
// Correct:
if (num > 5 && num < 10) {
printf("%d falls within the target range.\n", num);
} else {
printf("%d is outside the target range.\n", num);
}
return 0;
}