అర్రేలు (Arrays) & std::string

🌐 Modern C++ (C++20/C++17) 🟢 Chapter 10 of 20 📂 Phase 03: ఫంక్షన్స్, మెమరీ & పాయింటర్లు 📅 2026 Edition
📌 Covered in this chapter: C-style Arrays vs std::array · 2D Arrays · std::string మెథడ్స్ · std::string_view (C++17 జీరో-కాపీ స్ట్రింగ్స్)

నిజ జీవిత సాఫ్ట్‌వేర్ అప్లికేషన్లలో మనం ఒకే ఒక్క విలువతో పనిచేయలేం. ఒక కళాశాలలో 500 మంది విద్యార్థుల మార్కులు, ఈ-కామర్స్ పోర్టల్‌లో లక్షల ఉత్పత్తుల ధరలు, లేదా ట్రేడింగ్ ఎక్స్ఛేంజ్‌లో సెకనుకు వచ్చే వేలాది షేర్ల ధరల స్ట్రీమ్ వంటి సమూహాలను సమర్థవంతంగా భద్రపరచాలి. ఇటువంటి ఒకే రకమైన డేటా మూలకాల సమాహారాలనే మనం అర్రేలు (Arrays) అంటాం.

అలాగే కంప్యూటర్లు కేవలం సంఖ్యలతోనే కాకుండా, మానవులతో సంభాషించడానికి పేర్లు, చిరునామాలు, డాక్యుమెంట్లు మరియు నెట్‌వర్క్ సందేశాల వంటి టెక్స్ట్ డేటాను నిర్వహించాలి. దీని కోసమే C++ మనకు సాంప్రదాయ C-Style స్ట్రింగ్స్ నుండి ఆధునిక std::string మరియు సరికొత్త విప్లవాత్మక std::string_view (Zero-Copy Strings) వరకు అత్యున్నత సాధనాలను అందించింది.

ఈ సమగ్ర మాస్టర్‌క్లాస్‌లో మనం అర్రేల అంతర్గత కంటిగ్యువస్ మెమరీ లేఅవుట్, std::array vs C-Arrays, మల్టీ-డైమెన్షనల్ 2D అర్రేల Row-Major మెమరీ ప్రాసెసింగ్, std::string యొక్క Small String Optimization (SSO), మరియు అధునాతన std::string_view పనితీరును లోతుగా అధ్యయనం చేస్తాం. చివరిగా పూర్తి స్థాయి "Enterprise High-Performance Stock Ticker Tape & Text Analytics Engine" ప్రాజెక్ట్‌ను రన్ చేసి నైపుణ్యం సాధిద్దాం!

1 అర్రేల ఆవశ్యకత & మెమరీ లేఅవుట్ (Contiguous Memory Allocation)

ఒకే డేటా టైప్‌కు చెందిన బహుళ విలువలను మెమరీలో వరుసగా ఒకదాని పక్కన ఒకటి (Contiguous Memory Locations) నిల్వ చేసే డేటా స్ట్రక్చర్‌ను అర్రే (Array) అంటారు.

కంప్యూటర్ ఆర్కిటెక్చర్‌లో అర్రేలు ఎందుకు అత్యంత వేగవంతమైనవి? ఎందుకంటే మెమరీలో మూలకాలు వరుసగా ఉండటం వల్ల CPU కి క్రింది రెండు అద్భుతమైన ప్రయోజనాలు లభిస్తాయి:

🧠 CPU Hardware & Memory Addressing Formula (O(1) Direct Access)

అర్రేలోని ఏ ఇండెక్స్ i నైనా యాక్సెస్ చేయడానికి CPU ఎటువంటి లూప్‌లు లేదా సెర్చ్‌లు చేయాల్సిన అవసరం లేదు. అది క్రింది గణిత సూత్రం ద్వారా మెమరీ అడ్రస్‌ను ఒక్క క్లాక్ సైకిల్‌లో గణిస్తుంది:

Address(arr[i]) = Base_Address + (i * sizeof(DataType))

