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

التعامل مع المصفوفات ذات البعدين بواسطة المؤشرات

مغلق
بدأه b.m.s في 6 أغسطس 2004 · 21 رد · 1,983 مشاهدة · في الأسئلة المجابة
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

أقرأ هذا الكود ومن ثم أقرا السؤال في الأسفل

#include<iostream.h>

int main()
{
int a[4];

cout<<a <<"    "<<&a <<"\n";

return 0;
}

فإن ناتج الطباعة هو نفسة اي a = &a فكيف يتم ذلك ؟؟؟؟

ايضا تعتبر المصفوفة ذات البعد الواحد مثل [int a[10 هي مؤشر الى عدد صحيح مثل int *ptr

أي يمكن قول

ptr=a;

ولكن المصفوفة ذات البعدين مثل [int a[10][10 هل يمكن اعتبارها int **ptr

بحيث استطيع القول

ptr = a ;

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

خصوصا في لغة c++

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

تم تعديل هذه المشاركة بواسطة b.m.s في 6 أغسطس 2004 في 18:23

#2

السلام عليكم

أولا لابد أن تعلم شيء :

وهو أن اسم المصفوفة في لغة ++c و c هو مؤشر لأول عنصر بها أي تستطيع كتابة التالي

int * ptr = a;

أو كتابة التالي كله صح:

int * ptr = a[0];

وبالتالي تستطيع طباعة القيمة التي يحتويه العنصر الأو ل ب cout << *ptr;

وتزيد واحد للمؤشر وتطبع القيمة التالية وهكذا .

الخلاصة :اسم المصفوفة هو مؤشر لأول عنصر بها.

أما على ذات البعدين ( والعلم عند الله ) أنها ينطبق عليها نفس الكلام ( ولكن لم اجرب ذلك ) اذا جربتها وحدث عكس كلامي فصأصحهها هنا .

والسلام عليكم .وأهلا بك في المنتدى

اللهم علمنا ما ينفعنا وأنفعنا بما علمتنا أنك أنت العليم الحكيم

سبحان الله وبحمده سبحان الله العظيم

لاحول ولاقوة الا بالله( كنز من كنوز الجنة ).

#3

فعلا المصفوفة عبارة عن مؤشر في الذاكرة لبداية مصفوفة

بمعنى أنة رقم

مثال

int ii[4]={1,2,3,4};

فإن

ii

عبارة عن عنوان بداية المصفوفة

وهو الرقم 1 للإنتقال للرقم 2

++ii

وليس
ii++
لأن الأخيرة تزيد العدد 1

http://www.jaascois.com

*************************************************

مجموعة مواضيع - إحتراف البرمجة -

ّ~~~~~~~~~~~~~~~~~~~~~~

البرمجة المتقدمة & الهندسة العكسية & برمجة وأمن الأنظمة

/index.php?showtopic=45002

آخر المواضيع :

+- تحليل جرائم الكمبيوتر -+

أنظمة اليونكس(Solaris,HP, AIX,SCO)وانواع المعالجات

ثغرة SMS لأجهزة الجوال Siemens 3568i !

أخطاء وثغرات البرامج العربية !!!

سلسلة مواضيع - أمن وحماية مواقع الويب -

E البرمجة المتقدمة X للملفات التنفيذية E

سلسلة مواضيع ثغرات الأنظمة وإختراق الأجهزة

**************************************************

<span style='font-size:14pt;line-height:100%'>الإرادة تحـــقق السيـــادة</span>

**************************************************

#4

السهم الناري

مشكور على اجابتك

jaas

حبيت اصحح معلومة فقط

وهي ان عنوان المصفوفة

هو مؤشر ثابت اي int * const ptr

واذا حاولت ان تكتب

ptr++

او ++ptr

ستظهر لك الخطأ

وشكرا

#5

مرحبا

أولا مشكور على المعلومة مع إني ما زلت متمسك برأيي

شوف المثال

int ii[4];
int* pi;
char Num[100];
ii[0]=1;ii[1]=2;ii[2]=3;ii[3]=4;
pi=&ii[0];
++pi;
  
wsprintf(Num,"%d",pi[0]);
MessageBox (NULL,Num,NULL,NULL);

++pi;
wsprintf(Num,"%d",pi[0]);
MessageBox (NULL,Num,NULL,NULL);

وشكرا

http://www.jaascois.com

*************************************************

مجموعة مواضيع - إحتراف البرمجة -

ّ~~~~~~~~~~~~~~~~~~~~~~

البرمجة المتقدمة & الهندسة العكسية & برمجة وأمن الأنظمة

/index.php?showtopic=45002

آخر المواضيع :

+- تحليل جرائم الكمبيوتر -+

أنظمة اليونكس(Solaris,HP, AIX,SCO)وانواع المعالجات

ثغرة SMS لأجهزة الجوال Siemens 3568i !

أخطاء وثغرات البرامج العربية !!!

سلسلة مواضيع - أمن وحماية مواقع الويب -

E البرمجة المتقدمة X للملفات التنفيذية E

سلسلة مواضيع ثغرات الأنظمة وإختراق الأجهزة

**************************************************

<span style='font-size:14pt;line-height:100%'>الإرادة تحـــقق السيـــادة</span>

**************************************************

#6

هلا اخوي jaas

اولا: اعذرني نسيت اشكرك على ردك على استفساري الاول

ثانيا : انا قصدت اسم المصفوفة انه مؤشر ثابت ولم اقصد انك تحط عنوان

الموصفوفة في مؤشر اخر

وشكرا على تجاوبك معي

وبالتوفيق

#7

كلا م الاخ jess صحيح .

ولكن سؤالي الدالة wspritf() ماذا تعمل ( أقصد تطبع وين على الشاشة أم على ماذا ..

اللهم علمنا ما ينفعنا وأنفعنا بما علمتنا أنك أنت العليم الحكيم

سبحان الله وبحمده سبحان الله العظيم

لاحول ولاقوة الا بالله( كنز من كنوز الجنة ).

#8
اقتباس
كلا م الاخ jess صحيح .

يعني كلامي خطأ

مسألة بسيطه مثل هذه وانتم مختلفين فيها

:D الله يعين على الباقي

#9

مرحبا بالشباب

بالنسبة للأخ السهم

دالة

wsprintf

وضيفتها في برامج وندوز تقوم بعمل فورمات للنص

ولا تطبعة على الشاشة بدل ما تطبعة تخزنة في متغير

وتستخدم المتغير على راحتك

بالنسبة للأخ b.m.s

والله ما أختلفنا أنا أعرف إن كلامك صحيح

ولكن حبيت أضيف هذة الطريقة

++i

i++

ومتأسفين إذا غلطت حقك علينا

http://www.jaascois.com

*************************************************

مجموعة مواضيع - إحتراف البرمجة -

ّ~~~~~~~~~~~~~~~~~~~~~~

البرمجة المتقدمة & الهندسة العكسية & برمجة وأمن الأنظمة

/index.php?showtopic=45002

آخر المواضيع :

+- تحليل جرائم الكمبيوتر -+

أنظمة اليونكس(Solaris,HP, AIX,SCO)وانواع المعالجات

ثغرة SMS لأجهزة الجوال Siemens 3568i !

أخطاء وثغرات البرامج العربية !!!

سلسلة مواضيع - أمن وحماية مواقع الويب -

E البرمجة المتقدمة X للملفات التنفيذية E

سلسلة مواضيع ثغرات الأنظمة وإختراق الأجهزة

**************************************************

<span style='font-size:14pt;line-height:100%'>الإرادة تحـــقق السيـــادة</span>

**************************************************

#10

السلام عليكم

نحن لم نختلف بقدر مانحن متفقين الان وبشكل سليم.

كلامك أخ b.m.s نعم ايضا صحيح . ولكن انا اقصد نفس ماقصد أخي jass وهو ه i++ ونحوها .

هذا والله يعينا وأيك على الصبر والطاعة .

أهلا بالمزيد من مشاركاتك .

شكرا jass لكن الدالة تستخدم في الفجوال سي . هل هذا الكلام صحيح.

اللهم علمنا ما ينفعنا وأنفعنا بما علمتنا أنك أنت العليم الحكيم

سبحان الله وبحمده سبحان الله العظيم

لاحول ولاقوة الا بالله( كنز من كنوز الجنة ).

#11

أكيد الدالة تشتغل في الفجول سي

--

http://www.jaascois.com

*************************************************

مجموعة مواضيع - إحتراف البرمجة -

ّ~~~~~~~~~~~~~~~~~~~~~~

البرمجة المتقدمة & الهندسة العكسية & برمجة وأمن الأنظمة

/index.php?showtopic=45002

آخر المواضيع :

+- تحليل جرائم الكمبيوتر -+

أنظمة اليونكس(Solaris,HP, AIX,SCO)وانواع المعالجات

ثغرة SMS لأجهزة الجوال Siemens 3568i !

أخطاء وثغرات البرامج العربية !!!

سلسلة مواضيع - أمن وحماية مواقع الويب -

E البرمجة المتقدمة X للملفات التنفيذية E

سلسلة مواضيع ثغرات الأنظمة وإختراق الأجهزة

**************************************************

<span style='font-size:14pt;line-height:100%'>الإرادة تحـــقق السيـــادة</span>

**************************************************

#12

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

اللهم علمنا ما ينفعنا وأنفعنا بما علمتنا أنك أنت العليم الحكيم

سبحان الله وبحمده سبحان الله العظيم

لاحول ولاقوة الا بالله( كنز من كنوز الجنة ).

#13

السلام عليكم ,,

تعليقين على الموضوع ,,

الأول أن كلام b.m.s بخصوص المؤشر الثابت في الأعلى صحيح حيث لايمكن زيادة عنوان المصفوفة بالعامل ++ يعني :

int x[10];
x++;

//ERROR

لأن مؤشر المصفوفة ثابت ,, وتعرف على الشكل ,,

int * const x=new int [10];

x++;
//ERROR;

......................

الأمر الآخر أنه لم تتم الاجابة على سؤالك الأصلي وهو :

int x[10][20];
int **p;

p=x;
//ERROR

كيف يمكن تعديل الكود أعلاه ؟

int *x[10];
for(int q=0;q<10;q++)
x[q]=new int [20];

int **p;
p=x;
//OK here

لم أكتشف سبب عدم عمل الطريقة التقليدية

int x[10][2];

بدلا من

int* x[10];
for(int q=0;q<10;q++)
x[q]=new [20];

لكن سأبحث في السبب ,,

banner_60_468.gif

NOTHING IS IMPOSSIBLE

#14

بسم الله الرحمن الرحيم

أولا أهلا وسهلا ومبروك النجاح يأخ HGB و الحمد لله على السلامة.

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

#include <iostream.h>


int main()
{
	int x[5] = {10,20,30,40,50};

	int * ptr = x;

	cout << *ptr << "\n";

	for( int i=1; i<5; i++)
	{
  cout << *++ptr << "\n";
	}


	cout << "\n*********************\n";

	for( i=0; i<5; i++ )
	{
  cout << (x+i) << "\t" << *(x+i) <<  "\n";	
	}

	return  0;
}

أقصد هذه الطريقة في الطباعة :

cout << (x+i) << "\t" << *(x+i) <<  "\n";

هنا سيتم طباعة العنوان والقيمة الموجودة به ثم الزيادة بمقدار I والذهاب للعنوان التالي الذي بطول 4 بايت ف الذاكرة ثم طباعة القيمة التي به وهكذا هذا ماقصدته بالزيادة .

وشكرا على تصحيح المعلومة هذا مأردت توضيحه والله ولي التوفيق.

اللهم علمنا ما ينفعنا وأنفعنا بما علمتنا أنك أنت العليم الحكيم

سبحان الله وبحمده سبحان الله العظيم

لاحول ولاقوة الا بالله( كنز من كنوز الجنة ).

#15

بالضبط في هذه الحال ,, أن تغير في قيمة لعنوان متغير غير ثابت أبتدأ بقيمة عنوان هي من مصفوفة ثابتة ,, فلا يؤثر ذلك فعلا ,, وهي طريقة جيدة للتحايل على المؤشرات الثابتة

banner_60_468.gif

NOTHING IS IMPOSSIBLE

#16

أخي الكريم HGB

مامعنى هذا السطر في الكود المكتوب في مشاركتك

int   **p;

p = x;

ماهو معناه وماذا يعمل انا اعرف ان تعريف مؤشر يتم بذكر نوعه ثم علامة * ثم اسم المؤشر ولكن علامتي ** لافهمها ما معناها وجزاك الله خير.

اللهم علمنا ما ينفعنا وأنفعنا بما علمتنا أنك أنت العليم الحكيم

سبحان الله وبحمده سبحان الله العظيم

لاحول ولاقوة الا بالله( كنز من كنوز الجنة ).

#17

السلام عليكم ,,

يمكنك أن تكتب التالي :

int **************** x;

لو أردت ,, وكان لديك سبب منطقي لفعل ذلك :huh: ,, طبعا الا أن تكون ترغب في بعض أعمال فرانكنشتاين ,, ولديك مفهوم غريب تريد تطبيقه ,, لكنني لم أرى في حياتي أكثر من مؤشرين ,, ربما الثالث قد يكون منطقيا في نواحي خاصة جدا ,, لكن أكثر من ذلك أعتبرها هرطقة !!

المهم اسأل نفسك كيف يمكن أن تنشيء مصفوفة ديناميكية ببعدين وكلا البعدين متغير وستحدده وقت التشغيل ,,run-Time ؟

لايمكن فعل ذلك "أقصد بنفس مفهوم المصفوفات العادية " الا بالمؤشرين كالتالي في الكود :

int **p;
int x,y;

//LET x = 10;  y = 11

cin>>x>>y;
p=new int [x];
for(int q=0;q<x;q++)
p[q]=new int [y];

p[7][8]=666;
p[6][9]=33;
.
.
.

الان يمكن تشبيه ال ** بال [][]

يعني ,,

int **p;
int d[10][20];

كلا ال p وال d لهما نفس الأساس ,, لكن لايمكن المساواة بينهما الا اذا استخدمنا الكود ,,

int **p;
int d*[10];
for(int q=0;q<10;q++)
d[q]=new int[20];

p=x;

اذا أردت المزيد سنضيف مانستطيع ,, وفقك الله :)

banner_60_468.gif

NOTHING IS IMPOSSIBLE

#18

اخوي HGB

الحمد لله على السلامة

واخيرا جاء واحد يجواب على السؤال الثاني

وانا اظن ما نقدر نعرف ليش الطريق العادية ما يقبلها الكمبيوتر الا اذا عرف

كيف يمثل (COMPLIRE) المترجم هذه المصفوفة عنده وهذا رأيي

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

وبالنسبة لك اخوي السهم الناري اظن HGB وفى وكفى

تم تعديل هذه المشاركة بواسطة b.m.s في 11 أغسطس 2004 في 23:59

#19

أعتقد أن مسألة عدم قبول المترجم لتعريف مساحات كبيرة نسبياً بالطرق العادية تعود لأسباب تتعلق بحجز الذاكرة من الـstack ..... ففي حالة الحجز الديناميكي وهو حجز المصفوفات من الheap لا نجد أي مشكلة إلا عندما نحجز مساحات كبيرة جداً

#20

السلام عليكم ,, كيفكم شباب :)

فكرت في الأمر قليلا ووجدت أن المشكلة كالتالي:

اذا حجزت مصفوفة ببعدين كالتالي :

int Z[5][4];

فمعناها أن لديك 5 عناصر ولكل عنصر من ال 5 عناصر 4 عناصر داخلية ,,يعني 20 عنصر ,,

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

اذا ساوينا عنوان مؤشر * بمصفوفة بعد واحد كالتالي:

int *p;
int x[10];
p=x;
/code]
هنا عنوان ال P أصبح يساوي عنوان ال x ,, الان اذ كتبنا مباشرة بعد الكود أعلاه :
[code]
p++;

فالذي سيحدث أن عنوان ال p سيتغير وسيزيد بواحد ,, لكن لن يتغير معه عنوان ال x,, بل الذي سيتغير تباعا لذلك محتويات عنوان ال x أي قيمة ال x ,, وستكون قيمة ال x تساوي قيمة ال p ,,

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

يعني مثلا خذ الكود

int **p;
int *x[10];
for(int q=0;q<10;q++)
x[q]=new int [10];

p=x;
p++;

الذي سيحدث هنا بعد ال p++ ,, هو أن كل قيم ال x ستتغير ,,

يعني

x[0][0];
x[0][1];
x[0][2];
.
.
x[10][10];

أي أن كل العناوين في البعد الأول تغيرت تبعا لتغير المستوى الأدنى ,, اليس كذلك ,,

طيب لو كان عندنا مصفوفة كالتالي ببعدين ,,

int x[10][10];
int **p;
p=x;

p++;

فان المصرف سيرفض ولسبب بسيط ,, هو أن العناوين في البعد الثاني للمصفوفة x ستتغير ,, وليس البعد الأول "ملاحظة مهمة " ,,

والبعد الثاني مؤشر ثابت في المصفوفة لذا لايمكن تغييره ,,

لذا سيعترض المصرف من البداية أصلا على التعيين ,,

الكلام معقد قليلا ويحتاج لبعض التجارب لترسيخ مفهومه ,,

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

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

يعني أي تغيير في احدى المؤشرين سيعكس ذلك على المستويات الأعلى "وليس على مستوى المؤشر نفسه " ربما على مستوى المؤشر الذي فوقه او الذي فوقه ,, لايهم ,, وحتى القيمة الحقيقية ,,

هل الكلام واضح ؟

banner_60_468.gif

NOTHING IS IMPOSSIBLE

#21

اخوي هيثم راح احفظ الصفحة

وارجعها عندي بالبيت

لاني اكلمك من مقهى وراح اردك عليك بكرة بإذن الله

#22

بسم الله الرحمن الرحيم

السلام عليكم:

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

والمطلوب من مشرفنا العزيز HGB وكل عضو فاهم بالمؤشرات تقديم برنامج ( كود ) يوضح محاولة ربط دنميكي لمصفوفة ذات بعدين ولو بمثال واحد ويشرحه لنا حتى نفهمه ونطبق على شاكلته.

هذا والله ولي التوفيق.

البرنامج:

#include <iostream.h>


int main()
{
	int a;  //متغير يحتوي على عدد عناصر المصفوفة
	int * ptr;

	cout << "Enter number " << "\n a = ";
	cin  >> a;

	ptr = new int[a];  //الحجز الدنميكي

	//ادخال عنناصر المصفوفة
	for( int i=0; i<a; i++ )
	{
  cout << "Enter array[" << i+1 << "] : ";
  cin  >> ptr;
	}

	//طباعة عناصر المصفوفة
	for(  i=0; i<a; i++ )
	{
  cout <<  ptr << "\n";
	}

	return  0;
}

هذا هو الكود ونريد منك أخي HGB ولو أني ثقلت عليك بالكلام والشرح ياليت توضيح أكثر فهذه نقطة حساسة لابد أن تمر على الشخص ويفهمها أقصد المؤشرات اذا اراد أن يكون مرمجا ياليت توضح أكثر لذات البعدين وتعطينا كود صح ( يكفي المقالة مثال يوضح كل شيء ) .

الله يوفقنا واياكم.

اللهم علمنا ما ينفعنا وأنفعنا بما علمتنا أنك أنت العليم الحكيم

سبحان الله وبحمده سبحان الله العظيم

لاحول ولاقوة الا بالله( كنز من كنوز الجنة ).

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

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

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

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

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

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