الشبكة العربية لمطوري الألعاب

محترف مشرف عبد اللطيف حاجي علي مشاركة 11

التعليق على مشاركة راسم حسان في Mar 10, 2006 10:30 :

>
> int var1 = 15;
> int var2 
> = 25;
> 
> int * p = &var1;
> *p = 45;
> P = &var2;      // Of course, you mean a small p
>               // not a capital one (Remeber that C is case sensitive)
> *p = 35;
> 
> printf(“%d”,var1);
> putc(‘\n’);
> printf(“%d”,var2);
> putc(‘\n’);
> printf(“%d”,p);
> 
> /*
> The 
> result was:
> 45
> 25


أعتقد أن النتيجة يجب أن تكون 35 هنا.. أليس كذلك؟

> 2335120
> */
> 

>
> طيب ليش الـ compiler
> اختار العنوان 2335120 ؟ مش المفروض ياخد العنوان 1004
> ؟
لماذا؟ محمد ذكر الرقم 1004 على سبيل المثال فقط (في الحقيقة أنت لا تحصل أبداً على pointer من أربعة أرقام لأن حجم الـ pointer هو 4-bytes كما تذكر (في نظم الـ 32-bit ) )... أيضاً انتبه إلى أنه لا يمكنك الاعتماد على ثبات عنوان المتغير لأنه غالباً سيتغير مع كل تشغيل لبرنامجك (طبعاً سيظل ثابتاً خلال التشغيل الواحد) و التغيير سيكون عشوائياً (تقريباً)

> ع حسب استيعابي، ممكن باستخدام الـ pointer تتحكم بأي
> عدد من المتغيرات من متغير واحد. بس مش كأنها طريقة ملتفة
> للجواب عن وين دانيك؟
في الحقيقة هي طريقة ملتفة للجواب عن "وين متغيرك", تخيل معي السناريو التالي:
أنت كتبت إجراء يأخذ متغييرين و يقوم بقلبهما (قيمة الأول تصبح قيمة الثاني و بالعكس)
طبعاً لا تستطيع القيام بشيء كهذا:

void Foo(int iFirst, int iSecond)
{
	int iTemp = iFirst;
	iFirst = iSecond;
	iSecond = iTemp;
}


لأنك بهذا ستغير فقط المتغيرات الداخلية في الإجراء و ليس المتغيرات الحقيقية... باستخدام الـ pointer الإجراء السابق يصبح:

void Foo(int *pFirst, int *pSecond)
{
	int iTemp = *pFirst;
	*pFirst = *pSecond;
	*pSecond = iTemp;
}


و بهذا ستحصل على النتيجة المطلوية (بالطبع تستطيع استخدام الـ referencing بدل ذلك, ولكن لذلك محدودياته), هناك أيضاً فوائد و استخدامات كثيرة للـ pointers لا بد أنك ستصادفها و تشكر الله أنك تعرفت على هذا المنتدى الذي عرّفك عليها☺

عبد اللطيف حاجي علي
مبرمج
In|Framez

خبير مدير وسام البهنسي مشاركة 12

التعليق على مشاركة Abdo Haji-Ali في Mar 10, 2006 16:6 :

شكراً عبد اللطيف على مجموعة "الحقائق" التي طرحتها، وإن كان بعضها في غير محله.
تذكر أن هذا منتدى المبتدئين، إن سعيد كان يقوم بشرح الموضوع بطريقته الخاصة التي لا تلتزم بالضرورة بالدقة الكاملة وذلك بهدف تبسيط الأمور (ما زلنا بعيدين نوعاً ما هنا عن فروق أحجام المتغيرات عبر أنظمة التشغيل مثلاً، أليس كذلك؟)...
أرجو أن يكون القراء قد استطاعوا فهم هذه التفاصيل...

آسف للمقاطعة...


MSDN Game Technology Forums Moderator

وسام البهنسي
مبرمج في إنفيديا وإنفريمز

محترف مشرف عبد اللطيف حاجي علي مشاركة 13