ఉదాహరణకు బేస్ అడ్రస్ 0x1000 వద్ద int అర్రే (4 బైట్లు) ఉంటే: arr[3] యొక్క చిరునామా 0x1000 + (3 * 4) = 0x100C అవుతుంది. దీనివల్ల టైమ్ కాంప్లెక్సిటీ ఎల్లప్పుడూ O(1) కాన్స్టాంట్ టైమ్! అంతేకాకుండా CPU L1 Cache వరుస ఎలిమెంట్లను ముందే క్యాష్ మెమరీలోకి తెచ్చుకోవడం వల్ల Cache Hit Rate 99% కి చేరుకుంటుంది.

2 C-Style Fixed Arrays & Array Decay to Pointer ట్రాప్

C భాష నుండి C++ కి సంక్రమించిన సాంప్రదాయ అర్రేలను C-Style Arrays లేదా Raw Arrays అంటారు: int scores[5] = {90, 85, 78, 92, 88};.

⚠️ The Classic "Array Decay to Pointer" Trap

ఒక C-style అర్రేను ఫంక్షన్‌కు పారామీటర్‌గా పంపినప్పుడు (ఉదా: void process(int arr[])), అది తన సైజ్ సమాచారాన్ని పూర్తిగా కోల్పోయి, కేవలం మొదటి ఎలిమెంట్ యొక్క పాయింటర్‌గా (int*) మారిపోతుంది! దీనినే Array Decay అంటారు.
ఫలితంగా ఫంక్షన్ లోపల sizeof(arr) అని రాస్తే అది అర్రే సైజును ఇవ్వదు; కేవలం పాయింటర్ సైజును (64-bit సిస్టమ్‌లో 8 బైట్లు) మాత్రమే ఇస్తుంది! అందుకే C-style అర్రేలతో పాటు అర్రే సైజును కూడా వేరే పారామీటర్‌గా విధిగా పంపాల్సి వచ్చేది.

💻 Example 1: C-Style Array Declaration & Pointer Decay Demonstration
C++17
#include <iostream>

// ఫంక్షన్‌కు పాస్ అయినప్పుడు అర్రే పాయింటర్‌గా మారిపోతుంది (Array Decay)
void inspectCArray(int arr[], int size) {
    std::cout << "ఫంక్షన్ లోపల sizeof(arr): " << sizeof(arr) << " బైట్లు (కేవలం పాయింటర్ సైజ్!)\n";
    std::cout << "ఎలిమెంట్లు: ";
    for (int i = 0; i < size; ++i) {
        std::cout << arr[i] << " ";
    }
    std::cout << '\n';
}

int main() {
    int marks[5] = {95, 88, 76, 89, 92};

    std::cout << "main() లో sizeof(marks): " << sizeof(marks) << " బైట్లు (5 * 4 = 20 బైట్లు)\n";
    inspectCArray(marks, 5);

    return 0;
}

3 Modern C++11 std::array (Type-Safe Zero-Overhead Wrapper)

