فهم نقل القيمة في Java:
الكود 1:
اختبار الطبقة العامة { /** * @param args */ public static void main(String[] args) { StringBuffer buffer= new StringBuffer("SChange(buffer System.out.println( buffer }); public static void SChange (StringBuffer str) { str= new StringBuffer("huang" } }الكود 2:
اختبار الطبقة العامة { /** * @param args */ public static void main(String[] args) { StringBuffer buffer= new StringBuffer("SChange(buffer System.out.println( buffer }); public static void SChange (StringBuffer str) { //str= new StringBuffer("huang"); str.append(" huang" } }دعونا نستخدم صورتين لشرح الكود 1 والكود 2 أعلاه على التوالي:
الحالة الأصلية
مخطط الكود 1:
فهم الكود 2:
في الكود 1، يشير مرجع النسخة إلى كائن جديد. ولكن الكائن الأصلي يبقى دون تغيير.
في الكود 2، يغير مرجع النسخة الكائن الأصلي.
هذا هو تمرير Java بالقيمة.
الفرق بين نوعين من النقل في C++:
بالنسبة لتمرير قيمة C++، وتمرير المرجع، وأساليب المؤشر، استخدم الكود التالي لفهم الاختبار وتشغيله بنفسك
#include <stdio.h> #include <iostream> #include <typeinfo> void ByValue(int a) { a = a + 1 } void ByRef(int& a) { a = a + 1 } void ByPointer(int*; أ) { *a = *a + 1 } int main(int argv, char** args) { int v = 1; ByRef(v); // تمرير حسب المرجع ByPointer(&v); // تمرير حسب القيمة int* vp = &v; cout << typeid(vp).name() << std::endl; std::cout << "end" << std::endl }يتم تمرير الوظيفة الأولى حسب القيمة، ويتم تمرير الوظيفة الثانية حسب المرجع، ولكن بالنسبة للاثنين الأخيرين، يتم استدعاء نفس الوظيفة مرة واحدة عن طريق الاتصال حسب المرجع ومرة واحدة عن طريق الاتصال حسب القيمة.
لأن:
ByPointer(vp); إذا لم يتم تغيير vp، فلا يمكن تغييره. تمر بالقيمة
ByPointer(&v); التغييرات v. التمرير حسب المرجع (قد تقول إن ما تم تمريره هو في الواقع عنوان v، ولا يستطيع ByPointer تغيير عنوان v، لذا فإن هذا هو استدعاء حسب القيمة. يبدو هذا واضحًا بذاته، لكن عنوان v هو بيانات خالصة. عندما الاتصال غير موجود في الكود المربع بالنسبة للمتصل، يوجد فقط v، ويتم تغيير v بالفعل بواسطة وظيفة ByPointer إن السلوك المرجعي هو الهدف الأصلي لاستراتيجية التقييم، فإذا تم تلخيص كل شيء في القيم وتم النظر في المشكلة من منظور البيانات، فلا داعي لإدخال مفهوم استراتيجية التقييم لإرباك الجمهور. )
nob: يمكن استخدام طريقة المؤشر التكميلية بطريقتين: تمرير المؤشر؛ تمرير عنوان أو مرجع المتغير؛ عرض &v وvp، ستجد أن كلاهما من نوع النقطة، لذا فإن الأداءين، نفس النتيجة. قد تفكر بي بهذه الطريقة
ByValue(&v); //خطأ
، في حين أن تمرير معلمات من أنواع مختلفة في C++ لن يمرر التجميع مباشرة.
تلخيص:
لذا أعتقد أنه إذا مررت حسب القيمة أو المرجع، فأنت بحاجة فقط إلى رؤية كيف ستسير الأمور في الذاكرة.
مشاركة الذاكرة تعني تمرير مرجع، ونسخ الذاكرة يعني تمرير قيمة (مع ترك بعض الحالات الخاصة جانبًا أولاً)
في هذه الحالة:
C/C++: التمرير حسب القيمة بشكل افتراضي، والتمرير حسب المرجع، ويتم فهم المؤشرات بشكل منفصل (يمكن فهم المؤشرات على أنها تمرير حسب القيمة أو حسب المرجع، والنتائج هي نفسها)
JAVA: يتم تمرير أنواع البيانات الأساسية حسب القيمة، ويتم تمرير الكائنات أيضًا حسب القيمة (انسخ مرجع هذا الكائن)
C#: تمرير القيمة حسب نوع القيمة، والتمرير حسب المرجع حسب نوع المرجع، وفهم خاص للمرجع/الخارج
تحتاج السلاسل النصية في JAVA وC# إلى فهم خاص. يجب أن يتم تمرير المظهر حسب القيمة، لكن التنفيذ الفعلي يعتمد على الجهاز الظاهري.