Practical Implementation of Decision Logic in C Programming

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;
}

Tags: c-programming control-flow conditional-statements switch-case floating-point-precision

Posted on Wed, 02 Sep 2026 16:53:47 +0000 by PHPLRNR