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

حزورة لتنشيط الدماغ..

رائج
بدأه مصطفى 36a2 في 1 يوليو 2012 · 81 رد · 4,562 مشاهدة · في لغة C و ++C
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

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

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

int main(){	return 0;}

فقط لا أكثر ولا أقل ...
ولا يحق لك تغيير هذه الدالة أبداً .. او إضافة أو إزالة أي حرف أو رمز ...
ويمكنك كتابة ما تشاء خارج هذه الدالة ...

ويمكن للبرنامج أن يقوم بأي عمل تريد ... وفي سؤالنا اليوم .. لن نتجاوز كتابة Welcome to C++ I...
هل السؤال واضح ... اكتب برنامجا يقوم بطباعة العبارة Welcome to C++ I... وذلك دون أي تغيير في الدالة main والتي ستكون كما يلي :

int main(){	return 0;}

السؤال بسيط جدا ... تحتاج فقط إلى أن يكون قد مرّ عليك من قبل ...
أنتظر إجاباتكم والسلام عليكم

تم تعديل هذه المشاركة بواسطة مصطفى 36a2 في 7 مارس 2014 في 15:35

1
#2

السلام عليكم

يمكننا إنشاء فئة باسم Welcome مثلا, و نضع الجملة المُراد إظهارها داخل دالة البناء ثم ننشئ كائن جديد من الفئة Welcome قبل الدخول في الدالة الرئيسية, هكذا :

#include <iostream>

class Welcome {
public:

    Welcome() {
        std::cout << "Welcome to C++ !" << std::endl;
    }
} Welcome;

int main() {
    return 0;
}

بانتظار مختلف الأفكار :happy:

1
#3
اقتباس
بانتظار مختلف الأفكار

هل تعتقد ان هناك طريقة أخرى ؟؟

أظن أن هذه الطريقة الوحيدة......إلا إذا اعتبرنا مثلا أن هذه طريقة أيضاً :

#include <iostream>
using namespace std;
struct Welcome {
public:

	Welcome() {
    	cout << "Welcome to C++ !" << endl;
	}
} Welcome;

int main() {
	return 0;
}

تم تعديل هذه المشاركة بواسطة مصطفى 36a2 في 1 يوليو 2012 في 13:50

#4
اقتباس
أظن أن هذه الطريقة الوحيدة......إلا إذا اعتبرنا مثلا أن هذه طريقة أيضاً

...

كلتا الطريقتين يمثلان نفس الفكرة, لأن struct في الأصل هي نسخة مُخففة من class :)

اقتباس
هل تعتقد ان هناك طريقة أخرى ؟؟

لمَ لا ؟, يمكننا حل السؤال عن طريق الخدعة التالية :

#include <stdio.h>
#define return printf("Welcome to C !!");

void main() {
	 return;
}

مُخرجات الكود :

post-219439-021763700 1341140511_thumb.p
المرفقات
Welcome.png
1
#5

define مثل عملية "بحث وإستبدال" بحيث سيتم إستبدال return بالدالة لحظة تصريف البرنامج.

لو كان لدينا هذا البرنامج :

#include<stdio.h>

void my_function();

int main(void) {
    return(0);
}

void my_function() {
    printf("I'm my_function.\n");
}

عند تشغيله :

PS C:\Users\Barakat\Desktop> .\foo.exePS C:\Users\Barakat\Desktop>

يمكننا تنفيذ الدالة my_function عن طريق تغيير نقطة الإدخال entry point , وهي العنوان الذي يحدد فيه windows عنوان الدالة الرئيسية, إلى عنوان الدالة my_function :

0040139E  /. 55             PUSH EBP                                ; بداية دالتنا
0040139F  |. 89E5           MOV EBP,ESP
004013A1  |. 83EC 18        SUB ESP,18
004013A4  |. C70424 6430400>MOV DWORD PTR SS:[ESP],foo.00403064      ; |ASCII "I'm my_function."
004013AB  |. E8 58070000    CALL <JMP.&msvcrt.puts>                  ; \puts
004013B0  |. C9             LEAVE
004013B1  \. C3             RETN

عن طريق أي محرر PE , بعد التعديل :

PS C:\Users\Barakat\Desktop> .\foo.exeI'm my_function.
PS C:\Users\Barakat\Desktop>
#6

كلام جميل ... و أشك بوجود أي حل مغاير ( لمحدودية اللغة )...

وإليكم هذا السؤال أيضاً ... باعتبار المسألة مسلية .. لدينا الدالة main التالية ..

int main() 
{
     	return(Welcome To C++);
}

نفس القواعد السابقة ... اكتب ما ينقصك .. حتى يطبع البرنامج أي عبارة مكتوبة داخل قوسي return 049.gif

هناك جواب واحد فقط صحيح ... أنتظركم

#7

ما رأيك بهذا ؟ :D

