مضى على الشبكة و يوم من العطاء.

[ شرح ] لغة C وتخصيص الذاكرة (Memory Allocation) الشرح الأول

r00tki113rr00tki113r is verified member.

./عضو نشيط
>:: v1p ::<

السمعة:

بسم الله والحمد لله والصلاة والسلام على رسولنا محمد وعلى آله وصحبه أجمعين

اللهم علمنا ما ينفعنا وإنفعنا بم علمتنا إنك انت العليم الحكيم
السلام عليكم عائلتي الكريمة, إخواني وأخواتي الكرام جميعًا, حياكم الله

آسف للتأخر عليكم في نشر الشرح ولاكن كان لدي ظروف فإتطررت للتأخر عليكم, بتمنى من الجميع يسامحني ولنبدأ على بركة الله
في هذا الشرح, سوف نتحدث عن مفهوم تخصيص الذاكرة (Memory Allocation)

أولًا, ما هو تخصيص الذاكرة (Memory Allocation) ؟
كما يمكننا اأن نخمن من اسمه, تخصيص الذاكرة في لغة C هو حجز مكان في الرامات بمساحة معينة ومع عدد عناصر محدد وهنالك نوعين من تخصيص الذاكرة
طيب, ما هم هذان النوعان من تخصيص الذاكرة؟
هما:

  • تخصيص الذاكرة الثابتة (Static Memory Allocation)
  • تخصيص الذاكرة الديناميكية (Dynamic Memory Allocation)

طيب ماذا يعني تخصيص الذاكرة الثابتة؟
تخصيص الذاكرة الثابتة هو تخصيص مساحة من الذاكرة أثناء وقت الترجمة (compile time) من لغة عالية المستوى (High-Level Language) إلى لغة منخفضة المستوى (Low-Level Language) مثل binary (لغة الآلة), hexadecimal (نظام عد الستة عشري) او لغة اسامبلي
هذا يعني أن حجم الذاكرة المطلوبة يتم تحديده قبل تشغيل البرنامج وبالتالي لا يمكن تغيير حجم الذاكرة أثناء تشغيل البرنامج

طيب كيف ممكن أخصص مساحة, قسم أو جزء من الذاكرة كتخصيص ثابت ؟
بكل بساطة بقلك إنه هي العملية هي عبارة عن تعريف متغير كما سوف أفعل في الكود التالي:

C:
int staticVar;

في الكود الذي في الأعلى لقد تم حجز مساحة بالذاكرة لعنصر 1 بحجم int و staticVar هو اسم المتغير

بـتسألني وبتقول, طيب إذا بدنا نخزن أو نحجز 3 أماكن في الذاكرة وبحجم int بدي أكتب int int int staticVar; ؟؟

بقلك لا يانور عيوني, إذا بدك تحجز مكان في الذاكرة ل 3 عناصر وبحجم int وبدك إياهم يكونوا قريبين لبعض بمسار الذاكرة فبدك تسوي مصفوفة من نوع int وبتحتوي على 3 عناصر مثل ما مكتوب في الكود التالي:

C:
int staticVarArray[3];

وهيك بتكون حجزت مكان لثلاث عناصر والمسارات قريبة من بعضها وفي سطر كود واحد

بتقلي, طيب إذا بدي يكونوا بعيدين عن بعضهم كمسار في الذاكرة؟

بقلك سوي 3 متغيرات int وكل واحد منهم بيأخد منك سطر, فمجموع الأسطر لعمل هي العملية هو 3 أسطر وبالتالي فبتكون خسران بهالحركة إذا نظرت لك بعين محلل للخوارزميات والكود سوف يكون كالتالي:

C:
int staticVar1;
int staticVar2;
int staticVar3;

وهيك بنكون خلصنا من شرح تخصيص الذاكرة الثابتة

إذا ما هو تخصيص الذاكرة الديناميكية وما تفاصيله ؟
لا تستعجل يا أخي و أختي الكريم والكريمة, سوف أتوقع الأسئلة التي تخطر على بالكم وسوف أكتبها وأجيب عنها في هذا المنشور ولكن تحلى بالصبر, إنما للشياطين مكانه في أعمال العجلة أبعده الله عنا وعنكم وعن أمة المسلمين جميعًا

تخصيص الذاكرة الديناميكية هو تخصيص لمساحة الذاكرة أثناء وقت التشغيل (runtime), هذا يعني أن حجم الذاكرة يمكن أن يتغير أثناء تشغيل البرنامج

طيب كيف ممكن أخصص مساحة, قسم أو جزء من الذاكرة كتخصيص ديناميكي ؟ سوف أقول لك أن هناك طريقتين لتنفيذ هي العملية


ماهم هاتان الطريقتان, هما دالتين;
  • malloc (Memory Allocate)
  • calloc (Contiguous Allocate)

قبل أي شيء وأول شيء يجب علينا فعله هو إضافة المكتبة التي تدعم هذه الدوال أو الدالات التي نحتاج لاستخدامها في هذا الدرس والتي سوف نشرحها:
C:
#include<stdlib.h>

نقوم بإضافة الكود أعلاه إلى جانب المكاتب الملف أو إلى أعلى الكود

طيب ماهو ال syntax الخاص بهاتين الدالتين وهل يأخذان Parameters (باراميترات) أو مدخلات ؟
نعم, كلامك صحيح يا عزيزي القاريء, هناك مدخلات لكلا الدول منهم, لنتحدث عنهم بالترتيب

🔹 ماهي دالة malloc, كيف يمكنني استخدامها؟

دالة malloc هي دالة تستخدم لحجز او تخصيص مساحة ديناميكية, متغيرة في الذاكرة وبالتالي سيكون بإمكانك تغيير القيم أثناء عمل البرنامج بدون أية مشاكل والsyntax الخاص بالدالة malloc كالآتي:

C:
malloc(حجم البيانات);

وبالنسبة لأحجام البيانات فلا تقلق يا عزيزي القاريء, فأنا افتكرت ذلك و وضعته بالحسبان, هذا هو الجدول بكل البيانات التي سوف تحتاجها خلال مسيرتك في هذه العملية:

نوع البيانات (Data Type)​
المدى او النطاق (Range)​
الحجم بال بيت (Size in (Bytes))​
bool​
false او true​
1​
unsigned char​
0 إلى 255​
1​
signed char او char​
-128 إلى +127​
1​
wchar_t​
0 إلى 65,535​
2​
unsigned short int او unsigned short​
0 to 65,535​
2​
signed short int او short int او signed short او short​
-32,768 to 32,767​
2​
unsigned int​
0 to 4,294,967,295​
4​
signed int او int​
-2,147,483,648 to 2,147,483,647​
4​
unsigned long int او unsigned long​
0 to 4,294,967,295​
4​
signed long int او long int او signed long او long​
-2,147,483,648 to 2,147,483,647​
4​
unsigned long long int او unsigned long long​
0 to 18,446,744,073,709,551,615​
8​
signed long long int او signed long long او long long​
-9,223,372,036,854,775,808 to 9,223,372,036,854,775,807​
8​
float​
3.4E-38 to 3.4E+38 (7 خانات)​
4​
long float​
3.4E-38 to 3.4E+38 (7 خانات)​
4​
double​
1.7E-308 to 1.7E+308 (15 خانة)​
8​
long double​
1.7E-308 to 1.7E+308 (15 خانة)​
8​

طيب هل إذا بدي أكتب حجم الـ int بكتب 4 وهل مجبر أو يتوجب علي أن أحفظ أحجام أنواع البيانات؟
أسئلة جيدة يا عزيزي القاريء, السؤالين مرتبطين ببعضهم البعض لذا سأجيب عليهم بجواب واحد
نعم يمكنك كتابة 4 لحجم int ولكن في المجال هي الطريقة بدائية شوي وغير محببة وإن كنت تريد بأن تختصر على نفسك الوقت بالإضافة إلى ان يكون عملك شغل محترفين, فنصيحة مني استخدم الطريقة التالية فأنت محظوظ لأنك لن تكون مجبر على حفظ كل هذه المعلومات لأن الطريقة التالية تختصر عليك طريق ووقت ياعزيزي القاريء ولن تندم إن شاء الله
الحل هو استخدام دالة اسمها sizeof وهي الدالة له باراميتر أو مدخل واحد وهو متغير أو نوع البيانات, عندما تستدعي هذه الدالة وتعطيها ما تطلب فإنها تعطيك ما تريد, لنرى المثالين التاليين على استخدامها مع دالة malloc


C:
malloc(sizeof(نوع البيانات));
او
C:
malloc(sizeof(المتغير));

إذا نجحت عملية تخصيص المساحة فسوف ترجع الدالة مسار أو مؤشر أول عنصر من العناصر التي تم تخزينها في المصفوفة وفي الذاكرة أما إذا فشلت العملية فسوف يتم إرجاع قيمة NULL

بدك تقلي ممكن مثالين بالطريقتين, بقلك تكرم:

C:
malloc(sizeof(short));
C:
short sh3ll_users_count = 2056;
malloc(sizeof(sh3ll_users_count));

ونتيجة الكودين اللذان في الأعلى هي متساوية أو متطابقة بالأصح

بتقلي بدي أخزن القيمة في متغير, بقلك ممكن وتكرم عيونك ولكن لازم يكون متغير ومؤشر بنفس الوقت مثل ما في الكود التالي:


C:
int* ptr = (int*) malloc(sizeof(int));

أو يمكنك القيام بنفس العملية وتخزين القيمة بدون عمل تحويل لنوع البيانات (Casting)

C:
int* ptr = malloc(sizeof(int));

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

بتقلي ثانية ثانية, كيف, شلون خزنت مصفوفة بداخل متغير int من نوع مؤشر ؟

بقلك أنت قلتها, مؤشر وبالتالي المؤشر هو عبارة عن مسار ولا يعرف سوى إنه يمكن أن يحتوي على أكثر من قيمة في نفس المتغير ويمكن التعديل على حجم المتغير في الذاكرة لاحقا لذلك قرروا بأن تكون دائمًا نوع بياناته مصفوفة وبالتالي أصبحت تعرف يا عزيزي القاريء بأنك لا تحتاج لوضع اقواس مربعة بجانب اسم المتغير لجعله مصفوفة لأن المؤشر هو مصفوفة بالفعل.


ملاحظة: الطرق والاكواد يلي نفذناها بالأعلى تقوم بتخصيص ذاكرة ديناميكية لعنصر واحد فقط

شلون بدي أخصص ذاكرة ديناميكية لأكثر من عنصر ؟
الطريقة سهلة يا عزيزي القاريء, ما عليكم سوى ضرب حجم نوع البيانات بعدد العناصر والsyntax هو كالتالي:


C:
malloc(عدد العناصر * sizeof(نوع البيانات));

بدك مثال, تكرم:

C:
malloc(5*sizeof(long));

أما العدد 10 هو عدد العناصر وبالتالي ستكون قيمة المتغير هي مسار أول عنصر في الذاكرة وداخل المصفوفة

بتقلي طيب بدي اطبع القيمة الحقيقية للمتغير وليس مساره, بقلك تكرم:


C:
printf("%d ", ptr[0]);

قمنا بطباعة أول عنصر موجود في المصفوفة التي تم تخزينها في الذاكرة, وبالتالي سيتم طباعة رقم سلبي أو قيمة سلبية لأننا لم ندخل أي قيمة للعنصر رقم 0 في المصفوفة, خلينا ندخل قيمة للعنصر الأول في المصفوفة:

C:
ptr[0] = 2;

وهيك بنكون خلينا قيمة العنصر الأول في المصفوفة هي 2, خلينا نطبع قيمة العنصر الأول ونجرب ونشوف مع بعض:

C:
printf("%d ", ptr[0]);

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

C:
printf("%d ", ptr[11]);

بعد التجريب سوف ترون بأن النتيجة هي 0, طب بتقلي بدي أخلي القيم بعيدة عن بعضها, بقلك بدك تعمل مثل ماعملنا في تخصيص الذاكرة الثابتة, بدك تسوي متغيرات من نوع مؤشر منعزلة عن بعضها.

طيب ماهي دالة calloc, كيف يمكنني استخدامها؟

دالة calloc هي توأم الدالة malloc 😂

نصيحة مني هيك أعتبرها لأنها تأدي نفس وظيفة الدالة malloc ولكن تنفذ أمر إضافي في النهاية وهذا الذي يميذها عن malloc,

ما الفرق الذي يميز calloc عن malloc وما هو الsyntax الخاص بالدالة calloc

خلينا نشوف الفرق يلي بينهم مع بعض
شوف عزيزي القاريء, قلتلك أنه عند محاولة قرائة قيمة لعنصر من المصفوفة قبل إدخال قيمته فإنه يعطيك قيم سلبية أو أعداد عشوائية وليس لها أي مصدر

ولكن هذا الشيء لا يحصل مع دالة calloc لأنه يقوم بتغير جميع قيم العناصر إلى 0 وبالتالي هذه العملية التي تميز calloc عن malloc

أما بالنسبة للsyntax الخاص بدالة calloc فهو كالآتي:

C:
calloc(حجم العنصر, عدد العناصر);

لكي لا أطيل عليكم, أريد أن أقول لكم بأن كل شيئ ذكرناه حول دالة malloc يطبق أيضًا على دالة calloc بإستثناء الميزة التي تفرق بينهما

أريد أن أزيدك من الشعر بيت وأقلك يا عزيزي القاريء إنه من ممكن أن تصفر العناصر اأثناء استخدام دالة malloc, أقصد يمكنك تأدية نفس عملية calloc ولكن بدون الحاجة إليها, كيف؟ باستخدام دالة تدعى memset

ولكن لا يمكنك استخدامها بدون استدعاء المكتبة التي تحتويها, أليس كذلك؟ صحيح, هناك مكتبتين أعرفهم يدعمون الدالة التي نحتاجها وهم المكاتب التالية:


1-مكتبة string.h

C:
#include<string.h>

2-مكتبة memory.h

C:
#include<memory.h>

أنا شخصيًا استخدم مكتبة memory لأنني أراها مكتبة لها صلة بالكود منطقيًا, أما الخيار فأتركه لك عزيزي القاريء

ماهي دالة memset, ماذا تفعل, ماهو الsyntax الخاص بها او ماهي مدخلاتها او البراميترات الخاصة بها؟

دالة memset هي دالة تقوم بعملية تغيير قيم لكمية من العناصر المتواجدة في مصفوفة

دالة memset لها ثلاث باراميترات أو مدخلات والsyntax الخاص بها هو كالتالي:


C:
memset(حجم العناصر, قيمة العناصر, (نقطة البداية في المصفوفة) او المصفوفة نفسها)

لتحقيق هدفنا وهو تأدية وظيفة الدالة calloc ولكن بدون استخدامها, أقصد فقط باستخدام الدالة malloc و memset

أولًا, نقوم بتعريف متغير يحمل عدد عناصر المصفوفة والذي سيتم إستخدامه في دالة malloc

C:
int sh3ll_users_count = 10;

ثانيًا, نقوم بتعريف متغير يحمل قيمة الدالة malloc والذي يفترض بأن يكون مؤشر أو Pointer

C:
int* mPtr = (int*) malloc(sh3ll_users_count * sizeof(sh3ll_users_count));

ثالثًا, نقوم بطباعة القيم المتواجة في المصفوفة للإثبات والتأكد من صحة العملية

C:
printf("قبل تنفيذ دالة memset: \n");
for(int i = 0; i < sh3ll_users_count; i++) {
    printf("%d ", mPtr[i]);
}
printf("\n");
رابعا, نستخدم دالة memset لتصفير قيم جميع العناصر في المصفوفة كالآتي
C:
memset(mPtr, 0, sh3ll_users_count * sizeof(sh3ll_users_count));
خامسا, نطبع قيم المصفوفة للتأكد من انه تم تفير قيم العناصر فيها
C:
printf("بعد تنفيذ دالة memset: \n");
for(int i = 0; i < sh3ll_users_count; i++) {
    printf("%d ", mPtr[i]);
}
printf("\n");

وبعد أن تقوموا بتنفيذ الكود سوف نرى بأن قيم المصفوفة في نفس المسار في الذاكرة الديناميكية قد تم تغييرهم بنجاح

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


أتمنى الإفادة والإستفادة للجميع, بارك الله فيكم جميعًا
دمتم بسلام, تحياتي للجميع والسلام عليكم ورحمة الله وبركاته 🌹❤️
 
التعديل الأخير بواسطة المشرف:
بسم الله والحمد لله والصلاة والسلام على رسولنا محمد وعلى اله وصحبه اجمعين
اللهم علمنا ما ينفعنا وإنفعنا بم علمتنا إنك انت العليم الحكيم
السلام عليكم عائلتي الكريمة, اخواني واخواتي الكريمين والكرام جميعا, حياكم الله

