CALM/arwiki huggingface dataset:
المؤشرات والتحويل القسري.
في العديد من اللغات، يوجد في بعض المؤشرات قيد إضافي ألا وهو أن الكائن المُشار إليه كائن من نوع خاص. على سبيل المثال، ربما يُعلن عن المؤشر للإشارة إلى عدد صحيح؛ لذا ستحاول اللغة منع المبرمج من الإشارة إلى كائنات الأعداد بخلاف العدد الصحيح، مثل الأرقام العشرية، والتخلص من بعض الأخطاء.
على سبيل المثال في لغة السي C
char *bags;
سيكون money مؤشر لعدد صحيح و bags ستكون مؤشر char. سوف يُظهر الناتج التالي تحذير مترجم بان "مهمة من نوع مؤشر غير متجانس" وفقاً للغة GCC
bags = money;
نظراً لإعلان money و bags بأنواع مختلفة. يجب توضيح رغبتك الفعلية في عمل المهمة عن طريق typecasting وتعني " كيفية تغيير نوع البيانات من نوع إلي نوع أخر وقت البرمجة بدون التقييد بنوع معين وبدون التغيير في قيمتها إلا في حالات معينة فقط.
للتوضيح " وذلك لمنع ظهور هذا التحذير للمترجم.
bags = (char *)money;
يُوضح ذلك تغيير أو تحويل مؤشر العدد الصحيح لـ money إلى مؤشر char والإشارة إلى bags.
يجب أن تحتفظ مسودة 2005 للمتطلبات القياسية للغة السي C التي تقوم بتحويل مؤشر مستمد من أحد الأنواع إلى نوع آخر على الحيادية الصحيحة لكلا النوعين (مؤشرات 6.3.2.3، par.7)
char *external_buffer = "abcdef";
int *internal_data;
internal_data = (int *)external_buffer; // UNDEFINED BEHAVIOUR if "the resulting pointer
// is not correctly aligned"
تضع حسابات المؤشرات في الحسبان حجم النوع في اللغات التي تُمكن المؤشر الحسابي في اللغات التي تُمكن المؤشر الحسابي. على سبيل المثال، ينتج عن إضافة عدد صحيح إلى المؤشر إلى ظهور مؤشر جديد يُشير إلى عنوان أعلى بمقدار مضاعفة هذا الرقم لحجم هذا النوع. يُمكننا ذلك من حساب عنوان عناصر المصفوفة لهذا النوع المحدد بسهولة ويُسر كما وُضح سابقاً في مثال مصفوفات لغة السي C. يجب على المبرمج أن يتوقع أن المؤشر الحسابي سيتم حسابه بطريقة مختلفة وذلك عند تحويله لأحد مؤشرات أحد الأنواع إلى مؤشر من نوع أخر من حجم مختلف. على سبيل المثال إذا بدأت مصفوفة في لغة السي C بmoney عند 0x2000 وsizeof(int) 4 بايت حيث sizeof(char) 1 بايت ومن ثم (money+1) سوف يُشير إلى 0x2004 ولكن سوف بُشير (bags+1) إلى 0x2001. ويُعد فقدان البيانات عند كتابة البيانات "الكبيرة" في محل البيانات "الصغيرة" من مخاطر التحويل القسري (على سبيل المثال bags[0]=65537;)، تظهر نتائج غير متوقعة عند تحويل القيم bit-shifting، ومشكلات المقارنة، خاصة مع القيم في مقابل القيم الغير موقعة.
تقوم بعض اللغات بتخزين معلومات نوع التشغيل التي يُمكن استخدامها للتأكد من أن هذه الأشكال الهامة صالحة في عملية التشغيل على الرغم من استحالة تحديدها أي من هذه الأشكال آمنة في آن واحد وذلك بوجه عام، في حين ترفض اللغات الأخرى القيمة التقريبية الغير قابلة للتغير من الأشكال الآمنة، أو لا تقبل أي منها على الإطلاق.
زيادة مستوى أمان المؤشرات.
تسمح المؤشرات بوقوع العديد من أخطار البرمجة ويرجع ذلك لسماحها لبرنامج بالولوج إلى الكائنات التي لم يُعلن عنها بوضوح من قبل. بيد أن السلطة التي توفرها كبيرة جداً لدرجة أنه يُمكن أن يكون من الصعب القيام ببعض مهام البرمجة في غيابها. لذا فقد اختلقت بعض اللغات كائنات لها بعض خصائص المؤشرات المفيدة في حين تجنب بعض ثغراتها pitfalls للمساعدة في التعامل مع مثل هذه المشكلات.
تواجه المؤشرات مشكلة رئيسية ألا وهي أنه أثناء معالجتها بشكل مباشر كأرقام، يُمكن تشكيلها للإشارة إلى العناوين غير المستخدمة أو إلى البيانات التي تستخدم لأغراض أخرى. العديد من اللغات، بما في ذلك معظم لغات البرمجة الوظيفية functional programming languages واللغات الأمرية الحديثة imperative languages مثل لغة Java إلي تستبدل المؤشرات بنوع أكثر تعقيداً من المرجع والذي عادة ما يُشار إليه ببساطة كالمرجع والذي يمكن استخدامه فقط للإشارة إلى الكائنات ولا تُعالج كأرقام لمنع هذا النوع من الأخطاء.
تُتناول فهرسة المصفوفة كحالة خاصة.
يُطلق على المؤشر الذي لا يحتوي على أي عنوان محدد له اسم المؤشر البدائي wild pointer. يمكن لأي محاولة لاستخدام مثل هذه المؤشرات الغير مهيأة أن تؤدي إلى سلوك غير متوقع إما لأن القيمة المبدئية ليست عنوان صالح وإما لأن استخدامها يمكنه تدمير أجزاء أخرى من البرنامج. وغالباً ما تكون النتيجة ظهور خطأ التجزئة segmentation fault أو انتهاك قواعد التخزينstorage violation.
في الأنظمة تخصيص الذاكرة، من السهل بناء المؤشر التابع dangling pointer عن طريق عدم تخصيص منطقة الذاكرة التي تُشير إليها. يُعد هذا النوع من المؤشرات خطير ودقيق لأن منطقة الذاكرة الغير مخصصة يُمكنها أن تحتوي على نفس البيانات التي كانت بها قبل إلغاء تخصيصها ولكن يُمكن حينها إعادة تخصيصها والكتابة عليها من خلال استخدام كود غير متصل بها، غير معروف للكود السابق. يُزعم أن اللغات التي تحتوي على garbage collection تمنع هذا النوع من الأخطاء (حيث تتم عملية إلغاء التخصيص يتم بشكل تلقائي) ولكن لا تتم إزالة المؤشر نفسه بواسطة garbage collector ويمكن أن يشير إلى بيانات ذات صلة وغير متوقعة إذا أعيد استخدامها في أي وقت بعد إلغاء تخصيصها.
تُدعم بعض اللغات مثل لغة C++ المؤشرات الذكية smart pointers والتي تستخدم نموذج مبسط من حساب المرجع للمساعدة في تتبع تخصيص الذاكرة الديناميكية بالإضافة إلى العمل كمرجع. في غياب حلقات المرجع، حيث يشير الكائن إلى نفسه بصورة غير مباشرة من خلال سلسلة من المؤشرات الذكية smart pointers,، يلغي هذا على إمكانية المؤشرات التابعة dangling pointer وتسريبات الذاكرة. تدعم سلاسل Delphi حساب المرجع محلياً.
مؤشر Null.
غالباً ما يحتوي مؤشر Nullعلى قيمة محددة، ولكنها ليست بالضرورة أن تكون القيمة صفر، توضح أنه لا يشير إلى أي كائن. تُستخدم مؤشرات Null روتينياً، خاصة في لغة C ولغة C++ حيث يستخدم compile-time constant (بالرغم من تفضيل الأعداد الصحيح للصفر في لغة C++ إلا أن لغة C++0x أدخلت nullptr constant لاستخدامه كبديل)، لتوضيح ظروف مثل القصور في successor للكائن الأخير في القائمة المرتبطة linked list، مع الحفاظ على بنية متسقة لنقاط القائمة. هذا الاستخدام لمؤشرات Null يمكن مقارنتها مع أنواع nullable ومع قيم null في قواعد البيانات الارتباطية ومع قيم Nothing في option type. قد اخترعت مراجع Nullable من قبل C.A.R. Hoare في عام 1965 كجزء من لغة Algol W. وقد وصف Hoare اختراعه لاحقاً (2009) بأنه "خطأ بمليار دولار":
لقد أطلقت عليه خطأ المليار دولار الخاص بي. كان اختراع مرجع null في عام 1965. في هذا الوقت، كنت أصمم أول نظام النوع الشامل للمراجع في اللغة غرضية التوجه (ALGOL W). كان هدفي من ذلك هو التأكيد على أن كل استخدامات المراجع لابد وأن تكون آمنة، مع التحقق من التنفيذ التلقائي عن طريق المجمع. ولكن لم أستطع مقاومة الإغراءات لوضع مرجع null ببساطة لأن تنفيذه كان سهل جداً. أدى هذا إلى عدد لا يحصى من الأخطاء ونقاط الضعف ووقوع أعطال في النظام والتي ربما تسببت في مليار دولار من الألم والضرر في الأربعين سنة الماضية.
نظراً لعدم إشارة مؤشر null إلى أي كائن ذات معنى، فإن محاولة تتبع مؤشر null عادة ما يتسبب في ظهور خطأ بالتشغيل. إذا لم يتم التعامل مع هذا الخطأ فإن البرنامج يتوقف عن العمل على الفورً. في حالة لغة C على كمبيوتر عام، يتوقف التنفيذ من خطأ التجزئة segmentation fault لأن عنوان null الحرفي لا يقسم أبداً لبرنامج قيد التشغيل (يُمكن حدوث العديد من الأشياء مع برنامج لغة C في الأنظمة المدمجة embedded system). في لغة Java يشغل الولوج إلى مرجع null NullPointerException التي يُمكن الحصول عليها من خلال كود معالجة الخطأ، ولكن التطبيق المفضل هو التأكد من عدم حدوث هذه الاستثناءات مطلقاً. في اللغات الآمنة يمكن استبدال مؤشر null المحتمل بوحدات مرتبطة tagged union التي تفرض معالجة واضحة للحالة الاستثنائية؛ في الحقيقة يمكن رؤية مؤشر null على أنه مؤشر tagged pointer بإضافة محسوبة. توفر اللغات الأخرى، مثل لغة Objective-C، عملية إرسال الرسائل إلى عنوان nil (قيمة المؤشر الذي لا يشير إلى كائن صالح) دون التسبب في توقف البرنامج عن العمل؛ وسيتم تجاهل الرسالة ببساطة والقيمة المعادة (إذا وجدت) تكون صفر أو 0، اعتماداً على النوع.
يُضمن في برمجة لغة C ولغة C++، المقارنة العادلة بين مؤشرين null؛ تضمن لغة ANSI C أن أي مؤشر null يساوي 0 في مقارنة مع نوع العدد الصحيح؛ علاوة على ذلك يُعرَّف macro NULL على أنه مؤشر null ثابت، قيمته 0 (إما كأحد أنواع الأعداد الصحيح أو المحولة إلى مؤشر لـ void)، لذا سيقارن مؤشر null بالتساوي مع NULL.
وينبغي عدم الخلط بين مؤشر null والمؤشر الغير مهيأ: يُسمح لمؤشر null لمقارنة الغير متكافئ مع أي مؤشر صالح، بينما وفقاً للغة وتنفيذ المؤشر غير المهيأ قد تكون إما قيمة غير محددة (عشوائية أو قيمة بلا معنى) أو يمكن تهيئتها لثابت أولي (محتملة لكن ليس بالضرورة NULL).
تُعيد دالة malloc مؤشر null في معظم بيئات برمجة لغة السي C إذا لم يكن قادراً على تخصيص منطقة الذاكرة المطلوبة، والتي تنبه المتصل بعدم وجود ذاكرة كافية. بالرغم من ذلك بعض تطبيقات malloc(0) مع إعادة مؤشر null وبدلا من ذلك تحدد الفشل عن طريق إعادة مؤشر null وإدخال errno إلى قيمة مناسبة.
تقوم أنظمة الحاسب الآلي على tagged architecture القادرة على التفريق في الأجهزة بين تتبع Null والمحاولة المشروعة للولوج إلى كلمة أو بناء على العنوان صفر.
في بعض بيئات لغة البرمجة (على الأقل تطبيق Lisp على سبيل المثال) القيمة المستخدمة على مؤشر null (يطلق عليها اسم nil في Lisp) ربما يكون مؤشر لقالب من البيانات الداخلية المفيدة للتطبيق (لكن لا يمكن الوصول إليها بشكل جلي من خلال برامج المستخدم)، لذا يُفيد السماح باستخدام نفس العدد الصحيح كثابت وكذلك الطريقة السريعة للولوج إلى تطبيقات التنفيذ. يُعرف هذا بأنه ناقل nil.
مؤشر Autorelative.
مؤشر autorelative (أو self-relative) هو المؤشر الذي تُفسر قيمته كإزاحة من عنوان المؤشر نفسه؛ لذا، إذا كان هيكل البيانات M له مؤشر autorelative فالكائن p الذي يُشير إلى جزء من M نفسه فإن M ربما يعيد تخصيصها في الذاكرة من دون الحاجة إلى تحديث قيمة p.
مؤشر الارتكاز Based.
مؤشر الارتكاز هو المؤشر الذي قيمته عبارة عن إزاحة من قيمة مؤشر آخر. يمكن استخدامه لتخزين وتحميل كتل من البيانات، محددة عنوان بداية الكتلة إلى مؤشر الارتكاز.
المراوغة المزدوجة.
في بعض اللغات يمكن أن يشير المؤشر إلى مؤشر آخر، يتطلب عمليتان للتتبع للوصول للقيمة الأصلية. بينما كل مستوى من المراوغة ربما يضيف تكلفة أداء، وأحياناً ضرورية لتقديم سلوك صحيح لهياكل البيانات المعقدة. على سبيل المثال، في لغة C تُعرَّف القائمة المرتبطة من حيث الكائن الذي يحتوي مؤشر للكائن التالي في القائمة:
struct element
struct element * next;
struct element * head = NULL;
يستخدم هذا التطبيق مؤشر للكائن الأول في القائمة كبديل للقائمة ككل. إذا أضيفت قيمة جديدة إلى بداية القائمة يجب تغيير المقدمة للإشارة إلى الكائن الجديد. بما أن براهين C تمرر عادة بالقيمة، يتيح استخدام المراوغة المزدوجة بتنفيذ الإدخال بصورة صحيحة، وبه الآثار الجانبية المرغوبة للقضاء على كود الحالة الخاصة للتعامل مع المدخل في أول القائمة:
// Given a sorted list at *head, insert the element item at the first
// location where all earlier elements have lesser or equal value.
void insert(struct element **head, struct element *item)
struct element ** p; // p points to a pointer to an element
for (p = head; *p != NULL; p = &amp;(*p)-&gt;next)
if (item-&gt;value &lt;= (*p)-&gt;value)
item-&gt;next = *p;
*p = item;
// Caller does this:
insert(&amp;head, item);
في هذه الحالة، إذا كانت قيمة البند أقل من head فإن مقدمة المتصل تُحدَّث بشكل صحيح في عنوان البند الجديد.
المؤشرات البدائية.
المؤشرات البدائية هي المؤشرات التي لم يتم تهيأتها بعد (لا يوجد عنوان محدد للمؤشر البدائي) ربما تتسبب مثل هذه المؤشرات في تعطيل البرنامج أو العمل بطريقة بدائية. تُشير المؤشرات التي لم يتم تهيأتها في لغات برمجة Pascal أو لغة السي C إلى عناوين غير متوقعة في الذاكرة.
يوضح مثال الكود التالي مؤشر بدائي:
int func(void)
char *p1 = malloc(sizeof(char)); /* (undefined) value of some place on the heap */
char *p2; /* wild (uninitialized) pointer */
*p1 = 'a'; /* This is OK, assuming malloc() has not returned NULL. */
*p2 = 'b'; /* This invokes undefined behavior */
هنا، ربما تشير p2 إلى أي مكان في الذاكرة، لذا أداء المهمة *p2 = ‘b’ سيفسد منطقة غير معروفة من الذاكرة التي ربما تحتوي على بيانات حساسة.
الشعبة البدائية.
حيث يستخدم المؤشر كعنوان لنقطة الدخول لبرنامج أو بداية لروتين كما أنه يكون إما غير مهيأ أو فاسد، إذا تم الاتصال أو القفز مع ذلك إلى هذا العنوان، فيقال أنه تفسد "الشعبة البدائية". والعواقب دائماً غير متوقعة وربما يظهر الخطأ نفسه بعدة طرق مختلفة اعتماداً على إذا كان المؤشر عنوان صالح أم لا وإذا كان هناك (من قبيل الصدفة) إرشاد صالح (شفرة تشغيل) على هذا العنوان. يمكن أن يوضح اكتشاف الشعبة البدائية أحد أصعب عمليات التصحيح وأكثرها إحباطاً حيث أنه ربما تم بالفعل تدمير كثير من الأدلة من قبل أو عن طريق تنفيذ واحد أو أكثر من التعليمات الغير مناسبة في موقع الشعبة. في حالة ما إذا كان متاحاً، يمكن ألا تكون محاكاة مجموعة التعليمات عادة تضبط فقط الشعبة البدائية قبل دخولها حيز التنفيذ، لكن تقدم أيضاً تتبع كامل أو جزئي لتاريخها.
المحاكاة باستخدام فهرس المصفوفة.
من الممكن محاكاة سلوك المؤشر باستخدام فهرس المصفوفة (عادة بعد واحد).
بدايةً للغات التي لا تدعم المؤشرات بوضوح ولكن تدعم المصفوفات، يمكن اعتبار المصفوفة ومعالجتها كما لو كانت نطاق الذاكرة بالكامل (في نطاق مصفوفة محددة) وأي فهرس يمكن اعتباره مكافئ لسجل الغرض العام في لغة التجميع (يشير هذا إلى البايت الفردي ولكن التي تناسب قيمته الفعلية لبداية المصفوفة، ليس عنوانه المطلق في الذاكرة). على افتراض أن المصفوفة هي هيكل بيانات 16 ميجا بايت مترابط، وحدات البايت الفردي (أو سلسلة من وحدات البايت المرتبطة في المصفوفة) يمكن عنونتها مباشرة ومعالجتها باستخدام اسم المصفوفة مع العدد الصحيح 31 بايت الغير موقع كمؤشر المحاكاة (يماثل هذا أمثلة مصفوفات اللغة C الموضحة سابقاً). يمكن محاكاة المؤشر الحسابي بالإضافة أو الطرح من الفهرس، مع الحد الأدنى من الإضافات العامة التي تُقارن بالمؤشر الحسابي الحقيقي.
حتى انه من الممكن نظرياً، استخدام التقنية السابقة مع جهاز المحاكاة مجموعة الإرشادات لمحاكاة أي كود آلة أو الوسطية (كود البايت) لأي معالج/ لغة في لغة أخرى التي لا تدعم المؤشرات مطلقاً (على سبيل المثال، لغة Java / لغة JavaScript). لتحقيق هذا، يمكن تحميل الشفرة الثنائية بدايةً إلى وحدات بايت مرتبطة من المصفوفة لمحاكاة "القراءة"، التفسير والعمل كلياً مع الذاكرة المحتوية على نفس المصفوفة. إذا كان ضرورياً، لتجنب مشاكل تجاوز سعة المخزن كليةً يمكن للتدقيق الفائق العمل للمجمع (أو إذا لم يكن، كتابة الكود في جهاز المحاكاة)
الدعم في العديد من لغات البرمجة.
لغة Ada.
Ada هي لغة كتابة قوية حيث أن جميع المؤشرات تكتب ويسمح فقط بالمحادثة المكتوبة الآمنة. تهيأ جميع المؤشرات افتراضياً إلى null، وأي محاولة للولوج إلى البيانات عن طريق مؤشر null يسبب ظهور استثناء. تسمى المؤشرات في لغة Ada بأنماط الولوج. لا تسمح لغة Ada 83 بالحسابات على أنماط الولوج (على الرغم من أن العديد من الموردين المقدمين لها كميزة غير معيارية)، لكن لغة Ada 95 تُدعم الحسابات "الآمنة" على أنماط الولوج عبر حزمة System.Storage_Elements.
لغة Basic.
لا تدعم لغة Basic المؤشرات بصورة عامة. اللهجات الحديثة في لغة Basic، مثل FreeBASIC أو BlitzMax لديها تطبيق شامل للمؤشر.
في FreeBASIC، تُعامل حسابات مؤشرات ANY (تعادل void* في لغة C) كما لو كان مؤشرANY نطاقه 1 بايت. لا يمكن تتبع مؤشرات ANY، كما في لغة C. أيضاً، الإلقاء بين ANY وأي مؤشر من نوع آخر من المؤشرات لن يسبب أي مخاطر.
dim as integer f = 257
dim as any ptr g = @f
dim as integer ptr i = g
assert(*i = 257)
assert((g + 4) = (@f + 1))
لغة C ولغة C++.
المؤشرات في لغة C ولغة C++ هي المتغيرات التي تخزن العناوين ويمكن أن تكون null. يسير كل مؤشر إلى نوع خاص به، ولكن يمكن للفرد التنقل بحرية بين أنواع المؤشرات، على الرغم من أن السلوك هو تطبيق معروف. يسمح نوع خاص من المؤشرات يطلق عليه "مؤشر void" بالإشارة إلى أي نوع من المتغيرات، ولكن تحده حقيقة أنه لا يمكن تتبعه مباشرةً. غالباً يمكن معالجة العنوان نفسه مباشرة بإلقاء مؤشر من وإلى نوع متكامل بحجم مناسب، على الرغم من أن النتائج هي تطبيقات معروفة ويمكن أن تتسبب في سلوكيات غير معروفة؛ بينما لا يوجد لدى معايير لغة C السابقة نوع متكامل الذي ضُمن أن يكون كبير بدرجة كافية، لغة C99 تحدد اسم uintptr_t typedef المعرَّفة في &lt;stdint.h&gt;، لكن لا يحتاج التطبيق لتوافرها.
تدعم لغة ++C بالكامل مؤشرات لغة السيC وتحويل نوع المتغير typecasting لغة C. كما تدعم مجموعة جديدة من مشغلات التحويل نوع المتغير typecasting للمساعدة في التقاط بعض الاشكال الخطيرة في الوقت الواحد. كما تقدم المكتبة المعيارية للغة C++ auto ptr نوع من المؤشرات الذكية الذي يمكن استخدامه في بعض المواقف كبديل آمن للمؤشرات الأولية في لغة C. كما تدعم لغة C++ شكل آخر من المرجع، مختلف عن المؤشر يطلق عليه ببساطة المرجع أو نمط المرجع.
المؤشر الحسابي هو القدرة على تعديل عنوان المؤشر المستهدف بعمليات حسابية (وكذلك مقارنات الحجم) ويقتصر على معايير اللغة للبقاء ضمن حدود كائن المصفوفة الواحدة (أو فقط بعد ذلك)، على الرغم من أن العديد من الهياكل المتكاملة ستسمح بالمزيد من التساهلات الحسابية. الإضافة أو الطرح من مؤشر يحركه بمضاعفات الحجم من نوع البيانات التي تشير إليها. على سبيل المثال، إضافة 1 إلى مؤشر قيمته 4 بايت سيزيد المؤشر بمقدار 4. وهذا له تأثير في زيادة المؤشر للإشارة إلى الكائن التالي في المصفوفة المرتبطة من الأعداد الصحية- غالباً ما تكون هذه هي النتيجة المطلوبة. لا يمكن للمؤشر الحسابي الأداء على مؤشر void لأن نوع void ليس له حجم، وبالتالي لا يمكن إضافة العنوان المشار إليه، عل الرغم من أن gcc وغيرها من المجمعات ستؤدي حسابات البايت على void* كامتداد غير معياري. للعمل مباشرةً مع وحدات البايت يلقوا عادةً المؤشرات إلى BYTE*، أو char* غير الموقعة إذا لم تُعرَّف BYTE في المكتبة المعيارية المستخدمة.
يقدم المؤشر الحسابي للمبرمج طريقة واحدة للتعامل مع مختلف الأنواع: إضافة وطرح رقم الكائن المطلوب بدلاً من الإزاحة الفعلية بوحدات البايت. (مع ذلك مؤشر char، يُعرف char بأنه الحصول دائما على حجم بقيمة 1 بايت، يسمح بإزاحة الكائن من المؤشر الحسابي إلى الممارسة ليتساوى مع إزاحة البايت الواحد) على وجه الخصوص، يوضح تعريف لغة Cصراحةً أن الصيغة a[n] حيث أن n-th كائن في المصفوفة a، تكافئ *(a+n) وهو محتوى الكائن المشار إليه بواسطة a+n. يعني هذا أن n[a] يتساوى مع n[a] ويمكن كتابة مثلاً a[3] أو [a]3 سيلج كلاهما إلى الكائن الرابع من المصفوفة A.
بينما يمكن للمؤشر الحسابي أن يكون مصدر bugs الحاسب الآلي. فإنه يميل إلى إرباك المبرمجين المبتدئين، مما يضطرهم إلى سياقات مختلفة: يمكن أن يكون تعبير حسابي عادي أو أن يكون تعبير مؤشر حسابي، وأحياناً من السهل عمل خطأ في أحدهما للآخر. واستجابة لهذا، العديد من لغات الحاسب الآلي الحديثة المتقدمة (على سبيل المثال Java) لا تسمح بالولوج المباشر إلى الذاكرة باستخدام العنوان. كذلك، تتناول لهجة لغة C الآمنة Cyclone العديد من الموضوعات المتعلقة بالمؤشرات. راجع لغة البرمجة C للمزيد من الانتقادات.
مؤشر void أو void* يُدعمه ANSI لغة C ولغة C++ كنوع مؤشر عام. مؤشر void يمكنه تخزين عنوان لأي نوع بيانات وفي لغة C يتحول ضمنياً إلى أي نوع آخر من المؤشرات أثناء المهمة، ويجب أن يلقى صراحة إذا كان تتبع المؤشر ضمني. K&amp;R تستخدم لغة C char* لغرض "المؤشر agnostic" (قبل ANSI C).
int x = 4;
void* q = &amp;x;
int* p = q; /* void* implicitly converted to int*: valid C, but not C++ */
int i = *p;
int j = *(int*)q; /* when dereferencing inline, there is no implicit conversion */
لا تسمح لغة C++ بالتحويل الضمني لـ void* إلى نوع آخر من المؤشرات، حتى أثناء المهمات. كان هذا قرار في التصميم لتجنب الإهمال وحتى الاشكال غير المرغوبة، مع ذلك معظم المجمعين يستخرجون التحذيرات فقط وليس الأخطاء عند مواجهة إلقاءات أخرى سيئة.
// int* p = q; This fails in C++: there is no implicit conversion from void*
int* a = (int*)q; // C-style cast
int* b = static_cast&lt;int*&gt;(q); // C++ cast
في لغة C++، لا يوجد void&amp; (مرجع لـ void) لاستكمال void*، لأن المراجع تتصرف مثل الأسماء المستعارة للمتغيرات التي تشير إليها، ولا يمكن وجود متغير من نوع void.
لغة C#.
في لغة برمجة C#، تُدعم للمؤشرات تحت شروط معينة: أي كتلة من الكود المتضمنة المؤشرات لابد من الإشارة عليها بعلامة غير آمن. تتطلب مثل هذه الكتل أذونا أمان أعلى من المسموح بها لتشغيلها. الصيغة هي نفسها الموجودة في لغة C++ والعنوان المشار إليه يمكن أن يكون إما ذاكرة متحكم بها أو غير متحكم بها. مع ذلك، مؤشرات الذاكرة المتحكم بها (أي مؤشر لكائن متحكم به) يجب الإعلان عنها باستخدام كلمة أساسية ثابتة، والتي تمنع garbage collector من تحريك الكائن المشار إليه كجزء من التحكم بالذاكرة بينما يكون المؤشر في النطاق وهذا يحافظ على صلاحية العنوان.
استثناء هذا من استخدام بنية IntPtr وهو تحكم آمن يتساوى مع int* ولا يتطلب كود عدم الأمان. يستعاد هذا النوع غالباً عند استخدام طرق من النظام. Runtime.InteropServices على سبيل المثال:
// Get 16 bytes of memory from the process's unmanaged memory
IntPtr pointer = System.Runtime.InteropServices.Marshal.AllocHGlobal(16);
// Do something with the allocated memory
لغة COBOL.
لغة البرمجة COBOL تدعم المؤشرات إلى المتغيرات. عناصر البيانات الولية أو المجمعة (المسجلة) والمعلنة في LINKAGE SECTION من البرنامج التي تقوم طبيعياً على المؤشر مع وجود مساحة لعنوان كائن البيانات (عادة ما تكون كلمة واحدة للذاكرة) مخصصة مثل بند البيانات الحقيقي (ضمني خفي). في كود مصدر البرنامج، تستخدم هذه المتغيرات مثل أي متغير تخزيني آخر لكن محتوياتهم يولج إليها ضمنيا بطرقة غير مباشرة من خلال مؤشراتهم.
مساحة الذاكرة لكل كائن بيانات مشار إليه يقسم ديناميكياً عادةً باستخدام بيانات الاتصال الخارجي أو عن طريق بناء اللغة الموسع المتكامل مثل بيانات EXEC CICS أو EXEC CICS.
كما تقدم الإصدارات الممتدة من COBOL متغيرات المؤشر المعلن عنه في شروط استخدام المؤشر. فيم مثل هذه المؤشرات تحددت وعدلت باستخدام بيانات SET و SET ADDRESS.
كما تقدم بعض الإصدارات الممتدة من لغة COBOL متغيرات PROCEDURE-POINTER القادرة على تخزين عنوان الكود القابل للتنفيذ.
لغة D.
لغة البرمجة D مشتقة من لغة C ولغة C++ وهي تؤيد مؤشرات C وتحويل نوع المتغير typecasting C تأييداً كاملاً.
لغة Eiffel.
تدعم اللغة الوجهة Eiffel المؤشرات في شكل المراجع، التي تكتب ولا تسمح بأي شكل من أشكال المؤشر الحسابي. معيار ECMA من لغة Eiffel يتضمن آلية "النوع المرفق" التي تدَّعي ضمان سلامة void.
لغة Fortran.
توضح لغة Fortran-90 قدرة المؤشر الكتابي القوية. تحتوي مؤشرات Fortran على أكثر من مجرد عنوان ذاكرة بسيط. كما تنطوي على الحدود العليا والدنيا من أبعاد المصفوفة، الخطوات (على سبيل المثال لدعم أقسام المصفوفة التعسفية)، وغيرها من البيانات الوصفية. المشغل المنتسب، =&gt; يستخدم لينسب المؤشر إلى متغير له صفة الهدف. بيانات تخصيص لغة Fortran-90 يمكن استخدامها أيضا لنسب المؤشر إلى كتلة من الذاكرة. على سبيل المثال، يمكن استخدام الكود التالي لتعريف وتكوين هيكل قائمة مرتبطة:
type real_list_t
real :: sample_data(100)
type (real_list_t), pointer :: next =&gt; null ()
end type
type (real_list_t), target :: my_real_list
type (real_list_t), pointer :: real_list_temp
real_list_temp =&gt; my_real_list
read (1,iostat=ioerr) real_list_temp%sample_data
if (ioerr /= 0) exit
allocate (real_list_temp%next)
real_list_temp =&gt; real_list_temp%next
end do
تضيف لغة Fortran-2003 دعم للمؤشرات الإجرائية. كذلك، كجزء من ميزة التشغيل المتداخل في لغة C تدعم لغة Fortran-2003 الوظائف الجوهرية لتحويل أنواع مؤشرات C إلى مؤشرات Fortran وإعادتها.
لغة Go.
تحتوي لغة Go على مؤشرات. تتماثل صيغتها المعلنة مع مؤشرات لغة C، ولكن تكتب بالعكس، منتهية بالنوع. على عكس لغة C، لدى Go garbage collection ولا تسمح بالمؤشر الحسابي. لا يمكن تعريف أنواع المرجع مثل لغة C++ لكن يتم تمرير بعض الأنواع الضمنية عن طريق المرجع؛ يجب أن تتكون تلك بجعل الكلمة الأساسية بدلاً من الجديدة. كطريقة مختلفة (عن أنواع المرجع) لتوحيد الصيغة بين المؤشر وغير المؤشر، انخفض مشغل السهم (-&gt;)والمجمع يعرف فقط أن المبرمج يعني تتبع المؤشر باستخدام مشغل النقطة (.) (بينما على لغة C ولغة C++ سيكون هذا خطأ كامل).
لغة Modula-2.
يتم تطبيق المؤشرات كثيرا كما في Pascal، كذلك باراميترات VAR في الإجراءات يطلق عليها Modula-2 وهي أقوى كتابياً من Pascal،، مع عدد قليل من الطرق للهروب من نظام الكتابة. بعض المتغيرات في لغة Modula-2 (مثل Modula-3) تحتوي على garbage collection.
لغة Oberon.
كثيراً ما تتوافر المؤشرات مع Modula-2. ما زال هناك القليل من الطرق للتهرب من النظام الكتابي وبذلك تكون لغة Oberon ومتغيراتها ما زالت آمنه فيما يتعلق بالمؤشرات أكثر من لغة Modula-2 ومتغيراتها. كما في Modula-3 تمثل garbage collection جزء من مواصفات اللغة.
لغة Pascal.
على النقيض من العديد من اللغات التي تميز المؤشرات فإن معيار ISO Pascal يسمح فقط للمؤشرات بالإشارة إلى المؤشرات المكتوبة ديناميكياً والغير معروفة ولا يسمح لهم بالإشارة إلى المعيار الثابت أو المتغيرات المحلية. لا يوجد بها مؤشر حسابي. يجب أن تحتوي المؤشرات أيضاً على نوع مترابط والمؤشر من نوع ما لا يتفق مع المؤشر من نوع آخر (مثل مؤشر char لا يتفق مع مؤشر العدد الصحيح). يساعد هذا على القضاء على القضايا الأمنية المتأصلة تطبيقات المؤشر الآخر، تستخدم هذه خاصة للغة PL/I أو للغة C. كما أنها تزيل بعض المخاطر التي يسببها المؤشر المتدلي، ولكن القدرة على السماح الديناميكي للمساحة المتبعة باستخدام عملية معيار التصرف (الذي له نفس تأثير مثل وظيفة المكتبة الحرة الموجودة في اللغة C) مما يعني أن خطورة مؤشرات التدلي لم يتم القضاء عليها كلياً.
مع ذلك في بعض المصادر التجارية والمفتوحة للغة Pascal (أو مشتقاتها) يسمح بتطبيقات مثل Free Pascal أو Turbo Pascal أو Object Pascal في Embarcadero Delphi – يسمح للمؤشر بالإشارة إلى المعيار الثابت أو المتغيرات المحلية ويمكن الإلقاء من نوع من المؤشرات إلى آخر. علاوة على ذلك، المؤشر الحسابي غير مقيد: الإضافة أو الطرح من المؤشر يحركه بمقدار هذا الرقم من وحدات البايت في كلا الاتجاهين، لكن استخدام إجراءات معيار Inc أو dec معه يحرك المؤشر بحجم نوع البيانات المصرح للإشارة إليه.
لغة البرمجة Perl.
تدعم لغة برمجة Perl المؤشرات، على الرغم من ندرة استخدامها، في شكل وظائف من الحزم والتفريغ. تهدف هذه للتفاعلات البسيطة فقط مع مكتبات OS المجمعة. في جميع الحالات الأخرى، تستخدم لغة Perl المراجع المكتوبة والتي لا تسمح بوجود أي شكل من أشكال المؤشر الحسابي. فهي تستخدم لبناء تراكيب البيانات المعقدة.
آر بي جي RPG هي لغة برمجة عالية المستوى للتطبيقات الخاصة بالأعمال. الأحرف الأولى التي تصف اسم البرنامج ترمز إلى المعنى " مولد برنامج التقرير". وشركة IBM هي صانعة البرنامج والبائع الرئيسي له، ولكن اللغة متاحة أيضا من مصنعي أجهزة كمبيوتر رئيسية أخرى وأجهزة الكمبيوتر الضخمة ومنهم يونيسيس Unisys. النسخة الأخيرة من آر بي جي هي آر بي جي 4 RPG IV (وتعرف ب ILE RPG) وهي على خوادم باور آي الخاصة بIBM، وهي ترث النظام آي من سمات بيئة اللغة المتكاملة مثل وظائف النماذج الأصلية وإجراءاتها والروابط الديناميكية والثابتة والوصول إلى مكتبات لغة سي الروتينية، ومكاتب الرابط الديناميكي والشفرة الوحدوية المتكررة أو المعاد إدخالها.
تعرف لغة آر بي جي (التي تعرف أيضا باسم آر بي جي فور وRPGLE) بأنها لغة برمجة مألوفة لمنصة IBM Power i. وقد صنعت خصيصا كأداة لكتابة التقارير لIBM401 في بداية الستينات، وقد تطورت آر بي جي منذ هذا الوقت إلى لغة HLL مكافئة هي كوبول وبي إل آي