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

If Statement عجيبة في ++c, هل يمكنك معرفة السبب؟

مغلق
بدأه Khaled.Alshaya في 2 يناير 2008 · 19 رد · 3,286 مشاهدة · في اختبر قداراتك
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

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

كما عودتنا ++C, فإن شد الشعر و تكسير الشاشة بسبب طريقتها الغريبة في تفسير الكود :D

هذه المرة مع عبارة شرط تحتاج إلى تفكير عالي جداً :P

تصور أن لدينا السطور التالية في برنامجنا :

	int x = 4;

	if( -2 < x < 2 )
		cout << "Magic";

بدون تجربة المترجم, يعني عن طريق قراءة الكود فقط -_- هل تتوقع أن يتم تنفيذ الشرط في if statement أم لا ؟

و حتى لا يحصل غش :D يمكنك أن تجرب الكود, و لكن بعد ذلك أريد أن تكون إجابتك بنعم أو لا مع تفسير إجابتك ( هل سيتم طباعة الكلمة Magic أم لا مع السبب )..

أنا في انتظار الإجابات !!

تحياتي ,,

#2

لست مبرمج C++ لكن اعتقد سيتم طباعة كلمة Magic

والسبب انها لا تدخل ضمن الشرط IF

وشكرا لك علي هذة الأسئلة التي تجعل الواحد يفهم ولا يحفظ

#3

السلام عليكم أخ أحمد ..

اقتباس
لست مبرمج C++ لكن اعتقد سيتم طباعة كلمة Magic

والسبب انها لا تدخل ضمن الشرط IF

الحقيقة أن طباعة الكلمة من ضمن الشرط, في ++C لا يوجد فرق بين الكود الذي في الأعلى و الكود التالي :

int x = 4;

if( -2 < x < 2 )
{
	cout << "Magic"
}

تحياتي ,,

#4

ليس لدي كومبيلر الآن لكي أجرب عليه

لكن الإحتمالات بنعم أو لا واردة في ذهني

العبارة بالأعلى عبارة عن شرطين من غير استخدام and && أو or || !!!

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

و ربما أمرٌ آخر !!!!

بانتظار النتيجة ؟

تحياتي

،،

System Administrator

#5

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

أهلاً لك أخ ياسين ,,

اقتباس
العبارة بالأعلى عبارة عن شرطين من غير استخدام and && أو or || !!!

حسناً لقد اقتربت من الإجابة الصحيحة B) و لكن أريد معرفة كيفية يفسر المترجم هذه العبارة ؟ لأن العبارة التي في السؤال تفسر على مرحلتين!

تحياتي لمشاركتك ,,

#6

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

المفروض حسب الشرط لن يطبعها.

tvquran_6.gif

#7

بعد ماجربته , سيطبع .

وتفسيرها كما يبدو :

سيقارن بين x وبين سالب 2 ولأن سالب 2 اقل من 4 فسيكون نتيجة المقارنه الأولى true.

بعدين سيحول المترجم true الى 1 .

والواحد هو اقل من 2 وبالتالي true نتيجة المقارنه .

وترى كنت اظن ان المترجم سحول الـ2 الى true ولايطبع شيء وتكون :

true < true

لذا حكمت عليها مسبقا انها لن تطبع لكن بعد التجربه تبين انه تطبع .

يعني شدينا الشعر وماطلع معنا شي .

كله من ك ياخالد :wacko:

تم تعديل هذه المشاركة بواسطة الفدرالي في 2 يناير 2008 في 09:14

أتراك عين والعيون لها مدى *** ماجاوزته ولامدى لمداكا

إن لم تكن عيني تراك فإنني *** في كل شيء أستبين علاكا

يامنبت الأزهار عاطرة الشذى *** هذا الشذى الفواح نفح شذاكا

يامجري الأنهار ماجريانها *** الا انفعالة قطرة لنداكا

يارب هذا العصر الحد عندما *** سخرت ياربي له نعماكا

او مادرى الانسان ان جميع ما *** وصلت اليه يداه من نعماكا

لو شئت ياربي هوى صاروخه *** او لو أردت لماستطاع حراكا

فليرض عني الناس او فيسخطوا *** انا لم اعد اسعى لغير رضاكا

ذقت الهوى مرا ولم اذق الهوى *** يارب حلوا قبل ان اهواكا

يارب عدت الى رحابك تائبا *** مستسلما مستمسكا بعراكا

اتردني وترد صادق توبتي؟ *** حاشاك ترفض تائبا حاشاكا

فأقبل دعائي واستجب لرجاوتي*** ماخاب يوما من دعا ورجاكا

