ขอบเขตของตัวแปรในภาษา C++ (Scope of variables In C++)

ตัวแปรทั้งหมดที่เราทำการประกาศค่าไว้ก่อนแล้ว นั้นในภาษา C++ การประกาศค่าตัวแปรจะทำที่ใดของ source code ก็ได้ และระหว่างการประกาศตัวแปรนั้น แต่ละขอบเขตของฟังค์ชัน ( Scope of Function ) นั้นถึงแม้จะชื่อเหมือนกัน แต่ว่าก็ไม่ได้หมายความว่าจะเป็นตัวแปรจะค่าเหมือนกันแต่อย่างใด ซึ่ง ตัวแปร A ที่อยู่ใน ฟังค์ชัน X จะไม่เท่ากับค่าของตัวแปร A ที่อยู่ในฟังค์ชัน Y แต่อย่างใด เพราะว่าอยู่กันคนละขอบเขตกันเราเรียกตัวแปรในขอบเขตแบบนี้ว่า ตัวแปรเฉพาะที่ (ในบทความนี้ขอพูดทับศัพท์ไปเลย เพื่อให้เข้าใจง่ายว่า Local Variables) ซึ่งจะมีค่าและสามารถใช้งานได้เฉพาะฟังค์ชัน ที่มันเกิดร่วมด้วยเท่านั้น


ตัวอย่าง 1

int X () {

   int A = 5;

   return A;

}

int Y () {

   int A = 10;

   return A;

}

int main() {

   std::cout < < X()<< ”;

   std::cout << Y()<< ”;

   return 0;

}


ผล

5 10


ในบางครั้งการเขียนโปรแกรมแบบประกาศตัวแปรภายนอกฟังค์ชัน ไม่ว่าจะที่ใดก็ตาม มันจะเป็น ตัวแปรสากล (ในบทความนี้ขอพูดทับศัพท์ไปเลย เพื่อให้เข้าใจง่ายว่า Global Variables) ไปทันที ซึ่งจะทำให้การประกาศแบบ ตัวแปร A มีค่าค่าหนึ่งในฟังค์ชัน X และตัวแปร A มีค่าอีกค่าหนึ่งในฟังค์ชัน Y จะทำแบบนี้ไม่ได้ เพราะว่าถูกการประกาศไว้แล้ว ภายนอกฟังค์ชัน ในภายนอกฟังค์ชันนั้นเอง ทำให้การที่ใช้ตัวแปรนั้นๆ ที่ประกาศไว้นอกฟังค์ชันไปใช้อาจทำให้เกิดการคำนวณหรือการทำงานที่ผิดพลาดได้


ตัวอย่าง 2

int x = 5; // Global Variable

int main() {

   double y = 3.1415; // Local Variable

   std::cout < < y << ”; std::cout << x << ”; return 0;

}


ผล

3.1415 5


แต่ ……

มันยังมีข้อที่เรามองข้ามไปคือ ถ้าเราประกาศตัวแปร เหมือนกับ Global Variable แล้วนั้น จะทำให้ตัว Compiler มองว่าตัวที่ประกาศอยู่ในฟังค์ชันคือตัวแปรที่มีความสำคัญหรือ ศักดิ์มากกว่า


ตัวอย่าง 3

int x = 5;

int main() {

   double x = 3.1415; /* ทำการซ่อน Global Variable x = 5 ไว้ */

   std::cout < < x << ”; /* แสดงตัวค่าตัวแปร Local Variable แทน */

   std::cout << ::x << ”;

   /* ใช้ Scope resolution operator มาวางให้ข้างหน้าตัวแปร

   เพื่อบ่งบอกว่าเราต้องการใช้ตัวแปร Globale Variable

   แทน Local Variable*/

   return 0;

}


ผล

3.1415 5