آسف للتأخر عليكم في نشر الشرح ولاكن كان لدي ظروف فإتطررت للتأخر عليكم, بتمنى من الجميع يسامحني ولنبدأ على بركة الله
في هذا الشرح, سوف نتحدث عن مفهوم تخصيص الذاكرة (Memory Allocation)

اولا, ما هو تخصيص الذاكرة (Memory Allocation) ؟
كما يمكننا ان نخمن من اسمه, تخصيص الذاكرة في لغة C هو حجز مكان في الرامات بمساحة معينة ومع عدد عناصر محدد وهنالك نوعين من تخصيص الذاكرة
طيب, ما هم هاذان النوعان من تخصيص الذاكرة
هما;
  • تخصيص الذاكرة الثابتة (Static Memory Allocation)
  • تخصيص الذاكرة الديناميكية (Dynamic Memory Allocation)

طيب ماذا يعني تخصيص الذاكرة الثابتة
تخصيص الذاكرة الثابتة هو تخصيص مساحة من الذاكرة أثناء وقت الترجمة (compile time) من لغة عالية المستوى (High-Level Language) إلى لغة منخفضة المستوى (Low-Level Language) مثل binary (لغة الآلة), hexadecimal (نظام عد الستة عشري) او لغة اسامبلي
هذا يعني أن حجم الذاكرة المطلوبة يتم تحديده قبل تشغيل البرنامج وبالتالي لا يمكن تغيير حجم الذاكرة أثناء تشغيل البرنامج

طيب كيف ممكن اخصص مساحة, قسم او جزء من الذاكرة كتخصيص ثابت ؟
بكل بساطة بقلك انو هي العملية هي عبارة عن تعريف متغير كما سوف أفعل في الكود التالي
C:
int staticVar;
في الكود الذي في الأعلى لقد تم حجز مساحة بالذاكرة لعنصر 1 بحجم int و staticVar هو إسم المتغير

بـتسألني وبتقول, طيب إذا بدنا نخزن او نحجز 3 اماكن في الذاكرة وبحجم int بدي اكتب int int int staticVar; ؟؟
بقلك لا يانور عيوني, إذا بدك تحجز مكان في الذاكرة ل 3 عناصر وبحجم int وبدك إياهم يكونو قريبين لبعض بمسار الذاكرة فبدك تسوي مصفوفة من نوع int وبتحتوي على 3 عناصر مثل ما مكتوب في الكود التالي
C:
int staticVarArray[3];
وهيك بتكون حجزت مكان لثلاث عناصر والمسارات قريبة من بعضها وفي سطر كود واحد

بتقلي, طيب إذا بدي يكونو بعيدين عن بعضهم كمسار في الذاكرة
بقلك سوي 3 متغيرات int وكل واحد منهم بياخد منك سطر, فمجموع الأسطر لعمل هي العملية هو 3 أسطر وبالتالي فبتكون خسران بهالحركة إذا نظرت لك بعين محلل للخوارزميات والكود سوف يكون كالتالي
C:
int staticVar1;
int staticVar2;
int staticVar3;

وهيك بنكون خلصنا من شرح تخصيص الذاكرة الثابتة

إذا ما هو تخصيص الذاكرة الديناميكية وما تفاصيله ؟
لا تستعجل يا أخي و أختي الكريم والكريمة, سوف اتوقع الأسئلة التي تخطر على بالكم وسوف اكتبها واجيب عنها في هذا المنشور ولاكن تحلى بالصبر, إنما للشياطين مكانة في اعمال العجلة ابعده الله عنا وعنكم وعن امة المسلمين جميعا

تخصيص الذاكرة الديناميكية هو تخصيص لمساحة الذاكرة أثناء وقت التشغيل (runtime)
هذا يعني أن حجم الذاكرة يمكن أن يتغير أثناء تشغيل البرنامج

طيب كيف ممكن اخصص مساحة, قسم او جزء من الذاكرة كتخصيص ديناميكي ؟
سوف اقول لك ان هناك طريقتين لتنفيذ هي العملية

ماهم هاتان الطريقتان, هما دالتين;
  • malloc (Memory Allocate)
  • calloc (Contiguous Allocate)

قبل اي شيئ وأول شيئ يجب علينا فعله هو إضافة المكتبة التي تدعم هذه الدوال او الدالات التي نحتاج لإستخدامها في هذا الدرس والتي سوف نشرحها
C:
#include<stdlib.h>
نقوم بإضافة الكود اعلاه إلى جانب المكاتب الملف او الى اعلى الكود

طيب ماهو ال syntax الخاص بهاتين الدالتين وهل يأخذا Parameters (باراميترات) او مدخلات ؟
نعم, كلامك صحيح يا عزيزي القاريء, هناك مدخلات لكلا الدول منهم, لنتحدث عنهم بالترتيب

ماهي دالة malloc, كيف يمكنني إستخدامها؟
دالة malloc هي دالة تستخدم لحجز او تخصيص مساحة ديناميكية, متغيرة في الذاكرة وبالتالي سيكون بإمكانك تغيير القيم اثناء عمل البرنامج بدون اية مشاكل والsyntax الخاص بالدالة malloc كالآتي
C:
malloc(حجم البيانات);

