C స్ట్రక్చర్స్ (struct), యూనియన్స్ (union) & Structure Padding

⚡ Modern C (C99 / C11 / C17 Standards) 🟢 Chapter 17 of 20 📂 Phase 05: స్ట్రక్చర్స్, డైనమిక్ మెమరీ & ప్రాజెక్ట్ 📅 2026 Academic Edition
📌 Covered in this chapter: హెటిరోజీనియస్ డేటా గ్రూపింగ్ · డాట్ (.) vs యారో (->) ఆపరేటర్లు · Structure Padding & Byte Alignment · #pragma pack(1) · union షేర్డ్ మెమరీ · struct vs union పట్టిక · typedef మారుపేర్లు · నెస్టెడ్ స్ట్రక్చర్స్ · బిట్-ఫీల్డ్స్ · హాస్పిటల్ పేషెంట్ ప్రాజెక్ట్ · ఇంటరాక్టివ్ క్విజ్

ఒక పెద్ద సూపర్-స్పెషాలిటీ ఆసుపత్రిలోని పేషెంట్ మెడికల్ కార్డును లేదా మీ కాలేజీ ఐడీ కార్డును ఊహించుకోండి. ఆ కార్డుపై మీ పేరు (Text: char name[50]), మీ రోల్ నంబర్ (Integer: int id), మీ రక్త వర్గం (char bloodGroup[5]), మరియు మీ హాజరు శాతం (Floating point: float attendance) ఉంటాయి. గత అధ్యాయాలలో మనం నేర్చుకున్న అర్రేలలో కేవలం ఒకే రకమైన డేటాను (Homogeneous) మాత్రమే భద్రపరచగలం. మరి ఒకే వ్యక్తికి సంబంధించిన ఈ విభిన్న డేటా టైప్స్ అన్నింటినీ కలిపి ఒకే కవరులో ఎలా భద్రపరచాలి?

కంప్యూటర్ సైన్స్‌లో ఈ సమస్యను పరిష్కరించే అత్యంత శక్తివంతమైన సాధనమే స్ట్రక్చర్స్ (Structures - struct)! విభిన్న డేటా టైప్స్‌ను ఏకం చేసి ప్రోగ్రామర్ తన స్వంత కస్టమ్ డేటా టైప్‌ను నిర్మించుకునే స్వేచ్ఛను C అందిస్తుంది. మరి యూనియన్ (Union) అంటే ఏమిటి? ఒకే హోటల్ గదిలోని మంచాన్ని (Shared Bed) ఉదయం ఒక అతిథి, సాయంత్రం మరొక అతిథి మాత్రమే పంచుకోగలిగినట్లు — ఒకే మెమరీ బ్లాక్‌ను వేర్వేరు వేరియబుల్స్ పంచుకోవడమే యూనియన్!

ఈ పదిహేడవ అధ్యాయంతో మనం Phase 05 (స్ట్రక్చర్స్, డైనమిక్ మెమరీ & ప్రాజెక్ట్) లోకి అడుగుపెడుతున్నాం. ఇందులో మెంబర్ యాక్సెస్ ఆపరేటర్లు (. vs ->), కంపైలర్ చేసే రహస్య Structure Padding & Alignment, బిట్-ఫీల్డ్స్ మరియు పూర్తి స్థాయి హాస్పిటల్ పేషెంట్ మేనేజ్‌మెంట్ & బిల్లింగ్ ఇంజిన్‌ను సమగ్రంగా నిర్మిద్దాం!

1ఈ Chapter లో మీరు నేర్చుకునే సమగ్ర అంశాలు (Roadmap)