#include <iostream>
int Welcome(){
    std::cout<<"Welcome To C++"<<std::endl;
    return 0;
}
int main() {
    return (Welcome());
}

لي عودة بعد الإنتهاء من فهرسة القسم :happy:

#8

laugh.gifجميلة ... ولكن .. أريد تماماً ... تنفيذ الmain السابقة :

int main() 
{
        return(Welcome To C++);
}

بدون تغيير... (وبدون علامات تنصيص...)006.gif

أنتظرك بعد الانتهاء من الفهرسة ...

تم تعديل هذه المشاركة بواسطة مصطفى 36a2 في 1 يوليو 2012 في 15:21

#9

هذه تتطلب macro لتبديل return بـprintf وإضافة الأقواس بإستخدام # :

#include<stdio.h>
#define return(string) printf(#string)  /* #string == "string" */

int main() 
{
        return(Welcome To C++);
}

PS C:\Users\Barakat\Desktop> .\foo.exe ; echo ""Welcome To C++
PS C:\Users\Barakat\Desktop>
#10

صحيح تماماً ... سيد B .. وطبعا سيعطينا warning لأننا تجاهلنا القيمة المعادة ...

هل لديك ... بعض الأسئلة من هذا القبيل .. أيضاً ...

هذه الأسئلة هي مجرد تجارب قمت بها وأحببت أن أشارككم فيها ... فهل يمكنك مشاركة المزيد ... قبل أن تبدأ جعبتي بالنفاد wink.gif

إليك هذه ..

#include<iostream>
using namespace std;
int main()
{
	int abc=0;
	int a,b,c;
	past(a,b,c)=5;
	cout<<abc<<endl;//Display 5
	return 0;
}

أضف سطرا واحدا يجعل هذا البرنامج صالح للعمل ...

حل واحد صحيح فقط ...

تم تعديل هذه المشاركة بواسطة مصطفى 36a2 في 1 يوليو 2012 في 16:13

#11

.. سبقني بها عُكاشة !! :D

جميل جدا أخي Mr.B :)

للفائدة, سأضع لكم برنامجين صغيرين و لكنهما يحتويان على بعض الخدع الجميلة (رغم بساطتها)

  • الكود الأول, يطلب من المستخدم عدد ثم يظهر مربعه (بافتراض أن زر النقطة الفاصلة معطل ! :D ) :
    #include<iostream> 
    void main( int x )                
    { 
        if(std::cout<<"Enter a Number:\t") {}
        if(std::cin>>x) {}
        if(std::cout<<"The result = "<<x*x) {}
    }


  • الكود الثاني, يطلب من المستخدم إدخال عدد, ما دام العدد المُدخل موجبا فيسطلب منه إدخال عدد جديد أما إن كان سالبا فيستوقف البرنامج :
    #include<stdio.h>
    int main()
    {
        int x;
        while(printf("x = "),scanf("%d",&x),x>0)
              printf("Le nombre est positif, veuillez saisir un nouveau nombre !\n");
        return 0;
    }


لي عودة.

#12

الحمد لله زر الفاصلة المنفوطة .. شغال ..laugh.gif

إليكم حزورة ..أخرى ..مفيدة بالفعل ...

كيف يمكن أن نجعل البرنامج يكرر نفسه دون توقف بدون استخدام أي حلقة أو goto ..؟

يعني اكتب تعليمة وحيدة في آخر البرنامج تجعله يعيد نفسه ..

تم تعديل هذه المشاركة بواسطة مصطفى 36a2 في 1 يوليو 2012 في 16:39

#13
اقتباس
إليكم حزورة ..أخرى ..مفيدة بالفعل ...

كيف يمكن أن نجعل البرنامج يكرر نفسه دون توقف بدون استخدام أي حلقة أو goto ..؟

يمكننا فعل ذلك عن طريق الــ Recursive function هكذا :

#include <iostream>
void Recurs() {
    std::cout<<"Welcome To C++"<<std::endl;
    Recurs();
}
int main() {
    Recurs();
    return 0;
}

اقتباس
أضف سطرا واحدا يجعل هذا البرنامج صالح للعمل ...

حل واحد صحيح فقط ...

لم أفهم هذا السؤال !, مالمطلوب بالضبط ؟؟

#14

فقط إستدع الدالة الرئيسية نفسها :

#include<stdio.h>

main(void) {
    printf("X");
    main();
}

وستعمل كما لو كانت printf في حلقة تكرار.

1
#15

ممتاز...ما شاء الله عليك سيد B .... ألا ترى أنها بالفعل طريقة عملية ...

أخي أحمد ...لديك هذا الكود ...

#include<iostream>
using namespace std;
int main()
{
        int abc=0;
        int a,b,c;
        past(a,b,c)=5;
        cout<<abc<<endl;//Display 5
        return 0;
}

