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

خبير مشرف مؤيد مارديني مشاركة 21

وفي 01 أيلول 2009 11:57 م، ظهر شبح ابتسامة على وجه علي محمد أسماعيل وهو يقول:

لو كانت اللغة مغلقة لما كان هناك اكثر من مجمع للغة.

راجع ما قاله وسام، مواصفات هذه اللغة وغيرها من اللغات كـ#C مواصفات معروفة ومعلن عنها، يمكنك الاستفادة منها لبناء مترجمك\مجمعك الخاص، ولكن بالتأكيد ليست جميع مترجمات اللغات المفتوحة المواصفات مفتوحة المصدر.
وبصراحة لا أعرف ما علاقة Lua بالأمر، ما علاقة Lua بلغة C، وهل إن كانت Lua مفتوحة المصدر تكون ++C\C مفتوحة المصدر؟!

Moayad Mardini,
MSDN Forums Moderator

مفصول علي محمد أسماعيل  مشاركة 22

في 02 أيلول 2009 12:13 ص، غمغم مؤيد مارديني باستغراب قائلاً:

راجع ما قاله وسام، مواصفات هذه اللغة وغيرها من اللغات كـ#C مواصفات معروفة ومعلن عنها،

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

بتاريخ 02 أيلول 2009 12:13 ص، قطب مؤيد مارديني حاجبيه بشدة وهو يقول:

وبصراحة لا أعرف ما علاقة Lua بالأمر، ما علاقة Lua بلغة C، وهل إن كانت Lua مفتوحة المصدر تكون ++C\C مفتوحة المصدر؟!

انا دائما اظطر الى اعادة كلامي مرتين....يال حظي السيء...قلت للأخ انس أن كان مهتما بلغة مفتوحة المصدر فله الاطلاع على لغة Lua والتي هي مكتوبة بلغة سي بما اننا كنا نتحدث عن لغة سي.
وشكرا

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

في 01 سبتمبر 2009 09:25 م، قال علي محمد أسماعيل بهدوء وتؤدة:

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

هناك الـ PHP مثلا او Python .

اما عن مواصفات اللغة فيمكنك اعتبار الـ Syntax و المبادئ الخاصة بالغة هي المواصفات. اللغة في حد ذاتها مخطط يعمل عليه المترجم.

مفصول علي محمد أسماعيل  مشاركة 24

في 02 أيلول 2009 12:39 ص، عقد انس حاجبيه بتفكير وقال:

هناك الـ PHP مثلا او Python .

أجل اعرف.وقد ذكرت Lua لتجربتي السابقة في التعامل معها ولكون الكود سهلا تقريبا وقابلا للقراءة.

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

أنس، كود مكتبة C القياسية موجود للتحميل من موقع FTP المفتوح هذا:
 
http://ftp.gnu.org/gnu/glibc/
 
يوجد العديد من الإصدارات هناك، وأنا بصدد تحميل أحدها لأحدد لك بالضبط الملف الذي يحوي تعريف إجراء sprintf.

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

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

حسناً لقد حملت الإصدار 2.9 من الكود، وتستطيع رؤية تعريف sprintf في الملف الآتي:
 
glibc-2.9\stdio-common\sprintf.c
 
الإجراء لا يقوم بأي عملية معقدة. فهو فقط يمرر البارامترات إلى الإجراء vsprintf. لذلك عليك أن تتابع سلسلة النداءات إلى أن تصل إلى النواة التي تقوم بالمعالجة الفعلية. بالنسبة لي فقد وجدت تلك النواة وطبعاً لم يخب ظني في وضوح الكود ☺   سأترك لك المفاجأة كي لا أفسدها عليك...
 
حظاً سعيداً...

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

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

السلام عليكم.

استطعت الوصول الى نواة الكود لكن ما ادهشني ليس غرابة الكود و انما فدم طريقة كتابته.

قد يكون ما اقوله تفهة لكن على حسب علمي فان :