రియల్-వరల్డ్ సాఫ్ట్‌వేర్ ఇంజనీరింగ్‌లో ఎంటిటీలను (ఉదా: కార్లు, బ్యాంక్ ఖాతాలు, ఉద్యోగులు) మోడలింగ్ చేయడానికి స్ట్రక్చర్స్ అనేవి ప్రాథమిక పునాది. ఈ అధ్యాయంలో కవర్ చేయబడే ప్రధానాంశాలు:

  • స్ట్రక్చర్స్ ఆవశ్యకత: హోమోజీనియస్ అర్రేల పరిమితులు మరియు యూజర్-డిఫైన్డ్ హెటిరోజీనియస్ రికార్డులు.
  • struct సింటాక్స్ & డిక్లరేషన్: మెంబర్ వేరియబుల్స్, ట్యాగ్ నేమ్స్ మరియు డిజైగ్నేటెడ్ ఇనిషియలైజర్స్ (C99).
  • డాట్ ఆపరేటర్ (.): సాధారణ స్ట్రక్చర్ వేరియబుల్ మెంబర్లను చదవడం మరియు మార్చడం.
  • స్ట్రక్చర్ పాయింటర్లు & యారో ఆపరేటర్ (->): (*ptr).member వర్సెస్ ptr->member మధ్య తేడా.
  • హార్డ్‌వేర్ లెవల్ Structure Padding & Alignment: CPU వర్డ్ సైజు (4/8 bytes) కోసం కంపైలర్ ఖాళీ బైట్లను ఎందుకు చేరుస్తుంది?
  • పాడింగ్ నియంత్రణ: #pragma pack(1) మరియు నెట్‌వర్క్ ప్యాకెట్లలో మెమరీ ఆదా చేసే విధానం.
  • యూనియన్స్ (Unions) షేర్డ్ మెమరీ: ఒకే మెమరీని వేర్వేరు టైప్స్ షేర్ చేసుకోవడం & అతిపెద్ద మెంబర్ సైజు రూల్.
  • సమగ్ర తులనాత్మక పట్టిక: struct vs union పక్కపక్కనే లోతైన విశ్లేషణ.
  • typedef కీవర్డ్: సంక్లిష్టమైన పేర్లకు అందమైన మారుపేర్లు (Type Aliases) ఇవ్వడం.
  • నెస్టెడ్ స్ట్రక్చర్స్: ఒక స్ట్రక్చర్ లోపల మరొక స్ట్రక్చర్ (ఉదా: ఎంప్లాయ్ లోపల అడ్రస్ లేదా పుట్టిన తేదీ).
  • బిట్-ఫీల్డ్స్ (Bit-Fields): ఎంబెడెడ్ డివైసెస్‌లో మెమరీని బిట్ల స్థాయిలో పొదుపు చేసే కళ.
  • సమగ్ర రియల్ వరల్డ్ ప్రాజెక్ట్: హాస్పిటల్ పేషెంట్ అడ్మిషన్, మెడికల్ రికార్డ్ & డిశ్చార్జ్ బిల్లింగ్ ఇంజిన్.
  • స్వీయ మూల్యాంకన క్విజ్: 5 లోతైన ప్రాక్టికల్ ప్రశ్నలు & గేట్ ఎగ్జామ్ కాన్సెప్ట్స్.
2స్ట్రక్చర్స్ ఎందుకు అవసరం? అర్రేల పరిమితులు & హెటిరోజీనియస్ మోడలింగ్

గత అధ్యాయాలలో మనం నేర్చుకున్న అర్రేలలో కేవలం ఒకే రకమైన డేటాను (Homogeneous) మాత్రమే ఉంచగలం. ఒక విద్యార్థి వివరాల కోసం int roll[], char name[][50], float fee[] అని వేర్వేరు అర్రేలు నిర్వహిస్తే, డేటా సింక్రొనైజేషన్ తప్పిపోయే ప్రమాదం ఉంది.

స్ట్రక్చర్ (struct) నిర్వచనం:

స్ట్రక్చర్ అనేది విభిన్న డేటా టైప్స్ (int, float, char, pointers...) కలిగిన వేరియబుల్స్‌ను ఒకే యూనిట్‌గా అనుసంధానించే యూజర్-డిఫైన్డ్ కాంపౌండ్ డేటా టైప్ (User-Defined Compound Type). దీని ద్వారా వాస్తవ ప్రపంచంలోని ఏ సంక్లిష్ట వస్తువునైనా కంప్యూటర్‌లో మోడల్ చేయవచ్చు!

3struct సింటాక్స్, డిక్లరేషన్ & డాట్ ఆపరేటర్ (.)

C లో స్ట్రక్చర్‌ను డిఫైన్ చేయడానికి మరియు వేరియబుల్స్ సృష్టించడానికి ప్రామాణిక సింటాక్స్ ఇది:

struct స్ట్రక్చర్_పేరు {
    డేటా_టైప్1 మెంబర్1;
    డేటా_టైప్2 మెంబర్2;
}; // <-- ఇక్కడ సెమికోలన్ (;) తప్పనిసరి!
C — Struct Declaration & Dot Operator Usage
#include <stdio.h>
#include <string.h>