ياايها الإنسان مهلا مالذي *** بالله جل جلاله أغراكا؟

فاسجد لمولاك القدير فإنما *** لابد يوما تنتهي دنياكا

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

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

#8

أهلاً بالأخوة ,,

أعتقد أننا حصلنا على عدد جيد من الإجابات و أقرب إجابة كانت للأخ الفدرالي :wink: لذلك سأقوم بوضع الإجابة الصحيحة للجميع ,,

اقتباس
سيقارن بين x وبين سالب 2 ولأن سالب 2 اقل من الإكس فسيكون نتيجة المقارنه الأولى true.

حسناً إلى هنا إجابتك صحيحة 100%, و لكن :

اقتباس
بعدين سيقارن البرنامج بين true وبين رقم 2

وسيفسر رقم 2 على انه true .

بعد ذلك يقارن بين true و true ولأنهما متساويان فسينتج عن الشرط false .

لأن اصبح يفهم على انه true اقل من false

وهذا خطأ لأنهما متساويان .

هنا أنت عكست العملية أخي العزيز,

بعد أن حصلنا على true من عملية المقارنة بين 2- و x سنأتي لتفسير الشرط الثاني بين 2 و x ,,

في الحقيقة المترجم لن يقوم باعتبار 2 على أنها true بدلاً من ذلك سيقوم باعتبار true على أنها عدد int :D

هذه التحويلات تسمى promotion conversions أي يقوم بالتحويل من النوع الأصغر للنوع الأكبر,, في هذه الحالة سيتم تفسير true على أنها 1 ,, بعد ذلك ستتم المقارنة :

1 < 2

و نتيجة هذه المقارنة true و بالتالي يتم تنفيذ الشرط و طباعة كلمة Magic ,,

تحياتي لجميع المشاركين ,,

تم تعديل هذه المشاركة بواسطة Khaled.Alshaya في 2 يناير 2008 في 09:10

#9

على ما أظن أن الأخ الفدرالي قريب جدا من الصواب وقد نبهني إلى جزئية لم أكن منتبها لها من قبل

لقد كنت أظن في البداية أن البرنامج سيعطي رسالة خطأ لأن المفترض أن أعطي له الشرطين منفصلين وبينهما كلمة or أو and لكني فوجئت عند تنفيذ البرنامج أنه لم يعطي أي خطأ

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

3*5+2=15+2=17

هنا أيضا سيحدث نفس الأمر مع ملاحظة أن true=1 و false=0 أي كالآتي

(-2 < x < 2) = ((-2 < x) < 2) = (true < 2) = (1 < 2) = true

ويمكن وضع مثال أكثر تعقيدا لتوضيح الأمر وقد جربته بنفسي

x=5
(4 < x < 2)= (true < 2) = (1 < 2) = true

وهذا مثال آخر

x=5
(6 < x < 1) = (false < 1) = (0 < 1) = true

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

من أقوال الأئمة

الإمام علي بن أبي طالب -رضي الله عنه-: "الناس ثلاثة : فعالم رباني ، ومتعلم على سبيل النجاة ، وهمج رِعاع غوغاء أتباع كل ناعق ، يميلون مع كل ريح ، لم يستضيئوا بنور العلم ، ولم يلجئوا إلى ركن وثيق".

الإمام مالك -رحمه الله- : " لن يصلح آخر هذه الأمة إلا بما أصلح به أولها ".

الإمام الأوزاعي -رحمه الله- : " عليك بآثار من سلف وإن رفضك الناس وإياك وآراء الرجال وإن زخرفوه لك بالقول ".

الإمام الفضيل بن عياض -رحمه الله- : " عليك بطرق الهدى و لا يضرك قلة السالكين و إياك و طرق الضلالة ولا يغرك كثرة الهالكين ".

علامة الزمان الإمام الألباني -رحمه الله- : " إن الخلاص إلى أيدي هؤلاء الشباب يتمثل في أمرين لا ثالث لهما ؛ التصفية والتربية ".

وكل خير في اتباع من سلف وكل شر في ابتداع من خلف

#10

عذرا لقد دخلت في الموضوع منذ أكثر من ساعة ثم انشغلت بشئ آخر وبعد كتابتي للرد فوجئت بردك

وقد جربت هذا الكود

int x = 5;
std::cout << int(6<x)<<"\n";
std::cout << int(4<x)<<"\n";

وكانت النتيجة

0

1

أما في الفيجوال بيسك فكانت 0 و -1

من أقوال الأئمة

