లూప్స్ (for, while, do-while)
కంప్యూటర్లు మానవుల కంటే ఎందుకు శక్తివంతమైనవని మనం అనుకుంటాం? ఎందుకంటే మనం ఒకే పనిని 10 సార్లు చేస్తే అలసిపోతాం లేదా బోర్ కొట్టి తప్పులు చేస్తాం. కానీ కంప్యూటర్ అదే పనిని సెకనుకు వందల కోట్ల సార్లు ఎలాంటి తప్పు లేకుండా నిరంతరం చేయగలదు! ప్రోగ్రామింగ్లో ఒకే కోడ్ బ్లాక్ను పదే పదే పునరావృతం చేయడానికి ఉపయోగించే అతి ముఖ్యమైన కాన్సెప్ట్ లూప్స్ (Loops / Iteration).
ఈ సమగ్ర మాస్టర్క్లాస్లో మనం సాంప్రదాయ for, while, do-while లూప్స్ నుండి మొదలుకొని — ఆధునిక C++11/C++20 యొక్క విప్లవాత్మక Range-based for Loop (for (const auto& x : collection)), CPU హార్డ్వేర్ ఆర్కిటెక్చర్లో Loop Unrolling మరియు L1 Cache Locality వేగం, పాయింటర్లు/ఇటరేటర్లలో ++i vs i++ రహస్యం, మరియు భయంకరమైన Off-By-One (OBOE) బగ్లను నివారించే పద్ధతులను కూలంకషంగా అధ్యయనం చేస్తాం. చివరిగా వాల్ స్ట్రీట్ ట్రేడింగ్ డెస్క్లు ఉపయోగించే పూర్తి స్థాయి "Enterprise Stock Portfolio Analytics & Risk Engine" ప్రాజెక్ట్ను లైవ్ కంపైలర్లో రన్ చేసి నేర్చుకుంటాం!
1 ఇటరేషన్ (Iteration) అంటే ఏమిటి? లూప్స్ కంప్యూటర్కు ఎందుకు అవసరం?
సాఫ్ట్వేర్ ఇంజనీరింగ్లో అత్యంత కీలకమైన సిద్ధాంతం DRY (Don't Repeat Yourself). మీరు ఒకే లైన్ ప్రింట్ను 100 సార్లు రాయడానికి 100 సార్లు std::cout రాస్తే, మీ కోడ్ పొడవు పెరగడమే కాకుండా దాన్ని మెయింటైన్ చేయడం దాదాపు అసాధ్యం.
ఒక నిర్దిష్ట నిబంధన (Condition) నిజమైనంత వరకు, ఒక కోడ్ బ్లాక్ను స్వయంచాలకంగా మళ్లీ మళ్లీ ఎగ్జిక్యూట్ చేసే ప్రోగ్రామింగ్ నిర్మాణాన్ని లూప్ (Loop) లేదా ఇటరేషన్ (Iteration) అంటారు.
⚙️ ఒక లూప్ యొక్క 4 మూలస్తంభాలు (The Anatomy of Any Loop)
int i = 0).2. Condition Check (నిబంధన తనిఖీ): లూప్ ఇంకా నడవాలో లేదో పరిశీలించడం (ఉదా:
i < 10).3. Loop Body (లూప్ బాడీ): కండిషన్ true అయినప్పుడు రన్ అయ్యే ప్రధాన వ్యాపార లాజిక్.
4. Update / Increment (నవీకరణ): తర్వాతి రౌండ్కు కౌంటర్ను మార్చడం (ఉదా:
++i). ఇది లేకపోతే లూప్ ఆగదు!
హార్డ్వేర్ స్థాయిలో అసెంబ్లీలో ఇది CMP (పోలిక), కండిషనల్ జంప్ (JNZ / JLE), మరియు ఇన్స్ట్రక్షన్ పాయింటర్ రీసెట్తో పనిచేస్తుంది. C++ లో మనకు ప్రధానంగా 4 రకాల లూప్స్ ఉన్నాయి:
forలూప్: ఇటరేషన్ల సంఖ్య ముందే తెలిసినప్పుడు అత్యుత్తమం.whileలూప్: ఎంట్రీ-కంట్రోల్డ్ లూప్; కండిషన్ ముందే సరిచూడాలి.do-whileలూప్: ఎగ్జిట్-కంట్రోల్డ్ లూప్; కనీసం ఒక్కసారైనా కోడ్ రన్ అవ్వాలి.Range-based forలూప్ (Modern C++): కలెక్షన్స్ & వెక్టర్లపై బగ్-ఫ్రీ ఇటరేషన్.
2 Standard for లూప్: ఆర్కిటెక్చర్ & సింటాక్స్ అనటమీ
C++ లో అత్యధికంగా వాడబడే లూప్ for లూప్. దీని ప్రత్యేకత ఏమిటంటే: ఇనిషియలైజేషన్, కండిషన్, మరియు అప్డేట్ మూడూ ఒకే లైన్లో పక్కపక్కనే రాయబడతాయి. దీనివల్ల డెవలపర్లు కౌంటర్ను అప్డేట్ చేయడం మర్చిపోయే ప్రమాదం చాలా తక్కువ!
// లూప్ బాడీ స్టేట్మెంట్లు
}
🔄 కంపైలర్ స్టెప్-బై-స్టెప్ ఎగ్జిక్యూషన్ ఫ్లో
దశ 1: initialization కేవలం మొదటిసారి మాత్రమే ఒక్కసారే రన్ అవుతుంది.
దశ 2: condition చెక్ చేయబడుతుంది. అది true అయితే బాడీలోకి వెళ్తుంది; false అయితే లూప్ ముగుస్తుంది.
దశ 3: లూప్ బాడీలోని కోడ్ పూర్తిగా ఎగ్జిక్యూట్ అవుతుంది.
దశ 4: లూప్ బాడీ పూర్తయిన వెంటనే update (ఉదా: ++i) రన్ అవుతుంది.
దశ 5: మళ్లీ దశ 2 (కండిషన్) కు వెళ్లి ప్రక్రియ పునరావృతమవుతుంది.
#include <iostream>
int main() {
std::cout << "🚀 ISRO చంద్రయాన్ రాకెట్ లాంచ్ కౌంట్డౌన్ ప్రారంభం:\n";
// 10 నుండి 1 వరకు రివర్స్ లూప్
for (int sec = 10; sec >= 1; --sec) {
std::cout << "T-minus " << sec << " సెకన్లు...\n";
}
std::cout << "🔥 ఇగ్నిషన్ ఆన్! రాకెట్ విజయవంతంగా నింగికెగిసింది!\n";
// గమనిక: 'sec' వేరియబుల్ స్కోప్ లూప్ బయట ఉండదు (Scope Isolation)
// std::cout << sec; // ❌ Compile Error!
return 0;
}
3 while లూప్: ఎంట్రీ-కంట్రోల్డ్ లూప్ (Entry-Controlled Loop)
ఒక లూప్ ఎన్నిసార్లు తిరగాలో ముందే కచ్చితంగా తెలియనప్పుడు (ఉదాహరణకు: నెట్వర్క్ సాకెట్ నుండి డేటా అయిపోయే వరకు చదవడం, లేదా ఒక సంఖ్య సున్నా అయ్యే వరకు డివైడ్ చేయడం), while లూప్ అత్యుత్తమ ఎంపిక.
దీనిని Entry-Controlled Loop అంటారు; ఎందుకంటే లూప్ బాడీలోకి అడుగుపెట్టడానికి ముందే కండిషన్ను తనిఖీ చేస్తుంది. మొదటిసారే కండిషన్ false అయితే, బాడీ అసలు ఒక్కసారి కూడా రన్ అవ్వదు!
#include <iostream>
int main() {
int originalNumber = 98452;
int temp = originalNumber;
int sumOfDigits = 0;
int reversedNumber = 0;
std::cout << "అసలు సంఖ్య: " << originalNumber << "\n";
// సంఖ్య 0 కంటే ఎక్కువ ఉన్నంత వరకు లూప్ రన్ అవుతుంది
while (temp > 0) {
int lastDigit = temp % 10; // చివరి అంకెను తీయండి
sumOfDigits += lastDigit; // మొత్తానికి కలపండి
reversedNumber = (reversedNumber * 10) + lastDigit; // రివర్స్ సంఖ్య నిర్మాణం
temp /= 10; // చివరి అంకెను తొలగించండి (Update)
}
std::cout << "అంకెల మొత్తం (Sum of Digits) : " << sumOfDigits << "\n";
std::cout << "రివర్స్ సంఖ్య (Reversed Number) : " << reversedNumber << "\n";
return 0;
}
4 do-while లూప్: ఎగ్జిట్-కంట్రోల్డ్ లూప్ (Exit-Controlled Loop)
కండిషన్ నిజమైనా అబద్ధమైనా సరే — కనీసం ఒక్కసారైనా (At least once) కోడ్ బ్లాక్ తప్పనిసరిగా రన్ కావాలి అనుకున్నప్పుడు మనం do-while లూప్ వాడతాం.
ఇది బాడీలోని కోడ్ను ముందుగా రన్ చేసి, చివరిలో నిబంధనను తనిఖీ చేస్తుంది. అందుకే దీనిని Exit-Controlled Loop అంటారు.
⚠️ The Mandatory Semicolon Trap (;)
C++ లోని అన్ని లూప్లలో కేవలం do-while లూప్ మాత్రమే చివరి బ్రాకెట్ తర్వాత సెమికోలన్ ; ను తప్పనిసరిగా కలిగి ఉండాలి: do { ... } while (condition);. ఇది పెట్టడం మర్చిపోతే కంపైలర్ సింటాక్స్ ఎర్రర్ ఇస్తుంది!
#include <iostream>
int main() {
const int correctPin = 5544;
int enteredPin;
int attempts = 0;
const int maxAttempts = 3;
bool isAuthenticated = false;
// అనుకరణ: ఒక యూజర్ ప్రయత్నాలు
int simulatedInputs[] = { 1111, 2222, 5544 };
do {
enteredPin = simulatedInputs[attempts]; // యూజర్ పిన్ నమోదు
++attempts;
std::cout << "ప్రయత్నం " << attempts << ": మీరు నమోదు చేసిన పిన్: " << enteredPin << "\n";
if (enteredPin == correctPin) {
std::cout << "✅ పిన్ సరిపోయింది! ఖాతా లాగిన్ విజయవంతమైంది.\n";
isAuthenticated = true;
break;
} else {
std::cout << "❌ తప్పుడు పిన్! మిగిలిన అవకాశాలు: " << (maxAttempts - attempts) << "\n";
}
} while (!isAuthenticated && attempts < maxAttempts);
if (!isAuthenticated) {
std::cout << "🔒 భద్రతా కారణాల దృష్ట్యా మీ ఏటీఎం కార్డు 24 గంటలు బ్లాక్ చేయబడింది!\n";
}
return 0;
}
5 Modern C++11/C++20 విప్లవం: Range-based for Loop
సాంప్రదాయ C++ లో వెక్టర్లు లేదా అర్రేలపై లూప్ రాయడానికి ఇండెక్స్ for (size_t i = 0; i < vec.size(); ++i) వాడేవారు. కానీ దీనిలో Off-By-One బగ్లు, పొరపాటున పరిధి దాటి వెళ్ళే ప్రమాదాలు (Buffer Overflow & Segfaults) నిత్యం జరుగుతుండేవి.
దీనికి ఆధునిక పరిష్కారంగా Modern C++11 లో Range-based for Loop ప్రవేశపెట్టబడింది. దీని సింటాక్స్ అత్యంత సులభం మరియు సురక్షితం:
// ప్రతి ఎలిమెంట్ను నేరుగా యాక్సెస్ చేయండి
}
💎 The 3 Golden Ways of Range-based for (పెర్ఫార్మెన్స్ రహస్యాలు)
- 1.
for (auto x : vec): ప్రతి ఎలిమెంట్ కాపీ అవుతుంది (Deep Copy). ఇంటిజర్స్ వంటి చిన్న డేటాకు పర్వాలేదు కానీ పెద్ద స్ట్రింగ్స్ లేదా క్లాస్ ఆబ్జెక్టులకు ఇది తీవ్రమైన మెమరీ వేస్ట్! - 2.
for (auto& x : vec): రెఫరెన్స్ ద్వారా యాక్సెస్. వెక్టర్లోని ఒరిజినల్ ఎలిమెంట్లను నేరుగా మార్చడానికి (Modify) ఇది వాడాలి. - 3.
for (const auto& x : vec): 🏆 ఇండస్ట్రీ గోల్డెన్ స్టాండర్డ్! ఎటువంటి కాపీ జరగదు (Zero Copy Overhead) మరియు ఎలిమెంట్ రీడ్-ఓన్లీగా సురక్షితంగా ఉంటుంది. పెర్ఫార్మెన్స్ గరిష్టంగా ఉంటుంది.
#include <iostream>
#include <vector>
#include <string>
#include <iomanip>
struct Employee {
std::string name;
double salary;
};
int main() {
std::vector<Employee> team = {
{"రాజేష్ కుమార్", 85000.00},
{"స్వప్న ప్రియ", 92000.00},
{"విక్రమ్ ఆదిత్య", 115000.00},
{"దివ్య వాణి", 78000.00}
};
std::cout << std::fixed << std::setprecision(2);
std::cout << "--- ఉద్యోగుల వార్షిక ఇంక్రిమెంట్ ప్రక్రియ (10% పెంపు) ---\n";
// 1. auto& ద్వారా ఒరిజినల్ శాలరీని మోడిఫై చేస్తున్నాం
for (auto& emp : team) {
emp.salary *= 1.10; // 10% ఇంక్రిమెంట్
}
// 2. const auto& ద్వారా జీరో-కాపీ రీడ్-ఓన్లీ డిస్ప్లే
double totalPayroll = 0.0;
for (const auto& emp : team) {
std::cout << "ఉద్యోగి: " << emp.name << " | సవరించిన జీతం: ₹ " << emp.salary << '\n';
totalPayroll += emp.salary;
}
std::cout << "-------------------------------------------------------\n";
std::cout << "మొత్తం నెలవారీ పేరోల్ వ్యయం: ₹ " << totalPayroll << '\n';
return 0;
}
6 నెస్టెడ్ లూప్స్ (Nested Loops) & 2D గ్రిడ్/మ్యాట్రిక్స్ మేనిప్యులేషన్
ఒక లూప్ లోపల మరొక లూప్ను రాయడాన్ని Nested Loops అంటారు. సాధారణంగా మ్యాట్రిక్స్లు, ఇమేజ్ పిక్సెల్స్ ప్రాసెసింగ్ (Rows & Columns), మరియు గేమ్ బోర్డులు (Chess, Tic-Tac-Toe) నిర్వహించడానికి ఇది అవసరం.
గమనించవలసిన విషయం: ఔటర్ లూప్ (Outer Loop) ఒక్కసారి తిరిగిన ప్రతిసారీ, ఇన్నర్ లూప్ (Inner Loop) తన పూర్తి సైకిల్ను పూర్తి చేసుకుంటుంది!
#include <iostream>
#include <iomanip>
int main() {
std::cout << "=== గణిత గుణకార పట్టిక గ్రిడ్ (1 నుండి 5 ఎక్కాలు) ===\n\n";
// ఔటర్ లూప్: అడ్డు వరుసలు (Rows: 1 to 5)
for (int row = 1; row <= 5; ++row) {
// ఇన్నర్ లూప్: నిలువు వరుసలు (Columns: 1 to 5)
for (int col = 1; col <= 5; ++col) {
std::cout << std::setw(4) << (row * col) << " ";
}
std::cout << "\n"; // ప్రతి రో పూర్తయిన తర్వాత కొత్త లైన్
}
return 0;
}
7 ఇన్ఫైనైట్ లూప్స్ (Infinite Loops): ప్రమాదాలు vs ఉద్దేశపూర్వక వినియోగం
లూప్ యొక్క నిబంధన ఎప్పటికీ false కాకుండా నిరంతరం తిరుగుతూనే ఉంటే దానిని ఇన్ఫైనైట్ లూప్ (Infinite Loop) అంటారు.
❌ ప్రమాదకరమైన అనుకోని ఇన్ఫైనైట్ లూప్స్ (CPU Freeze Bug)
లూప్ వేరియబుల్ ఇంక్రిమెంట్ చేయడం మర్చిపోతే లేదా తప్పుడు కండిషన్ రాస్తే ప్రోగ్రామ్ ఆగకుండా CPU 100% కోర్ వినియోగానికి వెళ్లి యాప్ ఫ్రీజ్ అయిపోతుంది. దీనిని కిల్ చేయడానికి ఆపరేటింగ్ సిస్టమ్ టాస్క్ మేనేజర్ వాడాల్సి వస్తుంది.
✅ ఉద్దేశపూర్వక ఇన్ఫైనైట్ లూప్స్: గేమ్ ఇంజిన్స్ & వెబ్ సర్వర్లు
ఆపరేటింగ్ సిస్టమ్స్ (Windows, Linux), గేమ్ ఇంజిన్లు (Unreal), మరియు సర్వర్లు యూజర్ నిష్క్రమించే వరకు నిరంతరం నడుస్తూనే ఉండాలి. దీనికి while (true) లేదా for (;;) ఉపయోగిస్తారు. లోపల యూజర్ 'Exit' నొక్కినప్పుడు break; స్టేట్మెంట్ ద్వారా క్లీన్ గా బయటకు వస్తారు.
8 లూప్స్ & ఇటరేటర్ల అంతర్గత పనితీరు: ++i vs i++ రహస్యం
చాలా మంది బిగినర్లు లూప్లలో i++ లేదా ++i ఏదైనా ఒకటే కదా అనుకుంటారు. ప్రాథమిక పూర్ణాంకాలకు కంపైలర్ ఆప్టిమైజ్ చేస్తుంది కాబట్టి పెద్ద తేడా కనిపించకపోవచ్చు. కానీ STL ఇటరేటర్లు మరియు క్లాస్ ఆబ్జెక్టులపై లూప్ రాసేటప్పుడు ఇది భారీ పెర్ఫార్మెన్స్ తేడాను తెస్తుంది!
| ఫీచర్ | ప్రీ-ఇంక్రిమెంట్ (++i) 🏆 | పోస్ట్-ఇంక్రిమెంట్ (i++) ⚠️ |
|---|---|---|
| అంతర్గత మెకానిజం | నేరుగా విలువను 1 పెంచి అదే ఆబ్జెక్ట్ను రిటర్న్ చేస్తుంది. | పాత విలువను భద్రపరచడానికి ఒక తాత్కాలిక కాపీని (Temporary Copy) సృష్టిస్తుంది. |
| మెమరీ ఓవర్హెడ్ | జీరో కాపీ (Zero Overhead). సూపర్ ఫాస్ట్. | అనవసరపు కాపీ కన్స్ట్రక్టర్ & డిస్ట్రక్టర్ కాల్స్ జరుగుతాయి. |
| ఇండస్ట్రీ రికమండేషన్ | C++ లో లూప్స్ రాసేటప్పుడు ఎల్లప్పుడూ ++i మాత్రమే వాడాలి. |
పాత విలువ ఖచ్చితంగా అవసరమైనప్పుడు మాత్రమే వాడాలి. |
9 హార్డ్వేర్ & CPU ఆప్టిమైజేషన్: Loop Unrolling & SIMD వెక్టరైజేషన్
హై-పెర్ఫార్మెన్స్ కంప్యూటింగ్లో ఒక లూప్ ప్రతి రౌండ్లోనూ CMP మరియు జంప్ అసెంబ్లీ ఇన్స్ట్రక్షన్లను రన్ చేయాల్సి వస్తుంది. దీనివల్ల బ్రాంచింగ్ ఓవర్హెడ్ పెరుగుతుంది.
ఆధునిక C++ కంపైలర్లు (GCC, Clang) దీనిని తగ్గించడానికి Loop Unrolling అనే ఆటోమేటిక్ టెక్నిక్ను ఉపయోగిస్తాయి:
⚡ Loop Unrolling అసెంబ్లీ కాన్సెప్ట్
for (int i = 0; i < 4; ++i) { arr[i] *= 2; }
// కంపైలర్ అన్రోల్ చేసిన కోడ్ (జీరో జంప్స్! డైరెక్ట్ సీక్వెన్షియల్ ఎగ్జిక్యూషన్):
arr[0] *= 2;
arr[1] *= 2;
arr[2] *= 2;
arr[3] *= 2;
అంతేకాకుండా ఆధునిక CPU లలో ఉన్న AVX-512 / SSE వెక్టరైజేషన్ ద్వారా 8 లేదా 16 ఫ్లోటింగ్ పాయింట్ సంఖ్యలను ఒక్కే ఒక్క CPU క్లాక్ సైకిల్లో ఏకకాలంలో ప్రాసెస్ (SIMD: Single Instruction Multiple Data) చేయవచ్చు!
10 for vs while vs do-while vs Range-based for: సమగ్ర పోలిక పట్టిక
ఏ సందర్భంలో ఏ లూప్ ఎంచుకోవాలి అనే సందిగ్ధతను తొలగించడానికి ఈ సమగ్ర పోలిక పట్టిక మీకు సహాయపడుతుంది:
| లూప్ రకం | కండిషన్ చెక్ స్థానం | కనీస ఎగ్జిక్యూషన్లు | ఉత్తమ వినియోగ సందర్భం (Best Use-Case) | ఆధునిక ప్రాధాన్యత |
|---|---|---|---|---|
| Standard for | ప్రారంభంలో (Pre-check) | 0 సార్లు | ఇటరేషన్ల సంఖ్య ముందే తెలిసినప్పుడు (ఉదా: 1 నుండి 100 వరకు) | ఇండెక్స్ ఆధారిత పనులకు చాలా మంచిది |
| while | ప్రారంభంలో (Pre-check) | 0 సార్లు | ఈవెంట్ లేదా నిబంధన ఆధారంగా తిరిగే లాజిక్లకు (ఉదా: ఫైల్ రీడింగ్) | స్టాండర్డ్ వినియోగం |
| do-while | చివరిలో (Post-check) | 1 సారి ఖచ్చితంగా | మెనూ డిస్ప్లే, యూజర్ ఇన్పుట్ లేదా పాస్వర్డ్ పునఃప్రయత్నాలు | అవసరమైనప్పుడు మాత్రమే |
| Range-based for | ఆటోమేటిక్ (Iterators) | 0 సార్లు | వెక్టర్లు, అర్రేలు, సెట్లు, మ్యాప్లలోని డేటాను సురక్షితంగా బ్రౌజ్ చేయడానికి | 🏆 Modern C++ లో మొదటి ప్రాధాన్యత |
11 ఆధునిక C++20 లూపింగ్ ఫీచర్లు: std::ranges & Views (పైప్లైన్ ప్రోగ్రామింగ్)
Modern C++20 లూపింగ్ ప్రపంచంలోకి ఒక సరికొత్త విప్లవాన్ని తీసుకొచ్చింది: std::ranges మరియు Views.
సాంప్రదాయ లూప్లలో మనం ఫిల్టర్ చేయడం, మార్చడం వంటి వాటికి పెద్ద పెద్ద if కండిషన్లు రాసేవాళ్ళం. కానీ C++20 పైప్లైన్ ఆపరేటర్ (|) తో డేటాను లైనక్స్ పైప్స్ లాగా నేరుగా ప్రాసెస్ చేయవచ్చు:
#include <ranges>
// Modern C++20 Range Pipeline: కేవలం సరి సంఖ్యలను మాత్రమే ఫిల్టర్ చేసి స్క్వేర్ చేస్తుంది
for (int x : numbers | std::views::filter([](int n){ return n % 2 == 0; })
| std::views::transform([](int n){ return n * n; })) {
std::cout << x << ' '; // జీరో మెమరీ అలొకేషన్తో లేజీ ఎవాల్యుయేషన్ (Lazy Evaluation)!
}
12 సాధారణ బిగినర్ తప్పులు, బగ్స్ & Off-By-One (OBOE) ట్రాప్స్
లూప్స్ రాసేటప్పుడు ఎగ్జిక్యూషన్ క్రాష్లకు కారణమయ్యే ప్రధాన తప్పులు మరియు వాటి నివారణ మార్గాలు:
int arr[5] = {10, 20, 30, 40, 50};
for (int i = 0; i <= 5; ++i) { // ⚠️ ఘోరమైన తప్పు! ఇండెక్స్ 5 లేదు! కేవలం 0 to 4 మాత్రమే ఉన్నాయి!
std::cout << arr[i] << " "; // i = 5 అయినప్పుడు అన్డిఫైన్డ్ బిహేవియర్ లేదా క్రాష్!
}
పరిష్కారం: అర్రే సైజ్ N ఉన్నప్పుడు ఎల్లప్పుడూ i < N వాడాలి (లేదా మరింత సురక్షితమైన Range-based for వాడాలి).
for (int i = 0; i < 5; ++i); // ⚠️ సెమికోలన్ ఇక్కడే లూప్ను ఖాళీగా 5 సార్లు తిప్పి ముగించేసింది!
{
std::cout << "హలో!\n"; // ఇది లూప్లో భాగం కాదు! కేవలం ఒక్కసారే ప్రింట్ అవుతుంది!
}
for (unsigned int i = 5; i >= 0; --i) { // ⚠️ అన్సైన్డ్ ఎప్పటికీ రుణాత్మకం (Negative) కాలేదు!
// i = 0 తర్వాత --i చేస్తే 4,294,967,295 అవుతుంది! ఈ లూప్ ఎప్పటికీ ఆగదు!
}
13 రియల్-వరల్డ్ ప్రాక్టీస్ ప్రాజెక్ట్: "Enterprise Stock Portfolio Analytics & Risk Engine"
ఈ అధ్యాయంలో మనం నేర్చుకున్న for, while, do-while, మరియు Modern C++ Range-based for అన్నింటినీ ఉపయోగించి — వాల్ స్ట్రీట్ ఇన్వెస్ట్మెంట్ బ్యాంకింగ్ తరహా "Enterprise Stock Portfolio Analytics & Risk Assessment Engine" ప్రాజెక్ట్ను రన్ చేద్దాం:
#include <iostream>
#include <vector>
#include <string>
#include <iomanip>
// స్టాక్ హోల్డింగ్ డేటా స్ట్రక్చర్
struct StockHolding {
std::string ticker;
std::string companyName;
int quantity;
double buyPrice;
double currentPrice;
};
int main() {
std::vector<StockHolding> portfolio = {
{"TCS", "Tata Consultancy Services", 50, 3450.00, 3920.50},
{"INFY", "Infosys Technologies", 120, 1420.00, 1850.75},
{"HDFCBANK", "HDFC Bank Limited", 80, 1680.00, 1540.25},
{"RELIANCE", "Reliance Industries Ltd", 65, 2380.00, 2910.00},
{"TATAMOTORS", "Tata Motors Limited", 150, 620.00, 945.80}
};
std::cout << std::fixed << std::setprecision(2);
std::cout << "========================================================================================\n";
std::cout << " 🏛️ BOMBAY STOCK EXCHANGE (BSE) - ENTERPRISE PORTFOLIO RISK ANALYTICS \n";
std::cout << "========================================================================================\n";
std::cout << std::left << std::setw(12) << "సింబల్"
<< std::setw(28) << "కంపెనీ పేరు"
<< std::setw(8) << "పరిమాణం"
<< std::setw(14) << "కొన్న ధర (₹)"
<< std::setw(14) << "మార్కెట్ ధర (₹)"
<< "లాభం/నష్టం (P&L)\n";
std::cout << "----------------------------------------------------------------------------------------\n";
double totalInvested = 0.0;
double totalCurrentValue = 0.0;
// 1. Modern C++ Range-based for loop (const auto& zero-copy performance)
for (const auto& stock : portfolio) {
double investment = stock.quantity * stock.buyPrice;
double currentValue = stock.quantity * stock.currentPrice;
double pnl = currentValue - investment;
double pnlPercent = (pnl / investment) * 100.0;
totalInvested += investment;
totalCurrentValue += currentValue;
std::cout << std::left << std::setw(12) << stock.ticker
<< std::setw(28) << stock.companyName
<< std::setw(8) << stock.quantity
<< std::setw(14) << stock.buyPrice
<< std::setw(14) << stock.currentPrice;
if (pnl >= 0.0) {
std::cout << "🟢 +₹ " << std::setw(9) << pnl << " (+" << pnlPercent << "%)\n";
} else {
std::cout << "🔴 -₹ " << std::setw(9) << (-pnl) << " (" << pnlPercent << "%)\n";
}
}
double netProfit = totalCurrentValue - totalInvested;
double netReturnPercent = (netProfit / totalInvested) * 100.0;
std::cout << "========================================================================================\n";
std::cout << "మొత్తం పెట్టుబడి మొత్తం (Total Invested) : ₹ " << totalInvested << '\n';
std::cout << "ప్రస్తుత పోర్ట్ఫోలియో విలువ (Current Value) : ₹ " << totalCurrentValue << '\n';
std::cout << "నికర లాభం / నష్టం (Net Realized P&L) : "
<< (netProfit >= 0.0 ? "🟢 +₹ " : "🔴 -₹ ") << netProfit
<< " (" << netReturnPercent << "%)\n";
std::cout << "========================================================================================\n";
// 2. while లూప్: లైవ్ స్టాక్ ట్రేడింగ్ వాలటాలిటీ మోనిటరింగ్ అనుకరణ
std::cout << "\n[మార్కెట్ లైవ్ టిక్ వాలటాలిటీ అనలిసిస్ - while లూప్ అనుకరణ]:\n";
int simulationTicks = 3;
int tickCount = 0;
while (tickCount < simulationTicks) {
++tickCount;
std::cout << " ⏱️ టిక్ #" << tickCount << ": నిఫ్టీ 50 ఇండెక్స్ సాధారణ స్థాయిలలో హెచ్చుతగ్గులకు లోనవుతోంది.\n";
}
// 3. do-while లూప్: డైలీ రిస్క్ మేనేజ్మెంట్ ఆడిట్ చెక్
std::cout << "\n[సెబీ కంప్లయన్స్ రిస్క్ ఆడిట్ - do-while లూప్ చెక్]:\n";
int auditPasses = 0;
do {
++auditPasses;
std::cout << " 🛡️ ఆడిట్ రౌండ్ #" << auditPasses << ": పోర్ట్ఫోలియో మార్జిన్ లిమిట్స్ 100% సేఫ్ గా ఉన్నాయి.\n";
} while (auditPasses < 1);
std::cout << "========================================================================================\n";
return 0;
}
❓ ఇంటర్వ్యూ & పరీక్షల క్విజ్ (Knowledge Check)
ప్రశ్న 1: Modern C++ లో Range-based for వాడేటప్పుడు 'const auto&' ఎందుకు ఇండస్ట్రీ రికమండెడ్ స్టాండర్డ్?
for (auto x : vec) వాడితే కలెక్షన్లోని ప్రతి ఎలిమెంట్ కొత్త మెమరీ లొకేషన్లోకి కాపీ అవుతుంది (Deep Copy). ఇది పెద్ద ఆబ్జెక్ట్లు లేదా స్ట్రింగ్స్కు తీవ్రమైన రన్టైమ్ ఓవర్హెడ్ను కలిగిస్తుంది. const auto& వాడటం వల్ల ఎటువంటి కాపీ జరగదు (Zero Copy Overhead) మరియు డేటా రీడ్-ఓన్లీగా మారడం వల్ల పొరపాటున ఎలిమెంట్లు మోడిఫై కాకుండా టైప్-సేఫ్ గా ఉంటుంది.
ప్రశ్న 2: while లూప్ మరియు do-while లూప్ మధ్య గల ప్రధాన ఆర్కిటెక్చరల్ తేడా ఏమిటి?
while లూప్ అనేది ఎంట్రీ-కంట్రోల్డ్ (Entry-controlled). ఇది ప్రారంభంలోనే నిబంధనను పరిశీలిస్తుంది; మొదటిసారే కండిషన్ false అయితే లోపలి కోడ్ ఒక్కసారి కూడా రన్ అవ్వదు (కనీస ఎగ్జిక్యూషన్లు: 0). కానీ do-while అనేది ఎగ్జిట్-కంట్రోల్డ్ (Exit-controlled). ఇది బాడీని రన్ చేసిన తర్వాత మాత్రమే చివరిలో కండిషన్ చెక్ చేస్తుంది, కాబట్టి కండిషన్ false అయినా సరే కనీసం ఒక్కసారైనా (At least once) కోడ్ తప్పనిసరిగా రన్ అవుతుంది.
ప్రశ్న 3: లూప్లలో పోస్ట్-ఇంక్రిమెంట్ (i++) కంటే ప్రీ-ఇంక్రిమెంట్ (++i) ఎందుకు ప్రాధాన్యత ఇవ్వబడుతుంది?
i++ పాత విలువను గుర్తుంచుకోవడానికి ఒక తాత్కాలిక కాపీ ఆబ్జెక్ట్ను (Temporary Copy) సృష్టించి రిటర్న్ చేస్తుంది. కానీ ++i ఎటువంటి తాత్కాలిక కాపీని సృష్టించకుండా నేరుగా విలువను పెంచి రిఫరెన్స్ను అందిస్తుంది. సంక్లిష్టమైన STL ఇటరేటర్లపై లూప్ నడిపేటప్పుడు ++i అనవసరపు కాపీ కన్స్ట్రక్టర్లను నివారించి అత్యధిక వేగాన్ని అందిస్తుంది.
ప్రశ్న 4: Off-by-one Error (OBOE) అంటే ఏమిటి? ఇది మెమరీ లోపాలకి ఎలా దారితీస్తుంది?
size 10 గల అర్రేపై i <= 10 అని లూప్ రాయడం). 0 నుండి 9 వరకు మాత్రమే చెల్లుబాటు అయ్యే ఇండెక్స్ స్థానంలో i = 10 అయినప్పుడు లూప్ అర్రే పరిధి దాటి ఇతర మెమరీని చదవడానికి లేదా రాయడానికి ప్రయత్నిస్తుంది (Buffer Overflow), ఇది సిస్టమ్ క్రాష్లు మరియు సెగ్మెంటేషన్ ఫాల్ట్లకు దారితీస్తుంది.
ప్రశ్న 5: Loop Unrolling అంటే ఏమిటి? కంపైలర్ దీని ద్వారా పెర్ఫార్మెన్స్ను ఎలా పెంచుతుంది?
ఈ ప్రాజెక్ట్ను లైవ్గా మన కంపైలర్లో రన్ చేయండి!
ఎటువంటి లోకల్ సెటప్ లేకుండా, బ్రౌజర్లోనే నేరుగా Modern C++ (GCC 13 / C++20) కంపైలర్లో ఈ కోడ్ను ఎగ్జిక్యూట్ చేసి రన్టైమ్ అవుట్పుట్ను తనిఖీ చేయండి.