కండిషనల్ స్టేట్మెంట్స్ (if, else if, else & Nested Branches)
నిత్య జీవితంలో మనం తీసుకునే నిర్ణయాలను ఒక్కసారి గమనించండి: "వర్షం పడితే — గొడుగు తీసుకుని వెళ్ళు; లేకపోతే — సాధారణంగా వెళ్ళు", "బ్యాంక్ అకౌంట్లో సరిపడా డబ్బులు ఉంటేనే — ఏటీఎమ్ నుండి క్యాష్ ఇవ్వు; లేకపోతే — 'ఇన్సఫీషియంట్ బ్యాలెన్స్' అని చూపించు", "ట్రాఫిక్ లైట్ ఎరుపు రంగులో ఉంటే — బండి ఆపు; ఆకుపచ్చగా ఉంటే — ముందుకు సాగు". మన మానవ జీవితం మొత్తం ఇటువంటి వందలాది షరతులు (Conditions) మరియు నిర్ణయాల ఆధారంగానే ముందుకు సాగుతుంది.
కంప్యూటర్ ప్రోగ్రామ్లు కూడా అచ్చం ఇలాగే ఆలోచించగలగాలి! మొదటి 4 అధ్యాయాలలో (Phase 01) మనం రాసిన ప్రోగ్రామ్లు మొదటి లైన్ నుండి చివరి లైన్ వరకు వరుసగా ఒకే ట్రాక్లో వెళ్లిపోయేవి (Sequential Execution). కానీ నిజమైన సాఫ్ట్వేర్ అలా ఉండదు; అది యూజర్ ఇచ్చే ఇన్పుట్లను బట్టి, పరిస్థితులను బట్టి తన మార్గాన్ని మార్చుకోగలగాలి (Branching / Decision Making)!
కంప్యూటర్కు ఈ "ఆలోచించే మేధస్సును" అందించే అద్భుతమైన సాధనాలే కండిషనల్ స్టేట్మెంట్స్ (Conditional Statements). C లోని if, else, else if లాడర్, నెస్టెడ్ బ్రాంచెస్, మరియు ఇంటర్వ్యూలలో సీనియర్లను సైతం బోల్తా కొట్టించే if (x = 5) అసైన్మెంట్ బగ్స్ గురించి ఈ ఐదవ అధ్యాయంలో లోతుగా నేర్చుకుందాం!
- కంట్రోల్ ఫ్లో (Control Flow): సీక్వెన్షియల్ ఎగ్జిక్యూషన్ వర్సెస్ కండిషనల్ బ్రాంచింగ్.
- సింపుల్ if స్టేట్మెంట్ (Simple if): సింటాక్స్, కండిషన్ ట్రూ/ఫాల్స్ బైనరీ ఎవాల్యుయేషన్.
- if-else స్టేట్మెంట్: రెండు ప్రత్యామ్నాయ మార్గాలు (Two-Way Branching) & ఫాల్బ్యాక్ లాజిక్.
- రియల్ వరల్డ్ ప్రాజెక్ట్ 1 — ATM సిమ్యులేటర్: క్యాష్ విత్డ్రా మరియు పిన్ వెరిఫికేషన్ లాజిక్.
- else-if లాడర్ (Multi-Way Selection): బహుళ కండిషన్లు & కాలేజ్ మార్క్స్ గ్రేడింగ్ సిస్టమ్.
- నెస్టెడ్ if-else (Nested Conditions): ఒక కండిషన్ లోపల మరొక కండిషన్ పెట్టే మెకానిక్స్.
- ది డెడ్లీ అసైన్మెంట్ ట్రాప్:
if (x = 5)vsif (x == 5)— కంపైలర్ ఎందుకు ఎర్రర్ ఇవ్వదు? - ది డాంగ్లింగ్ else సమస్య (The Dangling else): కంపైలర్ else ని ఏ if కి జతచేస్తుందో తెలిపే అంతర్జాతీయ నియమం.
- కర్లీ బ్రేసెస్ {} లేకపోతే జరిగే ప్రమాదాలు: సింగిల్ స్టేట్మెంట్ ట్రాప్ & ఇండెంటేషన్ భ్రమలు.
- బిగినర్స్ చేసే టాప్ 5 కండిషనల్ తప్పులు:
if();సెమికోలన్ బగ్,10 < x < 20చైనింగ్ బగ్. - ఇంటరాక్టివ్ క్విజ్: 5 లోతైన ఆలోచింపజేసే ప్రాక్టికల్ ప్రశ్నలు & వివరణలు.
కంప్యూటర్ CPU మీ ప్రోగ్రామ్లోని లైన్లను ఏ క్రమంలో ఎగ్జిక్యూట్ చేస్తుందో తెలిపే విధానాన్నే కంట్రోల్ ఫ్లో (Control Flow) అంటారు. సాధారణంగా ప్రోగ్రామింగ్లో మూడు రకాల కంట్రోల్ ఫ్లోలు ఉంటాయి:
| కంట్రోల్ ఫ్లో రకం | ఎగ్జిక్యూషన్ విధానం | వాస్తవ ఉదాహరణ |
|---|---|---|
| 1. సీక్వెన్షియల్ (Sequential) | పై నుండి కిందికి వరుసగా ప్రతి లైన్ ఎగ్జిక్యూట్ అవుతుంది; ఏ లైన్ స్కిప్ అవ్వదు. | printf("Hello"); printf("World"); |
| 2. బ్రాంచింగ్ / సెలెక్షన్ (Branching) | కండిషన్ను బట్టి ఒక మార్గంలోకి వెళ్లి, మిగిలిన కోడ్ బ్లాక్ను పూర్తిగా స్కిప్ చేస్తుంది. | if (బ్యాలెన్స్ >= మొత్తం) క్యాష్ ఇవ్వు; else తిరస్కరించు; |
| 3. లూపింగ్ / ఇటరేషన్ (Looping) | కండిషన్ పూర్తయ్యేంత వరకు ఒకే కోడ్ బ్లాక్ను పదేపదే ఎగ్జిక్యూట్ చేస్తుంది. | 1 నుండి 100 వరకు సంఖ్యలు ప్రింట్ చేయడం (Chapter 7). |
C లాంగ్వేజ్లో బ్రాంచింగ్ కొరకు మనం ప్రధానంగా if-else మరియు switch-case లను ఉపయోగిస్తాం. ఈ అధ్యాయంలో if-else కుటుంబం మొత్తాన్ని సమగ్రంగా నేర్చుకుందాం!
ఒక నిర్దిష్ట షరతు నిజమైతేనే (Condition True అయితేనే) ఒక పని చేయాలి, లేకపోతే ఏమీ చేయకుండా ముందుకు వెళ్లిపోవాలి అనుకున్నప్పుడు సింపుల్ if ఉపయోగిస్తాం:
// కండిషన్ TRUE (సున్నా కాని సంఖ్య) అయితేనే ఈ కోడ్ రన్ అవుతుంది
}
#include <stdio.h>
int main(void) {
int temperature = 42;
printf("ప్రస్తుత ఉష్ణోగ్రత: %d°C\n", temperature);
// 40 దాటితే మాత్రమే ఈ వార్నింగ్ కనిపిస్తుంది
if (temperature > 40) {
printf("⚠️ తీవ్రమైన ఎండ! దయచేసి నీళ్ళు ఎక్కువగా తాగండి.\n");
}
printf("వాతావరణ నివేదిక ముగిసింది.\n");
return 0;
}
గుర్తుంచుకోండి: C లో
if (కండిషన్) లోపల ఉన్న ఎక్స్ప్రెషన్ విలువ 0 (Zero) అయితే అది ఫాల్స్ (False) గా భావించి కోడ్ బ్లాక్ను స్కిప్ చేస్తుంది. ఆ విలువ సున్నా కాకుండా మరే సంఖ్య అయినా (1, 100, -50) అది ట్రూ (True) గా పరిగణించబడి లోపలికి ప్రవేశిస్తుంది!
నిజ జీవితంలో ఒక షరతు నిజమైతే ఒక పని, అబద్ధమైతే మరొక పని చేయాల్సి ఉంటుంది. ఉదాహరణకు ఓటు హక్కు లభించాలంటే వయస్సు 18 లేదా అంతకంటే ఎక్కువ ఉండాలి; లేకపోతే అనర్హులుగా ప్రకటించాలి. దీనిని if-else ద్వారా సులభంగా నిర్మించవచ్చు:
#include <stdio.h>
int main(void) {
int age;
printf("మీ వయస్సు నమోదు చేయండి: ");
scanf("%d", &age);
if (age >= 18) {
printf("✅ అభినందనలు! మీకు ఓటు హక్కు ఉంది.\n");
} else {
int yearsLeft = 18 - age;
printf("❌ క్షమించండి! మీకు ఓటు హక్కు లేదు.\n");
printf("ఇంకా %d సంవత్సరాలు వేచి ఉండాలి.\n", yearsLeft);
}
return 0;
}
if-else నిర్మాణంలో ఖచ్చితంగా ఏదో ఒక బ్లాక్ మాత్రమే ఎగ్జిక్యూట్ అవుతుంది; రెండు బ్లాక్లు ఒకేసారి ఎప్పటికీ రన్ కావు, అలాగే రెండూ స్కిప్ కూడా కావు!
మనం రోజూ ఉపయోగించే బ్యాంక్ ATM మెషీన్ వెనుక ఉండే లాజిక్ను C లాంగ్వేజ్ if-else తో ఎలా నిర్మిస్తారో చూద్దాం:
#include <stdio.h>
int main(void) {
int accountBalance = 15000;
int withdrawAmount;
printf("=== మన బ్యాంక్ ATM సర్వీస్ ===\n");
printf("ప్రస్తుత బ్యాలెన్స్: ₹%d\n", accountBalance);
printf("విత్డ్రా చేయవలసిన మొత్తం నమోదు చేయండి: ₹");
scanf("%d", &withdrawAmount);
// కండిషన్ 1: మొత్తం 100 గుణిజాల్లో ఉందా? (% 100 == 0)
// కండిషన్ 2: అకౌంట్లో సరిపడా డబ్బులు ఉన్నాయా?
if (withdrawAmount <= 0) {
printf("❌ ఎర్రర్: దయచేసి సరైన మొత్తాన్ని నమోదు చేయండి!\n");
} else if (withdrawAmount % 100 != 0) {
printf("❌ ఎర్రర్: కేవలం ₹100, ₹500 నోట్లు మాత్రమే అందుబాటులో ఉన్నాయి!\n");
} else if (withdrawAmount > accountBalance) {
printf("❌ విత్డ్రా విఫలమైంది: మీ ఖాతాలో సరిపడా బ్యాలెన్స్ లేదు!\n");
} else {
accountBalance -= withdrawAmount;
printf("💵 దయచేసి మీ నగదు ₹%d స్వీకరించండి.\n", withdrawAmount);
printf("మిగిలిన బ్యాలెన్స్: ₹%d\n", accountBalance);
}
printf("ధన్యవాదాలు! మళ్ళీ సందర్శించండి.\n");
return 0;
}
రెండు కంటే ఎక్కువ ఎంపికలు ఉన్నప్పుడు (ఉదాహరణకు: ఫస్ట్ క్లాస్, సెకండ్ క్లాస్, థర్డ్ క్లాస్, ఫెయిల్) వరుసగా కండిషన్లను చెక్ చేసుకుంటూ వెళ్ళే నిర్మాణాన్ని else-if లాడర్ (Ladder) అంటారు:
#include <stdio.h>
int main(void) {
int marks;
printf("విద్యార్థి మార్కులు నమోదు చేయండి (0 - 100): ");
scanf("%d", &marks);
// చెల్లని మార్కులను ముందే ఫిల్టర్ చేయడం
if (marks < 0 || marks > 100) {
printf("❌ చెల్లని మార్కులు! దయచేసి 0 నుండి 100 మధ్య ఇవ్వండి.\n");
} else if (marks >= 90) {
printf("🏆 గ్రేడ్: O (Outstanding! టాపర్)\n");
} else if (marks >= 80) {
printf("🌟 గ్రేడ్: A+ (Excellent)\n");
} else if (marks >= 70) {
printf("👍 గ్రేడ్: A (Very Good)\n");
} else if (marks >= 60) {
printf("👌 గ్రేడ్: B (Good)\n");
} else if (marks >= 40) {
printf("⚠️ గ్రేడ్: C (Pass)\n");
} else {
printf("❌ గ్రేడ్: F (Fail - మళ్ళీ ప్రయత్నించండి)\n");
}
return 0;
}
else if లను అసలు పరిశీలించదు.
ఒక if లేదా else బ్లాక్ లోపల మరొక if-else రాస్తే దానిని నెస్టెడ్ if-else (Nested Branches) అంటారు. మొదటి షరతు నిజమైతేనే, లోపలి రెండవ షరతును పరిశీలించాల్సి వచ్చినప్పుడు ఇది ఉపయోగపడుతుంది:
#include <stdio.h>
int main(void) {
int hasKeyCard = 1; // 1 = కార్డు ఉంది, 0 = కార్డు లేదు
int currentWeight = 450; // కిలోలలో
const int MAX_WEIGHT = 500;
// మొదటి స్థాయి చెక్: సెక్యూరిటీ యాక్సెస్
if (hasKeyCard == 1) {
printf("🔑 యాక్సెస్ అనుమతించబడింది.\n");
// రెండవ స్థాయి నెస్టెడ్ చెక్: బరువు పరిమితి
if (currentWeight <= MAX_WEIGHT) {
printf("🛗 లిఫ్ట్ పై అంతస్తుకు కదులుతోంది...\n");
} else {
printf("🚨 హెచ్చరిక: లిఫ్ట్ ఓవర్లోడ్ అయింది! దయచేసి ఒకరు కిందకు దిగండి.\n");
}
} else {
printf("⛔ యాక్సెస్ తిరస్కరించబడింది: దయచేసి మీ స్మార్ట్ కార్డును స్వైప్ చేయండి.\n");
}
return 0;
}
C ప్రోగ్రామింగ్ చరిత్రలో బిలియన్ డాలర్ల నష్టాన్ని కలిగించిన అత్యంత భయంకరమైన బగ్ ఇది! ఒక పోలిక చేయబోయి పొరపాటున ఒకే ఒక్క = రాస్తే ఏం జరుగుతుందో చూడండి:
| స్టేట్మెంట్ | వాస్తవంగా ఏం జరుగుతుంది? | ఫలితం (Condition Result) |
|---|---|---|
if (x == 5) |
x లో ఉన్న విలువ 5 కి సమానమా అని పోలుస్తుంది (Comparison). |
x విలువ 5 అయితే True (1); లేకపోతే False (0). సరైనది! |
if (x = 5) |
x లోకి 5 ని అసైన్ చేస్తుంది (Assignment), ఆ అసైన్ అయిన 5 ని కండిషన్గా తీసుకుంటుంది! |
5 అనేది సున్నా కాని సంఖ్య కాబట్టి ఎల్లప్పుడూ TRUE అవుతుంది! తీవ్రమైన లాజిక్ బగ్! |
if (x = 0) |
x లోకి 0 ని అసైన్ చేస్తుంది. ఆ 0 కండిషన్ అవుతుంది. |
0 కాబట్టి ఎల్లప్పుడూ FALSE అవుతుంది! |
#include <stdio.h>
int main(void) {
int userRole = 0; // 0 = సాధారణ యూజర్, 1 = అడ్మిన్
// పొరపాటున == కి బదులుగా = రాశాం!
if (userRole = 1) {
printf("⚠️ భయంకరమైన బగ్: సాధారణ యూజర్కు అడ్మిన్ అధికారాలు లభించాయి!\n");
} else {
printf("సాధారణ యూజర్ డాష్బోర్డ్.\n");
}
return 0;
}
ఈ బగ్ను కంపైలర్ కూడా కనిపెట్టలేదు ఎందుకంటే C లో అసైన్మెంట్ కూడా ఒక లీగల్ ఎక్స్ప్రెషనే. దీనిని అడ్డుకోవడానికి సీనియర్ ప్రోగ్రామర్లు కాన్స్టాంట్ను ఎడమవైపు రాస్తారు:
if (5 == x).ఒకవేళ మీరు పొరపాటున
if (5 = x) అని రాస్తే — కాన్స్టాంట్కు విలువను అసైన్ చేయలేం కాబట్టి కంపైలర్ వెంటనే error: lvalue required as left operand of assignment అని ఎర్రర్ ఇచ్చి ప్రోగ్రామ్ను ఆపేస్తుంది!
నెస్టెడ్ కండిషన్లలో కర్లీ బ్రేసెస్ { } వాడనప్పుడు ఒక else ఏ if కి చెందుతుందో అర్థం కాక వచ్చే గందరగోళాన్నే Dangling else Problem అంటారు:
int a = 10;
int b = 20;
if (a > 5)
if (b > 30)
printf("A\n");
else
printf("B\n"); // ఈ else ఎవరికి చెందుతుంది? మొదటి if కా? రెండో if కా?
అంతర్జాతీయ C స్టాండర్డ్ నియమం:
C కంపైలర్లు ఎల్లప్పుడూ ఒక నిర్దిష్ట సూత్రాన్ని పాటిస్తాయి: "ఒక else ఎల్లప్పుడూ తనకు అత్యంత సమీపంలో ఉన్న (Nearest Unpaired) if కి మాత్రమే జతచేయబడుతుంది!"
పై కోడ్లో else అనేది if (b > 30) కి చెందుతుంది తప్ప మొదటి if (a > 5) కి కాదు! ఇండెంటేషన్ ఎలా ఉన్నా కంపైలర్ పట్టించుకోదు. అందుకే ఎల్లప్పుడూ కర్లీ బ్రేసెస్ { } తప్పనిసరిగా వాడాలి!
C లాంగ్వేజ్లో if తర్వాత కర్లీ బ్రేసెస్ { } పెట్టకపోతే — కంపైలర్ దాని తర్వాత వచ్చే కేవలం ఒక్కే ఒక్క స్టేట్మెంట్ను మాత్రమే if కింద పరిగణిస్తుంది!
#include <stdio.h>
int main(void) {
int isLoggedIn = 0; // లాగిన్ అవ్వలేదు
// బ్రేసెస్ లేవు!
if (isLoggedIn == 1)
printf("స్వాగతం, యూజర్!\n");
printf("మీ రహస్య బ్యాంక్ బ్యాలెన్స్: ₹50,000\n"); // ఇది if బయట ఉంది! ఎల్లప్పుడూ ప్రింట్ అవుతుంది!
return 0;
}
పై కోడ్లో యూజర్ లాగిన్ అవ్వకపోయినా — రెండవ లైన్ (బ్యాంక్ బ్యాలెన్స్) స్క్రీన్ మీద ప్రింట్ అయిపోతుంది! ఎందుకంటే బ్రేసెస్ లేకపోవడం వల్ల మొదటి లైన్ మాత్రమే if పరిధిలోకి వచ్చింది. రెండవ లైన్ సాధారణ కోడ్ లాగా రన్ అయిపోయింది. 2014 లో ఆపిల్ సంస్థ యొక్క ప్రసిద్ధ "goto fail" సెక్యూరిటీ బగ్ కు కూడా బ్రేసెస్ లేకపోవడమే కారణం!
if (age >= 18); { // తప్పు! సెమికోలన్ వల్ల if అక్కడితోనే ముగిసిపోయింది!
printf("ఓటు వేయవచ్చు"); // ఇది ఎల్లప్పుడూ రన్ అవుతుంది!
}
if(...) పక్కన సెమికోలన్ పెడితే అది "ఖాళీ స్టేట్మెంట్ (Null Statement)" అవుతుంది. ఆ తర్వాత ఉన్న కర్లీ బ్రేసెస్ సాధారణ బ్లాక్ అయిపోయి ఎల్లప్పుడూ రన్ అవుతుంది.
if (10 < x < 20) // తప్పు! C లో ఇది గణితం లాగా పనిచేయదు!
కంపైలర్ ముందుగా 10 < x ని ఎవాల్యుయేట్ చేసి 1 లేదా 0 ని ఇస్తుంది. ఆ తర్వాత 1 < 20 ఎల్లప్పుడూ True అవుతుంది! దీనిని ఎల్లప్పుడూ లాజికల్ AND తో రాయాలి: if (x > 10 && x < 20).
float f = 0.1f + 0.2f;
if (f == 0.3f) // చాలాసార్లు ఫాల్స్ అవుతుంది!
బైనరీ ఫ్లోటింగ్ పాయింట్ ప్రెసిషన్ లోపాల వల్ల దశాంశ సంఖ్యలు ఖచ్చితంగా సమానం కాకపోవచ్చు. వాటి మధ్య తేడాను (Epsilon) చెక్ చేయాలి: fabs(f - 0.3) < 0.00001.
ఈ అధ్యాయంలో మీరు నేర్చుకున్న డెసిషన్ మేకింగ్ భావనలను పరీక్షించుకోవడానికి క్రింది ప్రశ్నలపై క్లిక్ చేయండి:
❓ ప్రశ్న 1: C లాంగ్వేజ్లో if (-5) అని రాస్తే ఆ కండిషన్ True అవుతుందా లేక False అవుతుందా?
❓ ప్రశ్న 2: if (x = 0) అని రాస్తే ఆ బ్లాక్ లోపలి కోడ్ ఎగ్జిక్యూట్ అవుతుందా?
x = 0 అసైన్మెంట్ జరిగిన తర్వాత ఆ ఎక్స్ప్రెషన్ విలువ 0 అవుతుంది. 0 అంటే False కాబట్టి if బ్లాక్ స్కిప్ అవుతుంది.
❓ ప్రశ్న 3: ఒక if స్టేట్మెంట్ పక్కన కర్లీ బ్రేసెస్ లేకపోతే అది ఎన్ని స్టేట్మెంట్లను తన పరిధిలోకి తీసుకుంటుంది?
❓ ప్రశ్న 4: Dangling else సమస్యలో else క్లాజ్ ఏ if కి జతచేయబడుతుంది?
❓ ప్రశ్న 5: యోడా కండిషన్స్ (Yoda Conditions) అంటే ఏమిటి?
if (5 == x)). పొరపాటున ఒకే = రాసినా కంపైలేషన్ ఎర్రర్ వచ్చి బగ్ తక్షణమే బయటపడుతుంది.
పైన వివరించిన ATM క్యాష్ విత్డ్రా కోడ్ను మన ఆన్లైన్ C కంపైలర్లో ఓపెన్ చేసి స్వయంగా రకరకాల విత్డ్రా మొత్తాలను ఇచ్చి టెస్ట్ చేయండి. తప్పుడు పిన్, బ్యాలెన్స్ లోపాలు ఎలా హ్యాండిల్ అవుతున్నాయో గమనించండి!
📌 క్విక్ సారాంశం (Key Takeaways):
- కంట్రోల్ ఫ్లో: కండిషన్ల ఆధారంగా ప్రోగ్రామ్ మార్గాన్ని మార్చగలగడం.
- True vs False: C లో 0 అంటే False; సున్నా కాని ఏదైనా సంఖ్య True.
- else-if లాడర్: బహుళ ఎంపికలలో మొదటి సరైన కండిషన్ ఎగ్జిక్యూట్ అవ్వగానే బయటకు వస్తుంది.
- అసైన్మెంట్ బగ్:
if (x == 5)కి బదులుif (x = 5)రాస్తే ఎల్లప్పుడూ True అవుతుంది. - కర్లీ బ్రేసెస్: సింగిల్ లైన్ అయినా సరే ఎల్లప్పుడూ
{ }వాడటం ప్రొఫెషనల్ పద్ధతి.
else-if కంటే మెరుపు వేగంతో పనిచేసే switch-case స్టేట్మెంట్, O(1) Jump Tables ఆర్కిటెక్చర్, break ప్రాముఖ్యత, Fall-through మెకానిక్స్, మరియు పూర్తి సైంటిఫిక్ క్యాలిక్యులేటర్ ప్రాజెక్ట్ గురించి అత్యంత ఆసక్తికరంగా నేర్చుకుందాం!