الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

كيف اقوم بتعرييف array ذات بعدين ؟

مغلق
بدأه domainA في 29 يوليو 2006 · 13 رد · 870 مشاهدة · في الأسئلة المجابة
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم

اريد عمل برنامج يقوم بعمليات الضرب والقسمة الخاصة بالمصفوفات

وعندما اقوم بتعرييف مصفوفة هكذا :

int m,n

int array[m][n]={0}

لايقبلها المترجم

فمالحل ؟؟ هل هناك طريقة اخرى ؟

#2

لا يمكنك تعريف هذه المصفوفة في ++C حيث أن m , n متحولات ...

إما أن تعرف m , n على شكل ثوابت

const int m = 100;
const int n = 100;

أو أن تعرف مصفوفة ديناميكية حيث تعرف مؤشر على مصفوفة ... و بعد ذلك تحجز ديناميكيا أي أثناء الـ runtime و ليس أثناء الـ compile time كما في المصفوفات الساكنة ... و لكن أعتقد أن الأمر قد يكون صعبا عليك إذا كنت مبتدئ خصوصا إذا كانت المصفوفة ثنائية البعد و لكن سأضع لك مثالا بسطيا

بفرض أن n عدد الأسطر و m عدد الأعمدة

int m , n;
cin >> n >> m;
int* a = new[n*m];
for (int i = 0; i < n; i++)
	 for (int j = 0; j < m; j++)
	   a[j+i*n] = 0

لاحظ أننا وصلنا إلى العنصر [j] بالطريقة [j+i*n]

و هي تتعامل مع المصوفة تماما كما تخزن فالمصفوفة أكيد أنها لا تخزن في الذاكرة على شكل مربع و إنما على شكل تتالي من العناصر ... قانون الوصول إلى أي عنصر فيه هو (رقم العمود + عدد الأسطر*رقم السطر)

الشرح ليس جيدا بما فيه الكفاية ... ليس لدي الخبرة للشرح .. و لكن أرجو أن أكون قد ساعدتك ..

تم تعديل هذه المشاركة بواسطة aubada في 29 يوليو 2006 في 23:30

MAAAAAAAAAAAAAAAAAAAAAAAC

#3

THE TORNADO

جزاك الله كل خير اخي على توضيح طريقة المصفوفة الديناميكية ، الشرح واضح جداً

اشكرك مره اخرى اخي :)

#4

الأخ Tornado لم يقصر و لكن هناك ملاحظتين فقط ..

int *a = new int[n*m];

طبعا لا تنسى تعمل delete للدايناميك array

delete [] a

ثانيا يمكن أن تستخدم هذه الطريقه لتصفير المصفوفه ذات اتجاهين

int a[n][m]= {{0}}

لكن لازم تعرف حجم المصفوفات قبلا ..

#5
اقتباس
طبعا لا تنسى تعمل delete للدايناميك array

delete [] a

بهي معك حق ... راحت عن بالي ;)

MAAAAAAAAAAAAAAAAAAAAAAAC

#6

مالفائدة من عملية حذف المصفوفة ؟

#7

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

ثانيا : و لست متأكدا ... من الممكن أن يبقى الجزء المحجوز في الـ RAM حتى بعد انتهاء تنفيذ برنامجك ........

MAAAAAAAAAAAAAAAAAAAAAAAC

#8

تقوم عملية الحذف عزيزي على توفير عملية الذاكرة

يعني تخيل انك قمت بكتابة نفس كودك السابق لبرنامج عرضته لمستخدم وقام المستخدم بادخال مصفوفة ثنائية الابعاد ولكن حجمها كبير جدا مثلا 100 * 100

ثم انتهى دور المصفوفة واتيت لفقرة جديده .. انت لن تحتاج إلى هذا الكم الهائل من الحجز للذاكرة لذلك يفضل ان تقوم بمسحه باستخدام عملية []delete وعندها تزيد سرعة البرنامج

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

ملاحظة مهمه :

لاتعتقد انه يجب وضع عملية الحذف !!

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

بمجرد انتهاء المجال الخاص في main الداله الرأيسية ستنتهي المصفوفة نهائيا

}

المصفوفة

