سؤال

لقد بدأت مرة أخرى باستخدام لغة c++ وكنت أفكر في نطاق المتغيرات.إذا كان لدي متغير داخل دالة ثم قمت بإرجاع هذا المتغير، فهل سيكون المتغير "ميتًا" عند إعادته لأن النطاق الذي كان فيه قد انتهى؟

لقد جربت ذلك باستخدام دالة تُرجع سلسلة وقد نجحت.يمكن لأي شخص أن يفسر هذا؟أو على الأقل دلني على مكان ما يمكن أن يوضح لي هذا من فضلك.

شكرًا

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

المحلول

عندما تنتهي الوظيفة ، تحدث الخطوات التالية:

  • يتم نسخ قيمة إرجاع الوظيفة إلى العنصر النائب الذي تم وضعه على المكدس لهذا الغرض.

  • كل شيء بعد انتشار مؤشر إطار المكدس.هذا يدمر جميع المتغيرات والحجج المحلية.

  • يتم عرض قيمة الإرجاع من المكدس ويتم تعيينها كقيمة الوظيفة.إذا لم يتم تعيين قيمة الوظيفة لأي شيء ، فلن يتم إجراء أي مهمة ، وفقدت القيمة.

  • يتم عرض عنوان التعليمات التالية للتنفيذ قبالة المكدس ، واستئناف وحدة المعالجة المركزية في التنفيذ في تلك التعليمات.

المكدس والكومة

نصائح أخرى

عند إرجاع قيمة، يتم إنشاء نسخة. نطاق المتغير المحلي ينتهي، ولكن يتم إجراء نسخة، وعاد إلى وظيفة الدعوة. مثال:

int funcB() {
  int j = 12;
  return j;
}

void A() {
  int i;
  i = funcB();
}

ويتم نسخ قيمة (12) ي وعاد إلى i لدرجة أنني سوف تحصل على قيمة 12.

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

int *myBadAddingFunction(int a, int b)
{
    int result;

    result = a + b;
    return &result; // this is very bad and the result is undefined
}

char *myOtherBadFunction()
{
    char myString[256];

    strcpy(myString, "This is my string!");
    return myString; // also allocated on the stack, also bad
}

وفقط لأكثر قليلا من تفسير الذاكرة النموذج الموجه: عندما يتم استدعاء وظيفة، يتم إجراء مساحة مؤقتة لوظيفة لوضع المتغيرات المحلية، ودعا إطار <م> . عندما ترجع الدالة (المستدعي) قيمته، فإنه يضع قيمة الإرجاع في إطار وظيفة الذي يطلق عليه (المتصل)، ومن ثم يتم تدمير إطار المستدعي.

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

ويتم نسخ متغير محلي إلى قيمة الإرجاع. تسمى منشئات نسخة لفئات غير تافهة.

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

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

std::string someFunc( std::string& const s)
{
    return s + "copy";
}

وإذا كانت وظيفة تعود إشارة، ثم عليك أن تكون حذرا حول ما كنت عودته لأنه احتياجات العمر لتتجاوز عمر وظيفة، وسوف المتصل لا يكون بالضرورة قادرا todelete إذا كنت تستخدم new ل إنشاء كائن:

std::string& someFunc2( std::string const& s)
{
    return s + "reference to a copy";   // this is bad - the temp object created will 
                                        //  be destroyed after the expression the 
                                        //  function call is in finishes.
                                        //  Some, but not all, compilers will warn 
                                        //  about this.
}

وبطبيعة الحال، فإن مؤشرات عودته لديها اعتبارات العمر مماثلة.

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