الفرق بين أوامر أردوينو const و #define

: كيفيه الحصول علي مصدر طاقة للبوردة التجريبية خاصتك
October 1, 2015
ابدأ مع راسبري باي booting SD card
October 11, 2015

تحتوي بوردة الأردوينو على مساحة صغيرة من الذاكرة العشوائة RAM، فعلى سبيل المثال تحتوي بوردة أردوينو أونو على 2 كيلو بايت فقط كذاكرة RAM تسمح للمبرمج أن يسجل عليها متغيرات البرنامج، لذلك إذا كان لديك متغيرات لها قيم ثابتة ( كـ أرقام المخارج التي توصل عليها مكونات الدائرة ) فالأفضل لك أن تستخدم أمر #define أو const وفي هذا المقال سنتعرف على أيهما أنسب لبرنامجك.

ماهو أمر #define ؟

أمر #define في الأغلب يتم فهمه عن طريق الخطأ على أنه أمر برمجي، لكنه في الحقيقة إشارة أو macro يقوم باستبدال كلمة ما بقيمة ما في الكود قبل أن تتم عملية البرمجة .. مثال على ذلك هذا الكود

#define pin 13
void setup() {
   pinMode(pin, OUTPUT);
}
void loop() {
  digitalWrite(pin, HIGH);
  delay(500);
   digitalWrite(pin, LOW);   
   delay(500);
}

قبل أن يتم إرسال هذا الكود لتتم معالجته، يتم استبدال كل كلمة “pin” داخل الكود بالقيمة “13” .. أي أن الكود الذي تتم معالجته في الحقيقة يكون كالتالي

#define pin 13
void setup() {
   pinMode(13, OUTPUT);
}
void loop() {
  digitalWrite(13, HIGH);
  delay(500);
   digitalWrite(13, LOW);   
   delay(500);
}

فالأمر #define هو مجرد إشارة ولا يستهلك مطلقا أي جزء من الذاكرة العشوائية RAM لأنه لا يخلق متغيرات جديدة، لكن لهذا الأمر عيب، تخيل أننا قمنا بإعلان سلسلة نصية باستخدام أمر #define وسميناها باسم HelloMessage، فإننا إن أشرنا لكلمة HelloMessage مثلا 25 مرة في الكود، فإن كود البرنامج سيصبح ضخما جدا لأنه سيحتوي على 25 رسالة نصية متكررة، حيث أنه يتم استبدال كلمة HelloMessage في كل مرة من المرات الـ 25 بالسلسلة النصية قبل أن تتم معالجة البرنامج ولكن هذه المساحة ستكون جزءا من الـ SRAM ( الذاكرة التي يتم تسجيل كود البرنامج بها ) وليس من الـ RAM ( الذاكرة التي يتم تسجيل المتغيرات بها ) 

#define HelloMessage "Welcome to the wonderful world of Arduino. Enjoy your stay"

————–

وما هو الأمر const ؟

يقوم الأمر const بإخبار الأردوينو أن هناك متغيرا لكن قيمة هذا المتغير ثابتة طول عمل البرنامج ويتم تخزين تلك القيمة في الذاكرة SRAM،فالأردوينو يعلم أنه ليس هناك داعي من أن يحجز مكانا في الذاكرة RAM، ويقوم بجعل أمر const يعمل كأنه أمر #define ويستبدل القيم بنفس الطريقة السابق شرحها  .. لكن const يختلف في أنه يتم تحديد نوع المتغير ويقوم الأردوينو بحجز عدد من الـ bytes حسب هذا النوع، فمثلا عند استخدام أمر const int x = 13 فإن أردوينو يقوم بحجز 2 بايت من الذاكرة ويضع بهما الرقم 13 رغم أن الرقم 13 لا يحتاج سوى بايت واحد لتخزينه، لكن لاحظ أن هذا لا يمثل فرقا شاسعا في القيم الصغيرة .. مثال لكتابة الأمر const 

const int pin=13;
void setup() {
   pinMode(pin, OUTPUT);
}
void loop() {
  digitalWrite(pin, HIGH);
  delay(500);
   digitalWrite(pin, LOW);   
   delay(500);
}

————–

إذا، ماهو الفرق الفعلي بين const و #define ؟

كما ذكرنا فإننا يمكن أن نعتبر أنه لايوجد فرق بينهما من حيث استخدام الذاكرة عند التعامل مع القيم الصغيرة، ولكن يفضل استخدام const عن #define بشكل عام حتى يسهل اكتشاف الأخطاء في الكود، حيث أنه هناك خطأ شائع يقع فيه الكثير من الناس عند كتابة أمر #define .. لاحظ الكود التالي

#define pin 13;
void setup() {
    pinMode(pin, INPUT);
}
void loop() {
    digitalWrite(pin, HIGH);
    delay(500);
    digitalWrite(pin, LOW);
    delay(500);
}

في هذا الكود خطأ وهو إضافة semicolon بعد سطر #define .. مما يترتب عليه أن يقوم البرنامج باستبدال كل كلمة “pin” بالقيمة “13;” ويصبح الكود بالشكل التالي:

#define pin 13;
void setup() {
    pinMode(13;, INPUT);
}
void loop() {
    digitalWrite(13;, HIGH);
    delay(500);
    digitalWrite(13;, LOW);
    delay(500);
}

وهذا يؤدي إلى أخطاء كثيرة في الكود وقد يتعسر على البعض فهم مصدر الخطأ، لكنه في النهاية كل ما تحتاجه هو تعديل بسيط وإزالة الـ semicolon

————–

مراجع:

  • http://forum.arduino.cc/index.php?topic=44023.0
  • http://stackoverflow.com/questions/3197913/size-of-define-values
  • https://www.baldengineer.com/const-vs-define-when-do-you-them-and-why.html