وبالنسبة لأحجام البيانات فلا تقلق يا عزيزي القاريء, فأنا افتكرت ذلك و وضعته بالحسبان
هذا هو الجدول بكل البيانات التي سوف تحتاجها خلال مسيرتك في هذه العملية
نوع البيانات (Data Type)​
المدى او النطاق (Range)​
الحجم بال بيت (Size in (Bytes))​
bool​
false او true​
1​
unsigned char​
0 إلى 255​
1​
signed char او char​
-128 إلى +127​
1​
wchar_t​
0 إلى 65,535​
2​
unsigned short int او unsigned short​
0 to 65,535​
2​
signed short int او short int او signed short او short​
-32,768 to 32,767​
2​
unsigned int​
0 to 4,294,967,295​
4​
signed int او int​
-2,147,483,648 to 2,147,483,647​
4​
unsigned long int او unsigned long​
0 to 4,294,967,295​
4​
signed long int او long int او signed long او long​
-2,147,483,648 to 2,147,483,647​
4​
unsigned long long int او unsigned long long​
0 to 18,446,744,073,709,551,615​
8​
signed long long int او signed long long او long long​
-9,223,372,036,854,775,808 to 9,223,372,036,854,775,807​
8​
float​
3.4E-38 to 3.4E+38 (7 خانات)​
4​
long float​
3.4E-38 to 3.4E+38 (7 خانات)​
4​
double​
1.7E-308 to 1.7E+308 (15 خانة)​
8​
long double​
1.7E-308 to 1.7E+308 (15 خانة)​
8​

طيب هل إذا بدي اكتب حجم الint بكتب 4 وهل مجبر او يتوجب علي ان احفظ احجام انواع البيانات؟
اسئلة جيدة يا عزيزي القاريء, السؤالين مرتبطين ببعضهم البعض لذا سأجيب عليهم بجواب واحد
نعم يمكنك كتابة 4 لحجم int ولاكن في المجال هي الطريقة بدائية شوي وغير محببة وإن كنت تريد بأن تختصر على نفسك الوقت بالإضافة إلى ان يكون عملك شغل محترفين فنصيحة مني استخدم الطريقة التالية فأنت محظوظ لأنك لن تكون مجبر على حفظ كل هذه المعلومات لأن الطريقة التالية تختصر عليك طريق ووقت ياعزيزي القاريء ولن تندم إن شاء الله
الحل هو إستخدام دالة اسمها sizeof وهي الدالة له باراميتر او مدخل واحد وهو متغير او نوع البيانات
عندما تستدعي هذه الدالة وتعطيها ما تطلب فإنها تعطيك ما تريد, لنرى المثالين التاليين على استخدامها مع دالة malloc
C:
malloc(sizeof(نوع البيانات));
او
C:
malloc(sizeof(المتغير));
إذا نجحت عملية تخصيص المساحة فسوف ترجع الدالة مسار او مؤشر اول عنصر من العناصر التي تم تخزينها في المصفوفة وفي الذاكرة اما إذا فشلت العملية فسوف يتم إرجاع قيمة NULL

بدك تقلي ممكن مثالين بالطريقتين, بقلك تكرم
C:
malloc(sizeof(short));
C:
short sh3ll_users_count = 2056;
malloc(sizeof(sh3ll_users_count));
ونتيجة الكودين اللذان في الأعلى هي متساوية او متطابقة بالأصح

بتقلي بدي اخزن القيمة في متغير, بقلك ممكن وتكرم عيونك ولاكن لازم يكون متغير ومؤشر بنفس الوقت مثل ما في الكود التالي
C:
int* ptr = (int*) malloc(sizeof(int));
او يمكنك القيام بنفس العملية وتخزين القيمة بدون عمل تحويل لنوع البيانات (Casting)
C:
int* ptr = malloc(sizeof(int));

بتسألني وبتقول, طيب ليش حاطط إشارة عملية الضرب والتي هي نجمة (*) بجانب int او نوع البيانات
بقلك لأنو هي النجمة (*) عندما يتم وضعها بجانب نوع البيانات او int فهي تحول نوع البيانات الى نوع البيانات نفسه ولاكن على انه مؤشر وبالتالي هو مسار لمتغير او قيمة في الذاكرة

بتقلي ثانية ثانية, كيف, شلون خزنت مصفوفة بداخل متغير int من نوع مؤشر ؟
بقلك انت قلتها, مؤشر وبالتالي المؤشر هو عبارة عن مسار ولا يعرف سوى انه يمكن ان يحتوي على اكثر من قيمة في نفس المتغير ويمكن التعديل على حجم المتغير في الذاكرة لاحقا لذلك قررو بأن تكون دائما نوع بياناته مصفوفة وبالتالي اصبحت تعرف يا عزيزي القاريء بأنك لا تحتاج لوضع اقواس مربعة بجانب أسم المتغير لجعله مصفوفة لأن المؤشر هو مصفوفة بالفعل

ملاحظة: الطرق والاكواد يلي نفذناها بالأعلى تقوم بتخصيص ذاكرة ديناميكية لعنصر واحد فقط

شلون بدي اخصص ذاكرة ديناميكية لأكثر من عنصر ؟
الطريقة سهلة يا عزيزي القاريء, ما عليكم سوى ضرب حجم نوع البيانات بعدد العناصر والsyntax هو كالتالي
C:
malloc(عدد العناصر * sizeof(نوع البيانات));
بدك مثال, تكرم
C:
malloc(5*sizeof(long));
اما العدد 10 هو عدد العناصر وبالتالي ستكون قيمة المتغير هي مسار اول عنصر في الذاكرة وداخل المصفوفة

بتقلي طيب بدي اطبع القيمة الحقيقية للمتغير وليس مساره, بقلك تكرم
C:
printf("%d ", ptr[0]);
قمنا بطباعة اول عنصر موجود في المصفوفة التي تم تخزينها في الذاكرة
وبالتالي سيتم طباعة رقم سلبي او قيمة سلبية لأننا لم ندخل اي قيمة للعنصر رقم 0 في المصفوفة
خلينا ندخل قيمة للعنصر الأول في المصفوفة
C:
ptr[0] = 2;
وهيك بنكون خلينا قيمة العنصر الأول في المصفوفة هي 2, خلينا نطبع قيمة العنصر الأول ونجرب ونشوف مع بعض
C:
printf("%d ", ptr[0]);
بعد التجريب سوف ترون بأن النتيجة هي2 وهذا يعني ان امورنا ماشية بالخير
اما إذا حاولنا نتخطى عدد العناصر يلي ضربناه بحجم نوع البيانات بداخل الدالة malloc فسوف تكون القيمة 0 اثناء محاولتنا لطباعته
C:
printf("%d ", ptr[11]);
بعد التجريب سوف ترون بأن النتيجة هي 0
طب بتقلي بدي اخلي القيم بعيدة عن بعضها
بقلك بدك تعمل مثل ماعملنا في تخصيص الذاكرة الثابتة, بدك تسوي متغيرات من نوع مؤشر منعزلة عن بعضها

