Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C++

Else และ Switch Statements พร้อม Initializers ใน C++17

ภาพรวม

C++17 เพิ่มฟีเจอร์ Init-Statements ให้กับ if, else, และ switch ช่วยจำกัด Scope ของตัวแปรและทำโค้ดสะอาดขึ้น

If-Else with Initializer

Syntax

if (init-statement; condition) {
    // ...
} else {
    // ...
}

ตัวอย่าง: ก่อน C++17 vs หลัง C++17

// Before C++17
{
    int val = foo();
    if (val > 0) { /* ... */ }
    else { /* ... */ }
} // val ยังคงอยู่ใน Scope นี้

// C++17 - Init Statement
if (int val = foo(); val > 0) {
    // ...
} else {
    // ...
} // val หายไปแล้ว (Scope จบที่ if-else)

// สามารถใช้ชื่อตัวแปรซ้ำได้ใน Block ถัดไป
if (auto val = bar(); val > 0) { /* ... */ }
else { /* ... */ }
// val ตัวนี้คนละตัวกับด้านบน

Switch with Initializer

Syntax

switch (init-statement; variable) {
    case ...: ...
}

ตัวอย่าง

switch (int val = rand() % 100; val) {
    case 0: cout << "Zero"; break;
    default: cout << "Non-zero: " << val; break;
}
// val Scope จำกัดใน Switch Block เท่านั้น

โค้ดตัวอย่างสมบูรณ์

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <map>
#include <string>
using namespace std;

// Mock function
int getDeviceStatus(int id) {
    static map<int, int> status = {{1, 200}, {2, 404}, {3, 500}};
    return status[id];
}

int main() {
    srand(time(nullptr));

    // If with Init - Scope Limited
    if (int status = getDeviceStatus(1); status == 200) {
        cout << "Device 1: OK (" << status << ")\n";
    } else {
        cout << "Device 1: Error (" << status << ")\n";
    }

    // Switch with Init
    switch (int deviceId = rand() % 3 + 1; int status = getDeviceStatus(deviceId); status) {
        case 200: cout << "Device " << deviceId << ": Online\n"; break;
        case 404: cout << "Device " << deviceId << ": Not Found\n"; break;
        case 500: cout << "Device " << deviceId << ": Server Error\n"; break;
        default:  cout << "Device " << deviceId << ": Unknown (" << status << ")\n";
    }

    // Reuse variable name in another block
    if (auto val = 42; val > 0) {
        cout << "First block: " << val << endl;
    }
    if (auto val = 3.14; val > 3.0) {  // Different type, same name OK
        cout << "Second block: " << val << endl;
    }

    return 0;
}

ผลลัพธ์ (ตัวอย่าง)

Device 1: OK (200)
Device 2: Not Found
First block: 42
Second block: 3.14

ประโยชน์หลัก

  • Scope Safety: ตัวแปรหายทันทีหลัง Block ลด Bugs จากการใช้ตัวแปรเก่า
  • Name Reuse: ใช้ชื่อตัวแปรซ้ำได้ใน Block ถัดไป
  • Readability: Declaration และ Condition อยู่ที่เดียว
  • Performance: ไม่ต้อง Declare ภายนอก Loop/Block

ข้อจำกัด

  • Init-statement ต้องเป็น Declaration หรือ Expression Statement เท่านั้น
  • ไม่สามารถใช้ Structured Binding ใน Init Statement ได้ (C++17)
  • C++20: ใช้ได้ใน Range-based For: for (auto [k, v] : map) ...

สรุป Syntax ใหม่ C++17

ConstructSyntax
Ifif (init; cond) ... else ...
Switchswitch (init; var) { case ... }
For (C++20)for (init; cond; inc) ... (มีอยู่แล้ว)
Whileไม่รองรับ (ใช้ Block แยก)