
در آردوینو، دامنه (Scope) به معنی محدودهی دید یک متغیر در کد است — یعنی بخشی از برنامه که در آن متغیر قابل استفاده و شناختهشده است.
هر متغیر فقط در دامنهای که تعریف شده، «زنده» است. خارج از آن دامنه، گویی وجود ندارد!
توضیح برای مبتدیها: فرض کنید یک اسم دوست دارید، مثل «سارا». اگر این اسم را فقط داخل یک اتاق فریاد بزنید، کسی بیرون از اتاق آن را نمیشنود. در برنامهنویسی هم همینطور است: اگر متغیری را داخل یک تابع تعریف کنید، فقط در همان تابع قابل استفاده است — نه در جاهای دیگر کد.
درک دامنه به شما کمک میکند: — از خطاهای «متغیر تعریف نشده» جلوگیری کنید.
— کدهای تمیزتر و سازمانیافتهتر بنویسید.
— از تداخل ناخواسته بین متغیرها جلوگیری کنید.
— حافظه را بهینهتر مدیریت کنید (چون متغیرهای محلی پس از پایان تابع از حافظه پاک میشوند).
اگر متغیری را خارج از هر تابع (معمولاً در بالای کد، قبل از setup()) تعریف کنید، آن متغیر سراسری است.
یعنی در همه جای کد — چه در setup() و چه در loop() و چه در سایر توابع — قابل دسترسی است.
int globalCounter = 0; // متغیر سراسری
void setup() {
globalCounter = 10; // قابل دسترسی
}
void loop() {
globalCounter++; // قابل دسترسی
}
اگر متغیری را داخل یک تابع یا داخل یک بلوک کد (مثل داخل حلقه یا شرط) تعریف کنید، آن متغیر محلی است.
یعنی فقط در همان بلوک قابل استفاده است و خارج از آن «نامرئی» است.
void setup() {
int localVar = 5; // متغیر محلی — فقط در setup قابل دسترسی
Serial.println(localVar);
}
void loop() {
// Serial.println(localVar); // ❌ خطا: localVar was not declared in this scope
}
حتی داخل یک بلوک کوچک هم دامنه جداگانهای وجود دارد:
void loop() {
if (true) {
int temp = 100; // فقط داخل این بلوک if زنده است
}
// Serial.println(temp); // ❌ خطا: temp خارج از دامنه است
}
توضیح برای مبتدیها: هر بار که یک متغیر محلی تعریف میشود، آردوینو برای آن فضایی در RAM اختصاص میدهد. وقتی از آن بلوک خارج میشوید (مثلاً تابع تمام میشود)، آن فضا آزاد میشود. این باعث میشود RAM شما برای کارهای بعدی آماده بماند — خصوصاً در آردوینو Uno که فقط ۲ کیلوبایت RAM دارد!
در این مثال، یک شمارندهی سراسری برای کل سیستم و یک متغیر محلی برای محاسبهی موقت استفاده شده است:
const int SENSOR_PIN = A0;
int totalReadings = 0; // سراسری — برای ذخیره مجموع خواندنها
void setup() {
Serial.begin(9600);
}
void loop() {
int sensorValue = analogRead(SENSOR_PIN); // محلی — فقط برای این خواندن
totalReadings += sensorValue;
Serial.print("مقدار فعلی: ");
Serial.println(sensorValue); // ✅ در دامنه است
delay(1000);
}
// sensorValue اینجا وجود ندارد — پس RAM آزاد شده است
اگرچه متغیرهای سراسری راحت هستند، اما: — کد شما را پیچیده میکنند (هر تابعی میتواند آنها را تغییر دهد).
— خطاگیری را سخت میکنند (نمیدانید کدام تابع مقدار را عوض کرده).
— RAM را همیشه اشغال نگه میدارند.
قانون طلایی: هر متغیری را در کوچکترین دامنهی ممکن تعریف کنید — ترجیحاً محلی.
گاهی ممکن است یک متغیر محلی و یک متغیر سراسری نام یکسان داشته باشند. در این صورت، متغیر محلی متغیر سراسری را پنهان میکند (shadowing):
int value = 10; // سراسری
void loop() {
int value = 20; // محلی — سراسری را پنهان میکند
Serial.println(value); // چاپ میکند: 20
}
این رفتار گاهی عمدی است، اما اغلب باعث سردرگمی میشود. پس از نامهای متفاوت استفاده کنید یا از قراردادهای نامگذاری (مثل g_value برای سراسری) کمک بگیرید.
این مطلب بر اساس مستندات رسمی Arduino از بخش scope – Language Reference تهیه شده است، با توضیحات سادهشده، مثالهای کاربردی و نکات طلایی منحصربهفرد برای جامعه فارسیزبان.
برچسب های مهم