سؤال

في بلدي لا يتجزأ من برنامج c لدي البنية:

struct var{
    unsigned long value;
    unsigned long length;

    + More
}

مجموعة من هذه البنيات تستخدم لعقد المتغيرات.معظم المتغيرات المخزنة هي ببساطة المخزنة في "القيمة" و حتى على طول يتم تعيين إلى 1.
بيد أن بعض هذه المتغيرات والمصفوفات و أحاول تخزين عنوان البدء في "القيمة".

unsigned long lookup[10];
variables[x].length = 10;

ثم أنا لست متأكدا تماما كيف لتخزين عنوان...

variables[x].value = lookup;
// lookup is a pointer so I cant put it into value

أو

variables[x].value = (unsigned long)lookup;
// value reads back through sprintf+uart as '536874692'
// which couldnt be a valid memory address!

ربما تتخلى إضافة مؤشر متغير في بنية

تحرير:
كنت أرغب في تجنب إضافة مؤشر إلى البنية becasue أود أن أعود و كتابة فلاش قراءة/كتابة المهام أيضا حفظ المؤشر.هذه هي معقدة جدا حاليا العمل لذلك أنا أفضل أن لا تلمس لهم!

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

المحلول

لك يمكن أن تخزين عنوان في value قبل الصب إلى unsigned long, كما يمكنك إثبات.(أعتقد أنك تحصل على قيمة هو عنوان صالح...في عرافة ، فإنه يخرج كما 0x20000EC4...تبدو جزءا لا يتجزأ من نظام بيانات يبدأ الجزء في 0x20000000؟)

ومع ذلك, صب مؤشرات إلى رجات (أو يتوق) أبدا "نظيفة".لماذا لا تضيف

unsigned long *starting_address;

إلى البنية الخاصة بك?ثم يمكنك تجنب typecasts.إذا كنت قلقا من أن هذا سوف تتطلب المزيد من الذاكرة ، يمكنك استخدام الاتحاد الذي يخزن إما unsigned long *starting_address أو 'غير موقعة طويلة قيمة` التي لا تزال أنظف من الصب.

نصائح أخرى

نظافة خيار استخدام الاتحاد.

 struct var{
     union {
        unsigned long numeric;
        void *ptr;  
     } value;
     unsigned long length;

     + More
 }

يمكنك اختياريا تشمل أيضا نوع enum ، وغالبا ما يتم ذلك مع الاتحاد باستخدام قطعة.

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

struct var{
    unsigned short type;
    union {
        unsigned long i;
        void *p;
    } value;
    unsigned long length;

    + More
}

حيث يمكنك تخزين نوع في type.

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

struct var
{
   unsigned long *value;
   unsigned long length;

   unsigned long othervalue1;
   unsigned long othervalue2;
};

ولكن لا تنسى أن تخصيص الذاكرة على القيمة بشكل منفصل عن طريق استخدام malloc.أو إذا كانت كمية محددة من الفضاء تريد استخدام

unsigned long value[50];

ماذا يحدث إذا كنت sprintf+uart البحث.ما هي القيمة التي تعطي لك ؟

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

الحل فقط استخدام مؤشر جيد.إذا كنت تريد حقا أن استخدام int, يجب عليك استخدام intptr_t الذي هو ضمان أن تكون كبيرة بما يكفي لتناسب مؤشر.

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

لست متأكدا لماذا أنت لست تحديد قيمة غير موقعة طويلة*.

بدلا من أن تفعل شيئا مثل:

struct var{
  union{
    unsigned long solo_value;
    unsigned long* multi_values;
  }

  unsigned long length;
  + More
};

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

*من الناحية الفنية malloc() وآخرون.al.تطبيق 8 بايت محاذاة القواعد ، وليس لغة.

أفضل خيار هو استخدام التعداد, كما سبق ذكره:

typedef struct var{
     union {
        unsigned long numeric;
        void *ptr;  
     } value;
     unsigned long length;

     // + More
 } composition_t;

ثم استخدام طول عضو تميز نوع البيانات:

composition_t array[2];
unsigned long lookup[10];

// Just a plain unsigned long value
array[0].value.numeric = 100;
array[0].length= 1;

// An array of 10 long values
array[0].value.ptr= lookup;
array[x].length = 10;

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

هل أنت على علم من offsetof?http://en.wikipedia.org/wiki/Offsetof

لست متأكدا ما كنت تحاول حقا أن تفعل ، ولكن تخزين عنوان واحد بنية الأعضاء في نفس الهيكل يبدو لا لزوم لها.

هناك أيضا container_of الكلي (جوجل) التي بنيت باستخدام offsetof و التي قد تكون مفيدة أيضا.

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