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

سؤال فى (المصفوفات - المؤشرات) ارجو الاجابة

مغلق
بدأه ahmed في 1 يونيو 2003 · 13 رد · 1,494 مشاهدة · في الأسئلة المجابة
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم اخوانى

انا مبتدا فى ال السى++ واريد منكم

شرح للمصفوفات ذات البعد الواحد وذات البعدين

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

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

ارجو تركيز الشرح اكثر على المصفوفة ذات البعدين لانها لا تريد ان تدخل دماغى خالص

اريد شرح عن المؤشرات وما الفائدة منها وهل هى مهمة اى تستعمل كثير

اريد ان يوجد امثلة على الشرح

وايضا اريد ان يكون الشرح سهل وبسيط عشان انا فهمى بطئ جدا

انا اسف يا جماعة انا سوف اتعبكم معايا ولكن المسلم يساعد اخية المسلم

وانا انتظر الرد منكم .......

اخوكم : احمد :D:D:D:D:D

اتمنى ان لا تنسو سؤالى

#2

انصحك بكتابين ، اظن انهما من احسن الكتب لل ++ C :

1) كتاب صادر من دار الميمان للنشر والتوزيع ( لايوجد غيره بنفس الموضوع ، اظن اسمه تعلم الc )

2) Resscued BY ++C ، اسم المؤلف : kris jamsa ، كان يباع في مكتبة جرير .

وان متاكد لو انك تذاكر من هاذين الكتابين ، لن تنجح بل ستتفوق باذن الله

#3

اشكرك على رايك الجميل

ولكن انا الان اريد الاجابة على سؤالى لو سمحتم

وانا ايضا عندى كتب لل السى++ ولكن اريد شرج اكثر

وهذا هو سبب طلبى

