ما هو الفرق الحقيقي بين المؤشرات والمراجع؟

StackOverflow https://stackoverflow.com/questions/92001

  •  01-07-2019
  •  | 
  •  

سؤال

AKA - ما هذا الهوس بالمؤشرات؟

بعد أن استخدمت فقط اللغات الحديثة الموجهة للكائنات مثل ActionScript وJava وC#، لا أفهم حقًا أهمية المؤشرات وما تستخدمه من أجله.ما الذي أفتقده هنا؟

هل كانت مفيدة؟

المحلول

الأمر كله مجرد غير مباشر:القدرة على عدم التعامل مع البيانات، ولكن القول "سأوجهك إلى بعض البيانات، هناك".لديك نفس المفهوم في Java وC#، ولكن بتنسيق مرجعي فقط.

تتمثل الاختلافات الرئيسية في أن المراجع هي علامات غير قابلة للتغيير بشكل فعال - فهي تشير دائمًا إلى شيء ما.هذا مفيد وسهل الفهم، ولكنه أقل مرونة من نموذج المؤشر C.مؤشرات C هي علامات يمكنك إعادة كتابتها بسعادة.هل تعلم أن السلسلة التي تبحث عنها موجودة بجوار السلسلة المشار إليها؟حسنًا، فقط قم بتغيير الإشارة قليلاً.

يتزاوج هذا جيدًا مع نهج C "القريب من العظم، ويتطلب مستوى منخفض من المعرفة".نحن يعرف انه char* foo يتكون من مجموعة من الأحرف تبدأ من الموقع المشار إليه بعلامة foo.إذا علمنا أيضًا أن السلسلة تتكون من 10 أحرف على الأقل، فيمكننا تغيير العلامة إلى (foo + 5) للإشارة إلى نفس السلسلة، ولكن ابدأ بنصف الطول.

تكون هذه المرونة مفيدة عندما تعرف ما تفعله، والموت إذا كنت لا تعرفه (حيث كلمة "اعرف" هي أكثر من مجرد "معرفة اللغة"، فهي "معرفة الحالة الدقيقة للبرنامج").إذا أخطأت في الفهم، فإن علامتك الإرشادية ستوجهك بعيدًا عن حافة الهاوية.المراجع لا تسمح لك بالعبث، لذا فأنت أكثر ثقة في قدرتك على متابعتها دون مخاطرة (خاصة عندما تقترن بقواعد مثل "الكائن المرجعي لن يختفي أبدًا"، كما هو الحال في معظم اللغات المجمعة المهملة).

نصائح أخرى

أنت في عداد المفقودين على الكثير!يعد فهم كيفية عمل الكمبيوتر في المستويات الأدنى مفيدًا جدًا في العديد من المواقف.سوف يقوم C والمجمع بذلك نيابةً عنك.

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

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

في لغة C، المؤشرات هي طريقة تمرير المراجع إلى البيانات.عند استدعاء دالة، فإنك لا تريد نسخ مليون بت إلى مكدس.بدلاً من ذلك، عليك فقط معرفة مكان وجود البيانات في الذاكرة الرئيسية.بمعنى آخر، أنت تعطي المؤشر إلى البيانات.

إلى حد ما هذا ما يحدث حتى مع جافا.يمكنك تمرير مراجع إلى الكائنات، وليس الكائنات نفسها.تذكر أن كل كائن في النهاية هو عبارة عن مجموعة من البتات الموجودة في الذاكرة الرئيسية للكمبيوتر.

المؤشرات مخصصة لمعالجة محتويات الذاكرة بشكل مباشر.

الأمر متروك لك فيما إذا كنت تعتقد أن هذا أمر جيد للقيام به، ولكنه الأساس لكيفية تنفيذ أي شيء في لغة C أو المجمّع.

