ماذا تعني النقطتان في إعلان البنية، مثل:1 أو:7 أو:16 أو:32؟

StackOverflow https://stackoverflow.com/questions/1604968

  •  05-07-2019
  •  | 
  •  

سؤال

ماذا يعني كود C++ التالي؟

unsigned char a : 1; 
unsigned char b : 7;

أعتقد أنه ينشئ حرفين a وb، ويجب أن يبلغ طول كل منهما بايت واحد، لكن ليس لدي أي فكرة عن ":1" و":7 "الجزء يفعل.

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

المحلول

يعد 1 و7 أحجام بت للحد من نطاق القيم.عادة ما يتم العثور عليهم في الهياكل والنقابات.على سبيل المثال، في بعض الأنظمة (يعتمد على char قواعد العرض والتعبئة، وما إلى ذلك)، الكود:

typedef struct {
    unsigned char a : 1;
    unsigned char b : 7;
} tOneAndSevenBits;

ينشئ قيمة 8 بت، بت واحد لـ a و 7 بت ل b.

يُستخدم عادةً في لغة C للوصول إلى القيم "المضغوطة" مثل nybble ذات 4 بت والتي قد تكون موجودة في النصف العلوي من حرف ذو 8 بت:

typedef struct {
    unsigned char leftFour  : 4;
    unsigned char rightFour : 4;
} tTwoNybbles;

بالنسبة لمحامي اللغة بيننا، يشرح القسم 9.6 من معيار C++11 هذا الأمر بالتفصيل، مع إعادة صياغته قليلاً:


حقول البت [class.bit]

عضو معلن للنموذج

     معرفيختار، يقررمحدد السمةيختار، يقرر   :   تعبير ثابت

يحدد حقل بت.يتم تحديد طوله من اسم حقل البت بنقطتين.الاختياري محدد السمة تخص الكيان الذي تم الإعلان عنه.سمة حقل البت ليست جزءًا من نوع عضو الفئة.

ال تعبير ثابت يجب أن يكون تعبيرًا ثابتًا متكاملاً بقيمة أكبر من أو تساوي الصفر.قد تكون قيمة التعبير الثابت المتكامل أكبر من عدد البتات في تمثيل الكائن لنوع حقل البت؛في مثل هذه الحالات، يتم استخدام البتات الإضافية كبتات حشو ولا تشارك في تمثيل القيمة لحقل البت.

يتم تحديد تخصيص حقول البت داخل كائن فئة من خلال التنفيذ.يتم تحديد محاذاة حقول البت من خلال التنفيذ.يتم تعبئة حقول البت في بعض وحدات التخصيص القابلة للعنونة.

ملحوظة: تنتشر حقول البت بين وحدات التخصيص في بعض الأجهزة وليس في أجهزة أخرى.يتم تعيين حقول البت من اليمين إلى اليسار في بعض الأجهزة، ومن اليسار إلى اليمين في أجهزة أخرى.- ملاحظة النهاية

نصائح أخرى

وأعتقد أن تلك ستكون bitfields.

بالمعنى الدقيق للكلمة، يجب أن يكون حقل البت عبارة عن int أو unsigned int أو _Bool.على الرغم من أن معظم المترجمين سيأخذون أي نوع متكامل.

المرجع C11 6.7.2.1:

يجب أن يكون لحقل البت نوع مؤهل أو غير مؤهل إصدار _Bool أو int موقع أو int غير موقع أو إصدار آخر النوع المحدد بالتنفيذ.

من المحتمل أن يقوم المترجم الخاص بك بتخصيص بايت واحد من مساحة التخزين، ولكن يمكنك الحصول على المزيد مجانًا.

المرجع C11 6.7.2.1:

يجوز للتنفيذ تخصيص أي وحدة تخزين قابلة للعنونة كبيرة بما يكفي لعقد حقل بت.

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

المرجع C11 6.7.2.1:

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

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