تجميع البيانات تحت مظلة واحدة باستخدام الـ Struct
السلام عليكم ورحمة الله وبركاته
الفهرس
المقدمة
شارفنا على الانتهاء من هذه السلسلة الجميلة عن أساسيات البرمجة
واليوم سيكون معنا موضوع مهم جداً وهو كيفية تجميع البيانات تحت مظلة واحدة
وهو مهم جدا لأنه سيمهد لنا الطريق للحديث عن الـ Object Oriented Programming
وهو موضوع مهم جداً في عالم البرمجة وعالم كامل بحد ذاته
المهم نحن سنتحدث عن الـ Struct
وهو نوع من البيانات يمكنك تعريفه بنفسك وتجميع البيانات تحته
وفي لغات أخرى يسمى Object
مثل في الـ Typescript
والـ Javascript
لنبدأ بالشرح ومعنا أول سؤال إذا كنت تريد بيانات مستخدم مثلاً
ماذا ستفعل ؟
ستقول لي أنا سأقوم بتعريف متغيرات لكل بيانات المستخدم
وليكن هكذا
string name = "Ahmed";
int age = 25;
string email = "[email protected]";
هذا جيد، الآن قم بتعريف بيانات أخرى لمستخدم آخر
string name2 = "Mahmoud";
int age2 = 24;
string email2 = "[email protected]";
هذا جيد أيضاً، قم بتعريف بيانات لمستخدم آخر
string name3 = "Kamal";
int age3 = 20;
string email3 = "[email protected]";
هل ترى المشكلة ؟
ستجد نفسك مع كل مستخدم تقوم بتعريف متغيرات جديدة
وتبدأ بترقيم هذه المتغيرات لتمييز بيانات كل مستخدم
هل يمكنك أن تقول لي أين المتغير الذي يحمل اسم Mahmoud
؟ ستقول لي أنه name2
هل يمكنك أن تقول لي أين البريد الإلكتروني لـ Kamal
؟ ستقول لي أنه email3
لكن هذه على مقياس بسيط جداً، ماذا لو كان لديك 100
مستخدم ؟ هل ستقوم بتعريف 100
نسخة من هذه البيانات وترقمها ؟
لنفترض أن رقمتها وسألتك أي المتغيرات الخاصة بالمستخدم الذي اسمه Kamal
هل ستتذكر رقمه ؟
لنفترض أنك تذكرت رقمه وقلت لي أنه name3
هذا بسبب أنك كإنسان أو كشخص كتب هذا الكود ستجاوب على هذا السؤال
حسنًا إن سألنا نفس السؤال للبرنامج هل سيفهم أن الـ name3
يعود لـ Kamal
؟ وبالتبعية هل سيعرف أن الـ age3
والـ email3
يعود لـ Kamal
؟
سؤال أخر إن قلت لك أحضر لي أسماء كل المستخدمين الذين أعمارهم أكبر من 20
سنة كيف ستقوم بحل هذه المسألة برمجيًا ؟
المشكلة هنا أنه لا يوجد رابط حقيقي بين المتغيرات بالنسبة للغة البرمجة إنها مجرد متغيرات مختلفة عشوائية لديها، ولا يوجد شيء حقيقي يربطهم
أنت كإنسان لديك الوعي لتفهم أن الـ age2
مرتبط بـ name2
بسبب أن إسم المتغير ينتهي برقم 2
هل سيفهم البرنامج او اللغة هذا الأمر ؟
هنا يأتي دور الـ Struct
ليسهل عليك تجميع البيانات تحت مظلة واحدة وتنظيمها وإدارتها
ما هو الـ Struct وكيف ننشئه ؟
الـ Struct
هو نوع من الأدوات التي توفرها لغات البرمجة لتسمح لك بتعريف وتجميع البيانات تحت مظلة واحدة
وستجد في باقي اللغات يسمى Object
وهو نفس الفكرة
وأيضًا عندما تدخل عالم الـ OOP
ستجد شيء يدعى الـ Class
وهو مشابه كثيرً للـ Struct
لكن يحمل مزايا أكثر
دعنا نركز على الـ Struct
ونرى كيف يمكننا استخدامه
أولاً قم بتعريف الـ Struct
struct اسم {
// بيانات المستخدم
};
هنا لتعريف الـ Struct
نقوم بكتابة الكلمة struct
ثم نكتب اسم الـ Struct
ونفتح قوسين المجموعة {}
وبداخل القوسين نقوم بتعريف بيانات المستخدم
هنا نحن نريد إنشاء Struct
للمستخدمين
لذا بديهيًا سنسميه User
ثم سنعرف بداخل بيانات مثل الإسم والعمر والبريد الإلكتروني
struct User {
string name;
int age;
string email;
};
هنا قمنا بتعريف Struct
يحمل اسم User
ويحتوي على بيانات المستخدم
هذا مجرد تعريف لنخبر لغة البرمجة كيف سيتعامل مع الشيء المدعو User
وما هي البيانات التي يحملها
لأنك كما تعرف لغات البرمجة لا تعرف ما هو User
وما هي البيانات التي يحملها
على سبيل المثال البرنامج لا يفهم ما هي الحيوانات البرمجة بشكل عام لا تعرف شيء يدعى Animal
انه مصطلح نستعمله نحن البشر، لكن البرنامج لا يعرفه، الأمر مماثل للسيارات البرنامج لا يعرف شيء يدعى سيارة
بمعنى اخر أي شيء نفهمه نحن البشر البرنامج لن يفهمه
فلذلك نحتاج لشيء لوصفه للبرنامج ليعرف كيف يتعامل معاه
لذا نحن نستخدم الـ Struct
و الذي من خلاله نصنف أو نمثل للبرنامج الشيء الغريب عليه ونبدأ في وصفه
نمثله أي نعطيه خواص وافعال وهي المتغيرات التي تمثل خواصه والدوال التي ستمثل الافعال
مثل ما فعلنا في الـ User
نحن قمنا بتعريف بيانات المستخدم
وأخبرناه أنهنك شيء يدعى User
ويحمل بيانات مثل الإسم والعمر والبريد الإلكتروني
تعريف متغير من الـ Struct
بعد أن قمنا بتعريف الـ Struct
نحن نستطيع الآن استخدامه كنوع بيانات جديد أي data type
مثل الـ int
والـ string
وغيرها
ونستطيع تعريف متغيرات من نوع الـ Struct
وتخزين البيانات بها
User user1;
هنا قمنا بتعريف متغير من نوع User
وأسميناه user1
الأمر بسيط جداً وهو مشابه لتعريف متغير من نوع int
أو string
int number;
string name;
هنا نحن نتعامل مع الـ User
بنفس الطريقة كنوع بيانات نحن قمنا بإنشائها
فهنا نحن نقوم بإنشاء متغير من نوع User
ونسميه user1
وهذا المتغير سيحمل بيانات المستخدم
تخزين البيانات في متغير من الـ Struct
الآن بعد بإنشاء Struct
لنعرف الـ User
للغة البرمجة
struct User {
string name;
int age;
string email;
};
وبعد أن قمنا بإنشاء متغير من نوع User
وأسميناه user1
User user1;
الآن لدينا متغير من نوع User
وهو user1
ونريد تخزين بيانات المستخدم فيه
نحن نعرف أن هذا المتغير بداخله 3
متغيرات name
و age
و email
والتي عرفناها في الـ Struct
ولذا السؤال حاليًا هو كيف نصل إلى هذه المتغيرات التي بداخل المتغير user1
؟
الطريقة بسيطة جداً وهي عن طريقة الـ dot
أي النقطة .
user1.name = "Ahmed";
لاحظ هنا أننا نقوم بكتابة اسم المتغير user1
ثم نكتب النقطة .
ثم نكتب اسم المتغير الذي نريد الوصول إليه
وهنا نحن استطعنا الوصول إلى المتغير name
الذي بداخل المتغير user1
وقمنا بتخزين القيمة Ahmed
فيه
نستطيع الآن تخزين البيانات الأخرى بنفس الطريقة
user1.name = "Ahmed";
user1.age = 25;
user1.email = "[email protected]";
لاحظ الآن أن المتغيرات name
و age
و email
أصبحت تنتمي إلى كيان موحد يجمعها وهو المتغير user1
وليست متفرقة كما كانت في السابقة
يمكنك اعطاء البيانات عند تعريف المتغير بشكل مباشر
User user1 = {"Ahmed", 25, "[email protected]"};
لاحظ هنا أننا نعرفها كأنها أراي ونعطيها القيم مباشرة
لكنها ليست أراي بل هي Struct
ولذلك يمكنك تعريفها بهذه الطريقة
لكن هذه علي مراعاة ترتيب البيانات بالترتيب الذي تم تعريفها به في الـ Struct
بمعنى أنه أننا هنا قمنا بتعريف الـ User
بالترتيب name
ثم age
ثم email
لذا عند تعريف المتغير user1
يجب أن نعطيه القيم بنفس الترتيب
struct User {
string name;
int age;
string email;
};
User user1 = {"Ahmed", 25, "[email protected]"}; // ✅
User user2 = {25, "Ahmed", "[email protected]"}; // ❌
User user3 = {"Ahmed", "[email protected]", 25}; // ❌
User user4 = {"[email protected]", 25, "Ahmed"}; // ... ✅ لكن البريد الإلكتروني سيكون الاسم والاسم سيكون البريد الإلكتروني
أراي من الـ Struct ؟
قلنا أن الـ Struct
نستخدمه لتعريف نوع بيانات جديد للغة مثل الـ int
والـ string
وهذا ما قمنا به
وأنشأنا نوع بيانات جديد يدعى User
لذا طالما يمكننا عمل أراي من الـ int
والـ string
فهل يمكننا عمل أراي من الـ Struct
؟
الاجابة بالطبع نعم
User users[3];
هنا قمنا بتعريف أراي من الـ User
وأسميناه users
وطوله 3
بمعنى أنه أراي يحتوي على 3
عناصر من الـ User
بالتالي المستخدم الأول سيكون في الـ index
رقم 0
والمستخدم التاني سيكون في الـ index
رقم 1
والمستخدم الثالث سيكون في الـ index
رقم 2
وهنا يمكنك تخزين البيانات في كل عنصر من الأراي بنفس الطريقة
users[0].name = "Ahmed";
users[0].age = 25;
users[0].email = "[email protected]";
// أو بشكل مباشر
users[1] = {"Mahmoud", 24, "[email protected]"};
users[2] = {"Kamal", 20, "[email protected]"};
حل مسألة عن طريق الـ Struct
الآن لنرجع لسؤالنا السابق إذا كان لديك 100
مستخدم كيف ستقوم بتخزين بياناتهم والوصول إليها ؟
الآن بعد أن تعرفنا على الـ Struct
أظن اجابة السؤال واضحة
User users[100] = {
{"Ahmed", 25, "[email protected]"},
{"Mahmoud", 24, "[email protected]"},
{"Kamal", 20, "[email protected]"},
{"Ali", 15, "[email protected]"},
{"Salah", 30, "[email protected]"},
// ...
};
هنا قمنا بتعريف أراي من الـ User
وطوله 100
وقمنا بتعريف بيانات المستخدمين مباشرة
كأننا الآن نمتلك قاعدة بيانات صغيرة تحتوي على 100
مستخدم
ما رأيك في السؤال الذي طرحته سابقًا أحضر لي أسماء كل المستخدمين الذين أعمارهم أكبر من 20
سنة ؟
الآن نحن نمتلك أراي من الـ User
وكل مستخدم لديه بياناته الخاصة متجمعة تحت مظلة واحدة
بالتالي يمكننا الآن القيام بالعمليات البحثية والتحليلية على هذه البيانات بسهولة
تريد أن تعرف كم عدد المستخدمين الذين أعمارهم أكبر من 20
سنة ؟ حسنًا لا مشكلة
يمكننا عمل loop
على الأراي ومع كل لفة نقوم بالتحقق من عمر المستخدم وإذا كان أكبر من 20
نقوم بطباعة اسمه
for (int i = 0; i < 100; i++) {
if (users[i].age > 20) {
cout << users[i].name << '\n';
}
}
// OUTPUT:
// Ahmed
// Mahmoud
// Salah
// ... etc
لاحظ هنا أننا قمنا بعمل loop
على الأراي بالتالي مع كل لفة سيكون users[i]
هو المستخدم الذي نقف عنده لأن i
هو الـ index
الذي يزيد بمقدار 1
مع كل لفة
وبعد ذلك نقوم بالتحقق من عمر المستخدم بشرط بسيط users[i].age > 20
فإذا كان أكبر من 20
نقوم بطباعة اسمه
ما رأيك بسؤال آخر، ابحث عن صاحب هذا البريد الإلكتروني [email protected]
هل يمكنك القيام بذلك ؟ بالطبع يمكنك
for (int i = 0; i < 100; i++) {
if (users[i].email == "[email protected]") {
cout << users[i].name << '\n';
break; // لا داعي لاستكمال البحث طالما عثرنا على المطلوب
}
}
هنا قمنا بعمل loop
على الأراي ونقوم بالتحقق من البريد الإلكتروني لكل مستخدم
وإذا وجدنا المستخدم الذي يحمل البريد الإلكتروني المطلوب نقوم بطباعة اسمه وننهي البحث
الخاتمة
كما رأينا الـ Struct
هو أداة مهمة جداً في البرمجة لتجميع البيانات تحت مظلة واحدة
وتسهل علينا الكثير من الأمور وتساعدنا في تنظيم البيانات وإدارتها والوصول إليها بسهولة
وهي تتبع مبدأ الـ Encapsulation
وهو مبدأ مهم في الـ OOP
وسنتحدث عنه في مقالات الـ OOP
الموجودة في المدونة
هناك أمور تعمدت أن لا أتطرق لها في هذا المقال متعلقة بالـ Struct
لأنها تتعلق بالـ OOP
لذا سنتحدث عنها في مقالات الـ OOP
وهي مثل الـ Constructor
وإنشاء دوال خاصة بالـ Struct
والتي تسمى Methods
وغيرها من الأمور
ويمكنك أن اريك نبذة خاطفة عن انشاء دالة خاصة بالـ Struct
وهي
struct User {
string name;
int age;
string email;
void print() {
cout << "Name: " << name << '\n';
cout << "Age: " << age << '\n';
cout << "Email: " << email << '\n';
}
};
User user1 = {"Ahmed", 25, "[email protected]"};
user1.print();
هنا قمنا بإنشاء دالة داخل الـ Struct
وهي print
وهذه الدالة تقوم بطباعة بيانات المستخدم
وبعد ذلك قمنا بإنشاء متغير من الـ User
وأسميناه user1
وقمنا بطباعة بياناته بواسطة الدالة print
وهذا مثال بسيط عن كيفية إنشاء دوال خاصة بالـ Struct
بالطبع تعمدت أن لا أتطرق لهذه الأمور لأنني أريد أن استفيض فيها في مقالات الـ OOP
بالطبع مفهوم الـ Struct
ليس محصورًا في الـ C
أو C++
فقط بل هو موجود في العديد من لغات البرمجة الأخرى
ففي لغة Go
يوجد مفهوم الـ Struct
ويكتب هكذا
type User struct {
name string
age int
email string
}
user1 := User{
name: "Ahmed",
age: 25,
email: "[email protected]"
}
ففي الـ Typescript
والـ Javascript
يوجد مفهوم الـ Object
وهو نفس الفكرة
ويكتب هكذا
let user = {
name: 'Ahmed',
age: 25,
email: '[email protected]',
};
وفي الـ Python
يوجد مفهوم الـ Dictionary
user = {
'name': 'Ahmed',
'age': 25,
'email': '[email protected]',
}
وغيرهم من اللغات الأخرى
وأيضًا يوجد عالم كامل قائم على فكرة الـ Struct
وتجميع البيانات تحت مظلة واحدة وكل تلك الأمور
وهو عالم الـ Object Oriented Programming
وهو شيء مهم جدًا في عالم البرمجة وستجده في أي لغة تقريبًا وهو اسلوب برمجي يعتمد على الـ Object
والـ Class
والـ Encapsulation
والـ Inheritance
والـ Polymorphism
وغيرها من المفاهيم الهامة
وشرحناها في مقالات الـ OOP
الموجودة في المدونة
وهذا هو النهاية لهذا المقال وأتمنى أن تكون قد استفدت منه وأن تكون قد فهمت مفهوم الـ Struct
وكيفية استخدامه
لم أكن أريد أن أطيل عليك في هذا المقال لأنني أريد أن أترك لك الفرصة لتجربة الأمور بنفسك وتكتشفها بنفسك
ولأمهد لك الطريق لتتعرف على الـ OOP
والعالم الجميل الذي ستدخله