จากตัวอย่างจะเห็นว่าเราจะทำการประกาศตัวแปรทับซ้อนกันก็ได้ได้แต่ว่าไม่เป็นผลดีและอาจเกิดการสับสนใจการใช้งานได้ ทำให้ส่วนใหญ่แล้วจะใช้ Local Variable กันเยอะมาก เพราะว่าจัดการได้ง่าย แต่ก็มีในหลายๆ กรณีเช่นกันที่ต้องใช้ อย่างเช่นตัวแปรที่ต้องการแชร์ค่าเริ่มต้นการทำงานเช่นค่าของ Percen (100) หรือ ค่าของ Pi (3.1415) เป็นต้น เพราะเป็นค่าที่ไม่มีการเปลี่ยนแปลงไม่ว่ากรณีใดๆ

Note !

คุณสามารถที่จะบอก Compiler ว่าคุณต้องการใช้ Global Variables แทนการใช้ Local Variable ได้เมื่อคุณตั้งชื่อ Variable ภายใน Function นั้นเหมือนกับ Global Variable โดยใช้ :: (The Scope Resolution Operator) ไว้ด้านหน้าตัวแปรนั้นๆ …

:: identifier

class-name :: identifier

namespace :: identifier

ซึ่งการอ้างถึงของ :: (The Scope Resolution Operator) นั้นสามารถอ้างได้ตั้งแต่ variable, class และnamespace ได้ด้วย

ซึ่งจาก "ตัวอย่างที่ 3" ถ้าคุณมี Nested Local Scopes (มี Scope ตัวแปรซ้ำซ้อนกับ Global Variable ) ตัว Compiler จะไปเอาค่าหรืออ้างอิงตัวแปรที่อยู่ใน Function ก่อนเสมอ ถ้าจะใช้ Global Variable ก็เพียงทำหลักการของ The Scope Resolution Operator นั้นเอง

จากที่เราได้รู้แล้วว่า คำว่า Global Variables นั้นสามารถที่จะอ้างอิงได้จากทุกๆ ที่ใน code หรือใน ฟังค์ชัน ซึ่งจะคงอยู่ตลอดหลังจากการตั้งตัวแปรนั้นๆ ขึ้นมาใช้งานแล้ว แต่คำว่าตัวแปรเฉพาะที่ Local Variables นั้นตัวแปรจะถูกจำกัดอยู่ในขอบเขตที่ตัวเองได้เกิดขึ้น แต่ถ้าคุณสร้างมันในตอนแรกของฟังค์ชัน (ในที่นี่หมายถึง main ฟังค์ชันของ C++) ตัวแปรนั้นๆ จะอยู่ใน main ฟังค์ชันเท่านั้น และจะไม่ไปยุ่งกับตัวแปรอื่นๆ ในฟังค์ชันอื่นๆ ด้วยถึงแม้ชื่อจะเหมือนกันในฟังค์ชันอื่นๆ ก็ตามที

ใน C++ นั้น ขอบเขต ของ Local Variables นั้นจะอยู่ที่ ( brackets { } signs ) นั้นเอง ซึ่งถ้าคุณตั้งมันในขอบเขตดังกล่าวแล้ว ตัวแปรจะไม่ยุ่งเกี่ยวกับภายนอกฟังค์ชันแน่นอน


ตัวอย่าง 4

int main(){

   for (int i = 0; i < 100; ++i) {

      int x = 42;

      if (x < i) {

         double x = 3.14; std::cout << x; // Output ที่จะ Print ออกมาจากหน้าจอคือ 3.14

      }

      std::cout << x; // Output ที่จะ Print ออกมาจากหน้าจอคือ 42

      } // ส่วนนี้จะ Error เพราะว่าเราไม่ได้ตั้งตัวแปรไว้ในขอบเขตนี้ ด้วยเหตุผลได้กล่าวไปแล้วในข้างต้น

   std::cout << x;

   return 0;

}


จากเนื่อหาด้านบนคงทำให้หลายๆ คนเห็นภาพมากขึ้นในเรื่องของขอบเขตของตัวแปรในภาษา C++ นะครับ

อ้างอิงจากหนังสือ C++ in a Nutshell ของ O’Reilly