إذا حاولت ترجمته فسيعطيك خطأ .. ويطلب تعريف الدالةpast

السؤال هو .. عرّف الدالة past بحيث يطبع سطر الإخراج قيمة المتحولabc

تم تعديل هذه المشاركة بواسطة مصطفى 36a2 في 1 يوليو 2012 في 16:56

#16
اقتباس
إذا حاولت ترجمته فسيعطيك خطأ .. ويطلب تعريف الدالةpast

السؤال هو .. عرّف الدالة past بحيث يطبع سطر الإخراج قيمة المتحولabc

لا أدري إن كنتُ قد فهمتُ السؤال جيدا !!

.. هل هذا ما تريده ؟ :

#include<iostream>
#define past(a,b,c) abc
main() {
    int abc = 0;
    int a,b,c;
    std::cout<<past(a,b,c)<<std::endl;
    return 0;
}
#17

ما أضفته صحيح ...

ولكن الفكرة التي أريد إيصالها هي تابع لصق الحروف ...

ربما الكود التالي سيوضح ما أريده أكثر ...

 #include<iostream>
using namespace std;
int main()
{
	int abc=0;
	int cba=0;
	int a,b,c;
	past(a,b,c)=5;
	past(c,b,a)=4;
	cout<<abc<<endl;//Display 5
	cout<<cba<<endl;//Display 4
	return 0;
}

وحتى يكون الحل وحيد :

حاول حل المسألة بالنسبة لهذا الكود :

#include<iostream>
using namespace std;
int main()
{
    	int abc=0;
    	int cba=0;
    	past(a,b,c)=5;
    	past(c,b,a)=4;
    	cout<<abc<<endl;//Display 5
    	cout<<cba<<endl;//Display 4
    	return 0;
}

تم تعديل هذه المشاركة بواسطة مصطفى 36a2 في 1 يوليو 2012 في 17:18

#18

حسنا أنا مضطر للذهاب الآن ...

إذا لم تعرف الحل فقد تركته لك في المرفقات ...

حتى لا يبقى شيء في ذمتيhappy.gif

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

define.txt

#19

ماشاء الله تبارك الرحمن عليكم

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

وإن شاء الله اصير محترفه مثلكم :) :sad: :)

تم تعديل هذه المشاركة بواسطة صعب تكراري في 1 يوليو 2012 في 23:11

#20

يلزم إستخدام التوجيه ## لضم جزئين :

#include<stdio.h>
#define FOO(A, B)   A ## B

int main(void) {

    printf("%d\n", FOO(1, 2));  // 12

    return(0);
}

الجواب :

#include<iostream>
#define past(A,B,C)     A ## B ## C // A ## B ## C == ABC
using namespace std;
int main()
{
        int abc=0;
        int cba=0;
        past(a,b,c)=5;
        past(c,b,a)=4;
        cout<<abc<<endl;//Display 5
        cout<<cba<<endl;//Display 4
        return 0;
}

----------

لدي سؤال صغير, لدينا هذا البرنامج البسيط :

#include<stdio.h>

int main(void) {

    char array[1]   = {'A'};

    printf("%c\n", array[0]);

    return(0);
}

البرنامج سيطبع A. إجعل البرنامج يطبع A بطريقة أخرى "وبدون أن تزيد عليه أو تنقص منه حرف واحد!".

#21

مرحبا أخي Mr.B, هل هذا ما تريده ؟ :

#include<stdio.h>

int main(void) {

	 char array[1]   = {'A'};

	 printf("%c\n", 0[array]);

	 return(0);
}
2
#22

بالمناسبة, تعريف المصفوفة array يجب أن يكون هكذا :

char array[2]   = {'A'};
OR
char array[]   = {'A','\0'};
#23

أحسنت, هذا ماقصدته. الجزء :

array[0]

سيحول عند التصريف إلى :

*(array+0)

ولو عكست سينتج :

*(0+array) -> 0[array]

فكلاهما فعلياً نفس الشيء :

*(array+0) == *(0+array)

@: ليست واجباً أن تنتهي المصفوفة بـnull سوى السلسة النصية. قد تكون مثلاً مصفوفة لبيانات ملف.

#24

جميل ... حسنا إليكم هذا السؤال ...

كيف يمكن أن ننشئ مؤشراً يؤشر على عنوان معين ...(وليس على متحول )

طبعا هذا العنوان سيكون في الHeap وليس في الStack

أعتذر على تغيبي عن السؤال الأخير ... رغم معرفتي به والحمد لله..

تم تعديل هذه المشاركة بواسطة مصطفى 36a2 في 2 يوليو 2012 في 22:46

1
#25

ما رأيك لو قمنا بالإعلان عن global variable اسمه G مثلا, (سيتم تخزين عنوان G في الــ bss section) ثم ننشئ (باستخدام new) مؤشر يشير إلى G ؟

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