طيب ماهي دالة calloc, كيف يمكنني إستخدامها؟
دالة calloc هي توأم الدالة malloc 😂
نصيحة مني هيك أعتبرها لأنها تأدي نفس وظيفة الدالة malloc ولاكن تنفذ امر إضافي في النهاية وهذا الذي يميذها عن malloc,
ما الفرق الذي يميز calloc عن malloc وما هو الsyntax الخاص بالدالة calloc

خلينا نشوف الفرق يلي بينهم مع بعض
شوف عزيزي القاريء, قلتلك انه عند محاولة قرائة قيمة لعنصر من المصفوفة قبل إدخال قيمته فإنه يعطيك قيم سلبية او اعداد عشوائية وليس لها اي مصدر
ولكن هذا الشيء لا يحصل مع دالة calloc لأنه يقوم بتغير جميع قيم العناصر إلى 0 وبالتالي هذه العملية التي تميز calloc عن malloc

اما بالنسبة للsyntax الخاص بدالة calloc فهو كالآتي
C:
calloc(حجم العنصر, عدد العناصر);

لكي لا أطيل عليكم, أريد ان اقول لكم بأن كل شيئ ذكرناه حول دالة malloc يطبق ايضا على دالة calloc بإثتثناء الميزة التي تفرق بينهما

أريد ان ازيدك من الشعر بيت واقلك يا عزيزي القاريء انه من ممكن ان تصفر العناصر اثناء استخدام دالة malloc, اقصد يمكنك تأدية نفس عملية calloc ولاكن بدون الحاجة إليها
كيف؟
بأستخدام دالة تدعى memset

ولاكن لايمكنك استخدامها بدون استدعاء المكتبة التي تحتويها, اليس كذلك؟
صحيح, هناك مكتبتين اعرفهم يدعمون الدالة التي نحتاجها وهم المكاتب التالية
1-مكتبة string.h
C:
#include<string.h>

2-مكتبة memory.h
C:
#include<memory.h>

انا شخصيا استخدم مكتبة memory لأنني اراها مكتبة لها صلة بالكود منطقيا, اما الخيار فأتركه لك عزيزي القاريء

ماهي دالة memset, ماذا تفعل, ماهو الsyntax الخاص بها او ماهي مدخلاتها او البراميترات الخاصة بها؟
دالة memset هي دالة تقوم بعملية تغيير قيم لكمية من العناصر المتواجدة في مصفوفة

دالة memset لها ثلاث باراميترات او مدخلات والsyntax الخاص بها هو كالتالي
C:
memset(حجم العناصر, قيمة العناصر, (نقطة البداية في المصفوفة) او المصفوفة نفسها)

لتحقيق هدفنا وهو تأدية وظيفة الدالة calloc ولاكن بدون إستخدامها, اقصد فقط بإستخدام الدالة malloc و memset
اولا, نقوم بتعريف متغير يحمل عدد عناصر المصفوفة والذي سيتم إستخدامه في دالة malloc
C:
int sh3ll_users_count = 10;
ثانيا, نقوم بتعريف متغير يحمل قيمة الدالة malloc والذي يفترض بأن يكون مؤشر او Pointer
C:
int* mPtr = (int*) malloc(sh3ll_users_count * sizeof(sh3ll_users_count));
ثالثا, نقوم بطباعة القيم المتواجة في المصفوفة للإثبات والتأكد من صحة العملية
C:
printf("قبل تنفيذ دالة memset: \n");
for(int i = 0; i < sh3ll_users_count; i++) {
    printf("%d ", mPtr[i]);
}
printf("\n");
رابعا, نستخدم دالة memset لتصفير قيم جميع العناصر في المصفوفة كالآتي
C:
memset(mPtr, 0, sh3ll_users_count * sizeof(sh3ll_users_count));
خامسا, نطبع قيم المصفوفة للتأكد من انه تم تفير قيم العناصر فيها
C:
printf("بعد تنفيذ دالة memset: \n");
for(int i = 0; i < sh3ll_users_count; i++) {
    printf("%d ", mPtr[i]);
}
printf("\n");
وبعد ان تقومو بتنفيذ الكود سوف نرى بأن قيم المصفوفة في نفس المسار في الذاكرة الديناميكية قد تم تغييرهم بنجاح

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

كنت اريد ان اشرح لكم المزيد ولاكن لا أريد الإطالة عليكم, إذا اردتم فممكن اكمل الشرح في المنشور القادم إن شاء الله
اتمنى الإفادة والإستفادة للجميع, بارك الله فيكم جميعا
دمتم بسلام, تحياتي للجميع والسلام عليكم ورحمة الله وبركاته 🌹 ❤️
ما شاء الله لا قوة الا بالله
بارك الله فيك اخي وجزاك الله كل خير على هذا الطرح الرائع
الجدير بالذكر ان الاختلافات تظهر عند قدرة ال c على استخدام ال Heap في الميموري
بينما يعيش باقي الرفاق مع ال Stack في سعادة عارمة :D

ننتظر جديدك دائماً
تقبل مروري
 
