اذهب إلى المحتوى

السؤال

Recommended Posts

  • 1
نشر

مرحبًا @محمد خالد19

النوع الأول وهو value type أو ما يسمى بالأنواع البدائية primitive types وقد تكون عبارة عن أحد هذه الأنواع (String - Number - Boolean - Null - Undefined)

النوع الثاني reference type وهو وقد يكون عبارة عن أحد هذه الأنواع (object - Array - Function)

ولفهم الفرق بينهما أكثر سأشرح المثال التالي:

var x = 1
var y = x
x = 3

console.log(x)	// Output: 3

console.log(y)	// Output: 1

في الكود أعلاه يظهر أن قيمة المتغير x تم إسنادها إلى المتغير y، لاحظ القيمة فقط ما تم إسنادة إلى المتغير y، لذلك عند تغير قيمة المتغير x لم يتأثر المتغير y لأن كل منهما مستقل بذاته عن الآخر بالرغم من أنهما يحتويان قيم متساوية في البداية. (وهذا لأن المتغير x من نوع number)

var x = {name: 'Sameh'}
var y = x
x.name = 'Ali'

console.log(x)	// Output: {name: 'Ali'}
console.log(y)	// Output: {name: 'Ali'}

أما في هذا المثال نلاحظ أن قيمة المتغير y تغيرت بعد أن قمنا بتغير قيمة المتغير x وهذا لأن المتغير y لا يحتوي على قيمة المتغير x بل يحتوي على مرجع reference للمتغير x (أي يشير إلى قيمة المتغير x) (وهذا لأن المتغير x من نوع object)

  • 0
نشر

إن كلا التقنيتين تستخدمان عند تمرير الوسطاء parameters للدوال functions.

نستخدم value type (نمط القيمة) عندما نريد تمرير نسخة من قيمة متحول Variable ما من مرحلة تنفيذ البرنامج بهذه اللحظة للدالة الهدف ويمكننا عندها استقبال النتيجة منها عن طريق return أو طباعة النتيجة مباشرة. (لن تتغير قيمة المتحول الأصلية)

نستخدم reference type (نمط المرجع) عندما نريد للدالة المستدعاة التعديل على فقيمة المتحول مباشرة وليس أخذ نسخة عنه، أي أن أي تعديل يتم على المتحول في تلك الدالة (التي مررنا لها المتحول بالعنوان) ستعمل على تغييير قيمته في البرنامج بشكل عام.

الأمثلة المقدمة من لغة ++C: ( للتمرير بالعنوان نضع & بين نمط المتحول و اسمه في جزء تعريف الدالة)

#include <iostream> 
using namespace std; 
  
void add_val(int  x, int  y) 
{ 
	x = x + y; 
} 
  
void add_ref(int& x, int& y) 
{ 
	x = x + y; 
} 
  
int main() 
{ 
    int a,b;
  	
  	a = 5, b = 10;
  	add_val(a, b);
  
  	cout << "a = " << a << " b = " << b << "\n"; 
  
  	a = 5, b = 10;  
    add_ref(a, b); 
  

    cout << "a = " << a << " b = " << b << "\n"; 
}

نلاحظ أن تنفيذ الدالة الأولى لا يؤثر على المتغيرين a , b المعرفين ضمن الدالة main بعد استدعاء الدالة add_val.

أما الدالة الثانية التي تأخذ الوسيط عن طريق المرجع add_ref تغيير x أو y سيؤدي لتغيير a, b.

خلاصة: عند التمرير بالقيمة تقوم الدالة بتعريف متغير جديد في الذاكرة لكنه يأخذ قيمة الوسيط المقابل له الممر عند الاستدعاء.

أما في حالة التمرير بالمرجع تستخدم الدالة اسم مستعار لنفس المتغير الأصلي (في حالتنا x بدل a و y بدل b) أي أنهما ليسا متغيريين جديدين، إنما أصبحو متغيرات اسميه مختلفة لنفس المواقع في الذاكرة التي تحفظ البينات الخاصة بهم.

pass-by-reference-vs-pass-by-value-animation.gif

call-by-value-and-call-by-reference-in-cpp1.png

  • 0
نشر
بتاريخ 15 دقائق مضت قال محمد خالد19:

لم انوه فانا اتعلم  C#

لا يختلف المفهوم باختلاف لغات البرمجة، إنما بعض الرموز مثلا في #C لأخذ قيمة مرجعية نستخدم الكلمة المفتاحية ref 

class Program
{
    static void Main(string[] args)
    {
        int arg;

        // Passing by value.
        // The value of arg in Main is not changed.
        arg = 4;
        squareVal(arg);
        Console.WriteLine(arg);
        // Output: 4

        // Passing by reference.
        // The value of arg in Main is changed.
        arg = 4;
        squareRef(ref arg);
        Console.WriteLine(arg);
        // Output: 16
    }

    static void squareVal(int valParameter)
    {
        valParameter *= valParameter;
    }

    // Passing by reference
    static void squareRef(ref int refParameter)
    {
        refParameter *= refParameter;
    }
}

إذا كان لديك شيفرة برمجية تريد شرحها تفضل بكتابتها

  • 0
نشر
namespace test
{
    class Program 
    {
        static void  one (int num)
        {
         num =5;
            Console.WriteLine("Write number" + num);
            

        }
        static void Main(string[] args)
             
        {
            int num = 6;
            one(num);
            Console.WriteLine("number" + num);
            Console.ReadLine();
        }
    }
}

اجد انك تستخدم (args) دون كتابة(static void  one (int num))

(args)هل هي شاملا
 

  • 0
نشر
بتاريخ 1 دقيقة مضت قال محمد خالد19:

(args)هل هي شاملا

نستخدم args في التابع Main عندما نريد تنفيذ البرنامج من محرر الأوامر CMD مثلا أو تمرير بيانات للبرنامج عند تشغيله.

تعتبر args إختيارية، يمكنك حذفها و تجريب البرنامج.

إن البيانات الممررة للتابع one تعتبر محلية ضمن البرنامج وليست مُدخلات خارجية.

إن args تعتبر مصفوفة نصية و يمكن الوصول لبياناتها عن طريق دليل العنصر.

using System;

namespace helloWorld
{
    class MainClass
    {
        public static void Main(string[] args)
        {
            if (args.Length > 0)
            {
                Console.WriteLine("Hello " + args[0]); // هنا
            }
            else
            { 
                Console.WriteLine("Hello World!");
            }
        }
    }
}

في حال استخدامك visual studio code يمكنك تمرير البيانات عن طريق args بالطريقة التالية:

Options > Run > Configurations > Default .. Arguments

args-vs.thumb.png.78011460fbb0ca229ef3e474788fea5f.png

تنفذ بسطر الأوامر بهذه الطريقة:

Path/to/YourProg.exe arg1 arg2

مثال كامل: أولا البرنامج ثم لتفتح CMD في المسار الصحيح و تنفيذ التعليمات التالية بعد البرنامج:

using System;

namespace helloWorld
{
    class Program
    {
        static void Main(string[] args)
        {
            string name = args[0];
            Console.WriteLine("Hello {0}", name);
        }
    }
}
ترجمة الملف
csc Program.cs

تنفيذه
Program.exe Bob   or// Program Bob
Hello Bob

يمكنك تشغيل البرنامج يالذهاب للمجلد بعد أن تنفذ الترجمة.

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...