هذا ليس سؤالًا نموذجيًا لكارهي المؤشر، ولكنه سؤال مثير جدًا للاهتمام.
المؤشرات هي مفهوم قوي وعظيم، ولكن هذا ما هو عليه: مفهوم. فلماذا تم اختراع مترجم لغة C بمثل هذه القطعة المعزولة من المنطق وبناء الجملة المخصصة للمؤشرات؟
لا تفهموني خطأ، أنا أحب الفرص التي توفرها لنا المؤشرات وصياغتها الحالية. إنها ميزة أساسية للغاية، حيث حققت تطورًا في هياكل البيانات الديناميكية والكائنات والفئات ومشاركة الذاكرة متعددة الخيوط وقابلية تغيير الكائنات وتكرار القيمة المنخفضة التكرار وغير ذلك الكثير.
ولكن إذا تخيلت حدث اختراع لغة C، فإن المؤشرات في الوقت الحالي تبدو فكرة أكثر إثارة للإعجاب من المفهوم الأول البديهي. دعونا نلقي نظرة أعمق على ما أعنيه.
إذا نظرت إلى بنية المؤشر، فهي في الأساس عبارة عن مؤشر طويل غير موقّع (ويُعرف أيضًا باسم 4 [نظام 32 بت] أو 8 بايت في الذاكرة). الأشياء التي تفصل المؤشرات عن الرسائل الطويلة غير الموقعة هي الميزات الخاصة بالمؤشر.
يحتوي المؤشر على صيغة إعلان خاصة به وله عامل تشغيل خاص به: المُرجع.
int a = 5; int *ptr = &a; //declaration int value = *ptr; //dereference
ولكن دعونا نتخيل أن هذا لم يتم اختراعه أبدًا. بعد ذلك سيكون ما يلي ممكنًا بسهولة إذا كانت ميزة إلغاء الإشارة مرتبطة فقط بأي نوع عدد صحيح:
int a = 5; unsigned long adress = &a; int value = *adress;
في هذه الحالة، يمكنك أيضًا القيام بأشياء مثل هذا:
int firstIntInMemory = *(0); //manually dereferences (4bytes at) adress 0`
بالحديث عن المحلل اللغوي، هذا ليس بناء جملة متضاربًا على الإطلاق نظرًا لأن النجم كمزيل الانكسار هو عامل أحادي بينما النجم كمضاعف حسابي هو دائمًا عامل ثنائي.
إن عامل إلغاء الإشارة الخيالي هذا كما وصفته أعلاه هو في الحقيقة الجوهر الأولي لمفهوم المؤشر. إن مقارنة هذا بالتنفيذ الحقيقي الحالي يجعل السؤال الرئيسي مثيرًا للاهتمام للتفكير فيه. كان من الممكن أن يكون هناك الكثير من النتائج.
الشيء الوحيد المميز الذي يفعله المؤشر الحسابي هو أخذ أحجام الكتابة في الاعتبار مع العمليات الحسابية. عندما يكون لدي مصفوفة، وأريد الحصول على العنصر الثاني، أقوم فقط بإضافة 1 إلى المؤشر. إذا كان مؤشرًا صحيحًا، فسيؤدي ذلك ضمنيًا إلى إضافة قيمة 4 إلى العنوان (إذا كان sizeof(int) == 4 على نظامك):
int arr[5] = {1,2,3,4,5}; int second = *(arr 1);
ولكن لنكن صادقين، ما يلي في الواقع أكثر منطقية إذا كنت تفكر بشكل حدسي في الذاكرة:
int arr[5] = {1,2,3,4,5}; int second = *(arr sizeof(int));
وسيكون هذا مجرد حساب عدد صحيح قياسي. إذا نظرت إلى الأمر بهذه الطريقة، فليس هناك حقًا سبب لاختراع مؤشر الحساب على الإطلاق.
بطبيعة الحال، فإن بناء الجملة '*' يجعل الاستخدامات المقصودة أكثر وضوحًا. إذا رأيت ذلك، فأنت تعرف على الفور أن هذا المتغير يستخدم لمعالجة الذاكرة. كما تم تصميم كل وظيفة مكتبة معالجة الذاكرة للمؤشرات.
ولكن مع ذلك، إذا لم يتم اختراعه مطلقًا، وبدلاً من ذلك كان لدينا هذه الأطوال غير الموقعة التي يمكن إلغاء الرجوع إليها، لكان الناس قد توصلوا للتو إلى اصطلاحات التصميم والتسمية، مثل إلحاق معرفات متغير المؤشر بلاحقة "_p". ومكتبات معالجة الذاكرة قد تطورت حول هذا الأمر.
لذا حقًا، إذا فكرت في الأمر، كان من الممكن أن تظل لغة C بنفس الطريقة التي تعيش بها الآن إذا لم يتم اختراع المؤشرات أبدًا كميزة للغة. سيتم اختراعها كمفهوم من قبل المبرمجين، وتعمل بنفس الطريقة التي توجد بها حاليًا.
أجد هذه قصة مثيرة للاهتمام للتحقيق فيها بشكل أعمق.
لماذا اخترع لغة C المؤشر؟
هل كان هذا هو السبب الذي يجعلنا نتوقع: الاتساق والوضوح والسلامة ضد إساءة استخدام إلغاء الإعجاز؟
أم أن هناك سببًا أعمق ومنطقًا أكثر تعقيدًا بكثير من الطريقة التي غطيت بها المؤشرات في هذا المنشور، مما يجعلها في الواقع أكثر كفاءة بشكل ملحوظ من فعل الشيء نفسه مع الأعداد الصحيحة للأغراض العامة؟
تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.
Copyright© 2022 湘ICP备2022001581号-3