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

نتائج غير معروفة undefined

بدأه محمد عودة في 25 فبراير 2012 · 3 رد · 784 مشاهدة · في المواضيع والدروس
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

نتائج غير معرفة

أهلا بك مجددا هل تريد ان تخرج عن المعتاد وتقرأ شئ ينعش ذاكرتك واصل القراءة

أن لم يتم تعريف قاعدة لعملية محددة فى ترجمة كود سي فأن الكود يسمى غير معرف undefined لذلك تجد كل مترجم يعطيك نتيجة مختلفة لنفس الكود.

عادا المترجمات ﻻتفحص اﻻكواد او العمليات الغير معرفة ففحص الكود يرجع لمعرفتك بقواعد اللغة

مثال:

#include <stdio.h>
int main(void)
{
    char buffer[5];
    strcpy(buffer, "Hello World");

    printf("Hello World!\n%s", buffer);
    return 0;
}

كما بالمثال السابق أن عملية نسخ النص الى المصفوفة buffer التى حجمها أصغر من النص نفسة هذة تسمى عملية غير معرفة undefined أى ليس لها قاعدة حتى تتبعها المترجمات آثناء فحص الكود .

والكود مر على المترجم مرور السلام مع أنه خاطئ

اﻻسئلة الغير معرفة اﻻكثر شيوعا:

1. ماهى مخرجات الكود التالى؟

int i = 7;
printf( "%d",i++ * i++ );

2. ما الذى يمكن ان يحدث للمصوفة بعد تنفيذ الكود التالى:

int a[5], i = 1;
a = i++;

3. ماهى قيمة المتغير i بعد تشغيل الكود التالى:

int i = 7;
i = ++i;

هذة اﻻسئلة يسميها بعض المبرمجين اﻻسئلة( الغبية) اى التى تحتار فيها يا ترى صحيحة أم خاطئة؟ اذا لو ان مثل هذة اﻻسئلة سئلت فأن اﻻجابة الصحيحة هى غير معرف undefined .

ﻻحظ: بالنسبة للبرامج أعلاة قد تحصل على مخرجات. ولكنها خاطئة. يجب عليك ان تفهم ان المترجمات ربما لن تفحص القواعد الغير معرفة .

تحياتى العطرة والله ولى التوفيق

تم تعديل هذه المشاركة بواسطة محمد ابوزايد في 25 فبراير 2012 في 16:58

1

post-15367-027053900%201340345097.gifpost-15367-087183200%201340344597.gif
post-247365-0-10080400-1379403554_thumb.

#2

مرحبا أخي محمد :)

الواحد ينتهى من قراءة موضوعك ولسه ماحس بيها, فعلا الموضوع شيق :happy:

اقتباس
عملية نسخ النص الى المصفوفة buffer التى حجمها أصغر من النص نفسة هذة تسمى عملية غير معرفة undefined أى ليس لها قاعدة حتى تتبعها المترجمات آثناء فحص الكود .

بالنسبة لي, أرى أن موضوع الـ Undefined Behavior يُعتبر من نقاط ضعف لغة السي :blush: لأنه ناتج عن عدم صرامة اللغة !, سأعطيك مثال. عندما نكتب :

int x = 76;
printf("xFloat = %f",x);

كيف ستكون قيمة المُخرجات ؟ ببساطة .. لا أحد يملك الجواب !, لأن هذا سلوك غير معروف بينما لو كتبنا هكذا :

int x = 76;
printf("xFloat = %f",float(x));

ستكون المُخرجات ثابتة في كل مترجم :

xFloat = 76.000000

Process returned 0 (0x0) execution time : 1.161 s

هذا الخطأ مثلا لا يمكن أن يحدث في الجافا أو السي++ لأنه لا يوجد رمز (%) لكل متغير, فقط نكتفي بتمرير عنوان المتغير :

System.out.println(x);//Java
cout<<x;//C++

لكن في المقابل إذا كانت printf تعتمد على الرموز, فلماذا لا تتحقق من الرمز المُرسل إليها قبل إظهار القيمة ؟؟ .... هنا تكمن المصيبة ! و أظن أن هذا نقص في تصميم الدالة أصلا ! :blush:, تعتمد دوال السي على فلسفة الــ Preconditions, فعندما تستعمل أي دالة .. يجب أن تناديها بشكل صحيح و إلا فالدالة ليست مسؤولة عن التحقق من صحة ما يمرر لها !

في بعض الأحيان تكون هذه ضريبة عدم خضوع C لــ OOP لعدم وجود استنثناءات لمثل هذه الحالات, فأكبر علاج لقضية الـ Undefined Behavior هو وجود Exception خاص بكل حالة.