// స్ట్రక్చర్ టెంప్లేట్ డిఫైన్ చేస్తున్నాం
struct Student {
    int rollNo;
    char name[30];
    float gpa;
};

int main() {
    // 1. డైరెక్ట్ ఇనిషియలైజేషన్
    struct Student s1 = {101, "కార్తీక్ వర్మ", 8.95f};

    // 2. డాట్ ఆపరేటర్ (.) ద్వారా మెంబర్లను చదవడం
    printf("=== విద్యార్థి ప్రొఫైల్ (డాట్ ఆపరేటర్ డెమో) ===\n");
    printf("రోల్ నంబర్: %d\n", s1.rollNo);
    printf("పేరు      : %s\n", s1.name);
    printf("GPA       : %.2f\n", s1.gpa);

    // డాట్ ఆపరేటర్ ద్వారా మెంబర్ విలువను సవరించడం
    s1.gpa = 9.40f;
    printf("అప్‌డేట్ చేసిన GPA: %.2f\n", s1.gpa);

    return 0;
}
4స్ట్రక్చర్ పాయింటర్లు & యారో ఆపరేటర్ (->)

స్ట్రక్చర్లు పరిమాణంలో చాలా పెద్దవిగా ఉంటాయి. వాటిని ఫంక్షన్లకు పాస్ చేసేటప్పుడు మొత్తం కాపీ చేయకుండా పాయింటర్ ద్వారా పాస్ చేయడం సర్వోత్తమ పద్ధతి. ఒక స్ట్రక్చర్ పాయింటర్ ద్వారా మెంబర్లను యాక్సెస్ చేయడానికి యారో ఆపరేటర్ (Arrow Operator: ->) ఉపయోగిస్తారు:

ptr->member     ≡     (*ptr).member
C — Structure Pointer & Arrow Operator Demo
#include <stdio.h>

struct Account {
    int accNumber;
    double balance;
};

// స్ట్రక్చర్ పాయింటర్‌ను పారామీటర్‌గా తీసుకునే ఫంక్షన్
void addInterest(struct Account *acc, double ratePercent) {
    // యారో ఆపరేటర్ (->) ద్వారా బ్యాలెన్స్ ను నేరుగా సవరిస్తున్నాం
    double interest = acc->balance * (ratePercent / 100.0);
    acc->balance += interest;
    printf("  [ఫంక్షన్ లోపల] వడ్డీ రూ. %.2f ఖాతా #%d కి జమ అయింది!\n", interest, acc->accNumber);
}

int main() {
    struct Account myAcc = {55401, 100000.00};

    printf("వడ్డీకి ముందు బ్యాలెన్స్: రూ. %.2f\n", myAcc.balance);
    addInterest(&myAcc, 7.5); // అడ్రస్ పాస్ చేస్తున్నాం (Call by Reference)
    printf("వడ్డీ తర్వాత బ్యాలెన్స్ : రూ. %.2f\n", myAcc.balance);

    return 0;
}
5హార్డ్‌వేర్ ఆర్కిటెక్చర్: Structure Padding & Alignment

ఇంటర్వ్యూలలో ప్రతి ఒక్కరినీ విస్మయపరిచే అత్యంత లోతైన కాన్సెప్ట్: Structure Padding. క్రింది చిన్న స్ట్రక్చర్‌ను పరిశీలించండి:

struct Test {
    char a;   // 1 byte
    int b;    // 4 bytes
    char c;   // 1 byte
};

సాధారణ లెక్క ప్రకారం దీని సైజు $1 + 4 + 1 = 6$ బైట్లు ఉండాలి కదా? కానీ sizeof(struct Test) ప్రింట్ చేస్తే కంపైలర్ 12 బైట్లు! అని చెబుతుంది! మిగిలిన 6 బైట్లు ఎక్కడి నుండి వచ్చాయి?

CPU వర్డ్ అలైన్‌మెంట్ రహస్యం (Word Alignment):