وانا انتظر الرد :(:(

#4

ياااااااااااااا اخوانى الاعزاء

لية انا واضع سؤالى لكى تساعدونى وانا اعرف ان هذا المنتدى يساعد من يريد المساعدة والاجابة على سؤالة

حتى الان لايوجد اى اجابة على سؤالى الا اخى الذى نصحنى بأن اشترى كتب معينة

ولكن الان انا ريد الاجابة علىىىىىىىىىىىىىىى سؤالى

اتمنى حد يرد عليا بالاجابة

اتمنى حد يعبرنى ويرد عليااااااااااااااااااااااا

ياااااااااااااااا رب سهل

انا انتظر :(:(:(:(:(:(

#5

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

او حدد ما الذي لم تفهمه بالضبط

اللهم انا نسألك علما نافعا ونعوذ بك من حماقة الجهلاء
#6

لو تخصص جز;););)ئيه بسيطه من الموضوعين هذي نساعدك إن شاء الله

#7

انا لا افهم باظبط المصفوفات ذات البعدين لا تريد ان تدخل دماغى خالص وما الفرق بين العد الواحد والبعدين وايضا لا افهم فكرة المؤشرات وما الفرق اعلان متغير عادى وبين اعلان عن متغير مؤشرات .

هذا هو اهم شى فى سؤالى اريد ان اعرفة ..

واتمنى الرد :):):)

#8

السلام عليكم

في أول مشاركة لي في منتداكم، أود مساعدتك أخي أحمد، ويا ليتني أوفق في ذلك

إنتظرني برهة من الوقت حتى أكتب لك بعض ما أعرفه عن المصفوفات

ملاحظة:

إسم المستخدم هو الهاوي وليس الهاوية

من يأخذ مني التاء المربوطة؟

رافقتكم السلامة

#9

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

لو اخذنا الرصيد بيكون لكل عميل رصيد بطبيعة الحال لكن كيف نعرف المتغير الذي يوضع فيه قيمة الرصيد

يتم كاالتالي:

انه نعرف مصفوفة بعدد العملاء يخزن فيها الرصيد مثلاً

float blance[100];

الان عرفنا مئة متفير من نوع float

العنصر الأول blance[0]

العنصر الثاني blance[1]

0

0

0

0

العنصر الأخير blance[99]

وبالنسبة للمصفوفة ذات بعدين تخيل شكل الجدول

العمود الأول الصف الأول

وهي مثل مصفوفة ذات البعد الواحد من حيث اغلب الخصائص

#10

السلام عليكم

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

كما هو معروف، فالذاكرة هي مجموعة من الخلايا المتجاورة والمعنونة، القادرة على حفظ البيانات بمختلف الأحجام.

البيانات هنا تقاس بالبايت (= 8 بت)، ولقد كانت كل خلية ذاكرية سابقا، قادرة على حفظ 1 بايت فقط، وفي شرحنا هنا سنعمل وفق هذا المنطلق.

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

كيف يعرف المعالج مواقع البيانات؟

ما معنى مصفوفة ذات بعدين؟

ما هي فائدة المؤشرات في ذلك؟

باختلاف أحجام البيانات، يختلف مفهوم التصريح: فالعدد الصحيح يتخذ غالبا حجم 2 بايت، والعدد الحقيقي 4 بايب، والحروف 1 بايت، وتختلف هذه الأحجام باختلاف أساليب العنونة في الذكرة وتخضع أيضا للاحتياجات الحسابية غالبا.

لو قمنا بالتصريح بجدول من 5 خانات، وهي كلها من نوع حرفي، فالجملة تكون على شكل

char TabOfChar[5];

أما شكل الجدول فتقريبا على ها الشكل يكون:

---------------------

| | | | | |

---------------------

علما أن كل خانة تحتل ما حجمه 1 بايت (الذي يساوي 8 بت) فقط من الذاكرة تكفي لحجز حروف وأرقام(0-9) وبعض الرموز الخاصةأي عدد الإحتمالات الممكنة هو 256إحتمالأ، أي 2 أس 8.

لا نذهب بعيدا، كيف يمكننا ملء هذه الخانات أو الخلايا الذاكرية؟

بما أن الذاكرة معنونة، فإن كل خلية لها عنوانها.

عند تصريحنا بالجدول ذو البعد الواحد، يبحث المعالج في الذاكرة، وعند أول مكان شاغر، يحجز ما قيمته (عدد الخانات*حجم كل خانة)، وتعتبر الخانة الأولى هي عنوان هذا الجدول (أو هذه المصفوفة الأحادية).

في لغة السي يبدأ ترقيم الخانات من الصفر، وهو ما نشير إليه بالمؤشر

لنتخيل العناوين هكذا:

---------------------

| | | | | |

---------------------

04 03 02 01 00

فلو كتبنا للمعالج عنوان الخانة الرابعة (لأن الترقيم يبدأ من الصفر)، أي [3] فإنه يترجم هذا العنوان على شكل: (عنوان الجدول+عنوان الخانة)، فإذا فرضنا أن المعالج حجز عنوان الجدول في الموقع الذاكري 40520، فإن عنوان رابع خانة من هذا الجدول تكون في الموقع (إحذر) 40520+03.

إحذر هذه لتنبيهك أن هذا الترقيم حالة جداول حرفية، يكون حجم كل خانة فيها هو 1 بايت، تماما كحجم كل خلية ذاكرية.

لماذا نعقد الأمور ولا نكتفي بالشكل المبسط الآتي:

TabOfChar[0]='a';

TabOfChar[1]='b';

TabOfChar[2]='c';

TabOfChar[3]='d';

TabOfChar[4]='e';

فيصير بالتالي جدولنا على شكل:

---------------------

| a | b | c | d | e |

---------------------

04 03 02 01 00

نحتاج لمفهوم العنونة حالة استخذامنا للمؤشرات، وتظهر هذه الحاجة جليا عند استخدامنا لدوال تأخذ ضمن قائمة بارامتراتها عناوين مصفوفات مختلفة الأبعاد.

قبل المرور إلى المؤشرات نرجع قليلا إلى الوراء:

لقد ذكرنا أنه عند التصريح بجدول من نوع حروف، فإن المعالج يخصص له ما قيمته (عدد الخانات*حجم كل خانة)، ولأن حجم الحرف هو بايت، فإن حجم الجدول كان 5 بايت.

ماذا عن جداول للأعداد الصحيحة؟

نفس المثال ينطبق عليه (عدد الخانات*حجم كل خانة)، وعملا بحجم 2 بايت لكل عدد، فإن حجم الجدول يكون مضاعف.

مثال:

int TabOfInt[6];

حجم هذا الجدول سيكون 12 بايت

-------------------------------------

| | | | | | |

-------------------------------------

00 02 04 06 08 10

لكن ألا تختلط الأمور على المعالج؟

أبدا، إذ أنه سيقفز هذه المرة بين كل خانتين بخطوتين، لأن حجم كل خلية هو 2 بايت

إذا فرضنا أن عنوان هذا الجدول هو 40670 ، فعناوين الخانات تكون وفق هذا الأسلوب:

الخانة الأولى [0]: عنوانها 40670 + i * حجم الخلية = 40670

الخانة الأولى [1]: عنوانها 40670 + i * حجم الخلية = 40672

الخانة الأولى [2]: عنوانها 40670 + i * حجم الخلية = 40674

الخانة الأولى [3]: عنوانها 40670 + i * حجم الخلية = 40676

الخانة الأولى [4]: عنوانها 40670 + i * حجم الخلية = 40678

الخانة الأولى [5]: عنوانها 40670 + i * حجم الخلية = 40680

لكن لا تخف من هذه الحسابات، قم فقط بإعطاء المعالج موقع الخلية وهو يتكفل بالحسابات.

الآن: نعرف أن المؤشر هو متغير في الذاكرة يقوم بحفظ العناوين، وليس بحفظ القيم

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

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

لنفرض أنه عندنا ثلاثة جداول في الذاكرة:

char TabOfChar[10];

int TabOfInt[10];

float TabOfFloat[10];

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

char *PInt= &TabOfChar[];

int *PInt= TabOfInt;

float *PInt= TabOfFloat;

أسلوب إسناد عناوين الجداول صحيح في الحالتين الأولى والثانية.

المهم:

سيقوم المعالج بحجز ثلاثة مواقع في الذاكرة (مثلا: 100، 102 و 104) للمؤشرات بحيث يخزن فيها فقط العناوين.

تقريبا، سيكون شكلها على ها المنوال

إسم المؤشر: PFloat PInt PChar

----------- -------------------------

محتوى المؤشر: | ؟ | ؟ | ؟ |

------------- -------------------------

عنوان المؤشر: 100 102 104

ثم أسندنا لكل مؤشر عنون الجدول الخاص به، ولنفرض أن عناوين جداولنا الثلاثة هو 40500، 40600 و 40700

إذن محتوى المؤشرات سيكون هكذا:

إسم المؤشر: PFloat PInt PChar

----------- -------------------------

محتوى المؤشر: | 40500 | 40600 | 40700 |

------------- -------------------------

عنوان المؤشر: 100 102 104

ماذا يحدث إذا طلبنا من كل مؤشر أن يؤشر على ثالث خانة من الجدول (أي التي نشير إليها بـ [2])

PChar +=2;

PInt +=2;

PFloat +=2;

إذا استطعت تحديد محتوى كل مؤشر وحدك، لفإنك فهمت الدرس:

ستكون المحتويات حسب معطياتنا هكذا:

إسم المؤشر: PFloat PInt PChar

----------- -------------------------

محتوى المؤشر: | 40502 | 40604 | 40708 |

------------- -------------------------

عنوان المؤشر: 100 102 104

هكذا تقفز المؤشرات:

PChar يقفز بخطوة واحدة : 0 - 1 - 2

PInt يقفز بخطوتين : 0 - 2 - 4

PFloat يقفز بأربع خطوات: 0 - 4 - 8

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

Pint -= 2;

PChar +=1;

PFloat =1;//error

السطر الثالث يعني أنك تحاول إعطاء للمتغير قيمة عددية وليس عنوان ذاكري

كيف يمكننا طبع عنوان المؤشر، وكيف يمكننا طبع محتواه؟

لطبع موقع أو عنوان المؤشر نفسه، وليس القيمة التي يؤشر عليها:

printf("The Adress Of PChar is %d", &PChar);

لطبع موقع أو عنوان الشيء المؤشر عليه:

printf("The Adress Of The Current Element Of TabChar is %d", PChar);

لطبع محتوى وقيمة الشيء المؤشر عليه:

printf("The Value Of The Current Element Of TabChar is %c", *PChar);

الحديث حول المؤشرات يطول ويطول، وخير معين لفهم ذلك هو التطبيق، إذن حاول كتابة جمل برمجية بسيطة، وحاول طبع النتائج.

ماذا الآن عن جدول ثنائي البعد؟؟

لنفرض هذا الجدول من نوع حروف:

---------------------

| | | | | |

---------------------

| | | | | |

---------------------

| | | | | |

---------------------

إذن نحن نحتاج إلى جدول من ثلاثة سطور وخمسة أعمدة لمتغيراتنا الحرفية، فالتصريح لذلك يكون بهذا الشكل:

char D2Tab[3][5];

أول عنصر من هذا الجدول هو

D2Tab[0][0]

وآخر عنصر هو

D2Tab[2][4]

الإشكالية: كيف يقوم المعالج بحجز ومعالجة الذاكرة، في حين هذه الأخير هي سلسلة متتابعة من الخانات المتساوية الحجم:

بكل بساطة: يقوم بتحويل جدولنا ثنائي البعد إلى جدول أحادي البعد بحجم (Row*Column) أي بحجم 5*3 ويساوي 15 خانة.

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

نفرض أن جدولنا كان يحمل هذه الحروف:

---------------------

| a | b | c | d | e |

---------------------

| f | g | h | i | j |

---------------------

| k | l | m | n | o |

---------------------

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

-------------------------------------------------------------

| a | b | c | d | e | f | g | h | i | j | k | l | m | n | o |

-------------------------------------------------------------

كيف نصل إلى خانة ما، وكيف نغير محتواها أو نقرأه؟

إذا كتبنا للمعالج التعليمات الآتية:

int i=1, j=2;

printf("the element of D2Tab[%d][%d] is %c",i,j,D2Tab[j]);

فإنه سيطبع لنا الحرف h

لا تنسى أن الترقيم يبدأ دائما من الصفر، سواء على مستوى السطر أو العمود، حيث نقصد بD2Tab[1][2] العنصر المتواجد في السطر 2 وفي العمود 3.

كيف عرف المعالج الموقع الصحيح رغم أنه عنون الحروف في شكل جدول أحادي البعد

يعتمد في ذلك على القاعدة:

D2Tab[j]<==>D2Tab[i*SizeOfColumn+j]

أي أنه وبحلقة for أو while نستطيع مسح كل الخانات التابعة للجدول، سواء كان ثنائي أو ثلاثي أو نوني البعد.

لكن لماذا نعقد الأمور ثانية؟

هذا ما سيصير مع المؤشرات حالة جداول ثنائية البعد

يمكن التأشير نحو الحر h وفق هذا المثال:

char *PD2Tab=D2Tab;

int Row=3, Column=5;

int i=1, j=2;

printf("the element D2Tab[%d][%d] is %c",i,j,D2Tab[j]);

أو كذلك بهذا الشكل:

printf("the element D2Tab[%d][%d] is %c",i,j,*(PD2Tab+i*Column+j));

كما يمكننا مسح كل عناصر الجدول وفق هذا النموذج:

for (int i=0; i

for (int j=0; i

printf("the element D2Tab[%d][%d] is %c n",i,j,*(PD2Tab+i*Column+j));

الحمد لله الذي وفقني لكتابة هذه السطور

إن شاء الله تنفعك وتنفع كل من وجد فيها منفعة

كما آمل منكم أن تدعو لنا بالشفاء والهداية، آمين

رافقتكم السلامة

#11

اعزائى اخوانى منتدى الفريق العربى للبرمجة

اشكركم جدا جدا جدا على الاجابة علي سؤالى ولكن بعد ما صوتى انتهى من الندا حد يجاوب على سؤالى ولكن الحمد للة الاجابة وصلت

وكل الشكر لكل من ساعدنى فى الاجابة واشكرك اخى ( الهاوية ) واخى ( CS111 ) على ردكم عليا

ونردها لكم ان شاء الله

والسلام عليكم

اخوكم : احمد :D:D:D:D:D

#12

السلام عليكم

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

أما لو أنك تريد ردها لي، فيكفيني أنك تساعدني في حل هذه المشكلة

أملك نسخة intrnet Explorer 5 ، ولا أدري ماذا أصابه.

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

لو أقوم بإعادة التنسخة السابقة، أي الرابعة من الإكسبلورر فإنها تعمل من دون إشكال، لكنها لا تفهم أغلب السكريبتات، أما لو نصبت النسخة الخامسة، فإنها تقتلني قتلا.

كيف أجعل حاسبي يعمل عاديا أثناء التصفح؟؟؟؟؟

يا ليتكم تعينوني في ذلك؟

رافقتكم السلامة

#13

اخى الحبيب الهاوي

اريد ان منك شى وهو

ما هو اصدار النورتن الى على الجهاز

وما هو اصدار الويندوز ايضا

اريد ان اسئلك سؤال

هل جربت تعيد تنصيب الويندوز مرة ثانية

واذا كان لا الرجاء اعادة تنصيب الويندوز مرة ثانية

وان شاء الله سيكون سريع

وانا انتظر ردك

اخوك : احمد :):)

#14

السلام عليكم

أخي أحمد، أشكرك على الإهتمام

أظن أن موضوعي هذا يستحسن نقله إلى قسم الصيانة

إنتقل معي إلى هناك

رافقتكم السلامة

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

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

عدد الزوار حالياً

المتواجدون خلال آخر دقيقتين · يتحدّث كل ٣٠ ثانية

—الإجمالي—أعضاء مسجّلون—زوار بدون تسجيل

جارٍ التحقق من المتواجدين…