مما تمتاز به بقية اللغات الأخرى على السي/السي++ وجود مجموعة من الإستثناءات لبعض العمليات التي تنتج عنها أخطاء منطقية مثل القسمة على الصفر, السي و السي++ لا يحركان ساكنا في هذه الجزئية ! أما الجافا مثلا فتستدعي ArithmeticException عند القسمة على الصفر.

أيضا في الجافا, هناك استثناء خاص بالــ Underflow/Overflow و اسمه ArrayIndexOutOfBoundsException. وهكذا .. أظن أن الجافا تتغلب على السي/السي++ في هذه الجزئية.

اقتباس
1. ماهى مخرجات الكود التالى؟

int i = 7;
printf( "%d",i++ * i++ );

2. ما الذى يمكن ان يحدث للمصوفة بعد تنفيذ الكود التالى:

int a[5], i = 1;
a = i++;

3. ماهى قيمة المتغير i بعد تشغيل الكود التالى:

int i = 7;
i = ++i;

في كل مرة يحدث Undefined Behavior لأنك تقوم بتعديل قيمة متغير أكثر من مرة خلال Sequence Point واحدة.

تخيل أنك تقوم بالتالي:

int* addr = /* some random address */;
std::cout << *addr;

ما تراه عبارة عن Undefined Behavior, لأنك قمت بالوصول إلى ذاكرة لا تملكها. بالطبع في C و ++C لن يأتي أحد و يخبرك بأنك قمت بهذا الأمر, ببساطة ليس هناك run-time checking.

بمجرد محاولتك الوصول إلى ذلك المكان الذي يشير إليه addr فإن برنامجك دخل منطقة ضبابية, النتائج يمكن أن تكون أي شيء!

للمزيد : ما تقسيركم لهذا التصرف ؟

أيضا, قد يحدث الـــ Undefined Behavior عند استخدام المؤشرات كقيمه معاده من الدوال.

تحياتي.

#3

شكراً أخ محمد على إثاره هذه النقطه الجيده ...

وايضاً شكراً للأخ خالد على عرض النقطه ومقارنتها بلغات أخرى ...

وكلنا يعلم أن لغة السي هى الأقرب من التعامل مع العتاد الصلب للجهاز وبها حريه واسعه للتحكم فى كل موارد الجهاز لهذا يذهب لها دوماً كل من يريد أن ينتج برنامجاً قوياً من الصفر "ليس نحن ولكن الشركات الكبرى :D " , وإمتداداً لها هى لغة السي++ التى تدعم الكائنات وبالتالى تسهيل الأمور . فمن سوف يتعامل مع لغه السي فهو يعلم أنها لغه لا تقيد فيها فيأخذ حذره ويدرس ماهيه الدوال التى سوف يتعامل معها "يعنى عايزه مبرمج صاحى :D ".

ولكن ما أراه من وجهه نظرى هو أن الجافا أكثرت من وضع القيود !!! وأين ذهبت المؤشرات فى الجافا :D لكن ميكروسوفت لتغرى عين عملاءها من مبرمجى لغة ++c و c فهى سمحت لهم إستخدام المؤشرات بها ولكن على حسب هواها :D هما إشتروا المبرمجين ولا إيه :sleep:

ومتعه كتابه الكود بلغة الجافا لا تقارن بمتعه كتابته بلغة السي :D المؤشرات وما أدراك ما المؤشرات :D

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

لا إله إلا أنت سبحانك إني كنت من الظالمين

#4
اقتباس
ولكن ما أراه من وجهه نظرى هو أن الجافا أكثرت من وضع القيود !!! وأين ذهبت المؤشرات فى الجافا :D لكن ميكروسوفت لتغرى عين عملاءها من مبرمجى لغة ++c و c فهى سمحت لهم إستخدام المؤشرات بها ولكن على حسب هواها :D هما إشتروا المبرمجين ولا إيه :sleep:

ومتعه كتابه الكود بلغة الجافا لا تقارن بمتعه كتابته بلغة السي :D المؤشرات وما أدراك ما المؤشرات :D

الجافا لم تضع قيود على المؤشرات .. بل حذفتها بالكامل :D !! (أقصد التعامل المباشر مع المؤشرات)

لكن في المقابل, السي++ لم تُقدم الحماية الكافية لمبرمجيها كي لا يقعوا في أخطاء التشغيل (بما فيها الـ Undefined Behavior و الــ Underflow/Overflow ) التي قد تتسبب في توقف الحاسوب عن العمل ! :)

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