{

عندها انتهت المصفوفة حتى لو لم تحذفها

___________________________________________________________

مااعتقد في شرح اكثر من كذا :D

بالتوفيق

llback.jpg

اشهد ان لا إله إلا الله وان محمدا ً رسول الله

#9

بالتأكيد time1 ... فأي متحول يموت (يهدم) بعد الخروج من الـ scope التي تم تعريفه فيها

و لكني سمعت كلاما من البعض انه من الممكن أن يبقى الحجم المحجوز للمصفوفة الديناميكية في الـ RAM لأن المكان الذي تحجز فيها للمتحولات الديناميكية (المؤشرات) غير المكان الذي يحجز فيه للمتحولات .... ممكن توضيع إذا كنت واثق من كيفية تخزين متحولات البرنامج في stack و heap

و شكرا

MAAAAAAAAAAAAAAAAAAAAAAAC

#10

بمجرد انتهاء الProcess التي فيها البرنامج يقوم نظام التغيل بازالة كل متعلقاتها تماماً

Sr. Software Development Engineer
Hulu, LLC
My Blogs

#11

استاذي الفاضل

The Tornado

عندما نقوم بكتابة الكود لأي برنامج ونقوم بتنفيذه فإن البرنامج يحجز مكانه في الذاكرة RAM

وطبعا هو يحجز قسمين احدهم للشفرة والاخر يسمى بمقطع البيانات وفيه تكون المتحولات

لكن مقطع البيانات كما تعرف محدود الذاكرة ولا تكفي ربما لحجز عدد كبير من البيانات لذلك نستطيع ان نستخدم ماتبقى من الذاكرة RAM وهو حجم كبير طبعا

ويسمى كما تفضلت heap من خلال الأمر new ونقوم بإعادة عناوينها باستخدام المؤشرات

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

ولكن لمنع تسريب الذاكرة

التوضيح :

انظر معي لهذا الكود

main()
{
int *point=new int;
*point=50;
لاحظ هنا انه تم حجز مكان في heap 
من نوع صحيح واعطائة قيمة 50
نستطيع ان نجري عليها ما نشاء من عمليات مثلا: نطبعها
ثم لاحظ معي لو قمنا بالتالي
point=new int;
*point = 100;
هنا لو اردنا طباعة *point 
ستطبع 100 
لكن لو اردنا العودة إلى القيمة 50 كيف سنعود ؟!
القيمة 50 موجوده بالذاكرة ومحفوظة ولكن لا نعلم عنوانها 
عندها يوجد تسريب بالذاكرة .. فيوجد بيانات غير مهمه لاننا لا نعلم مكانها .. اذا يوجد حجز غير مهم 
لذلك نجتاج لاستخدام الامر delete point

ربما يظهر انه من غير المهم حذف هذا الحجز ولكن لو تم حجز مصفوفه 100*100 وسيتم حجز مصفوفه اخرى عندها سيكون 10000 عنصر موجودين بالذاكرة ولا يمكن الوصول إليهم .. عندها يكون تسريب بالذاكرة

لاحظ معي ان الحجز للمؤشر *pointيكون في قسم مقطع البيانات

اما الحجز بالامر new يكون في heap

اما بخصوص عدم كتابة الامر delete فان البيانات تحذف من الذاكرة مباشرة بعد انتهاء البرنامج

هذا والله اعلم

llback.jpg

اشهد ان لا إله إلا الله وان محمدا ً رسول الله

#12

شكرا جزيلا على التوضيح سيد time1 ... كنت أعلم بعض المعلومات و كلن البعض الآخر توضح بشكل أفضل الآن

MAAAAAAAAAAAAAAAAAAAAAAAC

#13

العفو استاذي الفاضل

لكن حبيت اضيف شيء معين بما ان الصورة وضحت عندك

الامر delete هو عبارة عن استدعاء تابع التدمير للغرض

فكما تعلم لغة السي ++ تنظر لكل شئ على انه غرض

وبنهاية مجال الرؤية يتم استدعاء التابع المدمر للغرض حتى ولو كان الحجز ديناميكي في heap

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

هذا والله اعلم

اتمنى التوفيق

llback.jpg

اشهد ان لا إله إلا الله وان محمدا ً رسول الله

#14
bashmohandes كتب:
بمجرد انتهاء الProcess التي فيها البرنامج يقوم نظام التغيل بازالة كل متعلقاتها تماماً

داه هو الكلام ;)

هذا الموضوع مغلق.

مواضيع مشابهة