الإمام علي بن أبي طالب -رضي الله عنه-: "الناس ثلاثة : فعالم رباني ، ومتعلم على سبيل النجاة ، وهمج رِعاع غوغاء أتباع كل ناعق ، يميلون مع كل ريح ، لم يستضيئوا بنور العلم ، ولم يلجئوا إلى ركن وثيق".

الإمام مالك -رحمه الله- : " لن يصلح آخر هذه الأمة إلا بما أصلح به أولها ".

الإمام الأوزاعي -رحمه الله- : " عليك بآثار من سلف وإن رفضك الناس وإياك وآراء الرجال وإن زخرفوه لك بالقول ".

الإمام الفضيل بن عياض -رحمه الله- : " عليك بطرق الهدى و لا يضرك قلة السالكين و إياك و طرق الضلالة ولا يغرك كثرة الهالكين ".

علامة الزمان الإمام الألباني -رحمه الله- : " إن الخلاص إلى أيدي هؤلاء الشباب يتمثل في أمرين لا ثالث لهما ؛ التصفية والتربية ".

وكل خير في اتباع من سلف وكل شر في ابتداع من خلف

#11

أهلاً أخ باسم ,,

الحقيقة أن الموضوع كله يمكن فهمه إذا تم الاطلاع على عمليات الـ Implicit Conversions و لكن للأسف لم أجد أي مقال يتحدث عن هذا الشيء بشيء من التفصيل,, لا أدري إن كان هناك مقال يتحدث عن الموضوع ,,

النقطة الثانية هي أن ++C/C لها فلسفة خاصة في التعامل مع البيانات و كيفية التحويل بين الأشكال المختلفة للبيانات ففي النهاية أي نوع من المتغيرات هو عبارة عن مجموعة من الـ Bits التي تمثل نوع من البيانات,

أذكر عند بداية تعلمي للبرمجة بدأت تعلم Java, و الحقيقة أني جربت هذا الكود في ما بعد على Java و اتضح أنها لا تسمح بمقارنة الـ boolean مع الـ int على عكس ++C/C التي تقوم بعملية الـ Promotion Conversions تلقائياً, و في أسوأ الحالات سيعطيك المترجم إنذار warning فقط لا غير,,

تحياتي لك أخ باسم ,,

#12

ليست السي فقط بل البيسك أيضا انظر آخر مشاركة في الصفحة الأولى فالبيسك تتعامل بنفس الطريقة

x = -5
(-6 < x) * 2 = -2

هذا الشرط سيكون كالتالي في البيسك

(true * 2) = -2
(-1 * 2) = -2
-2 = -2
true

من أقوال الأئمة

الإمام علي بن أبي طالب -رضي الله عنه-: "الناس ثلاثة : فعالم رباني ، ومتعلم على سبيل النجاة ، وهمج رِعاع غوغاء أتباع كل ناعق ، يميلون مع كل ريح ، لم يستضيئوا بنور العلم ، ولم يلجئوا إلى ركن وثيق".

الإمام مالك -رحمه الله- : " لن يصلح آخر هذه الأمة إلا بما أصلح به أولها ".

الإمام الأوزاعي -رحمه الله- : " عليك بآثار من سلف وإن رفضك الناس وإياك وآراء الرجال وإن زخرفوه لك بالقول ".

الإمام الفضيل بن عياض -رحمه الله- : " عليك بطرق الهدى و لا يضرك قلة السالكين و إياك و طرق الضلالة ولا يغرك كثرة الهالكين ".

علامة الزمان الإمام الألباني -رحمه الله- : " إن الخلاص إلى أيدي هؤلاء الشباب يتمثل في أمرين لا ثالث لهما ؛ التصفية والتربية ".

وكل خير في اتباع من سلف وكل شر في ابتداع من خلف

#13

أهلاً بك أخ باسم,,

الحقيقة تجاربي مع BASIC كانت في الأيام الغابرة أيام QBasic :D

شكراً على المعلومة حول الـ BASIC, لكن لم أفهم حتى الآن لماذا تمثل true بـ 1- بدلاً من 1 :D ,,

تحياتي لك أخ باسم ,,

#14

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

احب ان اضيف الي ما قاله اخي خالد.

ان المترجم يبداء دائما من الخلف للامام (من اليسار لليمين) وليس العكس

اي يتم مقارنة الرقم 2 مع x اولا ثم مقارنة النتيجة السابقة مع 2- (سالب 2)

انظر الي هذا الكود.

int x = -1;

if( -1 < x < 0 )
{
	cout << "Magic"
}

بالطريقة السابقة فلن يطبع المترجم الكلمة magic

لان سالب 1 مقارنة مع سالب 1 تنتج false وهي تعني صفر