التعليق على مشاركة وسام البهنسي في Mar 11, 2006 13:28 :

> التعليق على مشاركة Abdo Haji-Ali في Mar 10, 2006 16:6
> :
>
> شكراً عبد اللطيف على مجموعة "الحقائق" التي طرحتها،
> وإن كان بعضها في غير محله.
> تذكر أن هذا منتدى المبتدئين،
> إن سعيد كان يقوم بشرح الموضوع بطريقته الخاصة التي لا
> تلتزم بالضرورة بالدقة الكاملة وذلك بهدف تبسيط الأمور
> (ما زلنا بعيدين نوعاً ما هنا عن فروق أحجام المتغيرات
> عبر أنظمة التشغيل مثلاً، أليس كذلك؟)...
> أرجو أن يكون
> القراء قد استطاعوا فهم هذه التفاصيل...
>
> آسف للمقاطعة...
أتأسف حقاً، أظن أنني انجرفت بأفكاري... أعتذر لكل من سببت لهم الحيرة، وأعدكم أني سأحاول أن أكون أكثر تفهماُ...

أسف مرة أخرى

عبد اللطيف حاجي علي
مبرمج
In|Framez

خبير مدير وسام البهنسي مشاركة 14

أنا مازلت بانتظار إجاباتكم عن سؤال سعيد بسيوني... وفي هذه الأثناء، إليكم هذا التمرين:

أكتب برنامجاً بالـ C يقوم بطباعة أحجام المتغيرات المختلفة. أدخل الأنواع unsigned ضمن مجموعتك...


MSDN Game Technology Forums Moderator

وسام البهنسي
مبرمج في إنفيديا وإنفريمز

موهوب  راسم حسان مشاركة 15

التمرين الأول محلول. الكود كالآتي:
#include 
void main()
{
	printf("%d",sizeof(char));
	putchar('\n');
	printf("%d",sizeof(unsigned char));
	putchar('\n');
	printf("%d",sizeof(short));
	putchar('\n');
	printf("%d",sizeof(unsigned short));
	putchar('\n');
	printf("%d",sizeof(int));
	putchar('\n');
	printf("%d",sizeof(unsigned int));
	putchar('\n');
	printf("%d",sizeof(long));
	putchar('\n');
	printf("%d",sizeof(unsigned long));
	putchar('\n');
}

من هذا التمرين، ممكن جاوب سعيد على سؤاله...
النوع char حجمه بايت واحد فقط. النوع short حجمه بايتين. النوع int حجمه أربع بايتات. أما النوع long فكمان حجمه أربع بايتات كمان؟!!!
أيضاً من الملاحظ أن الأحجام لا تختلف عند استخدام unsigned مما يؤكد كلام سعيد وعبد اللطيف! أنا بعد بعيد عن البتات بس جايلها قريباً...
فهمت جزئيا ً مثال عبد اللطيف، بس بعد ما تعرفت عالـ pointers تمام بالـ C وخاصة تعاملها بالـ functions (الفصل القادم بالكتاب).
بدنا تمرين بسيط عالـ functions. تمرين من الحياة الواقعية لو أمكن!

راسم حسان

موهوب  حسن أيوب مشاركة 16

