سؤال

وهنا هو سيناريو معين لقد كنت واضحا حول (من حيث النطاق) لفترة طويلة.

والنظر في كود

#include <stdio.h>


typedef struct _t_t{
    int x;
    int y;
} t_t;

typedef struct _s_t{
    int a;
    int b;
    t_t t;
}s_t;

void test(s_t & s){
    t_t x = {502, 100};
    s.t = x;
}


int main(){
    s_t s; 
    test(s);

    printf("value is %d, %d\n", s.t.x, s.t.y);
    return 0;
}

والإخراج

value is 502, 100

ما هو الشيء مربكا بالنسبة لي هو ما يلي: إعلان

t_t x

وأعلن في نطاق اختبار وظيفة. لذلك من خلال ما قرأته حول البرمجة C، يجب أن تكون القمامة للخروج من هذا النطاق. ومع ذلك بإرجاع النتيجة الصحيحة. هل لأن "=" على الخط      s.t = س. نسخ قيم س في s.t؟

وتحرير ---

وبعد بعض التجارب

#include <stdio.h>


typedef struct _t_t{
    int x;
    int y;
} t_t;

typedef struct _s_t{
    int a;
    int b;
    t_t t;
}s_t;

void test(s_t & s){
    t_t x = {502, 100};
    t_t * pt = &(s.t);
    pt = &x;
}


int main(){
    s_t s; 
    test(s);

    printf("value is %d, %d\n", s.t.x, s.t.y);
    return 0;
}

والنواتج في الواقع

value is 134513915, 7446516

وكما هو متوقع.

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

المحلول

<اقتباس فقرة>   

هل لأن "=" على خط s.t = س. نسخ قيم س في s.t؟

نعم.

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

نصائح أخرى

<اقتباس فقرة>
   t_t x = {502, 100};
   s.t = x;

في أول اختبار الخاص بك ، أو كنت تعليمات المترجم إلى <م> نسخة قيمة x إلى s.t - وهذا يعمل كما هو متوقع. وx متغير محلي يخرج من نطاق، ولكن لم تتم الإشارة إليه خارج وظيفة - يتم نسخ البيانات الواردة فيه في البداية إلى عضو t من main() المتغير المحلي s ل. وسيكون على نحو فعال نفس إذا بدلا كتب:

t_t x = {502, 100};
s.t.x = x.x;
s.t.y = x.y;

في الاختبار الثاني ، أو تعيين مؤشر إلى مؤشر آخر، وكلاهما أعلن والمتغيرات المحلية. هذا لا يفعل شيئا مفيدا - القيمة في s.t لا تزال غير مهيأ. لقد المشروح رمز لمساعدتك على متابعته:

t_t x = {502, 100}; // local variable x initialized with 502, 100
t_t * pt = &(s.t); // local variable pt initialized with ADDRESS OF s.t
pt = &x; // local variable pt re-assigned to hold address of local variable x

// local variables go out of scope, output parameter s remains unmodified

وقراءة هذا: افتراضي copy- منشئات وعوامل التعيين

ومن خلال عدم توفير عامل التعيين، فإن _s_t البنية القيام الضحلة-نسخة من جميع أعضائها عندما يتم تعيينه. لأنك تخزين كل شيء في _t_t من حيث القيمة، يتم نسخ كافة البيانات من حيث القيمة.

والمشكلة أنك تصف هي عندما _t_t حاصل على مؤشر إلى البيانات.

وفي القضية:

typedef struct _s_t{
        int a;
        int b;
        t_t* t;
}s_t;

void test(s_t & s){
        t_t x = {502, 100};
        s.t = &x;
}

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

وETA: لأن قمت بإضافتها أكثر على السؤال ...

void test(s_t & s){
     t_t x = {502, 100};
     t_t * pt = &(s.t);
     pt = &x;
}

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

وأنت على حق، خط

s.t = x;

وسوف نسخ القيم من جديد.

وهناك asignment نسخ القيمة من متغير واحد في متغير آخر. ذلك على الرغم من ذهب س المحلي الأصلي، وكنت قد حصلت على نسخة في الصورة.

وسيكون مختلفا تماما عندما قمت بتعيينها مجرد مؤشر إلى x:

typedef struct _s_t{
        int a;
        int b;
        t_t* t;
}s_t;

void test(s_t & s){
        t_t x = {502, 100};
        s.t = &x;
}

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

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