اللغات عالية المستوى تخفي المؤشرات خلف الكواليس:على سبيل المثال، يتم تطبيق مرجع في Java كمؤشر في أي JVM تقريبًا، ولهذا السبب يطلق عليه NullPointerException بدلاً من NullReferenceException.لكنها لا تسمح للمبرمج بالوصول مباشرة إلى عنوان الذاكرة الذي يشير إليه، ولا يمكن تعديله ليأخذ قيمة أخرى غير عنوان كائن من النوع الصحيح.لذا فهي لا تقدم نفس القوة (والمسؤولية) التي توفرها المؤشرات في اللغات ذات المستوى المنخفض.

[يحرر:هذا إجابة على السؤال "ما هذا الهوس بالمؤشرات؟".كل ما قمت بمقارنته هو مؤشرات نمط المجمع/C مع مراجع Java.لقد تغير عنوان السؤال منذ ذلك الحين:لو شرعت في الإجابة على السؤال الجديد لربما ذكرت مراجع بلغات أخرى غير Java]

هذا يشبه السؤال، "ما هذا الهوس بتعليمات وحدة المعالجة المركزية؟هل يفوتني شيء ما من خلال عدم نشر تعليمات x86 MOV في كل مكان؟"

انت فقط يحتاج مؤشرات عند البرمجة على مستوى منخفض.في معظم تطبيقات لغات البرمجة ذات المستوى الأعلى، يتم استخدام المؤشرات على نطاق واسع كما هو الحال في لغة C، ولكنها مخفية عن المستخدم بواسطة المترجم.

لذا...لا تقلق.أنت تستخدم المؤشرات بالفعل - وبدون مخاطر القيام بذلك بشكل غير صحيح أيضًا.:)

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

هذا مشابه جدًا للبرمجة في الوقت الحالي.هناك حاجة لتطوير C/C++ على بعض البرامج.بعض الأمثلة هي الألعاب ثلاثية الأبعاد المتطورة، والبرامج المضمنة ذات المستوى المنخفض، والأشياء التي تمثل فيها السرعة جزءًا مهمًا من غرض البرنامج، واللغة ذات المستوى الأدنى التي تسمح لك بالوصول بشكل أقرب إلى البيانات الفعلية التي تحتاج إلى معالجة هي مفتاح هذا الأداء .ومع ذلك، فإن هذا ليس هو الحال بالنسبة لمعظم المبرمجين، كما أن عدم معرفة المؤشرات ليس معوقًا.ومع ذلك، أعتقد أنه يمكن للجميع الاستفادة من تعلم لغة C والمؤشرات وعمليات النقل اليدوية أيضًا.

نظرًا لأنك تقوم بالبرمجة بلغات موجهة للكائنات، دعني أطرح الأمر بهذه الطريقة.

يمكنك الحصول على كائن A لإنشاء كائن B، وتمريره كمعلمة أسلوب إلى الكائن C.يقوم الكائن C بتعديل بعض القيم في الكائن B.عندما تعود إلى رمز الكائن أ، يمكنك رؤية القيمة المتغيرة في الكائن ب.لماذا هو كذلك؟

لأنك مررت في مرجع من الكائن B إلى الكائن C، ولم يتم إنشاء نسخة أخرى من الكائن B.لذا فإن كلا من الكائن A والكائن C يحملان إشارات إلى نفس الكائن B في الذاكرة.يتغير من مكان ويظهر في مكان آخر.وهذا ما يسمى حسب المرجع.

الآن، إذا كنت تستخدم أنواعًا بدائية بدلاً من ذلك، مثل int أو float، وقمت بتمريرها كمعلمات طريقة، فلن يتمكن الكائن A من رؤية التغييرات في الكائن C، لأن الكائن A مرر فقط ينسخ بدلاً من مرجع نسخته الخاصة من المتغير.وهذا ما يسمى حسب القيمة.

ربما كنت تعرف ذلك بالفعل.

بالعودة إلى لغة C، تقوم الوظيفة A بتمرير بعض المتغيرات إلى الوظيفة B.معلمات الدالة هذه هي نسخ أصلاً، حسب القيمة.لكي تتمكن الوظيفة B من معالجة النسخة التي تنتمي إلى الوظيفة A، يجب أن تمر الوظيفة A المؤشر إلى المتغير، بحيث يصبح ممرًا حسب المرجع.

