struct (لغة البرمجة C)
في لغة البرمجة C ، تُستخدم الكلمة المفتاحية struct (التي تشير إلى بنية ) لتعريف نوع بيانات مُركّب ، يُعرف أيضًا باسم السجل ، وهو عبارة عن مجموعة مُسمّاة من القيم تشغل حيزًا من الذاكرة. يسمح هذا النوع بالوصول إلى القيم المختلفة عبر مُعرّف واحد ، غالبًا ما يكون مؤشرًا . يمكن أن تحتوي البنية على أنواع بيانات أخرى، لذا فهي تُستخدم للسجلات التي تحتوي على أنواع بيانات مُختلطة. على سبيل المثال، قد تحتوي بنية بيانات عميل بنكي على حقول لاسم العميل وعنوانه ورقم هاتفه ورصيده.
يشغل الهيكل (struct) كتلة متجاورة من الذاكرة، وعادةً ما يكون محددًا (مُقاسًا) بحدود طول الكلمة. وهو يُطابق الميزة التي تحمل الاسم نفسه والمتوفرة في بعض مُجمّعات معالجات إنتل. وبما أنه كتلة من الذاكرة المتجاورة، فإن كل حقل داخل الهيكل يقع عند إزاحة ثابتة مُحددة من البداية.
يُحدد عامل sizeof عدد البايتات اللازمة لتخزين بنية بيانات معينة، تمامًا كما هو الحال مع أنواع البيانات الأولية . ويعتمد محاذاة حقول معينة في البنية (بالنسبة لحدود الكلمات ) على التنفيذ، وقد يشمل ذلك إضافة حشو. تدعم المترجمات الحديثة عادةً التوجيه sizeof، الذي يُحدد حجم المحاذاة بالبايتات. [ 1 ]#pragma pack
تم اشتقاق ميزة بنية C من المفهوم الذي يحمل نفس الاسم في ALGOL 68. [ 2 ]
تصريح
يوضح المثال البسيط التالي كيفية تعريف بنية بيانات باسم MyStruct، تحتوي على حقلين من النوعين Type1و Type2على التوالي.
struct MyStruct { Type1 member1 ; Type2 member2 ; };إضافة الاسم MyStructاختيارية في بعض السياقات.
قد يتم إضافة حشوات إلى الأعضاء لتحسين محاذاة الذاكرة ، وبالتالي يُنصح غالبًا بترتيب الحقول من الأكبر إلى الأصغر حجمًا لتحقيق استخدام فعال للذاكرة.
قد تُعيد الدالة بنية بيانات مباشرةً، مع أن هذا الأسلوب غالبًا ما يكون غير فعال أثناء التشغيل. منذ معيار C99 ، يُمكن أن تنتهي بنية البيانات أيضًا بعضو مصفوفة مرن .
يمكن أن تتكون الهياكل من هياكل أخرى:
struct Date { int year ; int month ; int day ; };struct Birthday { char name [ 50 ]; struct Date dob ; };من القانوني تعريف بنية مجهولة داخل بنية أخرى، ولكن لا يمكن تسميتها في لغة C (لأنه لا يوجد مفهوم للأنواع المتداخلة ، على عكس لغة C++ حيث يكون تداخل البنى المسماة قانونيًا).
struct Person { char name [ 50 ]; int age ; struct { char city [ 50 ]; int zip ; } addr ; };يُستخدم عادةً هيكل البيانات الذي يحتوي على مؤشر إلى هيكل بيانات من نوعه الخاص لبناء هياكل البيانات المرتبطة :
struct LinkedList { void * item ; // يخزن العنصر الحالي struct LinkedList * next ; // يخزن القائمة التالية، أو NULL إذا لم يكن هناك عنصر تالٍ };يجب أن تتم الإشارة الدائرية بين بنيتين باستخدام التصريح المسبق والمؤشرات:
البنية B ؛struct A { struct B * b ; };struct B { struct A * a ; };تعريف النوع
باستخدام الكلمة المفتاحية typedef، يمكن الإشارة إلى نوع البنية دون استخدام الكلمة structالمفتاحية. مع ذلك، تنصح بعض أدلة أسلوب البرمجة [ 3 ] بعدم القيام بذلك، بدعوى أنه قد يُخفي نوع البنية.
على سبيل المثال:
typedef struct MyStruct { Type1 member1 ; Type2 member2 ; } Thing ;// يمكن الآن الإشارة إلى البنية MyStruct باسم 'Thing' Thing thing ;في لغة C++، يمكن الإشارة إلى النوع إما بـ struct Thingأو Thing(دون الحاجة إلى typedef). typedefكما يتم استبدال في C++ بالعبارة using، والتي يمكنها تسمية الأنواع التي تحتوي على قوالب .
التهيئة
بالنظر إلى تعريف البنية:
struct Point { int x ; int y ; };هناك ثلاث طرق لتهيئة بنية ما:
تُستخدم مُهيئات نمط C89 عندما يُمكن إعطاء أعضاء متجاورة. [ 4 ] على سبيل المثال:
struct Point a = { 1 , 2 };بالنسبة لقوائم الأعضاء غير المتجاورة أو غير المرتبة، يمكن استخدام نمط التهيئة المحدد (المقدم في C99). [ 5 ] على سبيل المثال:
struct Point a = { . x = 1 , . b = 2 };// قد يتم تهيئة الحقول خارج الترتيب أيضًا struct Point b = { . y = 4 , . x = -3 };إذا تم تحديد قيمة ابتدائية أو إذا تم تخصيص الكائن بشكل ثابت ، فسيتم تهيئة العناصر المحذوفة إلى 0.
ثمة طريقة ثالثة لتهيئة بنية ما، وهي نسخ قيمة كائن موجود من نفس النوع. على سبيل المثال:
struct Point b = a ;ينسخ
يمكن نسخ حالة بنية البيانات إلى نسخة أخرى. قد يستخدم المترجم هذه الطريقة memcpy()لنسخ بايتات كتلة الذاكرة.
struct Point a = { 1 , 3 }; struct Point b ; b = a ;حقول البت
قد تستخدم الهياكل أيضًا حقول البت للسماح للحقول بمشاركة وحدات التخزين نفسها، ولكن يتم تحديد التخطيطات من قبل التنفيذ.
struct Properties { // يمكن ضغط ثلاثة حقول في بايت واحد unsigned char visible : 1 ; // a يشغل بت واحد unsigned char color : 3 ; // b يشغل 3 بتات unsigned char size : 4 ; // c يشغل 4 بتات };نصائح
يمكن استخدام المؤشرات للإشارة إلى عنصر ما structبواسطة عنوانه. يُفيد هذا في تمرير بنية بيانات إلى دالة لتجنب تكلفة نسخ البنية. يقوم ->المعامل بإلغاء مرجعية المؤشر (المعامل الأيسر) والوصول إلى قيمة عنصر من عناصر البنية (المعامل الأيمن).
struct Point p = { 3 , 7 }; int x = p . x ; p . x = 10 ; struct Point * pp = & p ; x = pp -> x ; pp -> x = 8 ;يمكن للدوال أن تأخذ بنية بيانات كمعامل بالقيمة، لكن هذا مكلف لأنه ينسخ البنية بأكملها. في المقابل، يُفضل تمريرها عبر مؤشر لأن حجم المؤشر معروف (عادةً 4 أو 8 بايت).
#include <stdio.h>// بنية بيانات أكبر قد تحتوي على الكثير من البيانات struct Student { char name [ 50 ]; unsigned int id ; unsigned int chapter ; float gpa ; };// تمرير القيمة void print_student ( struct Student s ) { printf ( "الاسم: %s، الرقم التعريفي: %d، في الفصل الدراسي %d، بمعدل تراكمي: %.2f \n " , s . name , s . id , s . chapter , s . gpa ); }// تمرير البيانات بواسطة مؤشر void print_student ( struct Student * s ) { printf ( "الاسم: %s، الرقم الجامعي: %d، الفصل الدراسي %d، المعدل التراكمي: %.2f \n " , s -> name , s -> id , s -> chapter , s -> gpa ); }بلغات أخرى
تحتوي لغات البرمجة Crystal (لغة البرمجة) [ 6 ] و D [ 7 ] و Go و Julia [ 8 ] و Rust و Swift و Zig [ 9 ] على هياكل.
لغة سي++
في لغة C++ ، تُشابه البنية (struct) في جوهرها نظيرتها في لغة C، ولكنها تتضمن أيضًا الدوال (methods). علاوة على ذلك، تُشابه الفئة (class ) البنية (struct) ولكن مع اختلاف في مستوى الوصول الافتراضي : فأعضاء الفئة تكون خاصة افتراضيًا، بينما أعضاء البنية تكون عامة افتراضيًا.
.شبكة
تتميز لغات .NET بخاصية مشابهة لبنية البيانات (struct) في لغة C ، وتُسمى في C# وفي Visual Basic struct.NET . توفر هذه البنية العديد من خصائص الفئة، ولكنها تعمل كنوع قيمة بدلاً من نوع مرجعي . على سبيل المثال، عند تمرير بنية بيانات .NET إلى دالة، تُنسخ القيمة بحيث لا تؤثر التغييرات التي تُجرى على مُدخلات الدالة على القيمة المُمررة. [ 10 ]Structure
انظر أيضاً
- حقل البتات – بنية بيانات تربط بتًا واحدًا أو أكثر من البتات المتجاورة
- عضو مصفوفة مرن - ميزة في لغة C
- بنية البيانات السلبية – مصطلح آخر للسجل
- نوع الاتحاد – نوع بيانات يسمح بقيم تنتمي إلى أنواع بيانات متعددة مختلفة
مراجع
- ↑ "هيكلة تخطيط الذاكرة في لغة C" . موقع Stack Overflow .
- ↑ ريتشي، دينيس م. (مارس 1993). "تطور لغة C" . نشرة ACM SIGPLAN . 28 (3): 201-208 . doi : 10.1145/155360.155580 .
يدين نظام تركيب الأنواع الذي اعتمدته لغة C بالكثير للغة Algol 68، على الرغم من أنه ربما لم يظهر بالشكل الذي يرضي أنصار Algol. كان المفهوم الأساسي الذي استخلصته من Algol هو بنية الأنواع القائمة على الأنواع الذرية (بما في ذلك البنى)، والمُركبة في مصفوفات ومؤشرات (مراجع) ووظائف (إجراءات). كما كان لمفهوم الاتحادات والتحويلات في Algol 68 تأثير ظهر لاحقًا.
- ↑ "أسلوب برمجة نواة لينكس" .
- ↑ كيلي ، آل؛ بول، إيرا (2004). كتاب عن لغة سي: البرمجة بلغة سي ( الطبعة الرابعة). ص 418. ISBN 0-201-18399-4.
- ↑ "مترجمات IBM Linux. تهيئة الهياكل والاتحادات" .
- ↑ "الهياكل - كريستال" . crystal-lang.org . تم الاطلاع عليه بتاريخ 8 فبراير 2026 .
- ↑ "الهياكل والاتحادات - لغة البرمجة D" . dlang.org . تم الاطلاع عليه بتاريخ 8 يوليو 2025 .
- ↑ "الأنواع · لغة جوليا" . docs.julialang.org .
- ↑ "الهياكل | zig.guide" . zig.guide . 20 أبريل 2024. تم الاطلاع عليه في 8 يوليو 2025 .
- ↑ "تمرير المعاملات في لغة C#" .
- لغة البرمجة سي
