Phạm vi tĩnh và phạm vi động
Khám phá cuộc chiến cơ bản giữa các quy tắc phạm vi tĩnh và động.
Phạm vi biến đề cập đến phạm vi của chương trình có thể truy cập biến đó. Phạm vi giúp phân tách các biến được sử dụng trong các phần khác nhau của chương trình, ngay cả khi chúng có cùng tên. Điều này rất quan trọng vì lập trình viên thường sử dụng các tên biến chung chung như i, x hoặc count ở các phần khác nhau của chương trình.
Việc định nghĩa ranh giới thường được chia thành hai loại:
- Thiết lập ranh giới cố định
- Định nghĩa ranh giới động
Thiết lập ranh giới tĩnh:
Còn được gọi là phạm vi biến cố định (literal scoping), phương pháp này xác định phạm vi của các biến dựa trên cấu trúc của mã chương trình. Bằng cách này, các liên kết biến có thể được xác định bằng cách kiểm tra văn bản chương trình bất kể chương trình được thực thi như thế nào trong thời gian chạy. Trình biên dịch tìm kiếm các biến theo thứ tự sau: khối hiện tại, khối con, phạm vi toàn cục. Hầu hết các ngôn ngữ lập trình hiện đại, chẳng hạn như C, C++, Java và Python, đều sử dụng phạm vi biến tĩnh (static scoping). Vì phạm vi được biết tại thời điểm biên dịch, nên nó giúp chương trình dễ hiểu hơn, dễ gỡ lỗi hơn và dễ tối ưu hóa hơn.
// A C program to demonstrate static scoping.
#include<stdio.h>
int x = 10;
// Called by g()
int f()
{
return x;
}
// g() has its own variable
// named as x and calls f()
int g()
{
int x = 20;
return f();
}
int main()
{
printf("%d", g());
printf("\n");
return 0;
}Kết quả đầu ra:
10
Thiết lập ranh giới động:
Giá trị của một biến được xác định bởi lời gọi hàm cuối cùng trong ngăn xếp gọi hàm của chương trình, chứ không phải theo một cấu trúc chương trình cụ thể nào. Hệ thống thời gian chạy tìm kiếm định nghĩa của biến trong chuỗi các lời gọi hàm đang hoạt động. Thứ tự tìm kiếm là: hàm hiện tại, hàm gọi, hàm cao hơn trong ngăn xếp gọi. Cách tiếp cận này hiếm khi được sử dụng trong các ngôn ngữ lập trình hiện đại.
// Vì phạm vi biến động rất hiếm gặp trong
// các ngôn ngữ quen thuộc, chúng ta xem xét
// đoạn mã giả sau đây làm ví dụ. Nó
// in ra 20 trong một ngôn ngữ sử dụng phạm vi biến động.
int x = 10;
// Called by g()
int f()
{
return x;
}
// g() has its own variable
// named as x and calls f()
int g()
{
int x = 20;
return f();
}
main()
{
printf(g());
}Kết quả trong các ngôn ngữ sử dụng phạm vi động:
20