"مرحبًا، هذا هو عنوان الذاكرة للمتغير الصحيح الخاص بي.ضع القيمة الجديدة في موقع العنوان هذا وسألتقطها لاحقًا."

لاحظ أن المفهوم مشابه ولكنه ليس مشابهًا بنسبة 100%.يمكن للمؤشرات أن تفعل أكثر بكثير من مجرد المرور "بالرجوع".تسمح المؤشرات للوظائف بمعالجة المواقع العشوائية للذاكرة لأي قيمة مطلوبة.تُستخدم المؤشرات أيضًا للإشارة إلى العناوين الجديدة لـ رمز التنفيذ لتنفيذ المنطق التعسفي ديناميكيًا، وليس فقط متغيرات البيانات.قد تشير المؤشرات أيضًا إلى مؤشرات أخرى (مؤشر مزدوج).يعد هذا أمرًا قويًا ولكن من السهل جدًا أيضًا تقديم أخطاء ونقاط ضعف أمنية يصعب اكتشافها.

إذا لم تكن قد رأيت المؤشرات من قبل، فمن المؤكد أنك تفوت هذه الجوهرة الصغيرة:

void strcpy(char *dest, char *src)
{    
        while(*dest++ = *src++);
}

تاريخيًا، ما جعل البرمجة ممكنة هو إدراك أن مواقع الذاكرة يمكن أن تحتوي على تعليمات الكمبيوتر، وليس البيانات فقط.

نشأت المؤشرات من إدراك أن مواقع الذاكرة يمكن أن تحتوي أيضًا على عناوين مواقع الذاكرة الأخرى، مما يمنحنا توجيهًا غير مباشر.بدون مؤشرات (على مستوى منخفض) ستكون معظم هياكل البيانات المعقدة مستحيلة.لا توجد قوائم مرتبطة أو أشجار ثنائية أو جداول تجزئة.لا يوجد تمرير حسب المرجع، فقط من حيث القيمة.نظرًا لأن المؤشرات يمكن أن تشير إلى التعليمات البرمجية، فبدونها لن يكون لدينا أيضًا وظائف افتراضية أو جداول بحث عن الوظائف.