ఆధునిక 32-బిట్ లేదా 64-బిట్ CPU ప్రాసెసర్లు RAM నుండి డేటాను 1 బైట్ చొప్పున చదవవు; అవి 4 బైట్లు లేదా 8 బైట్ల గుణిజాల అడ్రస్‌ల వద్ద (4-byte / 8-byte Word Boundaries) మాత్రమే మెరుపు వేగంతో చదవగలవు. int ఎల్లప్పుడూ 4 యొక్క గుణిజం వద్దే ప్రారంభం కావాలి. అందుకే char a (1 బైట్) పక్కన కంపైలర్ 3 ఖాళీ బైట్లను (Padding Bytes) బలవంతంగా చేరుస్తుంది! అలాగే చివరన మరొక 3 బైట్ల పాడింగ్ జోడించి మొత్తం 12 బైట్లు చేస్తుంది!

C — Structure Padding vs Packed Structure (#pragma pack)
#include <stdio.h>

// సాధారణ స్ట్రక్చర్ (పాడింగ్ తో కూడినది)
struct NormalStruct {
    char a;  // 1 byte + 3 bytes padding
    int b;   // 4 bytes
    char c;  // 1 byte + 3 bytes padding
};

// పాడింగ్ తొలగించిన ప్యాక్డ్ స్ట్రక్చర్ (#pragma pack(1))
#pragma pack(push, 1)
struct PackedStruct {
    char a;  // 1 byte
    int b;   // 4 bytes
    char c;  // 1 byte
};
#pragma pack(pop)

int main() {
    printf("సాధారణ స్ట్రక్చర్ సైజు (With Padding) : %zu బైట్లు (ఆశించిన 6 కంటే ఎక్కువ!)\n", sizeof(struct NormalStruct));
    printf("ప్యాక్డ్ స్ట్రక్చర్ సైజు (#pragma pack(1)): %zu బైట్లు (ఖచ్చితమైన 6 బైట్లు!)\n", sizeof(struct PackedStruct));
    return 0;
}

💡 ఎంబెడెడ్ & నెట్‌వర్కింగ్ టిప్: ఇంటర్నెట్ ద్వారా నెట్‌వర్క్ ప్యాకెట్లు లేదా బ్లూటూత్ డేటా పంపేటప్పుడు మెమరీ వృధా కాకుండా ఉండటానికి #pragma pack(1) వాడతారు!

6యూనియన్స్ (Unions) — షేర్డ్ మెమరీ ఆర్కిటెక్చర్

స్ట్రక్చర్‌లో ప్రతి మెంబర్‌కు విడివిడిగా సొంత మెమరీ కేటాయించబడుతుంది. కానీ యూనియన్ (Union) లో పరిస్థితి పూర్తిగా భిన్నం: అన్ని మెంబర్లు ఒకే ఒక్క ఉమ్మడి మెమరీ లొకేషన్‌ను (Shared Memory) పంచుకుంటాయి!

📏 యూనియన్ సైజు నియమం: యూనియన్ యొక్క మొత్తం మెమరీ సైజు అందులోని అత్యంత పెద్ద మెంబర్ సైజుకు సమానంగా ఉంటుంది! ఒకే సమయంలో కేవలం ఒకే ఒక్క మెంబర్ మాత్రమే సజీవంగా ఉండగలదు. ఒక మెంబర్‌లోకి రాస్తే పాత మెంబర్ విలువ చెరిగిపోతుంది!
C — Union Shared Memory Demonstration
#include <stdio.h>

union DataPacket {
    int intVal;      // 4 bytes
    float floatVal;  // 4 bytes
    char charVal;    // 1 byte
};

int main() {
    union DataPacket packet;
    printf("యూనియన్ మొత్తం మెమరీ సైజు = %zu బైట్లు (Largest member = 4 bytes)\n\n", sizeof(packet));

    // 1. పూర్ణాంకం నిల్వ చేస్తున్నాం
    packet.intVal = 65;
    printf("intVal = %d  | charVal = '%c' (65 కి ASCII 'A')\n", packet.intVal, packet.charVal);

    // 2. ఇప్పుడు ఫ్లోట్ నిల్వ చేస్తే, పాత intVal ఓవర్‌రైట్ అయిపోతుంది!
    packet.floatVal = 99.75f;
    printf("floatVal = %.2f నిల్వ చేసిన తర్వాత:\n", packet.floatVal);
    printf("  floatVal = %.2f\n", packet.floatVal);
    printf("  intVal   = %d (కరప్ట్ అయింది! ఎందుకంటే ఫ్లోట్ ఓవర్‌రైట్ చేసింది)\n", packet.intVal);

    return 0;
}
7సమగ్ర తులనాత్మక పట్టిక (struct vs union)

స్ట్రక్చర్ మరియు యూనియన్ల మధ్య ఉన్న సమగ్ర సాంకేతిక వ్యత్యాసాలు:

ఫీచర్ / అంశం స్ట్రక్చర్ (struct) యూనియన్ (union)
కీవర్డ్ struct union
మెమరీ కేటాయింపు ప్రతి మెంబర్‌కు ప్రత్యేకమైన సొంత మెమరీ గది ఉంటుంది. అన్ని మెంబర్లు ఒకే ఉమ్మడి మెమరీని పంచుకుంటాయి.
మొత్తం పరిమాణం (sizeof) అన్ని మెంబర్ల సైజుల మొత్తం + పాడింగ్ బైట్లు. అత్యంత పెద్ద మెంబర్ సైజుకు మాత్రమే సమానం.
మెంబర్ల యాక్సెస్ అన్ని మెంబర్లను ఒకే సమయంలో స్వేచ్ఛగా వాడవచ్చు. ఒకే సమయంలో కేవలం ఒక్క మెంబర్‌ను మాత్రమే వాడాలి.
విలువ ఓవర్‌రైటింగ్ ఒక మెంబర్‌ను మార్చితే మిగిలిన వాటిపై ప్రభావం ఉండదు. కొత్త మెంబర్‌ను మార్చగానే పాత మెంబర్ విలువ చెరిగిపోతుంది.
ప్రధాన ఉపయోగం సంక్లిష్టమైన వస్తువుల మోడలింగ్ (Student, Employee, Car). మెమరీని ఆదా చేసే ఎంబెడెడ్ హార్డ్‌వేర్ & మల్టీ-ఫార్మాట్ డేటా.
8typedef కీవర్డ్ — టైప్ మారుపేర్ల మ్యాజిక్

ప్రతిసారీ struct Student s1; struct Student s2; అని పొడవాటి struct కీవర్డ్ రాయడం శ్రమతో కూడుకున్నది. C లో ఇప్పటికే ఉన్న డేటా టైప్‌లకు మనకు నచ్చిన చిన్న, అర్థవంతమైన మారుపేర్లను (Type Aliases) ఇవ్వడానికి typedef కీవర్డ్ ఉపయోగిస్తారు:

C — Clean Structs with typedef
#include <stdio.h>

// typedef ద్వారా struct Employee కి 'Employee' అనే మారుపేరు ఇచ్చాం
typedef struct {
    int id;
    char department[20];
    double salary;
} Employee;

int main() {
    // 'struct Employee' అని రాయనక్కర్లేదు! నేరుగా 'Employee' అని వాడవచ్చు!
    Employee emp1 = {4001, "సాఫ్ట్‌వేర్ ఇంజనీరింగ్", 85000.00};

    printf("ఎంప్లాయ్ ID : %d\n", emp1.id);
    printf("డిపార్ట్‌మెంట్: %s\n", emp1.department);
    printf("వేతనం        : రూ. %.2f\n", emp1.salary);

    return 0;
}
9నెస్టెడ్ స్ట్రక్చర్స్ (Structures within Structures)

ఒక స్ట్రక్చర్ లోపల మరొక స్ట్రక్చర్‌ను సభ్యుడిగా చేర్చడాన్ని నెస్టెడ్ స్ట్రక్చర్ (Nested Structure) అంటారు. ఉదాహరణకు ఒక ఉద్యోగి రికార్డులో పుట్టిన తేదీ (DateOfBirth) లేదా నివాస చిరునామా (Address) లు స్వయంగా వేరే స్ట్రక్చర్లుగా ఉంటాయి:

C — Nested Structure Implementation
#include <stdio.h>

struct Date {
    int day;
    int month;
    int year;
};

struct Citizen {
    char name[30];
    long long aadhaarNo;
    struct Date dob; // నెస్టెడ్ స్ట్రక్చర్!
};

int main() {
    struct Citizen c1 = {
        "రామకృష్ణ",
        987654321012LL,
        {15, 8, 1995} // లోపలి స్ట్రక్చర్ ఇనిషియలైజేషన్
    };

    printf("పౌరుడి పేరు: %s\n", c1.name);
    printf("ఆధార్ నంబర్: %lld\n", c1.aadhaarNo);
    // రెండు డాట్లతో యాక్సెస్ చేస్తున్నాం
    printf("పుట్టిన తేదీ: %02d-%02d-%d\n", c1.dob.day, c1.dob.month, c1.dob.year);

    return 0;
}
10బిట్-ఫీల్డ్స్ (Bit-Fields) — మైక్రో మెమరీ ఆప్టిమైజేషన్

ఎంబెడెడ్ సిస్టమ్స్ మరియు నెట్‌వర్క్ డ్రైవర్లలో కొన్ని వేరియబుల్స్‌కు కేవలం 0 లేదా 1 (బూలియన్ ఫ్లాగ్స్) మాత్రమే అవసరం. దానికి 4 బైట్ల (32 బిట్స్) ఇంటిజర్ కేటాయిస్తే 31 బిట్లు వృధా అవుతాయి. C లో బిట్-ఫీల్డ్స్ (Bit-Fields) ద్వారా ఒకే పూర్ణాంకంలో ఖచ్చితంగా ఎన్ని బిట్లు కావాలో నిర్దేశించవచ్చు:

C — Microcontroller Bit-Fields Optimization
#include <stdio.h>

struct DeviceStatus {
    unsigned int isPowerOn : 1; // కేవలం 1 బిట్ (0 లేదా 1)
    unsigned int isWiFiConnected : 1; // 1 బిట్
    unsigned int batteryLevel : 4; // 4 బిట్లు (0 నుండి 15 వరకు)
    unsigned int errorCode : 6; // 6 బిట్లు (0 నుండి 63 వరకు)
};

int main() {
    struct DeviceStatus iotDevice = {1, 1, 12, 0};

    printf("IoT డివైస్ మొత్తం మెమరీ సైజు = %zu బైట్లు (కేవలం ఒకే ఒక్క 4-బైట్ బ్లాక్!)\n", sizeof(iotDevice));
    printf("పవర్ స్టేటస్    : %s\n", iotDevice.isPowerOn ? "ON" : "OFF");
    printf("వైఫై కనెక్టెడ్ : %s\n", iotDevice.isWiFiConnected ? "YES" : "NO");
    printf("బ్యాటరీ స్థాయి : %u / 15\n", iotDevice.batteryLevel);

    return 0;
}
11సమగ్ర రియల్ వరల్డ్ ప్రాజెక్ట్ — హాస్పిటల్ పేషెంట్ మేనేజ్‌మెంట్ ఇంజిన్

ఇప్పటివరకు నేర్చుకున్న struct, typedef, యారో ఆపరేటర్ ->, మరియు నెస్టెడ్ స్ట్రక్చర్స్ ఉపయోగించి ఒక వాస్తవ ఆసుపత్రి పేషెంట్ అడ్మిషన్, రూమ్ కేటాయింపు & డిశ్చార్జ్ బిల్లింగ్ ఇంజిన్ (Healthcare Billing System) ను నిర్మిద్దాం:

C — Comprehensive Hospital Management & Billing System
#include <stdio.h>

// రూమ్ రకాలు
typedef enum { GENERAL = 1, SEMI_PRIVATE = 2, ICU = 3 } RoomType;

// పేషెంట్ అడ్రస్ స్ట్రక్చర్
typedef struct {
    char city[20];
    int pincode;
} Address;

// సమగ్ర పేషెంట్ రికార్డు స్ట్రక్చర్
typedef struct {
    int patientId;
    char name[30];
    int age;
    RoomType room;
    int daysAdmitted;
    double medicineCharges;
    Address location;
} Patient;

// బిల్లును లెక్కించే ఫంక్షన్ (పాయింటర్ పారామీటర్ ద్వారా)
double calculateDischargeBill(const Patient *p) {
    double roomRatePerDay = 0.0;
    switch (p->room) {
        case GENERAL:      roomRatePerDay = 1500.0; break;
        case SEMI_PRIVATE: roomRatePerDay = 3500.0; break;
        case ICU:          roomRatePerDay = 8000.0; break;
    }

    double totalRoomRent = p->daysAdmitted * roomRatePerDay;
    double doctorConsultation = p->daysAdmitted * 1000.0;
    double grandTotal = totalRoomRent + doctorConsultation + p->medicineCharges;

    printf("====================================================\n");
    printf("   మనా కేర్ హాస్పిటల్స్ - డిశ్చార్జ్ సమ్మరీ & బిల్లు\n");
    printf("====================================================\n");
    printf("పేషెంట్ ID     : #MED-%d\n", p->patientId);
    printf("పేషెంట్ పేరు   : %s (వయస్సు: %d)\n", p->name, p->age);
    printf("నగరం / పిన్‌కోడ్: %s - %d\n", p->location.city, p->location.pincode);
    printf("వార్డ్ రకం     : %s (రోజుకు రూ. %.2f)\n",
           p->room == ICU ? "ICU" : (p->room == SEMI_PRIVATE ? "సెమీ-ప్రైవేట్" : "జనరల్"), roomRatePerDay);
    printf("చికిత్స రోజులు : %d రోజులు\n", p->daysAdmitted);
    printf("----------------------------------------------------\n");
    printf("  రూమ్ అద్దె మొత్తం   : రూ. %10.2f\n", totalRoomRent);
    printf("  డాక్టర్ ఫీజు        : రూ. %10.2f\n", doctorConsultation);
    printf("  మందులు & ల్యాబ్ ఫీజు : రూ. %10.2f\n", p->medicineCharges);
    printf("----------------------------------------------------\n");
    printf("👉 చెల్లించాల్సిన మొత్తం: రూ. %10.2f\n", grandTotal);
    printf("====================================================\n\n");

    return grandTotal;
}

int main() {
    Patient p1 = {
        8801,
        "వెంకటేశ్వర రావు",
        58,
        ICU,
        4,
        24500.00,
        {"హైదరాబాద్", 500081}
    };

    calculateDischargeBill(&p1);
    return 0;
}
12సాధారణంగా బిగినర్స్ చేసే టాప్ 5 స్ట్రక్చర్ తప్పులు
1. struct చివర సెమికోలన్ మర్చిపోవడం:
struct Point { int x, y; } అని రాసి సెమికోలన్ ; పెట్టకపోతే కంపైలర్ భయంకరమైన ఎర్రర్లను కురిపిస్తుంది.
2. పాయింటర్‌కు డాట్ ఆపరేటర్ వాడటం (ptr.member):
పాయింటర్ వేరియబుల్ ఉన్నప్పుడు కచ్చితంగా యారో ptr->member లేదా (*ptr).member మాత్రమే వాడాలి.
3. యూనియన్‌లోని అన్ని మెంబర్లను ఒకేసారి చదవాలనుకోవడం:
యూనియన్‌లో చివరిగా ఏ మెంబర్‌ను అసైన్ చేశారో అది మాత్రమే సజీవంగా ఉంటుంది. మిగిలిన మెంబర్లు కరప్ట్ అయిపోతాయి.
4. పెద్ద స్ట్రక్చర్లను Call by Value ద్వారా పాస్ చేయడం:
1000 బైట్లు ఉన్న స్ట్రక్చర్‌ను నేరుగా పాస్ చేస్తే మెమరీ కాపీ అయి ప్రోగ్రామ్ నెమ్మదిస్తుంది. ఎల్లప్పుడూ పాయింటర్‌ను పాస్ చేయాలి.
5. Structure Padding ని మర్చిపోయి బైట్ లెక్కలు వేయడం:
హార్డ్‌వేర్ అలైన్‌మెంట్ కోసం కంపైలర్ పాడింగ్ బైట్లను కలుపుతుంది కాబట్టి sizeof ఎల్లప్పుడూ మెంబర్ల మొత్తం కంటే ఎక్కువగా ఉండవచ్చు.
13స్వీయ మూల్యాంకన క్విజ్ & మీరే స్వయంగా Try చేయండి!

ఈ పాఠంలోని లోతైన అంశాలను క్రింది 5 ప్రాక్టికల్ ప్రశ్నల ద్వారా పరీక్షించుకోండి:

❓ ప్రశ్న 1: స్ట్రక్చర్ (struct) మరియు యూనియన్ (union) మధ్య ముఖ్యమైన మెమరీ తేడా ఏమిటి?
సమాధానం: struct లో ప్రతి మెంబర్‌కు స్వతంత్ర మెమరీ ఉంటుంది (మొత్తం సైజ్ = మెంబర్ల మొత్తం + పాడింగ్). కానీ union లో అన్ని మెంబర్లు ఒకే ఉమ్మడి మెమరీని పంచుకుంటాయి (సైజ్ = అత్యంత పెద్ద మెంబర్ సైజు మాత్రమే).
❓ ప్రశ్న 2: Structure Padding ని కంపైలర్ ఎందుకు చేస్తుంది?
సమాధానం: CPU ప్రాసెసర్లు 4 లేదా 8 బైట్ల వర్డ్ బౌండరీస్ వద్ద డేటాను వేగంగా చదవడానికి అనువుగా మెమరీ అలైన్‌మెంట్ కోసం కంపైలర్ ఖాళీ బైట్లను (Padding Bytes) కలుపుతుంది.
❓ ప్రశ్న 3: (*ptr).member మరియు ptr->member ల మధ్య తేడా ఏమిటి?
సమాధానం: రెండూ పూర్తిగా ఒకటే! ptr->member అనేది (*ptr).member కోసం రాయడానికి సులభంగా ఉండే ప్రామాణిక షార్ట్‌హ్యాండ్ సింటాక్స్ (Arrow Operator).
❓ ప్రశ్న 4: #pragma pack(1) ను ఎప్పుడు ఉపయోగిస్తారు?
సమాధానం: కంపైలర్ చేసే స్ట్రక్చర్ పాడింగ్‌ను పూర్తిగా ఆపివేసి, 1-బైట్ అలైన్‌మెంట్‌తో మెమరీని పొదుపు చేయడానికి (ప్రత్యేకించి నెట్‌వర్క్ ప్రోటోకాల్ ప్యాకెట్లు మరియు బైనరీ ఫైల్ స్టోరేజ్‌లో) ఉపయోగిస్తారు.
❓ ప్రశ్న 5: typedef కీవర్డ్ యొక్క ముఖ్య ప్రయోజనం ఏమిటి?
సమాధానం: సంక్లిష్టమైన డేటా టైప్స్ లేదా struct Student వంటి పేర్లకు చిన్న, స్పష్టమైన మారుపేర్లను (Type Aliases) సృష్టించి కోడ్ రీడబిలిటీని పెంచడం.
🚀 హాస్పిటల్ మేనేజ్‌మెంట్ ఇంజిన్‌ను మన ఆన్‌లైన్ C కంపైలర్‌లో రన్ చేయండి!

పైన వివరించిన హాస్పిటల్ పేషెంట్ బిల్లింగ్ సిస్టమ్ మరియు Structure Padding vs Packed కోడ్‌లను మన ఆన్‌లైన్ C కంపైలర్‌లో ఓపెన్ చేసి స్వయంగా రన్ చేయండి. పేషెంట్ అడ్మిషన్ రోజులను మార్చి బిల్లు ఎలా రీకాలిక్యులేట్ అవుతుందో గమనించండి!

👉 Our Compiler లో C Compiler try చేయండి

📌 అధ్యాయ సారాంశం (Quick Summary):

  • struct: విభిన్న డేటా టైప్స్‌ను కలిపి కొత్త యూజర్-డిఫైన్డ్ రికార్డును నిర్మిస్తుంది.
  • డాట్ vs యారో: సాధారణ వేరియబుల్‌కు . వాడాలి; పాయింటర్‌కు -> వాడాలి.
  • పాడింగ్: CPU వేగవంతమైన రీడింగ్ కోసం ఖాళీ బైట్లను కలుపుతుంది.
  • union: అన్ని మెంబర్లు ఒకే ఉమ్మడి మెమరీని పంచుకుంటాయి.
  • typedef: పెద్ద పేర్లకు సులభమైన మారుపేర్లను అందిస్తుంది.
తర్వాతి అధ్యాయంలో (Chapter 18): ప్రోగ్రామ్ రన్ అవుతున్నప్పుడే కంప్యూటర్ నుండి కావలసినంత RAM మెమరీని అడిగి తీసుకునే డైనమిక్ మెమరీ అలొకేషన్ (malloc, calloc, realloc, free) మరియు మెమరీ లీక్స్ నివారణ గురించి అద్భుతంగా నేర్చుకుందాం!
← Prev: 16. పాయింటర్లు & అర్రేస్ Next: 18. డైనమిక్ మెమరీ (malloc/free) →
OC
Written by Our Compiler Technical Editorial Team
Reviewed for accuracy & tested on GCC 13+ / Clang 17 runtime · 2026 Academic Edition