break, continue & లూప్ కంట్రోల్
మునుపటి అధ్యాయంలో మనం లూప్స్ ద్వారా ఒకే పనిని పదే పదే ఎలా ఆటోమేట్ చేయవచ్చో నేర్చుకున్నాం. కానీ నిజ జీవితంలో ఒక లూప్ నిర్ణయించబడిన అన్ని రౌండ్లు తిరగాల్సిన అవసరం ఉండకపోవచ్చు! ఉదాహరణకు: 10 లక్షల రికార్డులలో ఒక యూజర్ సమాచారం 5వ రికార్డు వద్దే దొరికినప్పుడు, మిగిలిన 9,99,995 రౌండ్లు తిరగడం సమయం మరియు CPU రిసోర్స్లను తీవ్రంగా వృధా చేయడమే అవుతుంది.
ఇలాంటి సందర్భాలలో లూప్ యొక్క సాధారణ ప్రవాహాన్ని నియంత్రించడానికి C++ మనకు అందించే అస్త్రాలే జంప్ స్టేట్మెంట్లు: break మరియు continue. ఈ సమగ్ర మాస్టర్క్లాస్లో మనం:
1 కంట్రోల్ జంప్స్ అంటే ఏమిటి? లూప్స్ నుండి ముందస్తు నిష్క్రమణ (Early Exit) ఎందుకు అవసరం?
సాధారణంగా ఏ లూప్ అయినా తన కండిషన్ false అయ్యే వరకు తిరుగుతూనే ఉంటుంది. కానీ సాఫ్ట్వేర్ అప్లికేషన్లలో ఊహించని పరిస్థితులు (Exceptions), ఎర్రర్లు, లేదా ముందుగానే టార్గెట్ దొరకడం వంటివి జరుగుతుంటాయి.
లూప్ యొక్క పూర్తి సైకిల్స్ ముగియకముందే, మధ్యలోనే ఆ ప్రవాహాన్ని అడ్డుకుని బయటకు రావడాన్ని లేదా మార్చడాన్ని Early Exit (ముందస్తు నిష్క్రమణ) అంటారు.
🎯 C++ లోని 4 ప్రధాన జంప్ స్టేట్మెంట్లు (The 4 Jump Statements)
2. continue: ప్రస్తుత రౌండ్లోని మిగిలిన కోడ్ను వదిలేసి, వెంటనే తర్వాతి ఇటరేషన్కు దూకుతుంది.
3. return: లూప్తో పాటు యావత్ ఫంక్షన్ నుండే తక్షణమే ఫలితంతో బయటకు నిష్క్రమిస్తుంది.
4. goto: ప్రోగ్రామ్లోని ఏదైనా నిర్దిష్ట లేబుల్కు నేరుగా బలైపోయిన జంప్ చేస్తుంది (ప్రమాదకరం).
2 break స్టేట్మెంట్: తక్షణ లూప్ టెర్మినేషన్ (Instant Loop Termination)
ఒక లూప్ లోపల కంపైలర్కు break; ఎదురైన మరుక్షణమే, ఆ లూప్ యొక్క మిగిలిన అన్ని ఇటరేషన్లు తక్షణమే రద్దు చేయబడతాయి. కంట్రోల్ నేరుగా లూప్ కర్లీ బ్రాకెట్ల { ... } తర్వాత ఉన్న మొదటి స్టేట్మెంట్కు జంప్ చేస్తుంది.
#include <iostream>
#include <vector>
int main() {
std::vector<int> userIds = {1024, 2048, 4096, 8192, 16384, 32768, 65536};
int targetId = 8192;
int searchComparisons = 0;
bool isFound = false;
std::cout << "వెతుకుతున్న యూజర్ ఐడీ: " << targetId << "\n";
for (size_t i = 0; i < userIds.size(); ++i) {
++searchComparisons;
std::cout << "ఇండెక్స్ [" << i << "] పరిశీలన: ఐడీ " << userIds[i] << "...\n";
if (userIds[i] == targetId) {
std::cout << "🎉 ఐడీ విజయవంతంగా లభించింది! ఇండెక్స్: " << i << '\n';
isFound = true;
break; // 🛑 బ్రేక్! లక్ష్యం దొరికింది కాబట్టి మిగిలిన అర్రేను వెతకడం ఆపేయండి!
}
}
std::cout << "----------------------------------------------------\n";
std::cout << "మొత్తం పోలికల సంఖ్య: " << searchComparisons << " (లక్ష్యం లభించిన వెంటనే ఆగిపోయింది)\n";
return 0;
}
3 continue స్టేట్మెంట్: ప్రస్తుత ఇటరేషన్ను స్కిప్ చేయడం
break మొత్తం లూప్ను శాశ్వతంగా ఆపేస్తే, continue; స్టేట్మెంట్ కేవలం ఆ ప్రస్తుత రౌండ్ను మాత్రమే అర్ధాంతరంగా ముగించి, లూప్ను తర్వాతి రౌండ్కు (Next Iteration) ముందుకు నడిపిస్తుంది.
if (i % 2 == 0) continue; // సరి సంఖ్యలు వస్తే క్రింది కోడ్ను స్కిప్ చేయి
std::cout << i << " "; // కేవలం బేసి సంఖ్యలు మాత్రమే ప్రింట్ అవుతాయి (1 3 5 7 9)
}
⚠️ The Deadly while-loop continue Trap (భయంకరమైన ఇన్ఫైనైట్ లూప్ బగ్)
for లూప్లో continue కొట్టినప్పుడు అది ఆటోమేటిక్గా update (ఉదా: ++i) ను రన్ చేస్తుంది. కానీ while లూప్లో మీరు కౌంటర్ను లూప్ చివర పెట్టి, మధ్యలో continue కొడితే — కౌంటర్ అప్డేట్ అవ్వకుండా స్కిప్ అయిపోయి, లూప్ అనంతంగా తిరుగుతూ ప్రోగ్రామ్ ఫ్రీజ్ అయిపోతుంది!
#include <iostream>
int main() {
int count = 0;
std::cout << "1 నుండి 10 వరకు 3 యొక్క గుణిజాలను స్కిప్ చేయడం:\n";
while (count < 10) {
++count; // ✅ ఎల్లప్పుడూ continue కి ముందే కౌంటర్ను పెంచాలి!
if (count % 3 == 0) {
std::cout << "[స్కిప్: " << count << "] ";
continue; // 3, 6, 9 లు స్కిప్ అవుతాయి కానీ లూప్ సేఫ్ గా ముందుకు సాగుతుంది!
}
std::cout << count << " ";
}
std::cout << "\nలూప్ విజయవంతంగా ముగిసింది.\n";
return 0;
}
4 The Infamous goto స్టేట్మెంట్: చారిత్రక నేపథ్యం & "Spaghetti Code" ప్రమాదం
C మరియు C++ లలో ప్రారంభం నుండి ఉన్న ఒక పురాతన స్టేట్మెంట్ goto. ఇది కోడ్లో ఎక్కడైనా ఒక లేబుల్ (Label) పెట్టి, ప్రోగ్రామ్ను నేరుగా ఆ లేబుల్ వద్దకు దూకించడానికి అనుమతిస్తుంది: goto error_handler;.
📜 Dijkstra's 1968 Manifesto: "Go To Statement Considered Harmful"
కంప్యూటర్ సైన్స్ పితామహులలో ఒకరైన ప్రొఫెసర్ ఎడ్స్గర్ డైక్స్ట్రా (Edsger Dijkstra) 1968 లో రాసిన ప్రసిద్ధ పత్రం ఆధునిక సాఫ్ట్వేర్ ప్రపంచాన్ని మార్చేసింది. కోడ్లో విచ్చలవిడిగా goto లు రాస్తే, ప్రోగ్రామ్ ఫ్లో ఎటు నుండి ఎటు వెళ్తుందో ఎవరికీ అర్థం కాని నూడుల్స్ గిన్నెలా (Spaghetti Code) మారిపోతుంది! దీనివల్ల డీబగ్గింగ్ చేయడం అసాధ్యంగా మారుతుంది.
Modern C++ లో goto ఎందుకు దాదాపు నిషేధం?
C భాషలో ఎర్రర్ హ్యాండ్లింగ్ కోసం తప్పనిసరి పరిస్థితులలో goto cleanup; వాడేవారు. కానీ C++ లో మనకు RAII (Resource Acquisition Is Initialization), స్మార్ట్ పాయింటర్లు (std::unique_ptr), మరియు Exceptions ఉన్నాయి. C++ ఆబ్జెక్టుల డిస్ట్రక్టర్లు ఆటోమేటిక్గా మెమరీని క్లీన్ చేస్తాయి కాబట్టి Modern C++ లో goto వాడవలసిన అవసరం 100% లేదు!
5 మల్టీ-లెవల్ / నెస్టెడ్ లూప్స్ బ్రేకింగ్ (The Multi-Level Loop Break Challenge)
C++ లో బిగినర్స్ తరచుగా చేసే ఒక పెద్ద తప్పు: రెండు నెస్టెడ్ లూప్లు ఉన్నప్పుడు లోపలి లూప్లో break; రాస్తే రెండూ ఆగిపోతాయని అనుకోవడం!
C++ రూల్: break స్టేట్మెంట్ కేవలం తనకు అత్యంత సమీపంలో ఉన్న ఒకే ఒక్క లోపలి లూప్ను (Innermost Loop) మాత్రమే ఆపుతుంది. బయట ఉన్న ఔటర్ లూప్ ఇంకా నిరభ్యంతరంగా తిరుగుతూనే ఉంటుంది!
🏆 నెస్టెడ్ లూప్స్ నుండి బయటపడే 2 ఇండస్ట్రీ బెస్ట్ ప్రాక్టీసెస్
విధానం 1 (Boolean Flag): ఒక ఫ్లాగ్ వేరియబుల్ (bool exitBoth = false;) పెట్టి, ఇన్నర్ లూప్లో దాన్ని true చేసి బ్రేక్ చేయడం, ఔటర్ లూప్లో ఆ ఫ్లాగ్ను చెక్ చేసి మళ్లీ బ్రేక్ చేయడం.
విధానం 2 (Function Guard Return - Recommended): నెస్టెడ్ లూప్ను ఒక ప్రత్యేక ఫంక్షన్గా రాసి, టార్గెట్ దొరకగానే నేరుగా return చేయడం. ఇది అత్యంత క్లీన్ మరియు వేగవంతమైన ఆర్కిటెక్చరల్ పద్ధతి!
#include <iostream>
#include <vector>
// 2D మ్యాట్రిక్స్లో నంబర్ను వెతికే ఫంక్షన్: దొరకగానే నేరుగా return చేస్తుంది!
bool findInMatrix(const std::vector<std::vector<int>>& matrix, int target) {
for (size_t r = 0; r < matrix.size(); ++r) {
for (size_t c = 0; c < matrix[r].size(); ++c) {
if (matrix[r][c] == target) {
std::cout << "🎯 టార్గెట్ " << target << " రో [" << r << "], కాలమ్ [" << c << "] వద్ద దొరికింది!\n";
return true; // 🏆 మల్టీ-లెవల్ లూప్లన్నింటినీ ఒక్కేసారి బైపాస్ చేసి బయటకు వచ్చేస్తుంది!
}
}
}
return false; // ఎక్కడా దొరకలేదు
}
int main() {
std::vector<std::vector<int>> grid = {
{10, 20, 30},
{40, 50, 60},
{70, 80, 90}
};
findInMatrix(grid, 50);
return 0;
}
6 ఇన్ఫైనైట్ లూప్స్ సేఫ్ బ్రేకింగ్ & వాచ్డాగ్ టైమర్స్ (Watchdog Pattern)
ఎంబెడెడ్ సిస్టమ్స్ (IoT డివైజెస్, రోవర్లు, డ్రోన్లు) మరియు హై-అవైలబిలిటీ సర్వర్లలో ప్రోగ్రామ్ అకస్మాత్తుగా హ్యాంగ్ అయిపోకుండా చూసేందుకు వాచ్డాగ్ బ్రేక్ ప్యాటర్న్ (Watchdog Pattern) ఉపయోగిస్తారు.
ఒక while (true) లూప్ నిరంతరం రన్ అవుతున్నప్పటికీ, నిర్దిష్ట సమయం లేదా గరిష్ట ప్రయత్నాలు (Max Retries) దాటితే స్వయంచాలకంగా break అయి సిస్టమ్ను రీబూట్ లేదా ఎమర్జెన్సీ సేఫ్ మోడ్లోకి పంపుతుంది:
#include <iostream>
int main() {
int retryCount = 0;
const int maxRetries = 4;
bool isConnected = false;
std::cout << "🌐 క్లౌడ్ గేట్వే సర్వర్తో కనెక్ట్ అవ్వడానికి ప్రయత్నిస్తున్నాం...\n";
// ఇన్ఫైనైట్ లూప్ - కానీ వాచ్డాగ్ పరిమితితో సేఫ్ గా నియంత్రించబడింది!
while (true) {
++retryCount;
std::cout << "ప్రయత్నం #" << retryCount << "... ";
// 3వ ప్రయత్నంలో సర్వర్ రెస్పాండ్ అయిందని అనుకరిద్దాం
if (retryCount == 3) {
std::cout << "✅ కనెక్షన్ విజయవంతమైంది!\n";
isConnected = true;
break; // విజయవంతం కాగానే లూప్ టెర్మినేట్ అవుతుంది
}
std::cout << "❌ కనెక్షన్ విఫలమైంది.\n";
// వాచ్డాగ్ సేఫ్టీ చెక్: గరిష్ట పరిమితి దాటితే ఎమర్జెన్సీ బ్రేక్!
if (retryCount >= maxRetries) {
std::cout << "🛑 వాచ్డాగ్ అలర్ట్: గరిష్ట ప్రయత్నాలు పూర్తయ్యాయి. సర్వర్ డౌన్ అయింది!\n";
break;
}
}
return 0;
}
7 లూప్స్ లో return స్టేట్మెంట్: షార్ట్-సర్క్యూటింగ్ లూప్స్
ఒక ఫంక్షన్ లోపల మనం లూప్ నడిపిస్తున్నప్పుడు, break వాడితే లూప్ ముగిసిన తర్వాత ఆ ఫంక్షన్ లోని మిగిలిన లైన్లు కూడా రన్ అవుతాయి. కానీ కొన్ని సందర్భాలలో లూప్లో పని పూర్తి కాగానే మొత్తం ఫంక్షన్ అక్కడితో ముగిసిపోవాలి.
అటువంటి సందర్భాలలో break కు బదులుగా నేరుగా return వాడటం వల్ల ఫంక్షన్ ఎగ్జిక్యూషన్ తక్షణమే ముగిసి ఫలితాన్ని కాలర్కు అందిస్తుంది. దీనిని Short-Circuiting Loops via Return అంటారు.
8 ఫిల్టరింగ్ & డేటా శానిటైజేషన్ లో continue పాత్ర
నిజ జీవితంలో డేటాబేస్ లేదా వెబ్ API నుండి వచ్చే డేటాలో నల్ వాల్యూస్ (nullptr), ఖాళీ రికార్డులు లేదా నెగెటివ్ నంబర్లు వంటి అనవసరమైన చెత్త డేటా ఉంటుంది.
మెయిన్ బిజినెస్ లాజిక్ను పెద్ద పెద్ద if కండిషన్ల లోపల నెస్ట్ చేయకుండా, ప్రారంభంలోనే చెత్త రికార్డులను గుర్తించి continue; చేయడం ద్వారా కోడ్ను అత్యంత క్లీన్ గా ఉంచవచ్చు (Early Continue Guard Pattern):
#include <iostream>
#include <vector>
struct Order {
int orderId;
double amount;
bool isCancelled;
};
int main() {
std::vector<Order> orders = {
{101, 1500.0, false},
{102, -50.0, false}, // తప్పుడు అమౌంట్
{103, 3200.0, true}, // క్యాన్సిల్ అయిన ఆర్డర్
{104, 4500.0, false},
{105, 0.0, false} // ఉచిత ఆర్డర్
};
double validRevenue = 0.0;
int processedCount = 0;
std::cout << "--- ఈ-కామర్స్ ఆర్డర్ల రెవెన్యూ శానిటైజేషన్ పైప్లైన్ ---\n";
for (const auto& ord : orders) {
// 1. రద్దయిన ఆర్డర్లను స్కిప్ చేయండి
if (ord.isCancelled) {
std::cout << "ఆర్డర్ #" << ord.orderId << " రద్దు చేయబడింది. [స్కిప్]\n";
continue;
}
// 2. అమాన్యమైన రుణ లేదా సున్నా విలువలను స్కిప్ చేయండి
if (ord.amount <= 0.0) {
std::cout << "ఆర్డర్ #" << ord.orderId << " అమాన్యమైన మొత్తం: ₹" << ord.amount << " [స్కిప్]\n";
continue;
}
// 3. కేవలం చెల్లుబాటు అయ్యే ఆర్డర్లు మాత్రమే ఇక్కడికి చేరుకుంటాయి!
validRevenue += ord.amount;
++processedCount;
std::cout << "ఆర్డర్ #" << ord.orderId << " ప్రాసెస్ అయింది: ₹" << ord.amount << '\n';
}
std::cout << "-----------------------------------------------------\n";
std::cout << "విజయవంతంగా లెక్కించిన మొత్తం రెవెన్యూ: ₹" << validRevenue << '\n';
return 0;
}
9 హార్డ్వేర్ & అసెంబ్లీ స్థాయిలో బ్రేక్ & కంటిన్యూ (Unconditional Jumps)
కంపైలర్ break మరియు continue స్టేట్మెంట్లను మెషిన్ కోడ్గా మార్చే విధానం చాలా సున్నితమైనది:
breakఅసెంబ్లీ కోడ్: కంపైలర్ దీనినిJMP .L_LOOP_EXITఅనే షరతులేని జంప్ (Unconditional Jump) గా మారుస్తుంది. CPU తక్షణమే లూప్ బౌండరీ దాటి తదుపరి ఇన్స్ట్రక్షన్కు వెళ్లిపోతుంది.continueఅసెంబ్లీ కోడ్: కంపైలర్ దీనినిJMP .L_LOOP_UPDATEగా మారుస్తుంది. అంటే లూప్ వేరియబుల్ ఇంక్రిమెంట్ అయ్యే లేబుల్ వద్దకు జంప్ చేస్తుంది.
ఆధునిక CPU లలోని బ్రాంచ్ ప్రిడిక్టర్ (Branch Predictor) షరతులేని JMP సూచనలను 100% కచ్చితత్వంతో ముందే గ్రహిస్తుంది, కాబట్టి బ్రేక్ మరియు కంటిన్యూ ల వల్ల రన్టైమ్ పైప్లైన్ స్టాల్స్ దాదాపు సున్నా!
10 break vs continue vs return vs goto: సమగ్ర సాంకేతిక పోలిక
C++ లోని వివిధ జంప్ స్టేట్మెంట్ల స్వభావాన్ని సంపూర్ణంగా అర్థం చేసుకోవడానికి క్రింది పోలిక పట్టిక ఉపయోగపడుతుంది:
| ఫీచర్ / అంశం | break | continue | return | goto ⚠️ |
|---|---|---|---|---|
| ప్రభావ పరిధి (Scope) | ప్రస్తుత లూప్ లేదా switch మాత్రమే | ప్రస్తుత లూప్ యొక్క ఒక రౌండ్ మాత్రమే | మొత్తం ఫంక్షన్ అంతా | ఫంక్షన్ లోపల ఎక్కడికైనా జంప్ చేయవచ్చు |
| తర్వాతి గమ్యం | లూప్ ముగింపు బ్రాకెట్ తర్వాత | లూప్ అప్డేట్ / కండిషన్ వద్దకు | ఫంక్షన్ను పిలిచిన కాలర్ వద్దకు | నిర్దేశిత లేబుల్ వద్దకు |
| స్పాఘెట్టి కోడ్ రిస్క్ | చాలా తక్కువ (సురక్షితం) | చాలా తక్కువ (సురక్షితం) | చాలా తక్కువ (క్లీన్ కోడ్) | తీవ్రమైన ప్రమాదం (High Risk) |
| ఆధునిక వినియోగం | ఎర్లీ ఎగ్జిట్ & సెర్చ్ కోసం అత్యుత్తమం | ఫిల్టరింగ్ & శానిటైజేషన్ కొరకు | గార్డ్ క్లాజెస్ & షార్ట్-సర్క్యూట్ కొరకు | ఖచ్చితంగా నివారించాలి |
11 Modern C++ లో లూప్ జంప్స్ నివారణ: STL Algorithms & Ranges
Modern C++ లో అనుభవజ్ఞులైన డెవలపర్లు తరచుగా సాంప్రదాయ for లూప్లు మరియు break లను రాయడానికి బదులుగా Standard Library Algorithms ఉపయోగిస్తారు.
ఉదాహరణకు లీనియర్ సెర్చ్ మరియు బ్రేక్ స్థానంలో std::find_if వాడటం వల్ల కోడ్ ఎంతో స్పష్టంగా మారుతుంది:
#include <algorithm>
#include <vector>
std::vector<int> scores = {45, 68, 82, 95, 74};
// 90 కంటే ఎక్కువ మార్కులు సాధించిన మొదటి విద్యార్థిని వెతకడం (బ్రేక్ అవసరం లేదు!)
auto it = std::find_if(scores.begin(), scores.end(), [](int s) { return s >= 90; });
if (it != scores.end()) {
std::cout << "టాప్ స్కోరర్ మార్కులు: " << *it << '\n';
}
12 సాధారణ బిగినర్ తప్పులు, బగ్స్ & బెస్ట్ ప్రాక్టీసెస్
ఒక లూప్ లోపల switch ఉన్నప్పుడు, case లో రాసే break; కేవలం ఆ switch ను మాత్రమే ముగిస్తుంది! అది బయట ఉన్న లూప్ను ఎట్టి పరిస్థితుల్లోనూ ఆపదు. బయటి లూప్ను కూడా ఆపాలంటే ఫ్లాగ్ వేరియబుల్ లేదా ఫంక్షన్ రిటర్న్ వాడాలి.
ఒక లూప్ లోపల 5-6 చోట్ల break లు రాస్తే కోడ్ అర్థం చేసుకోవడం చాలా కష్టమవుతుంది. ఒక లూప్కు గరిష్టంగా 1 లేదా 2 స్పష్టమైన ఎగ్జిట్ పాయింట్లు మాత్రమే ఉండేలా డిజైన్ చేయాలి.
13 రియల్-వరల్డ్ ప్రాక్టీస్ ప్రాజెక్ట్: "Enterprise Cybersecurity Firewall & Deep Packet Inspection (DPI) Engine"
ఈ అధ్యాయంలో నేర్చుకున్న break, continue, Early Exit, మరియు మల్టీ-లెవల్ లూప్ కంట్రోల్ అన్నింటినీ ఉపయోగించి — సిస్కో లేదా ఫోర్టినెట్ తరహా పూర్తి స్థాయి "Enterprise Cybersecurity Network Firewall & Deep Packet Inspection Engine" ను నిర్మిద్దాం:
#include <iostream>
#include <vector>
#include <string>
#include <iomanip>
// నెట్వర్క్ ప్యాకెట్ డేటా నిర్మాణం
struct NetworkPacket {
int packetId;
std::string sourceIp;
int destPort;
std::string payload;
int threatScore; // 0 నుండి 100 వరకు రిస్క్ స్కోర్
};
int main() {
std::vector<NetworkPacket> packetStream = {
{1001, "192.168.1.15", 443, "GET /secure/dashboard HTTPS", 5},
{1002, "10.0.0.45", 80, "HEALTH_CHECK_PING", 0},
{1003, "172.16.0.88", 22, "SSH_BRUTE_FORCE_PAYLOAD", 85},
{1004, "192.168.1.18", 8080, "NORMAL_API_JSON_REQUEST", 10},
{1005, "45.33.32.156", 445, "MALWARE_RANSOMWARE_SIGNATURE",98}, // తీవ్రమైన సైబర్ దాడి!
{1006, "192.168.1.99", 443, "USER_IMAGE_UPLOAD", 12}
};
std::cout << "========================================================================================\n";
std::cout << " 🛡️ CLOUDSHIELD ENTERPRISE NEXT-GEN FIREWALL & PACKET INSPECTION ENGINE \n";
std::cout << "========================================================================================\n";
std::cout << std::left << std::setw(10) << "ప్యాకెట్ ID"
<< std::setw(18) << "సోర్స్ IP"
<< std::setw(8) << "పోర్ట్"
<< std::setw(14) << "రిస్క్ స్కోర్"
<< "ఫైర్వాల్ చర్య (Firewall Action)\n";
std::cout << "----------------------------------------------------------------------------------------\n";
int inspectedPackets = 0;
int passedPackets = 0;
int droppedPackets = 0;
bool emergencyLockdown = false;
// నెట్వర్క్ ప్యాకెట్ల స్ట్రీమ్ను పరిశీలించే లూప్
for (const auto& pkt : packetStream) {
++inspectedPackets;
// 1. continue ఉపయోగం: పోర్ట్ 80 హెల్త్చెక్ పింగ్ ప్యాకెట్లను తనిఖీ లేకుండా వైట్లిస్ట్ చేయండి
if (pkt.threatScore == 0 && pkt.destPort == 80) {
std::cout << std::left << std::setw(10) << pkt.packetId
<< std::setw(18) << pkt.sourceIp
<< std::setw(8) << pkt.destPort
<< std::setw(14) << pkt.threatScore
<< "⚪ [వైట్లిస్ట్ స్కిప్]: ఇంటర్నల్ హెల్త్చెక్ ప్యాకెట్.\n";
++passedPackets;
continue; // కరెంట్ ఇటరేషన్ను స్కిప్ చేసి తర్వాతి ప్యాకెట్కు వెళ్ళండి!
}
// 2. break ఉపయోగం: రిస్క్ స్కోర్ 90 దాటితే సిస్టమ్ పై క్రిటికల్ దాడి జరుగుతోందని గుర్తించి ఎమర్జెన్సీ లాక్డౌన్ చేయండి!
if (pkt.threatScore >= 90) {
std::cout << std::left << std::setw(10) << pkt.packetId
<< std::setw(18) << pkt.sourceIp
<< std::setw(8) << pkt.destPort
<< std::setw(14) << pkt.threatScore
<< "🚨 [క్రిటికల్ అటాక్]: మాల్వేర్ గుర్తించబడింది! పేలోడ్: " << pkt.payload << "\n";
emergencyLockdown = true;
++droppedPackets;
std::cout << "\n🛑 [EMERGENCY SYSTEM LOCKDOWN]: నెట్వర్క్ కనెక్షన్ తక్షణమే తెంచబడింది!\n";
break; // తక్షణమే లూప్ నుండి బ్రేక్ అయి బయటకు వచ్చేయండి!
}
// 3. సాధారణ త్రెట్ డ్రాపింగ్ (continue తో మిగిలిన కోడ్ బైపాస్)
if (pkt.threatScore >= 70) {
std::cout << std::left << std::setw(10) << pkt.packetId
<< std::setw(18) << pkt.sourceIp
<< std::setw(8) << pkt.destPort
<< std::setw(14) << pkt.threatScore
<< "🔴 [ప్యాకెట్ డ్రాప్]: అధిక రిస్క్ ఉన్నందున బ్లాక్ చేయబడింది.\n";
++droppedPackets;
continue;
}
// 4. క్లీన్ ప్యాకెట్లు సురక్షితంగా రౌట్ అవుతాయి
std::cout << std::left << std::setw(10) << pkt.packetId
<< std::setw(18) << pkt.sourceIp
<< std::setw(8) << pkt.destPort
<< std::setw(14) << pkt.threatScore
<< "🟢 [అనుమతించబడింది]: సురక్షితమైన ట్రాఫిక్.\n";
++passedPackets;
}
std::cout << "========================================================================================\n";
std::cout << "పరిశీలించిన ప్యాకెట్లు : " << inspectedPackets << " / " << packetStream.size() << "\n";
std::cout << "ఆమోదించబడిన ప్యాకెట్లు : " << passedPackets << "\n";
std::cout << "నిరోధించబడిన ప్యాకెట్లు : " << droppedPackets << "\n";
std::cout << "ఎమర్జెన్సీ లాక్డౌన్ స్టేటస్ : " << (emergencyLockdown ? "🔒 ACTIVE" : "🟢 NORMAL") << "\n";
std::cout << "========================================================================================\n";
return 0;
}
❓ ఇంటర్వ్యూ & పరీక్షల క్విజ్ (Knowledge Check)
ప్రశ్న 1: break మరియు continue స్టేట్మెంట్ల మధ్య గల ప్రధాన సాంకేతిక తేడా ఏమిటి?
break స్టేట్మెంట్ లూప్ను శాశ్వతంగా మరియు తక్షణమే ముగించివేసి, లూప్ తర్వాత ఉన్న కోడ్కు జంప్ చేస్తుంది (మిగిలిన ఏ ఇటరేషన్లు రన్ అవ్వవు). కానీ continue స్టేట్మెంట్ కేవలం ఆ ప్రస్తుత ఇటరేషన్లోని మిగిలిన భాగాలను మాత్రమే స్కిప్ చేసి, వెంటనే తర్వాతి ఇటరేషన్ను ప్రారంభిస్తుంది (లూప్ రద్దు కాదు).
ప్రశ్న 2: while లూప్లో continue వాడేటప్పుడు తలెత్తే అత్యంత ప్రమాదకరమైన బగ్ ఏమిటి?
while లూప్లో కౌంటర్ ఇంక్రిమెంట్ స్టేట్మెంట్ సాధారణంగా లూప్ చివరన ఉంటుంది. ఒకవేళ continue ఆ ఇంక్రిమెంట్ కంటే ముందే ట్రిగ్గర్ అయితే, కౌంటర్ పెరగకుండా స్కిప్ అయిపోతుంది. దీనివల్ల కండిషన్ ఎప్పటికీ false కాకుండా లూప్ అనంతంగా తిరుగుతూ (Infinite Loop) ప్రోగ్రామ్ ఫ్రీజ్ అయిపోతుంది. అందువల్ల while లో continue వాడే ముందు కౌంటర్ను తప్పనిసరిగా పెంచాలి.
ప్రశ్న 3: నెస్టెడ్ లూప్స్ లోపల రాసిన ఒకే ఒక్క break స్టేట్మెంట్ ఎన్ని లూప్లను ఆపుతుంది?
break కేవలం తనకు అత్యంత సమీపంలో ఉన్న లోపలి లూప్ను (Innermost loop) మాత్రమే ఆపుతుంది. బయటి ఔటర్ లూప్లు యధావిధిగా తిరుగుతూనే ఉంటాయి. అన్ని నెస్టెడ్ లూప్లను ఒకేసారి ఆపాలంటే బూలియన్ ఫ్లాగ్ వాడటం లేదా మొత్తం లూప్ను ఒక ఫంక్షన్లో ఉంచి return చేయడం అత్యుత్తమ పరిష్కారం.
ప్రశ్న 4: Modern C++ సాఫ్ట్వేర్ ఆర్కిటెక్చర్లో 'goto' స్టేట్మెంట్ను ఎందుకు నిషేధించాలి?
goto ప్రోగ్రామ్ ఫ్లోను అస్తవ్యస్తంగా మార్చి రీడబిలిటీని నాశనం చేసి "స్పాఘెట్టి కోడ్" కు దారితీస్తుంది. అంతేకాకుండా C++ లో వేరియబుల్స్ ప్రారంభం దాటి జంప్ చేస్తే ఆబ్జెక్ట్ లైఫ్సైకిల్ దెబ్బతింటుంది. C++ లో మనకు RAII, స్మార్ట్ పాయింటర్లు మరియు ఎక్సెప్షన్ హ్యాండ్లింగ్ ఉన్నందున మెమరీ క్లీనప్ కోసం goto అవసరమే ఉండదు.
ప్రశ్న 5: అసెంబ్లీ స్థాయిలో break మరియు continue ఎలా ఎగ్జిక్యూట్ అవుతాయి?
break ను షరతులేని జంప్ JMP .L_EXIT (లూప్ ముగింపు లేబుల్) గాను, continue ను JMP .L_UPDATE (లూప్ ఇంక్రిమెంట్ లేబుల్) గాను మారుస్తుంది. ఆధునిక CPU బ్రాంచ్ ప్రిడిక్టర్లు ఈ అన్కండిషనల్ జంప్స్ను 100% ముందుగానే అంచనా వేస్తాయి కాబట్టి ఎటువంటి పైప్లైన్ స్టాల్స్ కలగవు.
ఈ ప్రాజెక్ట్ను లైవ్గా మన కంపైలర్లో రన్ చేయండి!
ఎటువంటి లోకల్ సెటప్ లేకుండా, బ్రౌజర్లోనే నేరుగా Modern C++ (GCC 13 / C++20) కంపైలర్లో ఈ కోడ్ను ఎగ్జిక్యూట్ చేసి రన్టైమ్ అవుట్పుట్ను తనిఖీ చేయండి.