والله شغل تمام يا شباب, يعطيكن العافية.
فقط لعض الايضاحات:
1- ان المؤشرات Pointers, من أسهل وأسخف المواضيع في C++, وليس أصعبها وأعقدها, ولكن المشكلة أن الكتير من الكتب والمبرمجبن يفهمونها خطأ ويظنونها صعبة.
2-ان حجم المتغيرات (عدد البايت التي يحتاجها في الذاكرة) يختلف من نظام تشغيل الى آخر, ومن 32 بت الى 64 بت CPU, ومن Compiler الى آخر, ولكن على العموم, يمكنك ببساطة اضافة class stdio.h , واستعمال ال function sise_of, لمعرفة حجم المتغيرات, أو قراءة الكتاب الذي يأتي مع الCompiler الذي تستخدمه.
3- ان الCompiler, هو يقوم بالبحث عن مساحة فارغة في الذاكرة العشوائية Ram, ويضعه فيه المتغيرات حسب ال address الذي يجده, ورقم 1000 الذي استعمله الأخ بالشرح, هو فقط كمثال, والCompilers الذكية الآن تقوم بحساب عام لعدد المساحة الممكن احتياجها في Ram, قبل البدأ بحجزها.
4- ببساطة, ان ما شرحه الأخ عن الPointers هو كل شيء عن ال Pointers, وببساطة. ولكن الآن يجب التدرب عليها, والعمل بها كي تكون سلسة ثم نقوم بتعقيدها عبر دمجها مع أشياء أخرى شيئا فشيئا.
5- هذا هو شرح بسيط للFunctions:
ان الFunction تستعمل لتسهيل البرمجة وتقليل عدد الكود المستعمل
ان عملية انشاء ال Function مؤلفة من أربعة عمليات أساسية وهي:
1- احتيار اسمها.
2- تحديد ماذا تسقبل Parameters.
3- تحديد ماذا ستفعل.
4- تحديد نوع المتغير الذي سترده.
وشكل الFunction العام هو على هذا الشكل:
TYPE Function_Name(Parameters)
TYPE Function_Name(Parameters)
{
      // What The Fynction Will Do
     return // Variable
}

فمثلا لو أردنا كتابة Function تقوم باعطائنا حاصل ضرب عدد بنفسه (Square), فأول شيء يجب احتيار اسم مناسب للFunction, وليكن square, وثانيا ماذا ستسقبل منا هذه الFunction , وفي هذه الحالة سوف تستفبل رقما وبالتالي فالمتغير سيكون من نوع double لأنه ممكن أن يكون أي رقم وليكن اسمه num , ثم ستقوم الFunction بعمل العملية الحسابية التالية num*num, ثم سترده لنا لنستعمله ولذلك سيكون نوع الFunction هو double, والآن لنرى ماذا لدينا:
1- الاسم: square.
2- ستسقبل : double num .
3- ستعمل العملية الحسابية التالية: num * num .
4- سوف ترد رقم من نوع double, وبالتالي TYPE هو double.
ولنطبق هذه الأفكار على الشكل العام الذي كتيته قبل قليل يصبح لدينا هذا:
وهكذا يكون لدينا
double square(double num)
{
     double num2; // هذا السطر هو فقط لانشاء متغير لنحفظ فيه قيمة حاصل ضرب num بنفسه
     num2 = num*num;
     return num2;
}


وطبعا يمكننا الاستغناء عن تعريف متغير num2 عبر ارجاع القيمة المضرية بشكل فوري على الشكل التالي:
double square(double num)
{
      return num*num;
}

ولتجربة هذه الFunction في برنامج متكامل, يمكنكم كتابة الكود التالي على Microsoft C++ Compiler, او أي Compiler آخر يحترم نفسه:
#include 
using namespace std;
double square(double num)
{
      return num*num;
}
void main()
{
       double x=0;
       cin >> x;
       cout << "Please Insert A Number To Give You The Square Of It" << endl;
       cout << "The Number You Did Entered Is : " << x << " ." << endl <<
	"The Square Of: " << x << " Is: " <<  square(x) << " ." << endl;
}