ما شاء الله لا قوة الا بالله
بارك الله فيك اخي وجزاك الله كل خير على هذا الطرح الرائع
الجدير بالذكر ان الاختلافات تظهر عند قدرة ال c على استخدام ال Heap في الميموري
بينما يعيش باقي الرفاق مع ال Stack في سعادة عارمة :D

ننتظر جديدك دائماً
تقبل مروري
على راسي يا حبيب, والله هذا ماتعلمناه منك بنحاول نطبقه
عسى ان يجعل لنا رب العالمين مخرجا من المعاصي ويبعد عنا وعنكم الحرام والمساوئ

اصلا يا استاذي الكريم واخي العزيز, هي ميزة من بين ميزات لغة ال C يلي بتميذ لغة ال C عن جميعا لغات البرمجة, والاحلى من هيك انو لغة C بتعطيك الصلاحية والإمكانية للوصول لجذر النظام والتحكم به والكثير, عكس لغات البرمجة الأخرى
اما بالنسبة لساعدتك, فألله يسعدك طول عمرك يا أستاذي ويطول بعمرك
وبتشكرك جدا على كلماتك الراقية واللسان الحلو يلي عندك 😅
تحياتي لكم جميعا, دمتم بخير وسلام جميعا وجمعة مباركة على الجميع إن شاء الله ❤️🌹
 
  • Love
التفاعلات: STORM
على راسي يا حبيب, والله هذا ماتعلمناه منك بنحاول نطبقه
عسى ان يجعل لنا رب العالمين مخرجا من المعاصي ويبعد عنا وعنكم الحرام والمساوئ

اصلا يا استاذي الكريم واخي العزيز, هي ميزة من بين ميزات لغة ال C يلي بتميذ لغة ال C عن جميعا لغات البرمجة, والاحلى من هيك انو لغة C بتعطيك الصلاحية والإمكانية للوصول لجذر النظام والتحكم به والكثير, عكس لغات البرمجة الأخرى
اما بالنسبة لساعدتك, فألله يسعدك طول عمرك يا أستاذي ويطول بعمرك
وبتشكرك جدا على كلماتك الراقية واللسان الحلو يلي عندك 😅
تحياتي لكم جميعا, دمتم بخير وسلام جميعا وجمعة مباركة على الجميع إن شاء الله ❤️🌹
بارك الله فيك اخي على كلماتك الطيبة وجزاك الله كل خير عليها، انت انسان لطيف ومُحب للخير والله <3

اما بالنسبة لل C ف فعلاً هي الميزة التي فقد مفهومها الكثيير من الناس!
اذا كانت البداية بلغات ال interpreter اللي بتحجز مساحة Fixed من ال Stack ولا تسمح لأحد بالتحكم بها
وطبعاً لهذه اللغات ميزات وعيوب
لغة البرمجة بالنهاية هي موجودة لهدف واحد فقط لا غير وهو " حل المشكلة ".
وانا اجزم والله ان الناس بحاجة لهذه المفاهيم العميقة بالبرمجة ومدى تأثيرها على المشاريع والبرامج بشكل عام.

رفع الله قدرك واسأل الله ان يرضى عنك وعن اهلك على هذه التربية الصالحة
تقبل مروري
 
بارك الله فيك اخي على كلماتك الطيبة وجزاك الله كل خير عليها، انت انسان لطيف ومُحب للخير والله <3

اما بالنسبة لل C ف فعلاً هي الميزة التي فقد مفهومها الكثيير من الناس!
اذا كانت البداية بلغات ال interpreter اللي بتحجز مساحة Fixed من ال Stack ولا تسمح لأحد بالتحكم بها
وطبعاً لهذه اللغات ميزات وعيوب
لغة البرمجة بالنهاية هي موجودة لهدف واحد فقط لا غير وهو " حل المشكلة ".
وانا اجزم والله ان الناس بحاجة لهذه المفاهيم العميقة بالبرمجة ومدى تأثيرها على المشاريع والبرامج بشكل عام.

رفع الله قدرك واسأل الله ان يرضى عنك وعن اهلك على هذه التربية الصالحة
تقبل مروري
يخليلي اللسان الدافي انا 😅
والله خجلتني بحكيك الظريف وكلامك الرقيق يا استاذ

لايوجد الكثير من الناس يلي بتقدر المعلومات والعلم في الشعب العربي استاذي واخي الكريم
وبدون الدخول للسياسة بعتقد انه حتى الآن لا يوجد رئيس من رئساء العرب يلي بيريد شعبه في علوم التكنولوجيا إن ما فقط هم مهتمين بالمال ومصالحهم الشخصية
واكبر مثال هو الآن نعيشه ونراه اما اعيننا هو غزة, لا تسمع اي حس وصوت للرئساء إنما الخبرة يلي بيد ح*** هي التي تلعب الدور في المقايضات والتبادل والكشف والكثير

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

رفع الله مكانتك في الجنة ورضي عنك🌹❤️
 
  • Love
التفاعلات: STORM
يخليلي اللسان الدافي انا 😅
والله خجلتني بحكيك الظريف وكلامك الرقيق يا استاذ

لايوجد الكثير من الناس يلي بتقدر المعلومات والعلم في الشعب العربي استاذي واخي الكريم
وبدون الدخول للسياسة بعتقد انه حتى الآن لا يوجد رئيس من رئساء العرب يلي بيريد شعبه في علوم التكنولوجيا إن ما فقط هم مهتمين بالمال ومصالحهم الشخصية
واكبر مثال هو الآن نعيشه ونراه اما اعيننا هو غزة, لا تسمع اي حس وصوت للرئساء إنما الخبرة يلي بيد ح*** هي التي تلعب الدور في المقايضات والتبادل والكشف والكثير

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