static int _IO_strn_overflow (fp, c)  _IO_FILE *fp;  int c;
{

قديمة و ان الاصدار الحالي او الذي قبله للغة السي يقبل ما هو اسهل للقراءة مثل :

static int _IO_strn_overflow (_IO_FILE *fp, int c) 
{

اظن ان هذا اقضل بكثير ، و استغرب استعمال هذه الطريقة من هؤلاء المبرمجين.

الشيئ الثاني الذي اثار استغرابي هو مايلي :
*sf.f._sbf._f._IO_write_ptr = '\0';

او لم يكن من الافضل استعمال الرمز 
->


اما ما يحيرني دائما فهو سبب استعمال ال __ عند التسمية. هل هذا لتجنب تشابه اسماء الدوال الافتراضية مع دوال المبرمج المستعمل لها ؟

شكرا جزيلا استاذ وسام انا في صدد تحليل الكود و اي سؤال فلا اظنكم ستبخلون علي بالاجابة. اليس كذالك ☺

سلام

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

في 02 أيلول 2009 08:21 م، غمغم انس باستغراب قائلاً:

قديمة و ان الاصدار الحالي او الذي قبله للغة السي يقبل ما هو اسهل للقراءة


بالفعل. هذه من التراكيب القديمة للغة C. وهذا يدل أن هذا الكود لم يمس منذ زمن. على مبدأ: إن لم يكن مكسوراً فلا تصلحه.

بتاريخ 02 أيلول 2009 08:21 م، قطب انس حاجبيه بشدة وهو يقول:

او لم يكن من الافضل استعمال الرمز  ->

وكيف تقترج استخدامه؟ لاحظ أن للعملية . أولوية أكبر من العملية * لذلك فما تقوم به هنا هو dereference للمتغير _IO_write_ptr. 


وفي 02 أيلول 2009 08:21 م __اما ما يحيرني دائما فهو سبب استعمال ال، أعرب انس عن رأيه بالموقف كالآتي:

عند التسمي

حسب علمي فإن هذا الاصطلاح هو لتمييز المتغيرات الخاصة بمكتبة CRT عن تلك العامة والتي يستطيع المبرمج التعامل معها. خيث لم يكن هناك private و public في لغة C.

بشكل عام أنصحك بألا تلقي بالاً لطريقة كتابة الكود أو أن تعتبرها جيدة فقط لأن جماعة Microsoft أو غيرهم قد قامو بكتابتها. مبرمجو Microsoft ليسو أفضل من كتب كود (كإسباق اسماء الصفوف بـ C أو رمي مؤشرات بدل مراجع)

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

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

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



وفي 03 سبتمبر 2009 07:39 ص، أعرب عبد اللطيف حاجي علي عن رأيه بالموقف كالآتي:

وكيف تقترج استخدامه؟ لاحظ أن للعملية . أولوية أكبر من العملية * لذلك فما تقوم به هنا هو dereference للمتغير _IO_write_ptr. 
ساحاول شرح الفكرة التي استوعبها فلربما هي ناقصة :

عندما كتابة الكود التالي :
struct sprite {
BITMAP* surface;
int x , y ;
int w , h ;

};

struct player {

sprite* spr ;
int life ;
};
لكي نستطيع التعامل مع المؤشر هناك طريقتين:

الطريقة الاولى :
Player p1;

pl1->spr = creat_sprite();
pl1->spr->surface = creat_new_surface("image01.png");
الطريقة الثانية :

Player p1;

*pl1.spr = creat_sprite();

هذا ما كنت اقصدهـ هل هذه الفكرة صحيحة ؟

شكرا جزيلا.
سلام.

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

هذا ما ظننته لذلك ذكرتك بأولوية العمليات في لغات C. تذكر أن العملية (.) لها أولوية على العملية (*)

أنظر الكود التالي:
typedef struct _Test
{
	int* pMember;
}Test;

int main()
{
	Test test;
	Test *pTest;

	*test.pMember = 5;
	pTest->pMember = 5;
	*pTest->pMember = 5;
	*pTest.pMember = 5;
}


ثم لنحاول فهم كل احتمال على حدا


*test.pMember = 5;
هذا الكود يقوم بالوصول إلى pMember داخل test ثم عمل dereference له والكتابة فيه. لاحظ أن test ليس مؤشراً ولا يحتاج إلى dereference


pTest->pMember = 5;
هنا نصل إلى pMember عن طريق عمل dereference لـ pTest باستخدام العملية (->) ونحاول الكتابة في pMember مباشرة. (أي أن قيمة المؤشر تصبح 5)


*pTest->pMember = 5;
هذا السطر يشبه الذي قبله لكن ما نقوم به هو الكتابة في المكان الذي يؤشر له pMember وذلك بعد أن نعمل له dereference باستخدام العملية (*)


*pTest.pMember = 5;
نأتي إلى السطر المتهم. ما تعتقده أنت هو أن العملية (*) ستقوم بعمل dereference لـ pTest ثم نصل إلى pMember عن طريق الناتج ذي النوع Test باستخدام العملية (.)

لكن ما يحصل في الحقيقة هو العكس تماماً لأن العملية (.) لها أولوية على العملية (*). فأولاً نحاول الوصول إلى pMember داخل pTest ذي النوع Test* باستخدام العملية (.) ثم نقوم بعمل dereference للمتغير pMember باستخدام العملية (*) ونكتب في العنوان الذي يحويه. لاحظ أن هذا السطر سيعطي خطأ، ذلك أن النوع Test* لا يحوي pMember بعكس النوع Test.

أرجو أن تكون الفكرة قد وضحت

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