C-Style అర్రేల యొక్క పాయింటర్ డికే సమస్యను మరియు బఫర్ ఓవర్‌ఫ్లో ప్రమాదాలను శాశ్వతంగా తొలగించడానికి Modern C++11 లో std::array ప్రవేశపెట్టబడింది (హెడర్: #include <array>).

💎 std::array యొక్క విశిష్టతలు (Why std::array is Superior)

  • Zero Runtime Overhead: C-Style అర్రేతో పోలిస్తే ఒక్క బైట్ మెమరీ కూడా ఎక్కువ తీసుకోదు, ఒక్క క్లాక్ సైకిల్ కూడా ఆలస్యం చేయదు.
  • No Array Decay: ఫంక్షన్‌కు పాస్ చేసినప్పుడు పాయింటర్‌గా మారిపోదు. తన సైజును (.size()) గుర్తుంచుకుంటుంది.
  • Bounds Checking (.at()): arr[10] రాస్తే సెగ్మెంటేషన్ ఫాల్ట్ వస్తుంది; కానీ arr.at(10) రాస్తే అది std::out_of_range ఎక్సెప్షన్‌ను త్రో చేసి ప్రోగ్రామ్ సురక్షితంగా బయటపడుతుంది.
  • STL Algorithm Compatibility: std::sort, Range-based for లూప్స్ లతో అద్భుతంగా అనుసంధానమవుతుంది.
💻 Example 2: Modern C++11 std::array Operations
Modern C++ std::array
#include <iostream>
#include <array>
#include <algorithm>

// Pass by const reference: జీరో కాపీ రక్షణ
void printArray(const std::array<double, 4>& data) {
    std::cout << "అర్రే పరిమాణం (.size()): " << data.size() << "\nఎలిమెంట్లు: ";
    for (const auto& val : data) {
        std::cout << val << " ";
    }
    std::cout << "\nమొదటి ఎలిమెంట్: " << data.front() << " | చివరి ఎలిమెంట్: " << data.back() << '\n';
}

int main() {
    // టైప్ మరియు సైజ్ కంపైల్-టైమ్‌లోనే స్థిరీకరించబడతాయి
    std::array<double, 4> sensorReadings = {42.5, 18.2, 95.8, 63.1};

    printArray(sensorReadings);

    // STL సార్టింగ్
    std::sort(sensorReadings.begin(), sensorReadings.end());
    std::cout << "\nసార్ట్ చేసిన తర్వాత:\n";
    printArray(sensorReadings);

    // .at() తో సేఫ్ బౌండ్స్ చెకింగ్
    try {
        std::cout << "ఇండెక్స్ [2] విలువ: " << sensorReadings.at(2) << '\n';
        // std::cout << sensorReadings.at(10); // ఎక్సెప్షన్ త్రో చేస్తుంది!
    } catch (const std::out_of_range& e) {
        std::cout << "❌ బౌండరీ దాటిన ఎర్రర్: " << e.what() << '\n';
    }

    return 0;
}

4 మల్టీ-డైమెన్షనల్ 2D అర్రేలు & Row-Major మెమరీ ఆర్కిటెక్చర్

గణిత మ్యాట్రిక్స్‌లు, గ్రాఫిక్స్ ఇమేజ్ పిక్సెల్స్, లేదా స్ప్రెడ్‌షీట్‌ల వంటి అడ్డు వరుసలు (Rows) మరియు నిలువు వరుసలు (Columns) ఉన్న డేటాను నిర్వహించడానికి 2D అర్రేలు ఉపయోగిస్తాం.

⚡ Row-Major Order: హార్డ్‌వేర్ లెవల్ మెమరీ రహస్యం

కంప్యూటర్ RAM మెమరీ అనేది కేవలం ఒకే సరళరేఖ లాంటి 1D స్థలం మాత్రమే. C++ కంపైలర్ 2D అర్రేను స్టోర్ చేసేటప్పుడు Row-Major Order ను అనుసరిస్తుంది — అంటే మొదటి రో మొత్తాన్ని వరుసగా పెట్టి, దాని వెంటనే రెండవ రోని, దాని వెంటనే మూడవ రోని భద్రపరుస్తుంది.

పెర్ఫార్మెన్స్ గోల్డెన్ రూల్: 2D అర్రేలపై లూప్ రాసేటప్పుడు ఎల్లప్పుడూ ఔటర్ లూప్‌లో Row, ఇన్నర్ లూప్‌లో Column ఉండేలా రాయాలి: arr[r][c]. రివర్స్‌లో arr[c][r] రాస్తే CPU Cache Misses పెరిగి ప్రోగ్రామ్ 10 రెట్లు నెమ్మదిగా నడుస్తుంది!

5 C-Style Strings & The Null-Terminator ('\0')

C భాషలో స్ట్రింగ్స్ కోసం ప్రత్యేకమైన డేటా టైప్ ఉండేది కాదు. క్యారెక్టర్ల అర్రేను (char name[] = "India";) స్ట్రింగ్‌గా భావించేవారు.

ఆ స్ట్రింగ్ ఎక్కడ ముగిసిందో బ్రౌజర్ లేదా కంపైలర్‌కు తెలియజేయడానికి ఆఖరున ఒక ప్రత్యేకమైన అదృశ్య గుర్తు ఉంటుంది: Null-Terminator ('\0'). అంటే "India" లో 5 అక్షరాలు ఉన్నప్పటికీ, మెమరీలో అది 6 బైట్లు తీసుకుంటుంది: ['I', 'n', 'd', 'i', 'a', '\0']!

ఒకవేళ పొరపాటున '\0' లేకపోతే, ఫంక్షన్లు మెమరీలో ఎక్కడో ఒక సున్నా దొరికే వరకు గార్బేజ్ డేటాను చదువుతూ వెళ్లి భయంకరమైన Buffer Overflow మరియు Security Vulnerabilities కు కారణమవుతాయి.

6 Modern C++ std::string & Small String Optimization (SSO)

C-Style స్ట్రింగ్స్ యొక్క మెమరీ లీక్‌లు మరియు బఫర్ ఓవర్‌ఫ్లో ప్రమాదాలను అరికట్టడానికి C++ స్టాండర్డ్ లైబ్రరీ అందించిన అద్భుతమైన డైనమిక్ క్లాస్ std::string (హెడర్: #include <string>).

🚀 The SSO (Small String Optimization) Superpower

సాధారణంగా std::string డైనమిక్ హీప్ మెమరీ (Heap) ను వాడుతుంది. కానీ హీప్ అలొకేషన్ ఖరీదైనది. దీనిని నివారించడానికి ఆధునిక C++ కంపైలర్లు (GCC, Clang, MSVC) Small String Optimization (SSO) అనే ఇంజనీరింగ్ టెక్నిక్‌ను అమలు చేస్తాయి:

మీ స్ట్రింగ్ పొడవు 15 నుండి 22 అక్షరాల కంటే తక్కువగా ఉన్నప్పుడు (ఉదా: యూజర్ పేర్లు, స్టేటస్ కోడ్‌లు), అది హీప్ మెమరీని ముట్టుకోదు! నేరుగా స్టాక్ మెమరీలోని అంతర్గత బఫర్‌లోనే ఆ అక్షరాలను భద్రపరుస్తుంది. ఫలితంగా సున్నా మెమరీ అలొకేషన్‌తో సూపర్-ఫాస్ట్ స్పీడ్ లభిస్తుంది!

7 std::string ఎసెన్షియల్ మెథడ్స్ & మానిప్యులేషన్

std::string మనకు టెక్స్ట్ ప్రాసెసింగ్ కోసం అత్యంత శక్తివంతమైన అంతర్నిర్మిత ఫంక్షన్లను అందిస్తుంది:

💻 Example 3: Essential std::string Methods
C++17 std::string
#include <iostream>
#include <string>

int main() {
    std::string text = "Welcome to Modern C++ Programming Masterclass";

    std::cout << "అసలు టెక్స్ట్: " << text << "\n";
    std::cout << "పొడవు (.length()): " << text.length() << " అక్షరాలు\n";
    std::cout << "ఖాళీగా ఉందా? (.empty()): " << (text.empty() ? "అవును" : "కాదు") << "\n";

    // సబ్‌స్ట్రింగ్ తీయడం: .substr(start_index, length)
    std::string sub = text.substr(11, 10); // ఇండెక్స్ 11 నుండి 10 అక్షరాలు
    std::cout << "సబ్‌స్ట్రింగ్ (.substr(11, 10)): "" << sub << ""\n";

    // వెతకడం: .find()
    size_t foundPos = text.find("Masterclass");
    if (foundPos != std::string::npos) {
        std::cout << ""Masterclass" పదం ఇండెక్స్ " << foundPos << " వద్ద దొరికింది.\n";
    }

    // జోడించడం (Appending)
    text += " (2026 Edition)";
    std::cout << "నవీకరించబడిన టెక్స్ట్: " << text << '\n';

    return 0;
}

8 Modern C++17 విప్లవం: std::string_view (Zero-Copy Strings)

సాంప్రదాయకంగా ఒక ఫంక్షన్‌కు std::string ను సబ్‌స్ట్రింగ్‌గా పంపినప్పుడు, C++ మెమరీలో కొత్తగా మరో స్ట్రింగ్‌ను సృష్టించి కాపీ చేస్తుంది. భారీ టెక్స్ట్ ఫైల్స్ లేదా నెట్‌వర్క్ ప్యాకెట్లు ప్రాసెస్ చేసేటప్పుడు ఇది వేలాది హీప్ అలొకేషన్స్‌కు కారణమై పెర్ఫార్మెన్స్‌ను నాశనం చేస్తుంది.

ఈ సమస్యకు విప్లవాత్మక పరిష్కారంగా Modern C++17 లో std::string_view ప్రవేశపెట్టబడింది (హెడర్: #include <string_view>)!

🔍 std::string_view అంతర్గత నిర్మాణం (Pointer + Length)

std::string_view మెమరీలో ఎటువంటి డేటాను స్వయంగా కలిగి ఉండదు (Non-owning View)! దీని సైజు కేవలం 16 బైట్లు మాత్రమే. ఇది కేవలం రెండే రెండు విషయాలను కలిగి ఉంటుంది:
1. అసలు టెక్స్ట్ ఎక్కడ మొదలవుతుందో చూపే ఒక పాయింటర్ (const char* ptr).
2. ఎంత భాగం చదవాలో తెలిపే పొడవు (size_t length).

ఫలితంగా ఒక 1GB సైజు గల స్ట్రింగ్ నుండి 100 సార్లు సబ్‌స్ట్రింగ్స్ తీసినా — ఒక్క బైట్ మెమరీ కూడా కాపీ అవ్వదు (Zero-Allocation O(1) Performance)!

💻 Example 4: C++17 Zero-Copy std::string_view Demonstration
Modern C++17 string_view
#include <iostream>
#include <string_view>

// string_view ను పాస్-బై-వాల్యూ గా పంపవచ్చు (ఎందుకంటే దీని సైజ్ కేవలం 16 బైట్లు మాత్రమే!)
void printFastToken(std::string_view sv) {
    std::cout << "టోకెన్: "" << sv << "" (పొడవు: " << sv.length() << ")\n";
}

int main() {
    // 1. C-Style స్ట్రింగ్ లిటరల్ నుండి జీరో-కాపీ వ్యూ
    std::string_view sv1 = "High-Frequency Trading Engine";
    printFastToken(sv1);

    // 2. సబ్‌వ్యూ (Substring) తీసినా ఎటువంటి మెమరీ కాపీ జరగదు!
    std::string_view svPrefix = sv1.substr(0, 14); // "High-Frequency"
    printFastToken(svPrefix);

    return 0;
}

9 std::string_view లోని ప్రమాదాలు: Dangling String View Trap

std::string_view అద్భుతమైన వేగాన్ని ఇచ్చినప్పటికీ, ఒక తీవ్రమైన ప్రమాదం పొంచి ఉంది: Dangling String View!

❌ ప్రమాదకరమైన బగ్: తాత్కాలిక స్ట్రింగ్ నాశనమవడం

std::string_view getView() {
    std::string temp = "హలో ప్రపంచం";
    return temp; // ⚠️ ఘోరమైన తప్పు! ఫంక్షన్ ముగియగానే temp మెమరీ నుండి డిలీట్ అయిపోతుంది!
} // బయట ఆ వ్యూను వాడితే అది శ్మశానాన్ని చూస్తున్నట్టు (Dangling Pointer Segfault)!

గోల్డెన్ రూల్: std::string_view ను ఫంక్షన్ పారామీటర్‌గా వాడటానికి ఎల్లప్పుడూ ప్రాధాన్యత ఇవ్వండి; కానీ ఫంక్షన్ రిటర్న్ టైప్‌గా వాడేటప్పుడు అసలు స్ట్రింగ్ ఆబ్జెక్ట్ మెమరీలో బ్రతికే ఉందని 100% ఖచ్చితంగా నిర్ధారించుకోండి!

10 C-Array vs std::array vs std::vector vs std::string: సమగ్ర పోలిక పట్టిక

C++ లో వివిధ కలెక్షన్ల మధ్య ఉన్న సాంకేతిక వ్యత్యాసాలను అర్థం చేసుకోవడానికి ఈ సమగ్ర పట్టిక ఉపయోగపడుతుంది:

కలెక్షన్ రకం మెమరీ లొకేషన్ పరిమాణం (Size) బౌండ్స్ చెకింగ్ Pointer Decay? ఉత్తమ వినియోగం
C-Style Array స్టాక్ / గ్లోబల్ కంపైల్-టైమ్ ఫిక్స్‌డ్ ❌ లేదు (ప్రమాదకరం) ⚠️ అవును (Decays) పాత లెగసీ C కోడ్ ఇంటర్‌ఫేస్ కొరకు
std::array (C++11) స్టాక్ మెమరీ కంపైల్-టైమ్ ఫిక్స్‌డ్ ✅ ఉంది (.at()) 🛡️ కాదు (సేఫ్) పరిమాణం ముందే తెలిసిన ఫిక్స్‌డ్ కలెక్షన్స్
std::vector డైనమిక్ హీప్ మెమరీ రన్‌టైమ్‌లో పెరుగుతుంది ✅ ఉంది (.at()) 🛡️ కాదు (సేఫ్) సాధారణ డైనమిక్ డేటాబేస్ & జాబితాలు
std::string_view (C++17) నాన్-ఓనింగ్ వ్యూ (16 బైట్లు) లక్ష్య టెక్స్ట్‌పై ఆధారపడుతుంది ✅ ఉంది (.at()) 🛡️ కాదు రీడ్-ఓన్లీ ఫాస్ట్ స్ట్రింగ్ పారామీటర్లు

11 Modern C++20 ఫీచర్: std::span పరిచయం

C++17 లో std::string_view టెక్స్ట్ కోసం జీరో-కాపీ వ్యూను అందించినట్లే, Modern C++20 లో ఏదైనా కంటిగ్యువస్ అర్రేల కోసం (ఉదా: C-Array, std::array, std::vector అన్నింటికీ ఉమ్మడిగా) std::span ప్రవేశపెట్టబడింది (హెడర్: #include <span>).

దీనివల్ల ఒక ఫంక్షన్‌ను void process(std::span<int> data) అని రాస్తే, దానికి C-array అయినా, vector అయినా, std::array అయినా ఏ విధమైన కాపీ లేకుండా సురక్షితంగా పాస్ చేయవచ్చు!

12 సాధారణ బిగినర్ తప్పులు, బగ్స్ & బెస్ట్ ప్రాక్టీసెస్

❌ Trap 1: ఇండెక్స్ పరిధి దాటి వెళ్ళడం (Out of Bounds Access)

5 ఎలిమెంట్లు ఉన్న అర్రేలో arr[5] అని రాయడం (ఇండెక్స్‌లు 0 నుండి 4 మాత్రమే). ఇది కంపైల్-టైమ్‌లో ఎర్రర్ ఇవ్వదు కానీ రన్‌టైమ్‌లో తీవ్రమైన మెమరీ కరప్షన్‌కు దారితీస్తుంది. పరిష్కారం: .at() లేదా Range-based for వాడండి.

✅ Pro Practice: ఫంక్షన్లలో స్ట్రింగ్స్ పాస్ చేసేటప్పుడు std::string_view వాడండి

రీడ్-ఓన్లీ స్ట్రింగ్ పారామీటర్ల కోసం const std::string& కంటే std::string_view మరింత అధునాతనమైనది, ఎందుకంటే ఇది const char* మరియు std::string రెండింటినీ ఎటువంటి టెంపరరీ ఆబ్జెక్ట్ క్రియేషన్ లేకుండా అత్యంత వేగంగా స్వీకరించగలదు.

13 రియల్-వరల్డ్ ప్రాక్టీస్ ప్రాజెక్ట్: "Enterprise High-Performance Stock Ticker Tape & Text Analytics Engine"

ఈ అధ్యాయంలో నేర్చుకున్న std::array, 2D మెమరీ ప్రాసెసింగ్, std::string, మరియు Modern C++17 std::string_view అన్నింటినీ ఉపయోగించి — నేషనల్ స్టాక్ ఎక్స్ఛేంజ్ (NSE) తరహా "Enterprise High-Frequency Stock Ticker Tape & Analytics Engine" ప్రాజెక్ట్‌ను రన్ చేద్దాం:

💻 Complete Masterclass Practice Project: Stock Ticker Tape Engine
C++17 / C++20 Complete Project
#include <iostream>
#include <string>
#include <string_view>
#include <array>
#include <iomanip>

// స్టాక్ టిక్కర్ డేటా నిర్మాణం
struct StockQuote {
    std::string_view symbol; // జీరో-కాపీ టిక్కర్ వ్యూ
    double ltp;              // Last Traded Price
    double changePercent;
    long volume;
};

// ఫాస్ట్ స్ట్రింగ్ వ్యూ అనలైజర్: ఎటువంటి మెమరీ అలొకేషన్ లేకుండా సబ్‌స్ట్రింగ్స్ తనిఖీ
void analyzeTickerToken(std::string_view rawFeed) {
    std::cout << "  📡 [జీరో-కాపీ ప్యాకెట్ విశ్లేషణ]: "";
    if (rawFeed.find("NSE") != std::string_view::npos) {
        std::cout << rawFeed.substr(0, 15) << "... [NSE ఆథరైజ్డ్ ఫీడ్]\n";
    } else {
        std::cout << rawFeed << " [ఇతర మార్కెట్ ఫీడ్]\n";
    }
}

int main() {
    std::cout << std::fixed << std::setprecision(2);
    std::cout << "========================================================================================\n";
    std::cout << "       📈 NATIONAL STOCK EXCHANGE (NSE) - HIGH-FREQUENCY TICKER TAPE ENGINE             \n";
    std::cout << "========================================================================================\n";

    // 1. Modern C++11 std::array (స్టాక్ మెమరీలో 5 ప్రధాన బ్లూచిప్ షేర్ల కోట్స్)
    std::array<StockQuote, 5> liveMarketWatch = {{
        {"RELIANCE", 2950.40, +1.85, 4850200},
        {"TCS",      3980.15, -0.45, 1890450},
        {"HDFCBANK", 1585.60, +0.90, 7200150},
        {"INFY",     1825.00, +2.10, 3450900},
        {"ICICIBANK",1120.30, -0.20, 5100400}
    }};

    std::cout << std::left << std::setw(14) << "టిక్కర్ సింబల్" 
              << std::setw(18) << "మార్కెట్ ధర (LTP)" 
              << std::setw(16) << "మార్పు (%)" 
              << std::setw(16) << "ట్రేడింగ్ వాల్యూమ్" 
              << "స్టేటస్\n";
    std::cout << "----------------------------------------------------------------------------------------\n";

    double totalTurnover = 0.0;

    // Range-based for loop with const reference
    for (const auto& quote : liveMarketWatch) {
        double stockTurnover = quote.ltp * quote.volume;
        totalTurnover += stockTurnover;

        std::cout << std::left << std::setw(14) << quote.symbol
                  << "₹ " << std::setw(16) << quote.ltp;

        if (quote.changePercent >= 0.0) {
            std::cout << "🟢 +" << std::setw(12) << quote.changePercent;
        } else {
            std::cout << "🔴 "   << std::setw(13) << quote.changePercent;
        }

        std::cout << std::setw(16) << quote.volume;

        if (quote.changePercent >= 1.5) {
            std::cout << "🚀 బుల్లిష్ ర్యాలీ (Strong Bullish)\n";
        } else if (quote.changePercent <= -0.5) {
            std::cout << "📉 బేరిష్ క్షీణత (Bearish)\n";
        } else {
            std::cout << "⚪ సాధారణ స్థిరత్వం (Neutral)\n";
        }
    }

    std::cout << "========================================================================================\n";
    std::cout << "మొత్తం ట్రేడింగ్ టర్నోవర్: ₹ " << (totalTurnover / 10000000.0) << " కోట్లు\n";
    std::cout << "----------------------------------------------------------------------------------------\n";

    // 2. std::string_view జీరో-కాపీ నెట్‌వర్క్ ఫీడ్ ప్రాసెసింగ్ డెమో
    std::cout << "\n[Modern C++17 std::string_view నెట్‌వర్క్ స్ట్రీమ్ ప్రాసెసింగ్]:\n";
    std::string rawBroadcast = "NSE_TICKER_STREAM:TCS:3980.15:INFY:1825.00:TIMESTAMP_1730458920";

    analyzeTickerToken(rawBroadcast);
    analyzeTickerToken("BSE_SPOT_FEED:GOLD_MCX:78500.00");

    std::cout << "========================================================================================\n";
    return 0;
}

❓ ఇంటర్వ్యూ & పరీక్షల క్విజ్ (Knowledge Check)

ప్రశ్న 1: C-Style Array మరియు Modern C++11 std::array మధ్య గల ప్రధాన సాంకేతిక తేడాలు ఏమిటి?
సమాధానం: C-Style అర్రేను ఫంక్షన్‌కు పాస్ చేసినప్పుడు అది తన సైజును కోల్పోయి పాయింటర్‌గా మారిపోతుంది (Array Decay). అంతేకాకుండా ఇందులో బౌండ్స్ చెకింగ్ ఉండదు. కానీ std::array ఎటువంటి మెమరీ లేదా రన్‌టైమ్ ఓవర్‌హెడ్ లేకుండా (Zero Overhead) తన సైజును (.size()) గుర్తుంచుకుంటుంది, పాయింటర్‌గా డికే అవ్వదు, మరియు .at() ద్వారా సురక్షితమైన బౌండ్స్ చెకింగ్‌ను అందిస్తుంది.
ప్రశ్న 2: Modern C++ లో std::string యొక్క Small String Optimization (SSO) ఎలా పనిచేస్తుంది?
సమాధానం: సాధారణంగా స్ట్రింగ్స్ డైనమిక్ హీప్ మెమరీని వాడతాయి, ఇది ఖరీదైన ఆపరేషన్. చిన్న స్ట్రింగ్స్ (సాధారణంగా 15 నుండి 22 అక్షరాల వరకు) ఉన్నప్పుడు కంపైలర్ హీప్ అలొకేషన్ చేయకుండా నేరుగా స్టాక్ మెమరీలోని ఆబ్జెక్ట్ బఫర్‌లోనే టెక్స్ట్‌ను స్టోర్ చేస్తుంది. దీనినే SSO అంటారు. ఇది రన్‌టైమ్ మెమరీ అలొకేషన్‌ను నివారించి రాకెట్ వేగాన్ని అందిస్తుంది.
ప్రశ్న 3: Modern C++17 std::string_view ను ఎందుకు వాడాలి? దాని సైజు ఎంత ఉంటుంది?
సమాధానం: std::string_view అనేది ఒక నాన్-ఓనింగ్ వ్యూ (Non-owning View). ఇది మెమరీలో డేటాను కాపీ చేయకుండా కేవలం అసలు టెక్స్ట్ పాయింటర్ మరియు పొడవును (కేవలం 16 బైట్లు: const char* ptr + size_t len) మాత్రమే కలిగి ఉంటుంది. సబ్‌స్ట్రింగ్స్ తీసేటప్పుడు లేదా రీడ్-ఓన్లీ ఫంక్షన్ పారామీటర్లుగా వాడేటప్పుడు ఇది సున్నా కాపీతో (Zero-Copy) O(1) వేగాన్ని అందిస్తుంది.
ప్రశ్న 4: 2D అర్రేలలో Row-Major Order అంటే ఏమిటి? కాలమ్-వైజ్ లూప్ ఎందుకు నెమ్మదిగా నడుస్తుంది?
సమాధానం: C++ మెమరీలో 2D అర్రేను భద్రపరిచేటప్పుడు మొదటి రో పూర్తయిన తర్వాత రెండవ రోని నిల్వ చేస్తుంది (Row-Major). Row-వైజ్ లూప్ నడిపినప్పుడు డేటా కంటిగ్యువస్ గా ఉండటం వల్ల CPU L1 Cache వరుస ఎలిమెంట్లను ముందుగానే లోడ్ చేసుకుంటుంది (Cache Hit). కానీ Column-వైజ్ లూప్ నడిపితే ప్రతిసారీ మెమరీలో దూరం దూరం దూకాల్సి రావడం వల్ల Cache Misses పెరిగి ప్రోగ్రామ్ గణనీయంగా నెమ్మదిస్తుంది.
ప్రశ్న 5: Dangling string_view సమస్య అంటే ఏమిటి? దానిని ఎలా నివారించాలి?
సమాధానం: string_view డేటాను స్వయంగా కలిగి ఉండదు. ఒక తాత్కాలిక std::string లేదా లోకల్ వేరియబుల్ నాశనమైపోయిన తర్వాత కూడా (Destroyed), ఆ మెమరీని string_view చూపిస్తూ ఉంటే దానిని Dangling string_view అంటారు. దానిని యాక్సెస్ చేస్తే క్రాష్ లేదా గార్బేజ్ వస్తుంది. తాత్కాలిక ఆబ్జెక్టుల నుండి string_view రిటర్న్ చేయకపోవడం ద్వారా దీనిని నివారించవచ్చు.
← మునుపటి అధ్యాయం: Chapter 09: ఫంక్షన్స్ & Function Overloading
తదుపరి అధ్యాయం: Chapter 11: పాయింటర్లు & రిఫరెన్సెస్ →

ఈ ప్రాజెక్ట్‌ను లైవ్‌గా మన కంపైలర్‌లో రన్ చేయండి!

ఎటువంటి లోకల్ సెటప్ లేకుండా, బ్రౌజర్‌లోనే నేరుగా Modern C++ (GCC 13 / C++20) కంపైలర్‌లో ఈ కోడ్‌ను ఎగ్జిక్యూట్ చేసి రన్‌టైమ్ అవుట్‌పుట్‌ను తనిఖీ చేయండి.