رفع الله مكانتك في الجنة ورضي عنك🌹❤️
ربِّ يسعدك ويخليلك اهلك واحبابك.

بخصوص الرؤساء العرب هم ليسوا عمق المشكلة
حالنا ك عرب مسلمين هو تحصيل حاصل وحتى وجود رئيس جيد هو تحصيل حاصل باذن الله.

والمعنى من كلامي ان عمق المشكلة هي بالامم والشعوب، هي فينا نحن ك شباب، هي اننا ابتعدنا عن الصلاة وان صلينا ابتعدنا عن الخشوع، هي اننا ابتعدنا عن الزكاة والصدقة، هي اننا ابتعدنا عن الربط بين اننا مسلمون حقاً ونحمل افكار المسلمين ونتفكر بهذا وذاك ولكن الجسد لا يتحرك لعبادة الله، اي اننا اصبحنا نحب الله بأفكارنا ونسبح الله بلساننا دون قلبنا وعندما خرج علينا الضيف ليقول لنا انفروا خفافا وثقالا، اثّاقلنا الى الارض ورضينا بالحياة الدنيا ونصبح كل يوم لتطوير انفسنا كي نبني مستقبلنا وشبابنا مهمومٌ بأمور الدُنيا، فلا عاد احد يطيق السماع بأن صلاتنا اليوم وديننا وعملنا لن يزحزحنا عن العذاب الاليم!

قالها المهندس محمد الهامي في لقاء له أن الشعوب على دين ملوكهم.

ولكن طفرات الشعوب هي من تعما على تحويل الايمان القلبي لعمل جسدي وبدني هي من تنهض بالشعوب، أي ان الملوك اليوم لم يستطيعوا حجب القرآن الكريم عنا، وهو المصدر الاول والاساسي لتشريع حياة الانسان، لكن الانسان مسؤول عمّا يفعل، أي اننا لسنا بحاجة الى رئيس دولة لنفهم ديننا وماذا يجب علينا ان نفعل.

وانا طبعا بكل كلامي لم اشمل المستضعفين في الارض الذين لا حول لهم ولا قوة انما قصدت بكلامي من يستطيع ولهُ القدرة.

والنصر قادم والحكم الجبري زائل وهذه من انباء الغيب علّمها الله تبارك وتعالى لرسوله الكريم ونحن متجهون الى عالم جديد يسوده حكم الخلافة على منهج النبوة

تقبل مروري 🤍
 
ما شاء الله 🔥
الله يجزاك خير على هذا الشرح وينفع بك وبعلمك يارب… بانتظار القادم
 
ربِّ يسعدك ويخليلك اهلك واحبابك.

بخصوص الرؤساء العرب هم ليسوا عمق المشكلة
حالنا ك عرب مسلمين هو تحصيل حاصل وحتى وجود رئيس جيد هو تحصيل حاصل باذن الله.

والمعنى من كلامي ان عمق المشكلة هي بالامم والشعوب، هي فينا نحن ك شباب، هي اننا ابتعدنا عن الصلاة وان صلينا ابتعدنا عن الخشوع، هي اننا ابتعدنا عن الزكاة والصدقة، هي اننا ابتعدنا عن الربط بين اننا مسلمون حقاً ونحمل افكار المسلمين ونتفكر بهذا وذاك ولكن الجسد لا يتحرك لعبادة الله، اي اننا اصبحنا نحب الله بأفكارنا ونسبح الله بلساننا دون قلبنا وعندما خرج علينا الضيف ليقول لنا انفروا خفافا وثقالا، اثّاقلنا الى الارض ورضينا بالحياة الدنيا ونصبح كل يوم لتطوير انفسنا كي نبني مستقبلنا وشبابنا مهمومٌ بأمور الدُنيا، فلا عاد احد يطيق السماع بأن صلاتنا اليوم وديننا وعملنا لن يزحزحنا عن العذاب الاليم!

قالها المهندس محمد الهامي في لقاء له أن الشعوب على دين ملوكهم.

ولكن طفرات الشعوب هي من تعما على تحويل الايمان القلبي لعمل جسدي وبدني هي من تنهض بالشعوب، أي ان الملوك اليوم لم يستطيعوا حجب القرآن الكريم عنا، وهو المصدر الاول والاساسي لتشريع حياة الانسان، لكن الانسان مسؤول عمّا يفعل، أي اننا لسنا بحاجة الى رئيس دولة لنفهم ديننا وماذا يجب علينا ان نفعل.

وانا طبعا بكل كلامي لم اشمل المستضعفين في الارض الذين لا حول لهم ولا قوة انما قصدت بكلامي من يستطيع ولهُ القدرة.

والنصر قادم والحكم الجبري زائل وهذه من انباء الغيب علّمها الله تبارك وتعالى لرسوله الكريم ونحن متجهون الى عالم جديد يسوده حكم الخلافة على منهج النبوة

تقبل مروري 🤍
تحياتي لك من القلب, والله انك لصدقت وكلامك ذهب
إن نصر الله لقريب إن شاء الله وأحسن شي الله يفرج عنا وعنكم وعن جميع امة المسلمين إن شاء الله
تحياتي لك ودمت بخير والله يسعدك ويطول بعمرك ويحفظك انت واهلك والصالح من امتنا إن شاء الله ❤️ 🌹
 
  • Love
التفاعلات: STORM
ماشاء الله 🔥
بارك الله فيك وفي انتظار باقي الشروح عن لغة C
شكرا, كلك زوق
إن شاء الله في المستقبل بنشرحلكم وبنطرح عليكم معلومات اعمق واقوى
تحياتي لك, دمتم بخير وصحة وسلامة وربي يسعدك 🌹
 

آخر المشاركات

فانوس

رمضان
عودة
أعلى