أستخدم المؤشرات والمراجع بكثافة في عملي اليومي... في التعليمات البرمجية المُدارة (C#، Java) وغير المُدارة (C++، C).لقد تعلمت كيفية التعامل مع المؤشرات وما هي على يد المعلم نفسه...[بينكي!!][1] لا داعي لقول أي شيء آخر ;)

الفرق بين المؤشر والمرجع هو هذا.المؤشر هو عنوان لبعض كتلة الذاكرة.يمكن إعادة كتابتها، أو بعبارة أخرى، إعادة تعيينها إلى كتلة أخرى من الذاكرة.المرجع هو ببساطة إعادة تسمية لبعض الكائنات.لا يمكن تعيينه إلا مرة واحدة!بمجرد تعيينه إلى كائن، لا يمكن تعيينه إلى آخر.المرجع ليس عنوانا، بل هو اسم آخر للمتغير.الدفع الأسئلة الشائعة حول لغة C++ للمزيد عن هذا.

الرابط1

لينك2

أنا حاليًا أعمل على تصميم بعض برامج المؤسسات عالية المستوى حيث يتم الرجوع إلى أجزاء من البيانات (المخزنة في قاعدة بيانات SQL، في هذه الحالة) بواسطة كيان واحد أو أكثر.إذا بقي جزء من البيانات عندما لم تعد هناك كيانات تشير إليه، فإننا نهدر مساحة التخزين.إذا كان هناك مرجع يشير إلى بيانات غير موجودة، فهذه مشكلة كبيرة أيضًا.

هناك تشابه قوي بين مشكلاتنا وتلك المتعلقة بإدارة الذاكرة في لغة تستخدم المؤشرات.من المفيد للغاية أن أتمكن من التحدث مع زملائي فيما يتعلق بهذا التشبيه.يعد عدم حذف البيانات غير المرجعية بمثابة "تسرب للذاكرة".المرجع الذي لا يذهب إلى أي مكان هو "المؤشر المتدلي".يمكننا اختيار "إعفاءات" صريحة، أو يمكننا تنفيذ "جمع البيانات المهملة" باستخدام "العد المرجعي".

لذا، فإن فهم إدارة الذاكرة ذات المستوى المنخفض يساعد في تصميم التطبيقات عالية المستوى.

في Java، أنت تستخدم المؤشرات طوال الوقت.معظم المتغيرات هي مؤشرات للكائنات - ولهذا السبب:

StringBuffer x = new StringBuffer("Hello");
StringBuffer y = x;
x.append(" boys");
System.out.println(y);

...يطبع "Hello boys" وليس "Hello".

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

تعتبر السلاسل النصية أساسية للغة C (واللغات الأخرى ذات الصلة).عند البرمجة بلغة C أنت يجب إدارة الذاكرة الخاصة بك.أنت لا تقول فقط "حسنًا، سأحتاج إلى مجموعة من الخيوط"؛عليك أن تفكر في بنية البيانات.ما مقدار الذاكرة التي تحتاجها؟متى ستخصصها؟متى ستحرره؟لنفترض أنك تريد 10 سلاسل، لا يزيد طول كل منها عن 80 حرفًا.

حسنًا، كل سلسلة عبارة عن مصفوفة من الأحرف (81 حرفًا - يجب ألا تنسى القيمة الخالية وإلا ستأسف!) ومن ثم تكون كل سلسلة بحد ذاتها في مصفوفة.وستكون النتيجة النهائية عبارة عن مجموعة متعددة الأبعاد من هذا القبيل

char dict[10][81];

لاحظ، بالمناسبة، أن الإملاء ليس "سلسلة" أو "مصفوفة" أو "شار".إنه مؤشر.عندما تحاول طباعة إحدى هذه السلاسل، كل ما تفعله هو تمرير عنوان حرف واحد؛تفترض لغة C أنه إذا بدأت للتو في طباعة الأحرف، فإنها ستصل في النهاية إلى قيمة فارغة.ويفترض أنه إذا كنت في بداية سلسلة واحدة، وانتقلت للأمام بمقدار 81 بايت، فستكون في بداية السلسلة التالية.وفي الواقع، فإن أخذ المؤشر وإضافة 81 بايت إليه هو الحل الطريقة الوحيدة الممكنة للانتقال إلى السلسلة التالية.

إذن، لماذا تعتبر المؤشرات مهمة؟لأنه لا يمكنك فعل أي شيء بدونهم.لا يمكنك حتى القيام بشيء بسيط مثل طباعة مجموعة من الخيوط؛أنت بالتأكيد لا يمكنه فعل أي شيء مثير للاهتمام مثل تنفيذ القوائم المرتبطة، أو التجزئة، أو قوائم الانتظار، أو الأشجار، أو نظام الملفات، أو بعض أكواد إدارة الذاكرة، أو النواة أو... أيًا كان.أنت بحاجة إلى فهمها لأن لغة C تمنحك كتلة من الذاكرة وتتيح لك القيام بالباقي، والقيام بأي شيء باستخدام كتلة من الذاكرة الأولية يتطلب مؤشرات.

يقترح العديد من الأشخاص أيضًا أن القدرة على فهم المؤشرات ترتبط بشكل كبير بمهارة البرمجة.وقد قدم جويل هذه الحجة، من بين أمور أخرى.على سبيل المثال

الآن، أعترف بحرية أن البرمجة باستخدام المؤشرات ليست ضرورية في 90% من التعليمات البرمجية المكتوبة اليوم، وفي الواقع، إنها خطيرة تمامًا في تعليمات الإنتاج.نعم.هذا جيّد.والبرمجة الوظيفية لا تستخدم كثيرًا في الممارسة العملية.متفق.

لكنها لا تزال مهمة لبعض وظائف البرمجة الأكثر إثارة.بدون المؤشرات، على سبيل المثال، لن تتمكن أبدًا من العمل على نواة Linux.لا يمكنك فهم سطر من التعليمات البرمجية في Linux، أو في الواقع، أي نظام تشغيل، دون فهم المؤشرات حقًا.

من هنا.مقالة ممتازة.

لنكون صادقين، سيضحك معظم المطورين المتمرسين (نأمل أن يكونوا ودودين) إذا كنت لا تعرف المؤشرات.في وظيفتي السابقة، كان لدينا موظفان جديدان في العام الماضي (تخرجا للتو) لم يكن لديهما علم بالمؤشرات، وكان هذا وحده موضوع المحادثة معهم لمدة أسبوع تقريبًا.لا يمكن لأحد أن يصدق كيف يمكن لشخص أن يتخرج دون معرفة المؤشرات...

تختلف المراجع في C++ بشكل أساسي عن المراجع في لغات Java أو .NET؛تحتوي لغات .NET على أنواع خاصة تسمى "byrefs" والتي تتصرف بشكل يشبه إلى حد كبير "مراجع" C++.

مرجع C++ أو .NET byref (سأستخدم المصطلح الأخير، للتمييز عن مراجع .NET) هو نوع خاص لا يحتوي على متغير، ولكنه يحتوي على معلومات كافية لتحديد متغير (أو شيء يمكن أن يتصرف كواحدة، مثل فتحة المصفوفة) الموجودة في مكان آخر.يتم استخدام Byrefs عمومًا فقط كمعلمات/وسائط دالة، ويُقصد بها أن تكون سريعة الزوال.يضمن الكود الذي يمرر byref إلى دالة أن المتغير الذي تم تحديده بذلك سيكون موجودًا على الأقل حتى تعود تلك الوظيفة، وتضمن الوظائف عمومًا عدم الاحتفاظ بأي نسخة من byref بعد عودتها (لاحظ أنه في C++، لا يتم التقييد الأخير فرض).وبالتالي، لا يمكن للـ byrefs أن تعمر أكثر من المتغيرات المحددة بذلك.

في لغات Java و.NET، المرجع هو نوع يحدد كائن الكومة؛يحتوي كل كائن كومة على فئة مرتبطة، ويمكن للتعليمات البرمجية الموجودة في فئة كائن الكومة الوصول إلى البيانات المخزنة في الكائن.قد تمنح كائنات الكومة تعليمات برمجية خارجية وصولاً محدودًا أو كاملاً إلى البيانات المخزنة فيها، و/أو تسمح للتعليمات البرمجية الخارجية باستدعاء طرق معينة داخل فئتها.سيؤدي استخدام مرجع لاستدعاء طريقة من فئتها إلى إتاحة هذا المرجع لتلك الطريقة، والتي قد تستخدمها بعد ذلك للوصول إلى البيانات (حتى البيانات الخاصة) داخل كائن الكومة.

ما يجعل المراجع مميزة في لغات Java و.NET هو أنها تحافظ، باعتبارها ثابتة مطلقة، على أن كل مرجع غير فارغ سيستمر في تعريف نفس كائن الكومة طالما أن هذا المرجع موجود.بمجرد عدم وجود أي إشارة إلى كائن الكومة في أي مكان في الكون، فإن كائن الكومة سيتوقف عن الوجود ببساطة، ولكن لا توجد طريقة يمكن أن يتوقف بها كائن الكومة عن الوجود أثناء وجود أي إشارة إليه، ولا توجد أي طريقة لـ "طبيعي" "إشارة إلى كائن كومة الذاكرة المؤقتة لتصبح تلقائيًا أي شيء آخر غير الإشارة إلى ذلك الكائن.يحتوي كل من Java و.NET على أنواع خاصة من "المرجع الضعيف"، لكنهما يدعمان الثابت.إذا لم تكن هناك إشارات غير ضعيفة لكائن ما في أي مكان في الكون، فسيتم إبطال أي مراجع ضعيفة موجودة؛بمجرد حدوث ذلك، لن يكون هناك أي إشارات إلى الكائن وبالتالي يمكن إبطاله.

المؤشرات، مثل كل من مراجع C++ ومراجع Java/.NET، تحدد الكائنات، ولكن على عكس أنواع المراجع المذكورة أعلاه، يمكنها أن تظل أطول من الكائنات التي تحددها.إذا توقف الكائن المحدد بواسطة المؤشر عن الوجود ولكن المؤشر نفسه لم يعد موجودًا، فإن أي محاولة لاستخدام المؤشر ستؤدي إلى سلوك غير محدد.إذا لم يكن المؤشر معروفًا أيضًا null أو لتحديد كائن موجود حاليًا، لا توجد طريقة محددة للقيام بذلك أي شئ بهذا المؤشر بخلاف الكتابة فوقه بشيء آخر.من المشروع تمامًا أن يستمر المؤشر في الوجود بعد أن يتوقف الكائن المحدد عن القيام بذلك، بشرط ألا يستخدم أي شيء المؤشر على الإطلاق، ولكن من الضروري أن يشير شيء ما خارج المؤشر إلى ما إذا كان استخدامه آمنًا أم لا لأنه لا توجد طريقة لذلك اسأل المؤشر نفسه.

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

لفترة طويلة لم أفهم المؤشرات، لكنني فهمت معالجة المصفوفة.لذلك عادةً ما أقوم بتجميع بعض مساحة التخزين للكائنات الموجودة في مصفوفة، ثم أستخدم فهرسًا لتلك المصفوفة كمفهوم "المؤشر".

SomeObject store[100];
int a_ptr = 20;
SomeObject A = store[a_ptr];

إحدى مشكلات هذا الأسلوب هي أنه بعد تعديل "A"، يجب علي إعادة تعيينه إلى مصفوفة "store" حتى تكون التغييرات دائمة:

store[a_ptr] = A;

خلف الكواليس، كانت لغة البرمجة تقوم بعدة عمليات نسخ.في معظم الأحيان، لم يؤثر هذا على الأداء.لقد جعل في الغالب الكود عرضة للخطأ ومتكررًا.

بعد أن تعلمت فهم المؤشرات، ابتعدت عن تنفيذ نهج معالجة المصفوفة.هذا التشبيه لا يزال صالحا إلى حد ما.فقط ضع في اعتبارك أن مصفوفة "المتجر" تتم إدارتها من خلال وقت تشغيل لغة البرمجة.

SomeObject A;
SomeObject* a_ptr = &A;
// Any changes to a_ptr's contents hereafter will affect
// the one-true-object that it addresses. No need to reassign.

في الوقت الحاضر، أستخدم المؤشرات فقط عندما لا أستطيع نسخ كائن بشكل قانوني.هناك مجموعة من الأسباب التي قد تجعل هذا هو الحال:

  1. لتجنب عملية نسخة كائنات باهظة الثمن من أجل الأداء.
  2. لا يسمح بعض العوامل الأخرى بإجراء عملية طباعية للكائنات.
  3. تريد استدعاء دالة أن يكون لها آثار جانبية على كائن (لا تمر الكائن ، مرر المؤشر به).
  4. في بعض اللغات- إذا كنت ترغب في إرجاع أكثر من قيمة واحدة من وظيفة (على الرغم من تجنبها بشكل عام).

المؤشرات هي الطريقة الأكثر واقعية لتمثيل الاتجاه غير المباشر في لغات البرمجة ذات المستوى الأدنى.

المؤشرات مهمة!إنهم "يشيرون" إلى عنوان الذاكرة، ويتم تمثيل العديد من الهياكل الداخلية كمؤشرات، IE، مجموعة السلاسل هي في الواقع قائمة من المؤشرات إلى المؤشرات!يمكن أيضًا استخدام المؤشرات لتحديث المتغيرات التي تم تمريرها إلى الوظائف.

أنت في حاجة إليها إذا كنت تريد إنشاء "كائنات" في وقت التشغيل دون تخصيص الذاكرة مسبقًا على المكدس

كفاءة المعلمة - تمرير مؤشر (Int - 4 بايت) بدلاً من نسخ كائن كامل (كبير بشكل تعسفي).

يتم تمرير فئات Java عبر مرجع (مؤشر في الأساس) أيضًا، وهذا فقط ما هو مخفي في Java عن المبرمج.

البرمجة بلغات مثل C وC++ هي أقرب بكثير إلى "المعدن".تحتوي المؤشرات على موقع في الذاكرة حيث يتم تخزين المتغيرات والبيانات والوظائف وما إلى ذلك.يعيش.يمكنك تمرير المؤشر بدلاً من المرور حسب القيمة (نسخ المتغيرات والبيانات).

هناك شيئان صعبان مع المؤشرات:

  1. مؤشرات على المؤشرات والعنونة وما إلى ذلك.يمكن أن تصبح غامضة للغاية.يؤدي إلى الأخطاء، ويصعب قراءتها.
  2. غالبًا ما يتم تخصيص الذاكرة التي تشير إليها المؤشرات من الكومة، مما يعني أنك مسؤول عن تحرير تلك الذاكرة.كلما أصبح تطبيقك أكبر، أصبح من الصعب مواكبة هذا المطلب، وينتهي بك الأمر إلى حدوث تسرب في الذاكرة يصعب تعقبه.

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

من الجدير أيضًا ملاحظة أنه يمكنك استخدام المؤشرات في C# (على عكس المراجع العادية) عن طريق وضع علامة على كتلة من التعليمات البرمجية على أنها غير آمنة.بعد ذلك يمكنك التجول في تغيير عناوين الذاكرة مباشرة والقيام بحسابات المؤشر وكل تلك الأشياء الممتعة.إنه أمر رائع لمعالجة الصور بسرعة كبيرة (المكان الوحيد الذي استخدمته فيه شخصيًا).

بقدر ما أعرف، لا يدعم Java وActionScript التعليمات البرمجية والمؤشرات غير الآمنة.

أشعر دائمًا بالانزعاج من التركيز على أشياء مثل المؤشرات أو المراجع في اللغات عالية المستوى.من المفيد حقًا التفكير على مستوى أعلى من التجريد فيما يتعلق بسلوك الأشياء (أو حتى الوظائف فقط) بدلاً من التفكير من حيث "دعني أرى، إذا أرسلت عنوان هذا الشيء إلى هناك، فهذا الشيء سيعيد لي مؤشرًا إلى شيء آخر"

فكر حتى في وظيفة مبادلة بسيطة.اذا كنت تمتلك

مبادلة باطلة (int & a، int & b)

أو

مبادلة الإجراء (var a، b :عدد صحيح)

ثم قم بتفسيرها على أنها تعني أنه يمكن تغيير القيم.حقيقة أن هذا يتم تنفيذه عن طريق تمرير عناوين المتغيرات هي مجرد إلهاء عن الغرض.

نفس الشيء مع الكائنات --- لا تفكر في معرفات الكائنات كمؤشرات أو إشارات إلى "أشياء".بدلاً من ذلك، فكر فيها على أنها كائنات يمكنك إرسال الرسائل إليها.حتى في اللغات البدائية مثل C++، يمكنك المضي قدمًا بشكل أسرع بكثير من خلال التفكير (والكتابة) على أعلى مستوى ممكن.

اكتب أكثر من سطرين من c أو c++ وستكتشف ذلك.

إنها "مؤشرات" إلى موقع الذاكرة للمتغير.إنه مثل تمرير متغير حسب المرجع نوعا ما.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top