وطبعا الFunction يجب أن تكون اعلى main,(يمكننا كتابتها أسفل main, ولكن طريقتها مختلفة قليلا, كما يجب أن تعرفا انه احيانا الFunctions تكون لا ترجع شيئا, وبذلك يكون نوعها TYPE هو void, ومثال على ذلك Function للطباعة:
void print_square()
{
    cout << square(x);
}

والآن أريد منكم أن تعموا برنامج يعتمد على Functions, يقوم بضرب عددين ببعضهما وطباعة النتيجة,والبرنامج هو هذا:
void main()
{
    input();
    multiplication(x,y);
    outpout();
}

وأنتم عليكم أن تكتبو الFunctions, بدون أي تعديل على main, وعليكم أن تعرفوا بأنفسكم بعد قراءة الmain التي كتبتها انا بتمعن, كيف تجعلون الFunction تستقبل متغيرين x و y لتقوم بضربهما.
موفقين.

لا شيء مستحيل. الشي الوحيد المستحيل هو قول مستحيل. لذا لا تقلها.

محترف  انس مشاركة 17

السلام عليكم

هاهو الحل الذي توصلت اليه


#include 
#include 


int g_x, g_y , g_resultat ;

void input();
void multiplication(int x, int y);
void outpout();


int main()
{
    input() ;
    multiplication(g_x,g_y);
    outpout();
    return 0;
}

void input (){

 scanf("%d",&g_x);
 scanf("%d",&g_y);

}



void multiplication(int x, int y){
 g_resultat = g_x*g_y ;
}

void outpout(){
 printf( "%d x %d = %d \n",g_x,g_y,g_resultat);
}


البرنامج يؤدي دوره كما يجب لكن هل هذا ما كان يهدف اليه ؟ ام انني استخدمة طريقة خاطئة .

شكرا

محترف مشرف عبد اللطيف حاجي علي مشاركة 18

وفي 20 تشرين الثاني 2008 10:35 ص، أعرب tombston عن رأيه بالموقف كالآتي:

البرنامج يؤدي دوره كما يجب لكن هل هذا ما كان يهدف اليه ؟ ام انني استخدمة طريقة خاطئة .
 
اعتقد أن هذا البرنامج هو ما كان يهدف له حسن. وإن كانت الطريقة ،برأيي، خاطئة نوعاً ما. ذلك أنها تستخدم متغيرات عامة (global) والذي يعتبر خطأ في معظم الحالات. هل تستطيع تغيير البرنامج بحيث تستغني عن هذه المتغيرات؟
 
أريد التأكيد هنا أن البرنامج مكتوب بلغة C وليس لغة C++ حيث أن الطريقة "الصحيحة" باستخدام لغة C قد تكون طريقة "خاطئة" في لغة C++. هل تستطيع تحويل هذا البرنامج إلى لغة C++?

عبد اللطيف حاجي علي
مبرمج
In|Framez

محترف  انس مشاركة 19

وفي 20 نوفمبر 2008 10:44 ص، قال عبد اللطيف حاجي علي متحمساً:

ذلك أنها تستخدم متغيرات عامة (global) والذي يعتبر خطأ في معظم الحالات

المتغيرات العامة ليست خطأ و لكنها غير م


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


وفي 20 نوفمبر 2008 10:44 ص، ظهر شبح ابتسامة على وجه عبد اللطيف حاجي علي وهو يقول:

حيث أن الطريقة "الصحيحة" باستخدام لغة C قد تكون طريقة "خاطئة" في لغة C++

اه لم اكن اعرف ذلك , هلا اتيت بمثال ؟



أما في 20 نوفمبر 2008 10:44 ص، فقد تنهد عبد اللطيف حاجي علي بارتياح وهو يرد:

هل تستطيع تغيير البرنامج بحيث تستغني عن هذه المتغيرات؟

يمكنني ذلك لكن يلزم اضافة متغيرات في  main()



في 20 نوفمبر 2008 10:44 ص، غمغم عبد اللطيف حاجي علي باستغراب قائلاً:

هل تستطيع تحويل هذا البرنامج إلى لغة C++?

بتعويض printf    -> cout
scanf-->cin
stdlib -->iostream

و هكذا يصبح الكود قابل للتحرير ب c++

خبير  Mohammad Khashashneh مشاركة 20

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

هناك سهوة في الfunction التالي

void multiplication(int x, int y)
{
 g_resultat = g_x*g_y ;
}

فالمتغيرات x,y غير مستخدمة فعليا في عملية الضرب.

كما أشار عبد اللطيف, يستحسن إعادة صياغة البرنامج بحيث تستغني عن المتغيرات العامة.

محمد رسمي خشاشنة

من سار على الدرب وصل, من جد وجد...
بس عتبك على اللي بيسمع