ويتم تحويل false الي صفر (int)

ثم يتم مقارنة الصفر مع الصفر تنتج false فلن يتم طباعة اي كلمة.

لكن نري ان المترجم طبع الكلمة لماذا؟ :(

هذا لان مترجم السي بلس بلس لا يقراء من اليسار الي اليمين (كاللغة الانجلزية) لكنه يقراء من اليمن الي اليسار (يعني ان مترجم السي بلس بلس عربي رسمي وقانوني)

اي يتم مقارنة الصفر مع X اولاً

ثم مقارنة الناتج من العملية السابقة مع سالب واحد

( _ /)

(='.'=)

(")-(")

#15

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

أهلاً بك أخ garo ,,

اقتباس
هذا لان مترجم السي بلس بلس لا يقراء من اليسار الي اليمين (كاللغة الانجلزية) لكنه يقراء من اليمن الي اليسار (يعني ان مترجم السي بلس بلس عربي رسمي وقانوني)

الحقيقة أخ garo هذا الموضوع دائماً ما أعلق فيه :D أعتقد أن الأمر اختلط عليك قليلاً,,

المهم أن هذا يسمى expression evaluation ,, و كلامك صحيح أن المترجم يقوم بقراءة العبارات من اليمين لليسار, و لكن عملية تقييم العبارات تكون من اليسار لليمين,

أي أن المترجم سيقرأها بالعكس و لكن سيفسرها كما كتبتها في الكود حسب أولوية المعاملات, السبب طبعاً ليس واضحاً و لكن بشكل عام الـ Data Structures المستخدمة في الـ Parsers غالباً هي عبارة عن Stack و أحياناً تستخدم الـ Trees, و إذا كنت تعرف ما معنى Stack فستعرف لماذا يقرأ المترجم العبارات بالعكس :wink:

و ناتج الشرط الذي وضعته يساوي false لأن عملية المقارنة تتم من اليسار لليمين,,

و لنا عودة مع العبارات في ++C و كيف يمكن أن يكون الناتج غير متوقع حقاً ,, و هذا الأمر ليس بالسهولة التي يمكن للمبرمج المبتدئ مثلي :S استيعابها, فكثير من المبرمجين المحترفين يراسلون Bjarne Stroustrup لكي يفسر لهم النتائج غير المتوقعة الناتجة عن عبارات غريبة..

تحياتي لإضافتك الرائعة ,,

#16

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

سؤال جميل في موضوع جميل من عضو اجمل ..

اخي خالد ... تفسيري العلمي والمنطقي لهذه الحالة هو التالي ..

void main()
{
	int x;
			   do{
						 cin >> x;
if(-2< x < 2)
cout << "x number"<< endl;
}while(x!=0);
}

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

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

-3 ، 8 ، 7 ، -9 ، 0 ، -60 ..... نرى ان الاعداد الموجبه التي ادخلتها انا هي جميعها اكبر من سالب 2 .. والاعداد السالبه التي ادخلتها هي اصغر من موجب 2 .. ونصل في النتيجة الى ان كل الاعداد المدخله هي اما اقل من الموجب 2 او اكبر من السالب 2 فكلها تحقق الشرط ..

فالعباره التي استخدمتها في برنامجي هي نفس العباره التاليه ..

if(x>-2  || x<2)

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

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

مثلا لو كان الشرط ..

if( 0<x<2)

فإما ان تكون قيمة x اقل من 2 فتصل الى المالانهاية السالب .. او اكبر من صفر لتصل الى المالانهاية موجب ..

هذا جوابي والله اعلم ..

اخي خالد .. عجبتني فكرة طرح هذه النوعية من الاسئله لذلك سأطرح لغز رياضي برمجي ..

تحياتي العطرة . .. . .

يَارَبُ إِن ضَاقَت قُلُوُب الْنَّاسٍ عَنْ مّافِي .. مِنْ خَيْرٍٍ فَعَفْوكَ لَا يَضِيْقْ ..

#17

أخي سنان عذرا ولكن كلامك هذا غير صحيح ولتتأكد جرب هذا الكود

int x;
x=2;
if (0<x<1)
cout<<"Any Thing";

على حسب كلامك المفترض أن الشرط متحقق لأن x>0 ومع ذلك لن يقوم البرنامج بطباعة العبارة المطلوبة

الحقيقة أن الكومبايلر سيترجم هذا الشرط من اليسار إلى اليمين كالتالي

x>0 ستعطي true ولغة السي تفسر true على أنها واحد أي أن x>0 ستعطي واحد

ثم بعد ذلك سيقارن بين 1 الناتجة من true والواحد الآخر الموجود في الشرط ونظرا لأن الواحد الأول ليس أصغر من الواحد الثاني فلن يتحقق الشرط

لكن لو استبدلت الشرط بهذا

if (0<x<1.0001)

فستجد أن الشرط أصبح متحقق

لأن الواحد المتولد من عبارة x>0 أصغر من 1.0001

من أقوال الأئمة

الإمام علي بن أبي طالب -رضي الله عنه-: "الناس ثلاثة : فعالم رباني ، ومتعلم على سبيل النجاة ، وهمج رِعاع غوغاء أتباع كل ناعق ، يميلون مع كل ريح ، لم يستضيئوا بنور العلم ، ولم يلجئوا إلى ركن وثيق".

الإمام مالك -رحمه الله- : " لن يصلح آخر هذه الأمة إلا بما أصلح به أولها ".

الإمام الأوزاعي -رحمه الله- : " عليك بآثار من سلف وإن رفضك الناس وإياك وآراء الرجال وإن زخرفوه لك بالقول ".

الإمام الفضيل بن عياض -رحمه الله- : " عليك بطرق الهدى و لا يضرك قلة السالكين و إياك و طرق الضلالة ولا يغرك كثرة الهالكين ".

علامة الزمان الإمام الألباني -رحمه الله- : " إن الخلاص إلى أيدي هؤلاء الشباب يتمثل في أمرين لا ثالث لهما ؛ التصفية والتربية ".

وكل خير في اتباع من سلف وكل شر في ابتداع من خلف

#18

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

دائما استخدم في المقارنات العبارات المركبه والروابط || && .

مثلا لوكتبت

int x=2;
if(2<x<2) cout<<"TRUE";

سوف يطبع النتيجه ترو

tvquran_6.gif

#19

كلامك صحيح اخي باسم..

المشكله هي انه في حالات عديده يتحقق الشرط عند اي رقم .. وفي حالات لا يتحقق . . .

ولكن هو شي يحير بالفعل لانك لو جربت الكود التالي تجده يحقق مع العلم هومقارب لما كتبته انت ..

int x=3;
if(1<x<2)
cout << "any thing";

ما الفرق بين الكودين ..؟؟ مجرد اني اضفت واحد لكل رقم في الكود الذي كتبته انت .. نجده يحقق الشرط ..

حتى لو كان الشرط كالتالي ..

if(-1<x<2)

نجده يحقق الشرط عندما الرقم 3 ..

تحياتي العطرة ..

يَارَبُ إِن ضَاقَت قُلُوُب الْنَّاسٍ عَنْ مّافِي .. مِنْ خَيْرٍٍ فَعَفْوكَ لَا يَضِيْقْ ..

#20

عزيزي سنان الأمر ليس محير فهذا طبيعي بناء على الأسلوب الذي يفهم به السي هذا الأمر

يعني على سبيل المثال

if(any thing<x<2)
cout << "True";

هذا الكود سيعطي true دائما وأبدا مهما حدث لأنه لو كانت x>any thing فسيكون ناتج المقارنة الأولى 1 وإلا فسيكون صفر ثم بعد ذلك سيقوم المترجم بمقارنة هذا الناتج (1 أو 0) بالعدد 2 وفي كلتا الحالتين 2 أكبر من 1 وأكبر من صفر أي أنه سيعطي true دائما مهما كانت قيمة x أو any thing

من أقوال الأئمة

الإمام علي بن أبي طالب -رضي الله عنه-: "الناس ثلاثة : فعالم رباني ، ومتعلم على سبيل النجاة ، وهمج رِعاع غوغاء أتباع كل ناعق ، يميلون مع كل ريح ، لم يستضيئوا بنور العلم ، ولم يلجئوا إلى ركن وثيق".

الإمام مالك -رحمه الله- : " لن يصلح آخر هذه الأمة إلا بما أصلح به أولها ".

الإمام الأوزاعي -رحمه الله- : " عليك بآثار من سلف وإن رفضك الناس وإياك وآراء الرجال وإن زخرفوه لك بالقول ".

الإمام الفضيل بن عياض -رحمه الله- : " عليك بطرق الهدى و لا يضرك قلة السالكين و إياك و طرق الضلالة ولا يغرك كثرة الهالكين ".

علامة الزمان الإمام الألباني -رحمه الله- : " إن الخلاص إلى أيدي هؤلاء الشباب يتمثل في أمرين لا ثالث لهما ؛ التصفية والتربية ".

وكل خير في اتباع من سلف وكل شر في ابتداع من خلف

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

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