مؤشر (برمجة): الفرق بين النسختين

[نسخة منشورة][مراجعة غير مفحوصة]
تم حذف المحتوى تمت إضافة المحتوى
JarBot (نقاش | مساهمات)
ط بوت:التعريب V3.5
لا ملخص تعديل
وسوم: تحرير من المحمول تعديل في تطبيق الأجهزة المحمولة تعديل بتطبيق أندرويد
سطر 1:
{{مصدر|تاريخ=ديسمبر 2018}}
{{وضح|3=مؤشر (توضيح)}}
{{دمج|مؤشر (لغات البرمجةبرمجة)}}
[[File:Pointers.svg|thumb|<!-- Pointer ''''a'''' pointing to the memory address associated with variable ''''b''''.<ref>[https://books.google.com/books?id=JTYPKxug49IC&pg=PA204&lpg=PA204&dq=Harold+Lawson+pointer&source=web&ots=C5QdVz2xM8&sig=xhh0SWuR-L72H6H9xgEmxD5qzBc&hl=en&ei=lCuLSbTwKY_-0AWErp2iBw&sa=X&oi=book_result&resnum=10&ct=result Milestones in Computer Science and Information Technology] {{Webarchive|url=http://web.archive.org/web/20140629080820/http://books.google.com/books?id=JTYPKxug49IC&pg=PA204&lpg=PA204&dq=Harold+Lawson+pointer&source=web&ots=C5QdVz2xM8&sig=xhh0SWuR-L72H6H9xgEmxD5qzBc&hl=en&ei=lCuLSbTwKY_-0AWErp2iBw&sa=X&oi=book_result&resnum=10&ct=result |date=29 يونيو 2014}}</ref><ref>{{cite journal|author=[[دونالد كانوث]] |title=Structured Programming with go to Statements |journal=Computing Surveys |volume=6 |issue=5 |year=1974 |url=http://pplab.snu.ac.kr/courses/adv_pl05/papers/p261-knuth.pdf |pages=261–301 |doi=10.1145/356635.356640 |deadurl=yes |archiveurl=https://web.archive.org/web/20090824073244/http://pplab.snu.ac.kr/courses/adv_pl05/papers/p261-knuth.pdf |archivedate=August 24, 2009 }}</ref><ref>{{cite book |title=ANSI and ISO Standard C Programmer's Reference | last=Plauger |first=P J |authorlink=P. J. Plauger |author2=Brodie, Jim |year=1992 |publisher=Microsoft Press|location=Redmond, WA |isbn=1-55615-359-7 |pages=108, 51 |quote=An array type does not contain additional holes because all other types pack tightly when composed into arrays ''[at page 51]''}}</ref> Note that in this particular diagram, the computing architecture uses the same [[address space]] and [[#Formal_description|data primitive]] for both pointers and non-pointers; this need not be the case -->]]
[[File:Pointers.svg|thumb|<!-- Pointer ''''a'''' pointing to the memory address associated with variable ''''b''''. Note that in this particular diagram, the computing architecture uses the same [[address space]] and [[#Formal_description|data primitive]] for both pointers and non-pointers; this need not be the case -->]]
'''المؤشر''' {{إنج|Pointer}} في [[حوسبة|الحوسبة]] أو علوم الحاسوب، هو نوع من أنواع البيانات في بعض [[لغة برمجة|لغات البرمجة]] تمثل قيمته (أو تشير إلى) قيمة أخرى مخزنة في مكان آخر في ذاكرة [[حاسوب|الحاسوب]]، وذلك باستخدام عنوان الذاكرة لها.
'''المؤشر {{إنج|Pointer }}''' في [[لغة البرمجة]] ([[الحوسبة]] وهو مصطلح عادة ما يُطلق على فعالية استخدام برامج [[الحاسب الآلي]] وأجهزته ومراحل تطويرها)
عملية الحصول على القيمة التي يشير إليها المؤشر تسمى تتبع المؤشر dereferencing. يعتبر المؤشر تطبيق بسيط لنوع البيانات العام المرجع برغم أنه مختلف عن الوسيلة المسماة مرجع reference في لغة [[سي++]].
تفيد المؤشرات إلى البيانات في تحسين الأداء للعمليات المتكررة مثل تمرير [[سلسلة حرفية|السلاسل الحرفية]] و[[بنية|تراكيب]] (بنيات) [[شجرة بيانات|الأشجار]]. وتستخدم المؤشرات للدوال في ربط الوسائل methods في [[برمجة كائنية التوجه|البرمجة كائنية التوجه]] والربط عند وقت التشغيل بمكتبات الربط الديناميكية التي يرمز لها بـ DLL.
 
في حين أن المؤشرات قد استخدمت لتمثل المراجع عموماً إلا أنها تنطبق بشكل أكثر ملاءمة على تراكيب البيانات التي تسمح واجهتها بوضوح للمؤشر أن يعالج بوصفه عنوان ذاكرة. ولأن المؤشرات تسمح بالوصول الغير محمي بشكل واسع لعناوين [[الذاكرة|ذاكرة]] فإن هناك بعض الخطورة المصاحبة لاستخدامها.
يُشير المؤشر إلى عنوان الذاكرة المرتبط [[متغير (علم الحاسوب)|بالمتغير]] "b". يُمكن ملاحظة أن في هذا المخطط التفصيلي، تُستخدم بنية الحوسبة نفس مساحة العنوان والبيانات الأولية لكل من المؤشرات وغير المؤشرات، بيد انه هذه ليست هي القضية المُراد التطلع إليها.
يُعد المؤشر، في علوم الحاسب الآلي، هو أحد أنواع بيانات لغة البرمجة والذي ترجع قيمته بشكل مباشر إلى (أو "تُشير إلى") قيمة أخرى مُخزنة في مكان آخر في ذاكرة الحاسب الآلي مُستخدمة عنوانها. تحتل المؤشرات في [[لغات البرمجة]] عالية المستوى بشكلٍ فعال محل سجلات الأغراض العامة في [[لغات البرمجة]] ذات المستويات المتدنية مثل لغة التجميع والأكواد، بيد أنها قد تتواجد داخل الذاكرة المتوفرة.
مراجع المؤشر هي عبارة عن مكان في الذاكرة، ويُطلق على عملية الحصول على القيمة التي يُشير إليه المؤشر بـعملية تتبع المؤشر dereferencing. يُعتبر المؤشر تطبيقاً بسيطاً أقل إيجازاً لنوع بيانات المرجع الأكثر إيجازاً. تدعم مختلف لغات البرمجة بعضاً من أنواع المؤشرات، على الرغم من احتواء البعض منها على المزيد من القيود في استخدامها عن غيرها.
تُحسن المؤشرات إلى البيانات بشكل ملحوظ من أداء العمليات المتكررة مثل تمرير الحرفية وجداول البحث وجداول الرقابة وتراكيب (بنيات) الأشجار. تُعد المؤشرات في أغلب الأحيان وبشكل خاص أكثر توفيراً للوقت والمساحة وذلك خلال إجراء عمليات النسج وتتبع المؤشرات من ما هو عليه الحال عند إجراء عملية نسخ البيانات والولوج إليها إلى ما تُشير إليه المؤشرات.
تُستخدم المؤشرات أيضاً للاحتفاظ بعناوين نقاط الدخول لما يُطلق عليه الروتين الفرعي في البرمجة الإجرائية ولربط وقت التشغيل بمكتبات الربط الديناميكية التي يُرمز لها بالرمز (DLLS). تُستخدم المؤشرات إلى الوظائف في [[البرمجة كائنية التوجه]] (أو البرمجة غرضية التوجه) في ربط الوسائل، وغالباً ما يُستخدم ما يُطلق عليه اسم جداول الوسائل العملية virtual method tables.
.
في حين أن المؤشرات قد استخدمت لتمثل المراجع عموماً إلا أنها تنطبق بشكل أكثر ملاءمة على تراكيب البيانات التي تسمح لجهتها بوضوح للمؤشر بالمعالجة (بشكل حسابي عن طريق حساب المؤشر) بوصفه عنوان ذاكرة، وعلى النقيض منcookie أو الإمكانية capability حيث لا يستحيل ذلك. نظراً لإتاحة المؤشر لكل من الوصول الآمن والغير الآمن إلى عناوين الذاكرة، فان هناك بعض المخاطر المصاحبة لاستخدامها في الحالة الأخيرة بشكل خاص.
 
== المؤشرات في تراكيب البيانات ==
== تعريفات أساسية ==
عند القيام بإعداد تراكيب البيانات مثل [[قوائم|القوائم]] والأشجار، فإنه من الضروري استخدام المؤشرات للمساعدة في الطريقة التي تتم بها معالجة البيانات والتحكم بها.
المؤشر
(المؤشر)في [[علوم الحاسب|علوم الحاسبالآلي]] :هو أحد أنماط المرجع.
البيانات الأولية (أو الأولية فحسب) : هي أي وحدات بيانات يُمكن قراءتها أو كتابتها لذاكرة الحاسب الآلي باستخدام ولوج واحد للذاكرة (على سبيل المثال، كلاًّ من البايت والكلمة كلاهما من الأوليات).
تجميع البيانات (أو التجميع فحسب) هي عبارة عن مجموعة من الأوليات التي نُسقت بشكل منطقي في الذاكرة والتي تُعرض مُجمَّعة كوحدة بيانات واحدة (على سبيل المثال، يُمكن أن يتكون التجميع من ثلاثة من وحدات [[بايت|البايت]] مُنسقة منطقيًّا، القيم التي توضح الثلاث إحداثيات للإشارة في المساحة)؛ عندما يتألف التجميع كلياً من نفس النوع من الأوليات، يُمكن تسمية التجميع بـالمصفوفة array؛ بمعنى أن الكلمة الأولية ذات وحدات البايت المتعددة تُعد مصفوفة من وحدات البايت، وتستخدم بعض البرامج الكلمات بهذه الطريقة.
في سياق هذه التعريفات، يُعد البايت أصغر قيمة أولية؛ يُحدد كل عنوان ذاكرة بوحدة بايت مختلفة. يعتبر عنوان الذاكرة أول وحدة من وحدات البايت هو عنوان الذاكرة (أو عنوان الذاكرة الأساسي) لوحدات البايت بالكامل.
مؤشر الذاكرة (أو المؤشر فحسب) هو أحد الأوليات، القيمة ما يُراد استخدامه كعنوان ذاكرة؛ يُقال أن المؤشر يُمثل عنوان الذاكرة. كما يُقال أن المؤشر يُشير إلى وحدات البايت [في الذاكرة] عندما تكون قيمة المؤشر هي وحدات البايت الخاصة بعنوان الذاكرة.
يُعرف المؤشر بشكل عام على انه أحد أنواع المراجع، ويُقال أن مراجع المؤشر تُخزن وحدات البايت في مكان ما في الذاكرة؛ ويجب للحصول على وحدات البايت هذه إتباع عملية تتبع المؤشر. وتعتبر الصفة التي تُميز المؤشرات عن أنواع المراجع الأخرى هي أن قيمة المؤشر يُمكن تفسيرها كعنوان الذاكرة، ويعتبر ذلك مفهوم "مُتدني المستوى".
تخدم المراجع كأحد مستويات الإجراءات غير المباشرة: تُحدد قيمة المؤشر أي من عناوين للذاكرة (أي من المعطيات) التي سوف تُستخدم في العمليات الحسابية. حيث تُمثل الإجراءات غير المباشرة جانباً جوهرياً من الخوارزميات، وغالباً ما يُعبر عن المؤشرات كأحد أنواع البيانات الأساسي في لغات البرمجة؛ في لغات البرمجة المُصنفة بشكلٍ ثابت (أو بشكلٍ قوي)، يُحدد نوع المؤشر نوع وحدات البايت إلى التي يُشير إليها المؤشر.
 
== الاستخدامات ==
== الجمل المُقتبسة ==
إن المؤشرات مدعومة مباشرة ودون قيود في لغات مثل [[سي]]، [[سي++]]، [[باسكال]] ومعظم لغات التجميع. وهي تستخدم أساساً في بناء المراجع والتي تتسع بدورها تقريباً لبناء كل تراكيب البيانات وأيضا في تمرير البيانات بين الأجزاء المختلفة من البرنامج.
{{اقتباس|أنا بالفعل أضع في اعتباري أن البيانات المهمة ومتغيرات المؤشر تدخل ضمن أكثر كنوز المعرفة القيمة ل[[علوم الحاسب]] الآلي."
دونلد كنوث Donald Knuth (مدرس فخري [[استانفورد|باستانفورد]] في فن برمجة الحاسب الآلي)، البرمجة الهيكلية مع الانتقال إلى البيانات.<ref>{{cite journal
| المؤلف = [[دونالد كانوث]]
| العنوان = Structured Programming with go to Statements
| journal = Computing Surveys
| volume = 6
| issue = 4
| السنة = 1974
| المسار = http://pplab.snu.ac.kr/courses/adv_pl05/papers/p261-knuth.pdf
| الصفحات = 261–301
| doi = 10.1145/356635.356640
}}</ref>}}
 
في لغات البرمجة المعتمدة على الدوال والتي تستند بشكل كبير إلى القوائم؛ يتم التحكم بالمؤشرات والمراجع من اللغة باستخدام التركيبات الداخلية مثل cons.
== استخدامها في تراكيب البيانات ==
يجب توافر مؤشرات للمساعدة في إدارة كيفية تنفيذ التراكيب والتحكم بها عند إعداد تراكيب البيانات مثل القوائم، والصفوف، والأشجار. تُعد مؤشرات البداية ومؤشرات النهاية ومؤشرات التكدس من أمثلة المؤشرات النموذجية. يُمكن لهذه المؤشرات أن تكون إما مطلقة absolute (العنوان المادي الفعلي أو العنوان الواقعي في الذاكرة الواقعية) أو النسبية relative (إزاحة من عنوان البداية المطلق ("أساس") التي تستخدم فعلياً عدد أقل من وحدات البايت عنه من العنوان الكامل، ولكن عادة ما يتطلب ذلك عملية حسابية إضافية واحدة للوصول إلى الحل).
 
عند التعامل مع [[مصفوفة|المصفوفات]]، فإن عملية البحث الحيوي تشتمل على مرحلة تسمى "حساب العنوان" والتي تشمل بناء مؤشر إلى عنصر البيانات المرغوب في المصفوفة. وفي تراكيب البيانات الأخرى مثل القوائم المرتبطة تستخدم المؤشرات كمراجع لتربط قطعة معينة من الكود بأخرى.
يُمكن استخدام معادلين من وحدات البايت، يحتوي على 16 بايت، أعداد صحيحة، لتقديم معالجة نسبية لأكثر من 64 كيلو بايت من تراكيب البيانات. يُمكن أن يمتد ذلك إلى 128 كيلو بايت، أو 256 كيلو بايت، أو 512 كيلو بايت فإذا كان العنوان المُشار إليه لابد وأن يكون عند حد نصف كلمة، أو كلمة أو كلمة مزدوجة (لكن تتطلب عملية "تحويل يسار shift left " إضافية عملية بتwise – من خلال 1 أو 2 أو 3 بايت – وذلك من أجل ضبط المُعادل من خلال العامل المكون من 2 أو 3 أو 4 بايت وذلك قبل إضافته إلى العنوان الأساسي). يُفضل بوجه عام، على الرغم من احتواء مثل هذه الأنظمة على الكثير من المشكلات، وكذلك من اجل التيسير على المُبرمج، توافر مساحة العنوان المحددة.
 
تستخدم المؤشرات في تمرير المعاملات باستخدام مراجع لها، ويكون هذا مفيداً إذا أردنا أن يكون تعديل الدالة للمعامل مرئياً للجزء الذي قام باستدعائها. وهذا مفيد أيضا في إرجاع عدة قيم من دالة.
يُمكن استخدام معادل بايت واحد، مثل قيمة ASCII العشرية للرموز (مثل X"29") للإشارة إلى قيمة صحيحة بديلة (أو مؤشر) في مصفوفة (مثل X"01"). يُمكن بهذه الطريقة أن تترجم الرموز على نحو كاف من "البيانات الأولية" إلى مؤشر متسلسل قابل للاستخدام ومن ثم إلى عنوان مطلق من دون جدول البحث.
 
== استخدامهاالمؤشرات في جداوللغة التحكمسي ==
عادة ما تزيد جداول التحكم المُستخدمة في التحكم في تدفق البرنامج من استخدام المؤشرات. عادة ما تكون المؤشرات جزءاً لا يتجزأ من مدخل الجدول، كما انه يُمكن أن تُستخدم على سبيل المثال للإبقاء على نقاط الإدخال لإتمام عملية تنفيذ الروتين الفرعي، معتمدة في ذلك على عدة حالات محددة مُعرَّفة في مدخل الجدول ذاته. يُمكن فهرست المؤشرات ببساطة إلى أخرى منفصلة، لكن مرتبطة، تشكل الجداول مصفوفة من العناوين الفعلية أو العناوين نفسها (اعتماداً على بنيات وتراكيب [[لغة البرمجة]] المتوفرة). يُمكن كذلك استخدامها للإشارة (إلى الخلف) إلى مداخل الجدول السابقة (كما في حلقة المعالجة) أو إلى الإمام لتخطي بعض مداخل الجدول (كما في التحويل switch
 
أو الخروج "المبكر" من الحلقة). نظراً لهذا الغرض الأخير، يُمكن أن يُصبح "المؤشر" ببساطة رقم مدخل الجدول نفسه ويُمكن أن يتحول إلى عنوان فعلي من خلال عملية حسابية بسيطة.
 
== أصول المعمارية ==
المؤشرات هي عبارة عن فكرة تجريدية صغيرة جدا تحتل قمة إمكانيات المعالجة أو العنونة المُدعمة من قبل معظم المعماريات الحديثة. يُخصص أحد العناوين أو أحد المؤشرات الرقمية في أبسط المخططات لكل وحدة من وحدات الذاكرة في النظام، حيث تكون الوحدات إما البايت أو الكلمة، تُحول الذاكرة ككل بشكل فعال إلى [[مصفوفة]] كبيرة جداً. ومن ثم، إذا توفر لدينا العنوان، فسوف يُوفر النظام عملية لاستعادة القيمة المخزنة في وحدة الذاكرة في هذا العنوان (عادة ما تُستخدم أجهزة مسجلات الأغراض العامة).
 
عادة ما يكون المؤشر كبير بدرجة كافية لاحتواء المزيد من العناوين أكثر من وحدات الذاكرة الموجودة في النظام. يُقدم ذلك احتمالية محاولة البرنامج من الولوج إلى أحد العناوين الذي لا يتطابق مع أي من وحدات الذاكرة، ويرجع ذلك إما لعدم تثبيت مساحة كافية من الذاكرة (على سبيل المثال تخطي مدى الذاكرة المتوفرة) أو لعدم دعم المعمارية لمثل هذه العناوين. يُمكن أن يُطلق على الحالة الأولى، في بعض البرامج مثل معمارية أنتل x86، اسم خطأ التجزئة أو التخصيص segmentation fault (عادة ما تُختصر ب segfault). الحالة الثانية ممكنة في عمليات التنفيذ الحالية لـ AMD64، بحيث يصل طول المؤشرات إلى 64 بت ويصل امتداد العناوين إلى 48 بت فقط. هناك، يجب أن تتفق المؤشرات مع قواعد محددة (العناوين المُتعارف عليها canonical addresses)، لذا فانه في حالة تتبع المؤشر غير المُتعارف عليها، يظهر المعالج خطأ حماية عام.
 
على الصعيد الآخر، تحتوي بعض الأنظمة على المزيد من وحدات الذاكرة أكثر من ما تحتويه من عناوين. في هذه الحالة، يعمل نظام أكثر تعقيداً مثل أنظمة تخصيص أو تقطيع الذاكرة memory segmentation أو الصفحات المخزنة paging المُوظفة لاستخدام أجزاء مختلفة من الذاكرة في أوقات مختلفة. تدعم الأمثلة الأخيرة للمعمارية x86 إلى 36 بت من عناوين الذاكرة الفيزيائية، والتي نُظمت لمساحة العنوان الخطي 32 بت من خلال أجهزة الصفحات المخزنة أو التصفح PAE. لذا، يُمكن فقط الولوج إلى 1\16 من الذاكرة الكلية المتاحة في المرة الواحدة. ومثال آخر في نفس عائلة جهاز الحاسب الآلي كان وضع الحماية الـ 16 بايت من المعالج 80286، الذي يمكنه، على الرغم من دعم 16 ميجا بايت فقط من الذاكرة الفيزيائية، الولوج إلى 1جيجا بايت من الذاكرة التخيلية، ولكن مزيج من عنوان الـ 16 بيت والسجلات المجزأة جعلت ولوج أكثر من 64 كيلو بايت في ثقل بنية بيانات واحدة. قد تُصبح بعض قيود المؤشر الحسابي ANSI مناسبة لنماذج الذاكرة المجزأة لعائلة هذا المعالج.
 
دعمت بعض معماريات ذاكرة التخزين المُستخدمة في عمليات الإدخال والإخراج (memory-mapped I/O) والتي تُمكن بعض العناوين من الإشارة إلى وحدات من الذاكرة في حين تُشير أُخرى إلى مسجلات جهاز خاصة بأجهزة أخرى داخل الحاسب الآلي وذلك لتوفير واجهة متناسقة. تظهر بعض المفاهيم المشابهة مثل إزاحة الملف ومؤشرات المصفوفة ومراجع الكائن البعيد التي تخدم بعض من الأغراض المماثلة مثل العناوين لأنواع أخرى من الكائنات.
 
== الاستخدامات ==
تُدعم المؤشرات بشكل مباشر بدون وجود قيود في لغات برمجة مثل PL/I وC وC++ وPascal وأغلبية لغات التجميع. كما أنها تُستخدم بشكل أساس لتراكيب المراجع، والتي بدورها خطوة أساسية لبناء كل تراكيب البيانات تقريباً، تماماً كما يحدث في عملية تمرير البيانات بين الأجزاء المختلفة من البرنامج.
 
في اللغات البرمجة الوظيفية التي كثيراً ما تعتمد على القوائم، يتم التحكم بالمؤشرات والمراجع بشكل نظري من خلال اللغة باستخدام التراكيب الداخلية مثل cons.
 
عند التعامل مع [[المصفوفات]]، عادة ما تنطوي عملية البحث الحيوي على مرحلة تُدعى "حساب العنوان address calculation " والتي تتضمن بناء مؤشر كائن البيانات المطلوبة في المصفوفة. إذا كانت عناصر البيانات في المصفوفة لها الأطوال المخصصة من خلال طاقات ثنائية، عادة ما تكون هذه العمليات الحسابية أكثر كفاءة. كثيراً ما تستخدم البطانة أو الحشو Padding كآلية لضمان أن هذه هي الحالة المطلوبة، على الرغم من زيادة متطلبات الذاكرة. في تراكيب البيانات الأخرى، مثل القوائم المرتبطة، تستخدم المؤشرات كمراجع لربط أحد أجزاء التراكيب بالآخر.
 
تستخدم المؤشرات لتمرير المعاملات باستخدام مراجع لها. ويكون هذا مفيداً إذا أراد المبرمج أن يكون تعديل الدالة للمعامل مرئيا للجزء الذي قام باستدعائها. ويُفيد ذلك أيضا في استرجاع العديد من القيم من الدالة.
يُمكن استخدام المؤشرات أيضاً الذاكرة المخصصة وغير المخصصة للمتغيرات الديناميكية والمصفوفات داخل الذاكرة. في أغلب الأحيان ما يتحول المتغير إلى كائن زائد عن الحاجة بعد تحقيق الغرض منه، فإن الإبقاء عليه إهداراً للذاكرة، ولذا فمن الأفضل عدم تخصيصه أو توزيعه (مستخدماً مرجع المؤشر الأصلي) عندما انتهاء الحاجة إليه. قد يؤدي عدم القيام بهذه الخطوة إلى تسرب الذاكرة memory leak (حيث تقل مساحة الذاكرة الفارغة بشكل تدريجي، أو في الحالات الخطير بشكل سريعً، ويرجع ذلك إلى تراكم أعداد كبير من قوالب الذاكرة).
 
=== المؤشر في لغة السي "C " ===
الصيغة الأساسية للإعلان عن مؤشر هي:
<source lang="C">int *money; </source>
حيث يقوم هذا بالإعلان عن <code>money</code> كمؤشر إلى عدد صحيح.
 
يقوم هذا بالإشارة إلى القيمة " money" كمؤشر إلى عدد صحيح. حيثوحيث أن محتويات الذاكرة لا تضمنيضمن ما هي القيمة المحتملالتي من الممكن أن تحتويها في لغة السيالسي، فيجب لذاتوخي يجبالحذر الحرص على التأكدللتأكد من أن العنوان الذي يُشيريشير إليه " <code>money"</code> انههو عنوان صحيح ومناسب.صالح، ولهذا السببيرى يُقترح في بعض الأحيانالبعض استهلال المؤشر بالقيمة NULL (مع ذلك، يُمكن لاستهلال المؤشرات تورية التحليل وإخفاء الأخطاء).
 
<source lang="C">int *money = NULL;</source>
عندما يتم تتبع مؤشر له القيمة NULL فحينها يحدث خطأ تشغيل ويتوقف التنفيذ عادة مع segmentation fault.
 
عند إتمام عملية تتبع أحد المؤشرات له القيمة NULL فسوف يحدث خطأ في التشغيل ويتوقف التنفيذ ويحدث ذلك عادة مع أخطاء التخصيص segmentation fault. وعقبوبعد الإعلان عن المؤشرمؤشر فإن الخطوة المنطقية التالية هي جعله يشير إلى شيء ما.
 
<source lang="C">
int a = 5;
السطر 83 ⟵ 37:
money = &a;
</source>
ويقوم هذا بإسناد عنوان الذاكرة للمتغير الصحيح a إلى قيمة المؤشر money، على سبيل المثال إذا كان المتغير a مخزن في الذاكرة عند الموقع 0x8130 فستكون قيمة money هي 0x8130 بعد الإسناد.
ولتتبع المؤشر يتم استخدام علامة النجمة * مرة أخرى:
<source lang="C">*money = 8;</source>
ويخبر هذا مترجم الكود بأن يأخذ محتويات المؤشر money والتي هي 0x8130، وينتقل إلى ذلك العنوان ويعين القيمة المخزنة به إلى 8.
بعد ذلك إذا تم الدخول إلى a فسنجد قيمته 8.
 
ربما يكون هذا المثال أكثر وضوحا إذا تم فحص الذاكرة مباشرة.
ويقوم هذا بإسناد عنوان الذاكرة للمتغير الصحيح a إلى قيمة المؤشر " money "، على سبيل المثال إذا كان المتغير a مخزن في الذاكرة عند الموقع 0x8130 فستكون قيمة" money" هي 0x8130 بعد الإسناد. ولتتبع المؤشر يتم استخدام علامة النجمة * مرة أخرى:
افترض أن a له عنوان الذاكرة 0x8130 و money له العنوان 0x8134، وافترض أيضا أن الحاسوب المستخدم هو حاسوب 32بت حيث سعة نوع البيانات int هي 32 بت. فإن الشكل التالي هو ما سيتكون في الذاكرة بعد تنفيذ الكود التالي:
 
<source lang="C">*money = 8;</source>
 
ويُشير مترجم الكود بأن يأخذ محتويات المؤشر money والتي هي 0x8130 وينتقل إلى ذلك العنوان ويعين القيمة المخزنة به إلى 8. a فسوف تتضح قيمته ب 8.
قد يتخلى هذا المثال بشكل أكثر وضوحاً ما إذا تم فحص [[الذاكرة]] بشكل مباشر. افترضاً أن a له عنوان الذاكرة 0x8130 و money له العنوان 0x8134، وافترضاً أيضا أن الحاسوب المستخدم هو حاسوب 32 بت حيث أن سعة نوع البيانات int هي 32 بت. فإن الشكل التالي هو ما سوف يظهر في الذاكرة بعد تنفيذ الكود التالي:
<source lang="C">
int a = 5;
السطر 96 ⟵ 52:
 
:{| class="wikitable"
! Address !! Contents
! العنوان !! المحتويات
|-
| '''0x8130''' || 0x00000005
السطر 103 ⟵ 59:
|}
 
المؤشر ذو القيمة NULL المعروضة هنا هو 0x00000000.
وبتعيين عنوان المتغير a للمؤشر money باستخدام مؤثر التعيين &
 
<source lang="C">
السطر 109 ⟵ 66:
</source>
 
يكونوتكون الناتجالحصيلة في الذاكرة كما يلي:
 
:{| class="wikitable"
! Address !! Contents
! العنوان !! المحتويات
|-
| '''0x8130''' || 0x00000005
السطر 119 ⟵ 75:
|}
 
وعند تتبع المؤشر money مثل:
Then by dereferencing <code>money</code> by coding
 
<source lang="C">
*money = 8;
</source>
فإن الحاسوب سيأخذ محتويات المؤشر والتي هي 0x8130 وينتقل إلى ذلك العنوان ويعين القيمة 8 إلى ذلك الموقع وتكون حصيلة الذاكرة كما يلي:
 
سيأخذ الحاسب الآلي محتويات المؤشر والتي هي 0x8130 وينتقل إلى ذلك العنوان ويعين القيمة 8 إلى ذلك الموقع ويكون الناتج في الذاكرة كما يلي:
 
:{| class="wikitable"
! Address !! Contents
! العنوان !! المحتويات
|-
| '''0x8130''' || 0x00000008
السطر 134 ⟵ 87:
| '''0x8134''' || 0x00008130
|}
 
وكما هو واضح فإن استدعاء قيمة المتغير a سوف ينتج القيمة 8 لأن التعليمة السابقة قامت بتعديل محتويات المتغير a عن طريق المؤشر money.
 
=== مصفوفات لغة السيسي C ===
الخطوة التالية في الحديث عن المؤشرات في لغة السي هي المصفوفات.
تتم فهرسة المصفوفة في لغة السي C بشكل أساسي باستخدام المؤشر الحسابي، حيث أن معايير اللغة التي تتطلب أن يكون معادل إلى *(array+i).<ref name="Plauger1992">{{مرجع كتاب |العنوان=ANSI and ISO Standard C Programmer's Reference | الأخير=Plauger |الأول=P J |وصلة المؤلف=P. J. Plauger |المؤلفين المشاركين = Brodie, Jim |origyear=1992 |الناشر=Microsoft Press|المكان=Redmond, WA |الرقم المعياري=1556153597 |الصفحات=108, 51 |quote=An array type does not contain additional holes because all other types pack tightly when composed into arrays ''[at page 51]''}}</ref> لذا يُمكن اعتبار المصفوفات كمؤشرات لمناطق متتابعة من الذاكرة (بدون أي فجوات<ref name="Plauger1992"/>)، والصيغة المُستخدمة للولوج إلى المصفوفات مماثلة لتلك التي يُمكن أن تُستخدم في عملية تتبع المؤشر، ومثال على ذلك يُمكن الإعلان عن المصفوفة array واستخدامها على النحو التالي:
في لغة سي تتم عملية فهرسة المصفوفات باستخدام حسابات المؤشرات ؛ حيث أن معايير اللغة تتطلب أن يكون
 
<source lang="C">
array[i]
</source>
مكافئ إلى
<source lang="C">
*(array + i)
</source>
وبهذا في لغة سي يمكن اعتبار المصفوفات كمؤشرات لمناطق متتابعة من الذاكرة (ليس بينها فجوات)، والصيغة المستخدمة في الوصول إلى المصفوفات مماثلة لتلك المستخدمة في تتبع المؤشرات، على سبيل المثال المصفوفة array يمكن الإعلان عنها واستخدامها كما يلي:
<source lang="C">
int array[5]; /* Declaresتعلن عن 5 contiguousأعداد (perصحيحة متتالية (Plauger Standard C 1992) integers */
int *ptr = array; /* Arraysيمكن canاستخدام beالمصفوفات used as pointersكمؤشرات */
ptr[0] = 1; /* Pointersيمكن canفهرسة beالمؤشرات indexedبصيغة with array syntaxالمصفوفات */
*(array + 1) = 2; /* Arraysيمكن canتتبع beالمصفوفات dereferencedبصيغة with pointer syntaxالمؤشرات */
*(1 + array) = 3; /* Pointer addition is commutative */
2[array] = 4; /* Subscript operator is commutative */
</source>
ويقوم هذا بحجز موقع في الذاكرة لخمسة أعداد صحيحة ويعلن عن array كمؤشر لهذا الموقع، ومن الاستخدامات الشائعة الأخرى للمؤشرات هي الإشارة [[حجز ذاكرة ديناميكيا|للذاكرة المحجوزة ديناميكيا]] باستخدام دالة [[malloc]] والتي ترجع قطعة متصلة من الذاكرة بما لا يقل عن الحجم المطلوب الذي يمكن استخدامه كمصفوفة.
 
في حين أن معظم المؤثرات على المؤشرات والمصفوفات متكافئة إلا أنه من المهم أن نذكر أن دالة sizeof سوف تختلف. في هذا المثال <code>sizeof(array)</code> سوف تكون قيمتها <code>5*sizeof(int)</code> أي أن حجم المصفوفة 5×حجم متغير العدد الصحيح، ولكن <code>sizeof(ptr)</code> تكون قيمته <code>sizeof(int*)</code> أي حجم المؤشر نفسه.
بقوم هذا بحجز مكان خاص لخمسة أعداد صحيحة ويُطلق على هذا القالب اسم المصفوفة التي تعمل كمؤشر لهذا المكان. من الاستخدامات الشائعة أيضاً للمؤشرات هي الإشارة للذاكرة المحجوزة ديناميكياً باستخدام دالة malloc التي تُعيد قالب متصل من الذاكرة بحيث لا يقل حجمه عن الحجم المطلوب الذي يُمكن استخدامه كمصفوفة.
بينما معظم المؤثرات على المصفوفات والمؤشرات متكافئة إلا أنه من المهم الإشارة إلى أن دالة sizeof سوف تكون مختلف. في هذا المثال سوف تكون قيمة (المصفوفة) sizeof يُساوي 5*sizeof (int) (حجم المصفوفة)، بينما سوف تكون قيمة sizeof (ptr) تساوي sizeof (int) أي حجم المؤشر نفسه.
يُمكن الإعلان عن القيم الافتراضية للمصفوفة مثل:
 
يمكن الإعلان عن القيم الافتراضية لمصفوفة مثل:
<source lang="C">
int array[5] = {2,4,3,1,5};
</source>
إذا فرضت أن array تقع في الذاكرة بدءً من العنوان 0x1000 على حاسوب 32 بت وترتيب البيانات به little-endian، إذاً سوف تحتوي الذاكرة ما يلي:
 
إذا افترضت أن المصفوفة array تقع في الذاكرة بدايةً من العنوان 0x1000 على جهاز الحاسب الآلي 32 بايت وترتيب البيانات داخله little-andian فسوف تحتوي الذاكرة على التالي: (كون القيم الموجودة في نظام عد السادس عشري hexadecimal، مثل تلك الموجودة في العناوين):
 
:{| class="wikitable"
|-
| || '''0''' || '''1''' || '''2''' || '''3'''
|-
| '''1000''' || 202 || 000 || 000 || 000
|-
| '''1004''' || 404 || 000 || 000 || 000
|-
| '''1008''' || 303 || 000 || 000 || 000
|-
| '''100C''' || 101 || 000 || 000 || 000
|-
| '''1010''' || 505 || 000 || 000 || 000
|}
 
ويمثل الشكل 5 أعداد صحيحة 2 و4 و3 و1 و5.
يُوضح الشكل خمسة أعداد صحيحة 1 و2 و3 و4 و5. تشغل هذه الأرقام الخمسة 32 بت (أي 4 بايت) ويًخزن كل منها البايت الأقل أهمية أولاً (وهذه هي بنية المعالجة المركزية little-endian) وتُخزن بشكل متتالي بدءً من العنوان 0x1000.
هذه الأعداد الصحيحة الخمسة تشغل 32 بت (4بايت)، وكل منها يخزن البايت الأقل أهمية أولاً، لأن بنية الحاسوب little-endian وتخزن بالتوالي بدءً من عنوان الموقع 0x1000.
الصيغة المُستخدمة في لغة السي C مع المؤشرات هي:
 
* المصفوفة array تعني 0x1000
الصيغة العامة في لغة سي مع المؤشرات هي:
* المصفوفة array +1 تعني 0x1004 (لاحظ أن معنى "+1" هو إضافة مرة واحدة عدد حجم متغير int ولا يُقصد بذلك المعني الحرفي ("+ 1")
* <code>array</code> تعني 0x1000
* المصفوفة *array تعني تتبع محتويات المصفوفة array. بمعني اعتبار هذه المحتويات كعنوان الذاكرة (0x1000) والبحث عن القيمة في هذا العنوان (0x1000).
* <code>array+1</code> تعني 0x1004، لاحظ أن +1 تعني حقيقة إضافة مرة واحدة عدد حجم متغير int أي 4 بايت وليس حرفياً +1.
* array[i] تعني القسم i من المصفوفة والذي يترجم إلى *(array + i)
* <code>*array</code> تعني تتبع محتويات array بما يعني اعتبار المحتويات كعنوان الذاكرة (0x1000) والذهاب والبحث عن القيمة في ذلك العنوان (0x1000).
يوضح المثال الأخير طريقة الولوج إلى محتويات المصفوفة. وتفتيتها:
* <code>array[i]</code> تعني القسم i من المصفوفة والذي يترجم إلى <code>*(array + i)</code>.
* Array + i هو موقع الذاكرة الخاص بعامل المصفوفة th(i+1)
* مثال :
* <code>*(array + i)</code> يأخذها عنوان الذاكرة لوصول إلى القيمة.
array[3]
على سبيل المثال: array[3] يترادف مع *(array+3) يعنى *(0x1000 +3*sizeof(int))، والذي يُعلن "تتبع القيمة المخزنة في 0x100C" في هذه الحالة تكون القيمة 0x0001.
مماثل إلى:
* (array+3)
يعني
* (0x1000 + 3*sizeof(int))
والذي يخبر المترجم بتتبع القيمة المخزنة في العنوان 0x100C والتي هي في هذه الحالة 0x0001.
 
=== القوائم المرتبطة في لغةسي السي C ===
فيما يلي مثال يوضح تعريف القوائم المرتبطة في لغة السي C.
 
فيما يلي مثال على تعريف القوائم المرتبطة في لغة سي:
<source lang="C">
/* القائمة المرتبطة الفارغة تمثل باستخدام NULL أو قيمة إشارة أخرى */
#define EMPTY_LIST NULL
#تعريف القائمة المرتبطة الفارغة
 
struct link {
void *data; /* بيانات هذا الكائنالعنصر */
void *data;
الموقع التالي *next; /* الكائن التالي؛ EMPTY_LIST قائمة فارغة إذا كان الأخير */
/* العنصر التالي؛ EMPTY_LIST إذا كان الأخير */
struct link *next;
};
</source>
 
== التمرير باستخدام مرجع ==
يُمكن ملاحظة أن تعريف المؤشر التكراري هذا هو نفسه تعريف المرجع التكراري من لغة البرمجة Haskell:
يمكن استخدام المؤشرات لتمرير المتغيرات باستخدام مراجع لها، بما يسمح لقيمتها بأن تتغير، مثال:
Data link a = Nil
|Cons a (link a)
Nil هي القائمة الفارغة و Cons هي (Link a) هي خلية cons من النوع a مع رابط آخر من النوع a.
مع ذلك التعريف باستخدام المراجع تُفحص ولا تستخدم قيم الإشارة التي تحتمل أن تكون مربكة. لهذا السبب، عادةً ما يتم التعامل مع هيكل البيانات في لغة C عن طريق وظائف التضمين، والتي فُحصت بعناية للتأكد من صحتها.
 
=== التمرير باستخدام المؤشرات ===
يُمكن استخدام المؤشرات لتمرير المتغيرات باستخدام مراجع لها، بما يسمح لقيمتها بأن تتغير، على سبيل المثال انظر إلى كود لغة C++ التالي:
<source lang="C">
/* a copy of the int n is changed */
void not_alter(int n) {
n = 360;
}
 
/* the actual variable passed (by address) is changed */
void alter(int *n) {
*n = 120;
السطر 219 ⟵ 174:
void func(void) {
int x = 24;
 
/*pass x's address as the argument*/
alter(&x);
 
/* x now equal to 120 */
 
not_alter(x);
 
/* x stillلازالت equalتساوي to 12024 */
}
</source>
 
alter(&x);
=== تخصيص الذاكرة الديناميكية ===
تُستخدم المؤشرات في تخزين عناوين القوالب الذاكرة المخصصة ديناميكياً وإدارتها كذلك. كما تُستخدم مثل هذه القوالب أيضا في تخزين كائنات البيانات أو كائنات المصفوفات. توفر معظم اللغات المُنشاة المُنظمة واللغات غرضية التوجه مساحة من الذاكرة يُطلق عليها الكومة heap أو منطقة التخزين الحر، حيث يتم تخصيص الدوال ديناميكياً.
 
/* x تساوي الآن 120 */
يوضح مثال التالي لكود لغة السي C طريقة بناء الكائنات ديناميكياً طريقة تزويدها بالمراجع. تدعم مكتبة لغة السي C القياسية وظيفة دالة malloc() لتخصيص قوالب الذاكرة من الكومة heap. حيث تُسجل حجم الكائن بهدف تخصيصه على هيئة متغيرات ويُعيد المؤشر إلى قالب ذاكرة مقسم في شكل جديد بحيث يكون مُناسب لتخزين الكائن، أو تُعيد مؤشر null في حالة فشل عملية التخصيص.
 
<source lang="C">
/* مادة مخزون الأجزاء */
struct Item {
int id; /* رقم الجزء */
char * name; /* اسم الجزء */
float cost; /* التكلفة */
};
 
/* تخصيص وتهيئة مادة جديدة */
struct Item * make_item(const char *name) {
struct Item * item;
 
/* تخصيص مادة كائن جديد وإعادة شكله */
item = malloc(sizeof(struct Item));
if (item == NULL)
return NULL;
 
/* تهيئة أعضاء البند الجديد */
memset(item, 0, sizeof(struct Item));
item->id = -1;
item->name = NULL;
item->cost = 0.0;
 
/* احفظ نسخة من الاسم في البند الجديد */
item->name = malloc(strlen(name) + 1);
if (item->name == NULL) {
free(item);
return NULL;
}
strcpy(item->name, name);
 
/* إعادة مادة الكائن المُضاف حديثاً */
return item;
}
</source>
== مراجع ==
{{مراجع}}
 
{{شريط بوابات|برمجة الكمبيوتر}}
يُوضح الكود التالي كيفية عدم تخصيص كائنات الذاكرة ديناميكياً أي إعادتها إلى الكومة heap أو منطقة التخزين الحر. تُوفر المكتبة القياسية للغة C وظيفة free() لعدم تخصيص كقالب الذاكرة المخصصة مسبقاً وإعادتها إلى الكومة heap.
\* عدم تخصيص مادة الكائن*\
void destroy_item(struct item *item) {
\* البحث عن مؤشر الكائن null *\
if (item == NULL)
return;
\* عدم تخصيص سلسلة الاسم المحفوظة داخل المادة *\
if (item->name != NULL) {
free(item->name);
item->name = NULL;
}
 
\* عدم تخصيص المادة نفسها *\
free(item);
}
 
=== أجهزة الذاكرة المعنونة ===
يُمكن استخدام المؤشرات في بعض تراكيب وأبنية الحوسبة للمعالجة الذاكرة أو أجهزة الذاكرة المعنونة بشكل مباشر.
تُعد عملية تحديد عناوين للمؤشرات هي أحد الأدوات الهامة خلال برمجة المتحكمات الدقيقة أو [[مايكروكونترولر|المايكروكونترولر]] microcontrollers. فيما يلي مثال بسيط يُوضح مؤشر من نوع int وتهيئتها لعنوان نظام عد السداسي عشر hexademical وفي هذا المثال سوف تكون القيمة الثابتة هي 0x7FFF:
 
<source lang="C">
int *hardware_address = (int *)0x7FFF;
</source>
 
ظهر استخدام لغة BISO بهدف الوصول إلى إمكانيات الفيديو لأجهزة الحاسب الآلي في فترة منتصف الثمانينات بطيء السرعة. عادة ما تُستخدم التطبيقات ذات العرض المكثف للولوج إلى ذاكرة الفيديو CGA وذلك عن طريق تحويل قيمة نظام عد السداسي عشر hexademical الثابتة 0xB8000000 لمؤشر لمصفوفة تتكون من 80 من قيم -bit int 16 بالغير مُشار إليها. تتألف كل قيمة من كود ASCII في الخانة ذات الوزن المنخفض من وحدات البايت، والخانة ذات الألوان ذات وحدات البايت العالية. لذا، لوضع حرف "A" في الصف رقم 5 والعمود رقم 2 باللون الأبيض على الأزرق الساطع، يمكنك كتابة الكود كالتالي:
 
<source lang="C">
#define VID ((unsigned short (*)[80])0xB8000000)
 
void foo() {
VID[4][1] = 0x1F00 | 'A';
}
</source>
 
== المؤشرات والتحويل القسري ==
في العديد من اللغات، يوجد في بعض المؤشرات قيد إضافي ألا وهو أن الكائن المُشار إليه كائن من نوع خاص. على سبيل المثال، ربما يُعلن عن المؤشر للإشارة إلى عدد صحيح؛ لذا ستحاول اللغة منع المبرمج من الإشارة إلى كائنات الأعداد بخلاف العدد الصحيح، مثل [[رقم عشري|الأرقام العشرية]]، والتخلص من بعض الأخطاء.
على سبيل المثال في لغة السي C
 
<source lang="C">
int *money;
char *bags;
</source>
 
سيكون money مؤشر لعدد صحيح و bags ستكون مؤشر [[تشار (حوسبة)|char]]. سوف يُظهر الناتج التالي تحذير مترجم بان "مهمة من نوع مؤشر غير متجانس" وفقاً للغة GCC
 
<source lang="C">
bags = money;
</source>
 
نظراً لإعلان money و bags بأنواع مختلفة. يجب توضيح رغبتك الفعلية في عمل المهمة عن طريق typecasting وتعني " كيفية تغيير نوع البيانات من نوع إلي نوع أخر وقت البرمجة بدون التقييد بنوع معين وبدون التغيير في قيمتها إلا في حالات معينة فقط.
للتوضيح " وذلك لمنع ظهور هذا التحذير للمترجم.
 
<source lang="C">
bags = (char *)money;
</source>
 
يُوضح ذلك تغيير أو تحويل مؤشر العدد الصحيح لـ money إلى مؤشر char والإشارة إلى bags.
يجب أن تحتفظ مسودة 2005 للمتطلبات القياسية للغة السي C التي تقوم بتحويل مؤشر مستمد من أحد الأنواع إلى نوع آخر على الحيادية الصحيحة لكلا النوعين (مؤشرات 6.3.2.3، par.7)<ref>[http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf WG14 N1124], [http://www.open-std.org/jtc1/sc22/wg14/www/standards.html C - Approved standards: ISO/IEC 9899 - Programming languages - C], 2005-05-06. {{Webarchive|url=http://web.archive.org/web/20171227024416/http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf |date=27 ديسمبر 2017}}</ref>
 
<source lang="C">
char *external_buffer = "abcdef";
int *internal_data;
 
internal_data = (int *)external_buffer; // UNDEFINED BEHAVIOUR if "the resulting pointer
// is not correctly aligned"
</source>
 
تضع حسابات المؤشرات في الحسبان حجم النوع في اللغات التي تُمكن المؤشر الحسابي في اللغات التي تُمكن المؤشر الحسابي. على سبيل المثال، ينتج عن إضافة عدد صحيح إلى المؤشر إلى ظهور مؤشر جديد يُشير إلى عنوان أعلى بمقدار مضاعفة هذا الرقم لحجم هذا النوع. يُمكننا ذلك من حساب عنوان عناصر المصفوفة لهذا النوع المحدد بسهولة ويُسر كما وُضح سابقاً في مثال مصفوفات لغة السي 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++ <ref>{{مرجع كتاب |الأخير1=Stroustrup |الأول=Bjarne |وصلة المؤلف1=Bjarne_Stroustrup |العنوان=[[لغة البرمجة سي++ (كتاب)]] |الإصدار=14th printing of 3rd |السنة=2001 |month=March |الناشر=Addison-Wesley |المكان=United States and Canada |الرقم المعياري=0-201-88954-4 |الصفحة=88 |chapter=Chapter 5: Pointers, Arrays, and Structures: 5.1.1: Zero |quote=In C, it has been popular to define a macro <code>NULL</code> to represent the zero pointer. Because of C++'s tighter type checking, the use of plain 0, rather than any suggested <code>NULL</code> macro, leads to fewer problems. If you feel you must define <code>NULL</code>. use
: <code>const int NULL = 0;</code>
The <code>const</code> qualifier (§5.4) prevents accidental redefinition of <code>NULL</code> and ensures that <code>NULL</code> can be used where a constant is required.}}</ref> إلا أن لغة C++0x أدخلت nullptr constant لاستخدامه كبديل)، لتوضيح ظروف مثل القصور في successor للكائن الأخير في القائمة المرتبطة linked list، مع الحفاظ على بنية متسقة لنقاط القائمة. هذا الاستخدام لمؤشرات Null يمكن مقارنتها مع أنواع nullable ومع قيم null في قواعد البيانات الارتباطية ومع قيم Nothing في option type. قد اخترعت مراجع Nullable من قبل C.A.R. Hoare في عام 1965 كجزء من لغة Algol W. وقد وصف Hoare اختراعه لاحقاً (2009) بأنه "خطأ بمليار دولار":<ref>{{مرجع ويب
|المسار=http://qconlondon.com/london-2009/presentation/Null+References:+The+Billion+Dollar+Mistake
|العنوان=Null References: The Billion Dollar Mistake
|المكان=QCon London
|السنة=2009
|المؤلف=Tony Hoare}}</ref><ref>{{مرجع ويب
|المسار=http://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare
|العنوان=Null References: The Billion Dollar Mistake
|الناشر=InfoQ.com
|التاريخ=2009-08-25
|المؤلف=[[توني هور]]}}</ref>
 
لقد أطلقت عليه خطأ [[مليار|المليار]] [[دولار]] الخاص بي. كان اختراع مرجع 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، اعتماداً على النوع.<ref>''The Objective-C 2.0 Programming Language'', [http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocObjectsClasses.html#//apple_ref/doc/uid/TP30001163-CH11-SW7 section "Sending Messages to nil"]. {{وصلة مكسورة|date= فبراير 2018 |bot=JarBot}} {{Webarchive|url=http://web.archive.org/web/20090827124520/http://developer.apple.com:80/documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocObjectsClasses.html |date=27 أغسطس 2009}}</ref>
 
يُضمن في برمجة لغة 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.<ref>
{{cite patent
| country = us
| number = 6625718
| status = patent
| title = Pointers that are relative to their own present locations
| gdate = 2003-09-23
| fdate = 1998-02-05
| inventor = Steiner, Robert C. (Broomfield, CO)
| invent1 = Steiner, Robert
| assign1 = Avaya Technology Corp. (Basking Ridge, NJ)
}}
</ref>
 
== مؤشر الارتكاز Based ==
مؤشر الارتكاز هو المؤشر الذي قيمته عبارة عن إزاحة من قيمة مؤشر آخر. يمكن استخدامه لتخزين وتحميل كتل من البيانات، محددة عنوان بداية الكتلة إلى مؤشر الارتكاز.<ref>[http://msdn.microsoft.com/en-us/library/57a97k4e.aspx Based Pointers] {{Webarchive|url=http://web.archive.org/web/20171004022916/https://msdn.microsoft.com/en-us/library/57a97k4e.aspx |date=04 أكتوبر 2017}}</ref>
 
== المراوغة المزدوجة ==
في بعض اللغات يمكن أن يشير المؤشر إلى مؤشر آخر، يتطلب عمليتان للتتبع للوصول للقيمة الأصلية. بينما كل مستوى من المراوغة ربما يضيف تكلفة أداء، وأحياناً ضرورية لتقديم سلوك صحيح لهياكل البيانات المعقدة. على سبيل المثال، في لغة C تُعرَّف القائمة المرتبطة من حيث الكائن الذي يحتوي مؤشر للكائن التالي في القائمة:
 
<source lang="C">
struct element
{
struct element * next;
int value;
};
 
struct element * head = NULL;
</source>
 
يستخدم هذا التطبيق مؤشر للكائن الأول في القائمة كبديل للقائمة ككل. إذا أضيفت قيمة جديدة إلى بداية القائمة يجب تغيير المقدمة للإشارة إلى الكائن الجديد. بما أن براهين C تمرر عادة بالقيمة، يتيح استخدام المراوغة المزدوجة بتنفيذ الإدخال بصورة صحيحة، وبه الآثار الجانبية المرغوبة للقضاء على كود الحالة الخاصة للتعامل مع المدخل في أول القائمة:
 
<source lang="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 = &(*p)->next)
{
if (item->value <= (*p)->value)
break;
}
item->next = *p;
*p = item;
}
 
// Caller does this:
insert(&head, item);
</source>
 
في هذه الحالة، إذا كانت قيمة البند أقل من head فإن مقدمة المتصل تُحدَّث بشكل صحيح في عنوان البند الجديد.
 
== المؤشرات البدائية ==
المؤشرات البدائية هي المؤشرات التي لم يتم تهيأتها بعد (لا يوجد عنوان محدد للمؤشر البدائي) ربما تتسبب مثل هذه المؤشرات في تعطيل البرنامج أو العمل بطريقة بدائية. تُشير المؤشرات التي لم يتم تهيأتها في لغات برمجة Pascal أو لغة السي C إلى عناوين غير متوقعة في الذاكرة.
 
يوضح مثال الكود التالي مؤشر بدائي:
 
<source lang="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 */
}
</source>
 
هنا، ربما تشير 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 وأي مؤشر من نوع آخر من المؤشرات لن يسبب أي مخاطر.
 
<source lang="freebasic">
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))
</source>
 
=== لغة C ولغة C++ ===
المؤشرات في لغة C ولغة C++ هي المتغيرات التي تخزن العناوين ويمكن أن تكون null. يسير كل مؤشر إلى نوع خاص به، ولكن يمكن للفرد التنقل بحرية بين أنواع المؤشرات، على الرغم من أن السلوك هو تطبيق معروف. يسمح نوع خاص من المؤشرات يطلق عليه "مؤشر void" بالإشارة إلى أي نوع من المتغيرات، ولكن تحده حقيقة أنه لا يمكن تتبعه مباشرةً. غالباً يمكن معالجة العنوان نفسه مباشرة بإلقاء مؤشر من وإلى نوع متكامل بحجم مناسب، على الرغم من أن النتائج هي تطبيقات معروفة ويمكن أن تتسبب في سلوكيات غير معروفة؛ بينما لا يوجد لدى معايير لغة C السابقة نوع متكامل الذي ضُمن أن يكون كبير بدرجة كافية، لغة C99 تحدد اسم uintptr_t typedef المعرَّفة في <stdint.h>، لكن لا يحتاج التطبيق لتوافرها.
 
تدعم [[لغة ++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&R تستخدم لغة C char* لغرض "المؤشر agnostic" (قبل ANSI C).
 
<source lang="C">
int x = 4;
void* q = &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 */
</source>
 
لا تسمح لغة C++ بالتحويل الضمني لـ void* إلى نوع آخر من المؤشرات، حتى أثناء المهمات. كان هذا قرار في التصميم لتجنب الإهمال وحتى الاشكال غير المرغوبة، مع ذلك معظم المجمعين يستخرجون التحذيرات فقط وليس الأخطاء عند مواجهة إلقاءات أخرى سيئة.
 
<source lang="Cpp">
int x = 4;
void* q = &x;
// 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<int*>(q); // C++ cast
</source>
 
في لغة C++، لا يوجد void& (مرجع لـ void) لاستكمال void*، لأن المراجع تتصرف مثل الأسماء المستعارة للمتغيرات التي تشير إليها، ولا يمكن وجود متغير من نوع void.
 
=== لغة C# ===
في لغة برمجة C#، تُدعم للمؤشرات تحت شروط معينة: أي كتلة من الكود المتضمنة المؤشرات لابد من الإشارة عليها بعلامة غير آمن. تتطلب مثل هذه الكتل أذونا أمان أعلى من المسموح بها لتشغيلها. الصيغة هي نفسها الموجودة في لغة C++ والعنوان المشار إليه يمكن أن يكون إما ذاكرة متحكم بها أو غير متحكم بها. مع ذلك، مؤشرات الذاكرة المتحكم بها (أي مؤشر لكائن متحكم به) يجب الإعلان عنها باستخدام كلمة أساسية ثابتة، والتي تمنع garbage collector من تحريك الكائن المشار إليه كجزء من التحكم بالذاكرة بينما يكون المؤشر في النطاق وهذا يحافظ على صلاحية العنوان.
 
استثناء هذا من استخدام بنية IntPtr وهو تحكم آمن يتساوى مع int* ولا يتطلب كود عدم الأمان. يستعاد هذا النوع غالباً عند استخدام طرق من النظام. Runtime.InteropServices على سبيل المثال:
 
<source lang="csharp">
// 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
</source>
 
=== لغة 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 على أكثر من مجرد عنوان ذاكرة بسيط. كما تنطوي على الحدود العليا والدنيا من أبعاد المصفوفة، الخطوات (على سبيل المثال لدعم أقسام المصفوفة التعسفية)، وغيرها من البيانات الوصفية. المشغل المنتسب، => يستخدم لينسب المؤشر إلى متغير له صفة الهدف. بيانات تخصيص لغة Fortran-90 يمكن استخدامها أيضا لنسب المؤشر إلى كتلة من الذاكرة. على سبيل المثال، يمكن استخدام الكود التالي لتعريف وتكوين هيكل قائمة مرتبطة:
<source lang="Fortran">
type real_list_t
real :: sample_data(100)
type (real_list_t), pointer :: next => null ()
end type
 
type (real_list_t), target :: my_real_list
type (real_list_t), pointer :: real_list_temp
 
real_list_temp => my_real_list
do
read (1,iostat=ioerr) real_list_temp%sample_data
if (ioerr /= 0) exit
allocate (real_list_temp%next)
real_list_temp => real_list_temp%next
end do
</source>
 
تضيف لغة Fortran-2003 دعم للمؤشرات الإجرائية. كذلك، كجزء من ميزة التشغيل المتداخل في لغة C تدعم لغة Fortran-2003 الوظائف الجوهرية لتحويل أنواع مؤشرات C إلى مؤشرات Fortran وإعادتها.
 
=== لغة Go ===
تحتوي لغة Go على مؤشرات. تتماثل صيغتها المعلنة مع مؤشرات لغة C، ولكن تكتب بالعكس، منتهية بالنوع. على عكس لغة C، لدى Go garbage collection ولا تسمح بالمؤشر الحسابي. لا يمكن تعريف أنواع المرجع مثل لغة C++ لكن يتم تمرير بعض الأنواع الضمنية عن طريق المرجع؛ يجب أن تتكون تلك بجعل الكلمة الأساسية بدلاً من الجديدة. كطريقة مختلفة (عن أنواع المرجع) لتوحيد الصيغة بين المؤشر وغير المؤشر، انخفض مشغل السهم (->)والمجمع يعرف فقط أن المبرمج يعني تتبع المؤشر باستخدام مشغل النقطة (.) (بينما على لغة 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 يسمح فقط للمؤشرات بالإشارة إلى المؤشرات المكتوبة ديناميكياً والغير معروفة ولا يسمح لهم بالإشارة إلى المعيار الثابت أو المتغيرات المحلية.<ref>ISO 7185 Pascal Standard (unofficial copy), section [http://standardpascal.org/iso7185.html#6.4.4%20Pointer-types 6.4.4 Pointer-types] and subsequent. {{Webarchive|url=http://web.archive.org/web/20170424183023/http://www.standardpascal.org:80/iso7185.html |date=24 أبريل 2017}}</ref> لا يوجد بها مؤشر حسابي. يجب أن تحتوي المؤشرات أيضاً على نوع مترابط والمؤشر من نوع ما لا يتفق مع المؤشر من نوع آخر (مثل مؤشر char لا يتفق مع مؤشر العدد الصحيح). يساعد هذا على القضاء على القضايا الأمنية المتأصلة تطبيقات المؤشر الآخر، تستخدم هذه خاصة للغة PL/I أو للغة C. كما أنها تزيل بعض المخاطر التي يسببها المؤشر المتدلي، ولكن القدرة على السماح الديناميكي للمساحة المتبعة باستخدام عملية معيار التصرف (الذي له نفس تأثير مثل وظيفة المكتبة الحرة الموجودة في اللغة C) مما يعني أن خطورة مؤشرات التدلي لم يتم القضاء عليها كلياً.<ref>J. Welsh, W. J. Sneeringer, and C. A. R. Hoare, "Ambiguities and Insecurities in Pascal," ''Software Practice and Experience 7'', pp. 685-696 (1977)</ref>
 
مع ذلك في بعض المصادر التجارية والمفتوحة للغة Pascal (أو مشتقاتها) يسمح بتطبيقات مثل Free Pascal أو Turbo Pascal أو<ref>Free Pascal Language Reference guide, section [http://www.freepascal.org/docs-html/ref/refse15.html#x43-490003.4 3.4 Pointers] {{Webarchive|url=http://web.archive.org/web/20170428135112/http://freepascal.org:80/docs-html/ref/refse15.html |date=28 أبريل 2017}}</ref> Object Pascal في Embarcadero Delphi – يسمح للمؤشر بالإشارة إلى المعيار الثابت أو المتغيرات المحلية ويمكن الإلقاء من نوع من المؤشرات إلى آخر. علاوة على ذلك، المؤشر الحسابي غير مقيد: الإضافة أو الطرح من المؤشر يحركه بمقدار هذا الرقم من وحدات البايت في كلا الاتجاهين، لكن استخدام إجراءات معيار Inc أو dec معه يحرك المؤشر بحجم نوع البيانات المصرح للإشارة إليه.
 
=== لغة البرمجة Perl ===
تدعم لغة برمجة Perl المؤشرات، على الرغم من ندرة استخدامها، في شكل وظائف من الحزم والتفريغ. تهدف هذه للتفاعلات البسيطة فقط مع مكتبات OS المجمعة. في جميع الحالات الأخرى، تستخدم لغة Perl المراجع المكتوبة والتي لا تسمح بوجود أي شكل من أشكال المؤشر الحسابي. فهي تستخدم لبناء تراكيب البيانات المعقدة.<ref>[http://perldoc.perl.org/perlref.html#Making-References // Making References (Perl References and nested data structures)] {{Webarchive|url=http://web.archive.org/web/20180102013233/http://perldoc.perl.org:80/perlref.html |date=02 يناير 2018}}</ref>
 
==انظر أيضا==
{{col-begin}}
{{col-break|width=33%}}
* [[مؤشر لدالة]]
* [[Address constant]]
* [[Bounded pointer]]
* [[تجاوز سعة المخزن المؤقت]]
* [[مؤشر لدالة]]
* [[Hazard pointer]]
* [[Opaque pointer]]
{{col-break}}
* [[Pointer swizzling]]
* [[Reference (computer science)]]
* [[Static code analysis]]
* [[Storage violation]]
* [[متغير (علم الحاسوب)]]
{{نهاية-عمو}}
 
== المراجع ==
{{مراجع|2}}
 
{{تصنيف كومنز|Pointers (computing)}}
== وصلات خارجية ==
* [http://cslibrary.stanford.edu/ Pointers and Memory] Introduction to pointers – Stanford Computer Science Education Library
* [http://0pointer.de/ 0pointer.de] A terse list of minimum length source codes that dereference a null pointer in several different programming languages
* [http://publications.gbdirect.co.uk/c_book/chapter5/pointers.html "The C book" - containing pointer examples in ANSI C]
 
{{ضبط استنادي}}
{{شريط بوابات|برمجة الحاسوب}}
 
[[تصنيف:لغاتأنواع برمجة|*البيانات]]
[[تصنيف:حوسبةاختراعات أمريكية]]