• الإعلانات

    • فيصل الحربي

      تسجيل عضوية جديدة في المنتدى   01/31/2016

      السلام عليكم ورحمة الله وبركاته  عزيزي العضو الجديد :  حاليا رسالة الإيميل لتأكيد صحة إيميلكم تذهب للبريد العشوائي ( جاري حل المشكلة )  فإذا لم تجد رسالة التحقق من إيميلكم في صندوق الوارد لديكم إتجه للبريد العشوائي ( JUNK)  وقم بتفعيل إشتراككم من هناك   

Khaled Alshaya

المشرفون
  • عدد المشاركات

    2,052
  • تاريخ الانضمام

  • تاريخ اخر زياره

كل شيء نشر بواسطة Khaled Alshaya

  1. NFA Convertor

    شكراً أخي مهدي :) البرنامج فكرته رائعة جداً, و لا أدري إن كنت تريد تطويره :P عموماً, بعض الملاحظات: الـ initial state يمكن أن تكون final state أيضاً. لايوجد في البرنامج طريقة لتحديد lambda أو بمعنى أصح الـ empty string. و هذه تقريباً نفس النقطة الأولى, لأنه كون الـ initial state عبارة عن final state فهذا يعني أنك تقبل lambda ضمن اللغة. تحسينات: يمكن أن تقوم برسم الـ DFA بعد التحويل, و ستكون ميزة جبارة. يمكن أن تسمح للمستخدم بإدخال الـ Input alphabet بطريقة افضل, و من الأفضل أن تسمح له بإدخال groups كما في الـ regular expressions. مثلاً a-z و A-Z و 7-5 على سبيل المثال بدلاً من تحديد كل مدخل على حدة. يمكنك إضافة خيارات لتعديل ما تم إدخاله. هذا ما جاء في بالي حتى الآن, و لكن لم أطلع على الكود. بالنسبة لخوارزمية التحويل, فيمكن أن أضع موضوعاً عنها بعد فترة إن أحببت لمن يريد فهم عمل البرنامج و تطويره من الأخوة في قسم Java. البرنامج بعد أن يتم تطويره يمكن أن يأخذ مسارين, الأول أن يستخدم في الجامعات في مواد الـ Automata و هو برنامج رائع بلا مجاملة خصوصاً عملية الرسم. الأمر الآخر, هو استخدامه فعلياً لإنتاج الـ Regular Expressions حسب أي flavor أو عدة flavors تريد دعمها. و لكن أعتقد أنك تحتاج لبناء Optimizer في هذه الحالة :) تقبل تحياتي, و شكراً على مشاركة برنامجك.
  2. NFA Convertor

    السلام عليكم ... برنامج رائع أخي مهدي, هل من الممكن أن يتبرع أحد من الأخوة بترجمته لأني أريد تجربته بعد إذنكم :)
  3. "هناك حد أدنى للمعرفة قبل البدء بالسؤال عن أي شيء." -- مقتبسة بتصرف من busbar
  4. لا أدري إن كنت أكرر نفسي في هذا الموضوع بالذات! أستخدم OO في جهاز البيت, و يبدو أني اعتدت عليه. رغم وجود نسخة أصلية لدي من Office 2007 و لكني لم أقم بتركيبها حتى الآن. و لكن بكل صراحة الـ Usability في Office متقدمة بمراحل عن OO. لا أدري كأن Word يفهم ما أريد كتابته, و يقوم بعملية التنسيق بشكل سلس عكس OO الذي يعقدني في بعض الأحيان! أنا أعتقد أني مستخدم Intermediate لأني أقوم باستخدام بعض الخواص المتقدمة, و لكن لم أقم باستخدام الـ VBA أبداً. عموماً, هناك نصيحة قيلت لي منذ ست سنين تقريباً في دورة على Word و Excel و خصوصاً عملية استخدام الـ Word Processors و هي أن تقوم بكتابة النص كاملاً دون تنسيق.. ثم قم بعملية التنسيق و ستجد الأمر أكثر سهولة بكثير مما لو قمت بالتنسيق خلال الكتابة بغض النظر عن الـ WP نفسه. تحياتي...
  5. نصيحتكم,,هل اكمل c++

    هذا رأيي أنا أيضاً بالموضوع و أتفق مع أخي apex تماماً. الأمر يعود إليك أخت إسراء في النهاية.
  6. بدأت أحب الظلام ....

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

    لا أريد تعلم الصيد أريد السمكة :lol:
  8. السلام عليكم ... أخيراً وجدت بعض الوقت :) قمت بتنفيذ طلبك بحذافيره, و هو معرفة عدد الـ Computational Units الموجودة على الجهاز, و من ثم قمت بإنشاء threads بنفس العدد, مو لكن تركت الـ main thread غير مشغولة لكي يبقى البرنامج منفصلاً عن الكود في حالة استخدامه كقطعة في نظام أكبر. البعض و أنا منهم يفضل عدم التعامل مع الـ Threads يدوياً, و من الأفضل أن تستخدم High Level Multiprocessing و الـ Threads تعتبر الـ Low Level Side في هذا العالم, و لكن للفائدة لا أكثر. استخدمت boost, و المثال المرفق يعمل من سطر الأوامر, يمكنك بالطبع تعديله ليناسب احتياجاتك. بالنسبة للتعليقات, هي كثيرة و لكن هذه هي طريقتي في كتابة الكود :) #include <cstddef> #include <iostream> #include <algorithm> #include <exception> #include <boost/thread.hpp> #include <boost/lexical_cast.hpp> /* Welcome to the real world of "Multiproblems"! The standard streams are not thread-safe! */ std::vector<int> numbers; boost::mutex printing_guard; boost::thread_group threads; /* This is a very bad way of testing for primes, I think you have to "rethink" the way as a whole, because this is a very hard problem actually(prime test). Look at Sieve of Eratosthenes if you have a reasonable range to test */ bool is_prime(int number) { // primes start at 2 if(number <= 1) return false; for(int possible_factor = 2; possible_factor < number; ++possible_factor) { if(number % possible_factor == 0) // number is not prime number return false; } return true; } void print_if_prime(int number) { if(is_prime(number)) { printing_guard.lock(); std::cout << number << std::endl; printing_guard.unlock(); } } void is_prime_range(const std::vector<int>& numbers, std::size_t beg, std::size_t end) { std::for_each(numbers.begin()+beg, numbers.begin()+end, print_if_prime); } int main(int argc, char* argv[]) { /* get the numbers from the command line. For example: $ primes 1 2 3 4 5 6 7 8 9 10 output: 2 3 5 7 */ numbers.resize(argc-1); try { std::transform(argv+1, argv+argc, numbers.begin(), boost::lexical_cast<int, char*>); } catch(const std::exception&) { std::cout << "Error: You have entered invalid numbers."; } /* After we knew how many computational units we have on a specific machine, we create an equal number of threads, and we divide the work equally between them. If the work can't be divided equally, we assign the remaining data to a thread we call man thread. This case happens, when the "number" of "numbers" has a reminder modulus the number of threads. */ /* Boost is your friend here, don't reinvent the wheel :) boost::thread::hardware_concurrency() returns the number of computational units on the current machine. */ /* There is a main thread also! keep it responsive at least, we are working on three other CPUs on my machine. */ std::size_t number_of_threads = boost::thread::hardware_concurrency() - 1; std::size_t numbers_count = numbers.size(); std::size_t block_size = numbers_count / number_of_threads; std::size_t block = 0, cpu = 0; if(block_size) // if there is work to divide { // keep one thread for later usage, because we want // to assign the rest of the data to the last thread, // in the case that work doesn't divide equally between threads for( ; cpu < number_of_threads-1; ++cpu, ++block) { threads.add_thread( new boost::thread(is_prime_range, numbers, block*block_size, (block+1)*block_size) ); } } threads.add_thread( new boost::thread(is_prime_range, numbers, block*block_size, numbers.size()) ); threads.join_all(); } طريقة استخدامه بسيطة, استدع البرنامج من سطر الأوامر مع الأعداد التي تريد التحقق منها(للتجربة), و سيطبع الأعداد الأولية: $ primes 1 2 3 4 5 6 7 8 9 10 2 3 5 7 ---------------------------- Note That primes don't have to be ordered, because threads are working in parallel. This is just a hypothetical output. بالطبع يمكنك وضع الـ primes في vector و من ثم نقوم بترتيبهم لكي نطبعهم بشكل مرتب في النهاية: #include <cstddef> #include <iostream> #include <algorithm> #include <iterator> #include <exception> #include <boost/thread.hpp> #include <boost/lexical_cast.hpp> /* Welcome to the real world of "Multiproblems"! The standard streams are not thread-safe! */ std::vector<int> numbers; std::vector<int> primes; boost::mutex vector_guard; boost::thread_group threads; /* This is a very bad way of testing for primes, I think you have to "rethink" the way as a whole, because this is a very hard problem actually(prime test). Look at Sieve of Eratosthenes if you have a reasonable range to test */ bool is_prime(int number) { // primes start at 2 if(number <= 1) return false; for(int possible_factor = 2; possible_factor < number; ++possible_factor) { if(number % possible_factor == 0) // number is not prime number return false; } return true; } void keep_if_prime(int number) { if(is_prime(number)) { vector_guard.lock(); primes.push_back(number); vector_guard.unlock(); } } void is_prime_range(const std::vector<int>& numbers, std::size_t beg, std::size_t end) { std::for_each(numbers.begin()+beg, numbers.begin()+end, keep_if_prime); } int main(int argc, char* argv[]) { /* get the numbers from the command line. For example: $ primes 1 2 3 4 5 6 7 8 9 10 output: 2 3 5 7 */ numbers.resize(argc-1); try { std::transform(argv+1, argv+argc, numbers.begin(), boost::lexical_cast<int, char*>); } catch(const std::exception&) { std::cout << "Error: You have entered invalid numbers."; } /* After we knew how many computational units we have on a specific machine, we create an equal number of threads, and we divide the work equally between them. If the work can't be divided equally, we assign the remaining data to a thread we call man thread. This case happens, when the "number" of "numbers" has a reminder modulus the number of threads. */ /* Boost is your friend here, don't reinvent the wheel :) boost::thread::hardware_concurrency() returns the number of computational units on the current machine. */ /* There is a main thread also! keep it responsive at least, we are working on three other CPUs on my machine. */ std::size_t number_of_threads = boost::thread::hardware_concurrency() - 1; std::size_t numbers_count = numbers.size(); std::size_t block_size = numbers_count / number_of_threads; std::size_t block = 0, cpu = 0; if(block_size) // if there is work to divide { // keep one thread for later usage, because we want // to assign the rest of the data to the last thread, // in the case that work doesn't divide equally between threads for( ; cpu < number_of_threads-1; ++cpu, ++block) { threads.add_thread( new boost::thread(is_prime_range, numbers, block*block_size, (block+1)*block_size) ); } } threads.add_thread( new boost::thread(is_prime_range, numbers, block*block_size, numbers.size()) ); threads.join_all(); std::sort(primes.begin(), primes.end()); std::copy( primes.begin(), primes.end(), std::ostream_iterator<int>(std::cout, "\n")); } هل هذا هو طلبك؟ لا تنسى أنك تحتاج إلى أكثر من core لكي يعمل البرنامج(أعني هنا multiple threads) !
  9. الطرق التي أعرفها تخبرك كم عدد الـ Computational Units الموجودة في الجهاز الذي يعمل عليه البرنامج. بمعنى آخر, كم عدد الـ Cores و الـ Hyperthreading Units. عموماً, انظر لهذا الموضوع لتعرف الطريقة لأي نظام تريده: http://stackoverflow.com/questions/150355/programmatically-find-the-number-of-cores-on-a-machine بالنسبة لي, أرى أن العمل قد تم إنجازه من قبل باستخدام boost: std::size_t number_of_computational_units = boost::thread::hardware_concurrency(); الآن هل تعتقد أنك لو أنشأت 4 threads على جهاز يحمل 4 cores سوف يتم تنفيذهم كـ Parallel Threads؟ ليس هناك شرط على الإطلاق, هذا يرجع لنظام التشغيل و كمية البرامج التي تعمل على الجهاز, و في الغالب, سوف يكون تشغيل البرنامج Sequentially أسرع, لأن هناك عمليات IO تحصل على الدوام و كل الـ Threads تستخدمها في نفس الوقت.
  10. الـ std output عبارة عن resource مشترك, هو ليس thread safe في كل من C و ++C, لذلك يجب أن تقوم بعمل Synchronization لكي يصبح الكود صحيح, معنى أنه عمل على Implementation معين على نظام تشغيل معين حيث الـ std io معرفة على أنها thread safe, لا يعني أن الكود صحيح.
  11. معك حق, أنا لا أعلم عن OpenMP, و لكن هناك Syncronization Problem في الكود الذي وضعته, لأن جميع الـ Threads التي سوف تظهر تتشارك في شيء, ماهو هذا الشي؟! أنا أسميها Multiproblems بدلاً من Mutliprocessing 1+ لأول شخص يخبرنا :) تحياتي...
  12. ماهو الخطأ أخي الكريم, أعتقد أن الكود يعمل بشكل سليم, لأن الأعداد كلها أولية! كل ما في الأمر هو أنك تحتاج لقراءة فصل في أحد كتب أنظمة التشغيل عن الـ Multiprocessing, لتدرك أن ما حصل هو نتيجة طبيعية لأن الـ Threads تعمل بالتوازي, و هذا يعني أن كل thread ستطبع بالتوازي مع الآخرين. الحقيقة أن هناك خطأ ينتج عنه Race Condition في الكود الذي وضعه الأخوة, و لمن يعرفه له 1+ على طول :cool: و لكنه ليس الخطأ المفترض الذي تتكلم عنه أخي العزيز,
  13. بسم الله الرحمن الرحيم, لغات البرمجة تعتبر من أكثر الفروع التي تم بحثها, في العقول نظرياً و في أرض الواقع عملياً. إن فرع لغات البرمجة, يعتبر إن لم يكن أكثر الفرو ع الحاسوبية أصالة في البحث العلمي, مثل أنظمة التشغيل و قواعد البيانات...إلخ. كثير من المبرمجين, لا يدركون أن لغة البرمجة, هي عبارة عن حاسوب افتراضي, و كلمة Abstraction, لم تأتي من فراغ, و إنما من مصطلح Abstract Machine أو Abstract Computer و الأول أصح, لأن لغات البرمجة تمثل حاسوباً مع أجزاء من العالم الخارجي كالذاكرة و العديد من المفاهيم الأخرى التي لا يمكن حصرها هنا, و ليست مجرد "حواسيب" فقط. و مبحث علماء البرمجة, ينقسم إلى قسمين رئيسيين. الأول, هو الـ Computations و الثاني هو الـ Types. فالـ Computation يمثل كيفية تمثيلنا للحسابات, من الدوال, و عملية ندائها, و المباحث المتقدمة في هذا المجال تذهب للـ Functional Languages و المفاهيم التي تقدمها. بينما علم "الأنواع" فهو يهتم بتمثيل الأنواع التي نقوم بحسابها, و هذا لب موضوعنا. فنحن نستطيع أن نمثل الأنواع التي تتوفر في حاسوبنا على أنها اوعية بدائية جداً, كـ Registers كما في الحواسيب الحقيقية, و في هذه الحالة سنفرض أسلوباً معيناً على الـ Computational Model, و هو سيفرض بالمقابل أسلوباً معيناً على الأنواع و على كيفية مزجها, و على مباحث أخرى كثيرة. و نصل في أخر الطيف, إلى الـ Type Models المتقدمة جداً, كـ OOP و Generic Programming و Abstract Data Types و الأخير في الحقيقة الأساس الذي تستند عليه البرمجة الكائنية و البرمجة الـ Generic. إن أي لغة برمجة, يجب أن تحدد الطريقة التي يتم التعامل فيها بين الأنواع التي تحتويها. بمعنى آخر إن مصمم أي لغة برمجة, يجب أن يحدد العلاقات بين أجزاء الـ Type Model الذي سيضيفه إلى لغته. أحد أبرز القرارات التي يجب أن يتخذها هي كالتالي: أولاً: هل اللغة التي سوف أصنعها Type Safe؟ معنى أن تكون اللغة Type Safe, هو ضمان عدم حصول أي عملية على نوع غير النوع الذي صممت من أجله العملية, مما يؤدي إلى تطبيق عملية خاطئة على النوع. دعك من هذا التعريف المخيف, و انظر معي مالذي سيحصل في المثال التالي. عندما ظهرت ما يسمى K&R C أي لغة C الشهيرة في مهدها, كانت اللغة تسمح بانتهاك الـ Type Safety بشكل مباشر, و دون أدنى عناء من المبرمج, فمثلاً كان من الممكن أن نقوم بالتالي, بالمناسبة هذا الـ Syntax قد يبدو غريباً حتى على مبرمجي C الحاليين لأن هذا الـ Syntax مات منذ عشرات السنين. add(first, second) int first, int second; { int result = first+second; return result; } إن لم تفهم وظيفة الدالة فرجاءً لا تكمل المقال :) المهم هو أن تفهم, أننا عرفنا دالة تقوم باستقبال متغيرين من نوع int و تعيد int رغم أن النوع المعاد غير مكتوب إلى أنه في C القديمة Implicit int. ثم قمنا بجمع العددين ووضعناهما في متغير من نوع int. و من ثم قمنا بإعادة الناتج على شكل int, تصور أننا قمنا باستدعاء الدالة بالطريقة التالية: float first = 5.0, second = 1.0; float result = add(first, second); أنا متأكد أنني ربما أجد رداً يقول, و لكن هذا بكل تأكيد خطا لغوي في C! بالتأكيد C الحديثة ليست C القديمة. و لكن في C القديمة كان سيحصل أمر مثير. الذي سيحصل هو أن المتغيرات من النوع float سوف يتم تمريرها إلى الدالة, مع افتراض أن النوع الممرر هو int و هذا يعني ان الدالة سوف تعمل على تلك المتغيرات و التي ربما تكون من نفس الحجم و تقوم بتطبيق عملية الجمع عليها, و لكن على اعتبار أن الـ Bits التي تمثل تلك المتغيرات عبارة عن int! ثم سنعيد ذلك الناتج و نضعه في متغير من نوع float. رغم أن الناتج الذي وضع في الحقيقة, هو ناتج تطبيق عملية الجمع الصحيح على تلك الـ bits الموجودة في تلك المتغيرات من النوع float و التي تختلف في طريقة تمثيلها في الذاكرة عن الأنواع الصحيحة! هذا مثال مبسط للـ Type Safety. و لكن لا تقلق فأنا أضمن لك بأن أي لغة تستعملها تعتبر Type Safe بشكل كامل كما في Java, أو يمكن "اختراق" تلك الـ Type Safety كما في لغات أكثر تقدماً كما في الـ Unsafe Mode في #C. بالنسبة لأشهر اللغات التي يمكنك اختراق الـ Type Safety فيها هي C و ++C بدرجة أقل, و السبب هو أنها لغات للـ Systems Programming, و جميع ما تقوم به هاتان اللغتان هو تنظيم العملية و ليس منعها كما يعتقد البعض. بالطبع تحتاج إلى اختراق الـ Type Safety في أحيان نادرة في اللغات التي ننتج بها التطبيقات, بينما في أماكن كأنظمة التشغيل و معظم الـ System Programs فالأمر حاجة حقيقية و ليس Bad Style! الفرق بين C و ++C في هذا الموضوع, أن ++C أوجدت حلول للـ Systems Programming مع تقليل عمليات الاختراق دون خسارة الكفائة, و لكن للأسف تبقى تلك الأدوات حكراً على المحترفين في الغالب, و هي أمور الـ Generic Programming و الـ Compile-Time Metaprogramming و الأخيرة أثبتت تفوقها بشكل كبير على أسلوب الـ C في هذا المجال. نكون بهذا انتهينا من هذا الموضوع المعقد, و الذي لا تعتقد أنك لفهمك لهذا المثال قد فهمت الموضوع بشكل عام, لأنه بالفعل أحد أصعب المواضيع و يعتبر الـ tricky part في عملية تصميم اللغات. نأتي إلى الأمور الأكثر إثارة الآن :cool: إذا قام مصمم اللغة بجعل لغته Type Safe بشكل كبير حتى لو أوجد بعض طرق اختراقه في اللغة, يبقى عليه أمور كثيرة يجب أن يحددها. من أكثرها إثارة و صعوبة في نفس الوقت, هو جعل اللغة إما تميل للـ Weak Typing أو للـ Strong Typing! الـ Weak Typing يعني أن اللغة ستحاول إيجاد وسيلة لتطبيق عملية معينة على نوعين مختلفين و ذلك يرجع إلى مصمم اللغة بإيجاد الطريقة المناسبة, و الـ Strong Typing بكل بساطة يمنع العمليات بين الأنواع المختلفة إلا أن صرح المبرمج بذلك صراحة بواسطة أدوات توفرها اللغة! فمثلاً في Python التي تعتبر Strongly Typed: >>> 1 + '10' سوف تصدر خطأ! و لكن إذا أرد المبرمج يمكن أن يقوم بتحويل النص صراحة بالطريقة التالية: >>> 1 + int('10') 11 لن يكون هناك خطأ! بينما لو ذهبت إلى لغة مثل Perl, فسترحب بذلك دون تفكير: print(1 + '10'); 11 مالذي حصل؟! مصمم اللغة قرر بأنه عند تلاقي نص و عدد فإن النص يتم محاولة تحويله لعدد! ماذا لو كان هناك نص لا يمكن تحويله كأن يكون مكوناً من الحروف مثلاً! في هذه الحالة هناك قرار آخر يقرره مصمم اللغة. بالطبع العملية ليست "يا أبيض يا أسود"! فلغة Weakly Typed حتى النخاع تصبح معقدة أشد تعقيد, و حتى أعتى المبرمجين لابد أن يقع في أخطاء لا يمكن تصورها! و لغة Strongly Typed مئة بالمئة هي لغة لا تطاق و تصبح حتى أسهل العمليات فيها تحتاج تصريح من المبرمج. و لكن هناك إجماع أنه كلما كانت اللغة أقرب للـ Strong Typing كلما كان أفضل, و لمجاراة النقص في مرونة اللغة, فإنه يتم استحداث ما يسمى الـ Type Coercion. ببساطة لو أننا قمنا بجمع 1 + 1.0 فإن الطرف الأول من النوع int يتم تحويله إلى النوع double و إكمال العملية, لأننا نضمن أنه لن تكون هناك مفاجآت في هذا النوع من التحويل بين هذين النوعين, و هكذا بعض اللمسات البسيطة الأخرى. بقي فقرة أخرى تتحدث عن الـ Static Typing Vs Dynamic Typing, و لن أكملها في هذا الموضوع و لكن في الموضوع التالي بإذن الله. السبب هو أن هناك خلطاً رهيباً بين هذين المفهومين و اللذان يعتبران من خصائص الـ Implementation أو المترجم, المفسر سمه ما شئت, و بين الـ Weak Typing Vs Strong Typing و اللذان يتعبران من خصائص اللغة نفسها. و سنضرب بعض الأمثلة بإذن الله, عن لغات Static/Strongly Typed و عن لغات أخرى تعتبر Static/Weakly Typed و لغات أخرى Dynamic/Strongly Typed و لغات أخرى Dynamic/Weakly Typed!!!!! أتمنى أن يكون الموضوع ممتعاً, تحياتي...
  14. السلام عليكم .... أخي لا أدري ما هي مشكلتك بالضبط, فأنا قمت بتحميل النسخة الـ RC على Win 7, و لم أواجه مشكلة. و لولا الكسل لكنت قمت بتركيب النسخة الـ Professional الصادرة, و لكن ربما اعتدت قليلاً على VS2008 مع الأداة التي أعطانا إياها أخونا GM :wink: عموماً, البرنامج الذي وضعته لا أعتقد أصلاً أنه يعمل على VC2010, لأنه ليس كود ++C و لكن كود C أكل عليه الدهر و شرب :) #include<stdio.h> int main(){ /* main returns int! */ printf("jdsalfkjsdlj"); return 0; } الآن حاول تجربته, و أعتقد أنك غيرت الـ Extension من cpp إلى c, و لا أدري ما هو الكتاب حقيقة الذي يدرس, و لكنه قديم جداً بلاشك. تحياتي...
  15. لديك متغير و دالة يحملان نفس الاسم في نفس الـ scope, قم بتغيير اسم احداهما, أو ضع الدالة في namespace: # include <iostream> #include <cmath> using namespace std; double power(double,double); int main() { double base; double e; cout << "Enter the number : "; cin >> base; cout << "Enter the power number : "; cin >> e; cout << base << " ^ " << e << " = " << power(base,e) << endl; cin.get(); cin.get(); return 0; } double power(double b,double e) { return std::pow(b,e); }
  16. السلام عليكم ... كما قال الأخ ASDen و الأخ حسن, لاتوجد references في C, و إنما تم استحداثها في ++C, لأجل الـ Operators Overloading. أخ 0xAli, هذه هي الطريقة الصحيحة لطباعة المؤشرات: #include <stdio.h> int main(){ int x = 10; int *x_ref = &x; // There is no need for casting! // %p is the correct way to print the address of x printf("%i's address is %p",x,x_ref); return 0; } تحياتي...
  17. أكثر من معالج لعملية بسيطة كهذه :huh: هل المقصد هو تعلم الـ Multiprocessing أم تريد إنتاج الأعداد الأولية من واحد إلى كذا؟ بالمناسبة, عملية إنتاج الأعداد الأولية ليس من السهل عمل Parallelization لها.
  18. التأكد من صحة رابطة موقع ما

    السلام عليكم ... أخ زكيري, ليس هناك داع لطلب الصفحة كاملة عن طريق GET, يمكنك طلب الـ HEAD فقط. بالنسبة للـ email فلم أسمع بطريقة فعالة حتى الآن :) تحياتي...
  19. مشكلة في تنفيذ برنامج بايثون على الموبايل

    ماهي المشكلة بالضبط؟ الكود الذي يسبب المشكلة, نوع الموبايل, نسخة المفسر المستخدمة, أنواع الصور التي تتعاملين معاها, هل يتم عرض الصور بشكل صحيح قبل أن تقومي بعمل الـ Stenography, تحتاجين لتوضيح الكثير, قبل أن تكون هناك إجابة. و لكن أغلب الظن, أنه لايوجد دعم لذلك النوع في برنامج الموبايل, أو أن الـ Image Format يختلف عن الموجود في الحاسب لديك و تقومين بتخريب الـ headers.
  20. موضوع للنقاش حول clang

    السلام عليكم ... أولاً +1 على الموضوع الجميل. ثانياً, المشروع برأيي سيغير نظرة العديد من المبرمجين حول ++C. ليس لأنه مترجم آخر, و لكن لأنه بني ليسمح للآخرين باستخدامه بطرق شتى, و عملية الترجمة نفسها تصبح إحدى الخدمات لا أكثر. الاعتماد على LLVM يعني أن التطور في الـ Backend سيكون متواصلاً في نفس الوقت الذي تتطور فيه الـ front-end التي لازالت تجريبية في حالة ++C. عموماً, إذا كنت تريد استخدامه لترجمة C, فسمعته لايعلى عليها, بينما لـ ++C, فإنهم حتى الآن يقولون أنهم نجحوا في ترجمة أجزاء كبيرة جداً من Boost وهي بلاشك مقياس لأي مترجم ++C إن صح التعبير. لذلك, أفضل الانتظار قليلاً, حتى يظهر لنا الإصدار النهائي, أعتقد أنه سيصبح مترجمي المفضل :) تحياتي....
  21. template function pointer

    أهلاً أخ محمد, كيف لا يعلم المترجم النوع الفعلى، أليس T هو بحد ذاته نوع؟ صحيح, و لكن لغة ++C قواعدها Context Sensitive بمعنى آخر, تفسير ما تكتبه يعتمد على السياق بجانب الـ Syntax و ليس على الـ Syntax لوحده. فلو نظرنا إلى السطر التالي: factory<int>::OnObjectChanged fun = print_value; فإن المترجم, يمكنه أن يفسر OnObjectChanged بطريقتين, الأولى أنها static member, و هذا هو الـ Default Context و في الحالة الثانية, يمكنه أن يفسرها على أنها نوع داخي. الذي يجعله يفسرها على أنها نوع داخلي, هو أن المترجم يملك جميع المعلومات اللازمة حيث سيقوم بعمل Instantiation للـ Template المسمى factory و بالتالي, استطاع أن يحدد المطلوب. بينما في الحالة الثانية: typename factory<T>::OnObjectChanged _valueChanged; فإن المترجم لا يملك أي معلومات لأنه لم يقم بعمل Instantiation, بالتالي فإنه سيفترض أن المراد هو static member. بالطبع هذه هي قواعد اللغة نفسه, و المترجم يطبقها لا أكثر. و كما قلت لك, الموضوع وجع رأس أصلاً :P ربما في الأيام القادمة نلقي نظرة على Boost.Function و Boost.Signal, تحياتي....
  22. template function pointer

    السلام عليكم أخي محمد, و من قال لك أني أنا الحريف في الـ templates :P سأعطيك ما عندي باختصار, المشكلة هي أن المترجم في السطرين التاليين: void setOnObjectChanged(factory<T>::OnObjectChanged callback) ... factory<T>::OnObjectChanged _valueChanged; لا يمكنه معرفة أن: factory<T>::OnObjectChanged عبارة عن نوع, و ليس قيمة static كـ object مثلاً, و هذا أحد الأسباب التي تجعل قواعد ++C من نوع Context-Sensitive! إذا أردت البحث أكثر عنها يمكنك البحث عن Dependent Type Names. للأسف لا أعرف الكثير عن قواعدها و لا أريد المعرفة لأنها وجع رأس, حاولت أكثر من مرة و لكن لم أستطع الإلمام بها :( انظر كيف يمكن أن تقول للمترجم بأن ما نشيره إليه هو نوع, و ليس قيمة static: #include <iostream> using namespace std; template <class T> struct IObject; // IObject is struct! template <class T> struct factory { typedef void (*OnObjectChanged) (IObject<T>* obj); }; template <class T> struct IObject { IObject() : _valueChanged(0) {} virtual ~IObject() {} virtual T getValue() = 0; virtual void setValue( T value ) = 0; // precede it with typename void setOnObjectChanged(typename factory<T>::OnObjectChanged callback) { _valueChanged = callback; } bool IsOnObjectChangedPresent() { return _valueChanged != 0; } protected: // here is another situation! typename factory<T>::OnObjectChanged _valueChanged; }; struct Number : public IObject<int> { Number() : IObject<int>(), n(0) { } int getValue() { return n; } void setValue( int value ) { n = value; } private: int n; }; void print_value(IObject<int>* o) { std::cout << o->getValue(); } int main() { IObject<int>* o = new Number; o->setOnObjectChanged(print_value); // don't forget the semi-colon ;) o->setValue(101); } إضافة بسيطة للفائدة سأحاول فيها توضيح متى استخدام typename, و ربما طرأ السؤال في ذهنك و هو أن الكود الذي وضعته أنا في البداية يعمل دون الحاجة إلى typename. كيف تعرف أنك تحتاجها؟ ببساطة, عندما تقوم باستخدام نوع معرف داخل فئة ما, فإنه لابد من استخدام typename إذا قمت بتمرير أحد الـ Template Parameters الممررة إلى فئتك أصلاً!!!! مثال بسيط: template <class T> struct factory { typedef T inner_type; }; template <class T> struct user { factory<int>::inner_type value; }; لم نستخدم typename لأننا لم نمرر T إلى factory. بينما: template <class T> struct factory { typedef T inner_type; }; template <class T> struct user { typename factory<T>::inner_type value; }; نحتاج typename في هذه الحالة, لأننا قمنا بتمرير T إلى factory. ربما تتسائل عن السبب؟! و لكن ما أفهمه, هو أنه في الحالة الأولى عندما يرى المترجم: factory<int>::inner_type value; فإنه يستطيع الوصول إلى inner_type لأنه يعلم بالضبط ماهو النوع, بينما في الحالة الثانية لم يتم تحديد النوع, و لا تنخدع بتمرير T, لأن المترجم لا يعلم حتى الآن ماهو النوع الفعلي, فعلى سبيل المثال, يمكن أن يكون هناك Specializations تستخدم الاسم inner_type على أنه نوع, و أخرى تستخدم inner_type على أنها قيمة static من نوع ما. و طبعاً إن لم توضح أنه نوع, فإن اللغة تصميمها الأصلي يفترض أن ما بعد :: عبارة عن static member! و لهذا استحدثت typename! =================================================================== الآن بما أنك وضحت لنا طريقة استخدامك, سأطرح طريقة أبسط: template <class T> struct IObject { typedef void (*Callback) (IObject<T>*); IObject() : _valueChanged(0) {} virtual ~IObject() {} virtual T getValue() = 0; virtual void setValue( T value ) = 0; // precede it with typename void setOnObjectChanged(Callback callback) { _valueChanged = callback; } bool IsOnObjectChangedPresent() { return _valueChanged != 0; } protected: // here is another situation! Callback _valueChanged; }; ما رأيك بأن نلقي نظرة على Boost.Signal أيضاً :cool:
  23. template function pointer

    السلام عليكم ... لا أدري إن كان التالي هو ما تريده, و لكن لو وضعت مثالاً توضح فيه كيفية استخدامك من الممكن أن نصل إلى شيء أفضل: template <class T> struct IObject { virtual T getValue() = 0; virtual void setValue( T value ) = 0; }; struct Number : public IObject<int> { Number() : n(0) { } int getValue() { return n; } void setValue( int value ) { n = value; } private: int n; }; template <class T> struct factory { typedef void (*OnObjectChanged) (IObject<T>* obj); }; void print_value(IObject<int>* o) { std::cout << o->getValue(); } int main() { IObject<int>* o = new Number; factory<int>::OnObjectChanged fun = print_value; o->setValue(101); fun(o); } كل ما قمت به هو كتابة factory لإنتاج مؤشرات الدوال حسب الـ T التي تحددها. تحياتي...
  24. مشكلة فى كود اكسى

    السلام عليكم ... أعتقد أن المقصود هو ASCII Table! هناك أخطاء في الكود قمت بتعديها: #include<stdio.h> int main() // int main { char c; int i; printf(" num : "); scanf("%d",&i); c = (char)i; printf("%c\n",c); // %c } عموماً جدول ASCII يمتد من صفر إلى 127, ما فوق ذلك لايتبع له و إنما لجداول أخرى أكبر و لكنها في 99.9999999% منها تعتمد على جدول ASCII في أول ثمانية و عشرين رمزاً.
  25. لا أعتقد أنه عيب في IO streams, بل على العكس أراه عيباً في تصميم printf. الـ streams قابلة للتطور, بينما printf من غير الممكن تطويرها. السؤال, هو كم مكان وجدت فيه شخص يطبع عنوان مصفوفة حرفية, مقارنة بمن يريدون طباعة النص نفسه؟ لاحظ, أن عملية الـ overloading مفيدة لو نظرت من زاوية أكبر للموضوع. في ++C نوعين للمحارف, و هناك ثلاثة أنواع جديدة ستضاف في Cpp0x للتعامل مع Unicode بجميع الـ Encoding المعروفة utf8 و utf16 و utf32. في حالة الـ streams ستعاملها كأنها نص عادي للطباعة, و بالطبع من الأفضل بكل تأكيد استخدام الـ string classes الملحقة بالمكتبة القياسية! بينما في حالة printf, فإنك ستضيف رموز جديدة في الـ formatting string. بدلاً من s سيصبح لديك مثلاً s8 و s16 و s32.. و هكذا. بالنسبة للـ streams يمكن أن تجعل كائناتك تعمل كأنها متغيرات عادية: person p; cout << p; هذا أيضاً غير ممكن في حالة printf. في النهاية أنا مع الرأي القائل بأن printf تعتبر more elegant من الـ streams في حالة عمل formatting معقد. رغم أن الـ streams يمكن تخصيصها بشكل رهيب في حالة كون المطلوب أكثر من عملية formatting كعمل localization و نحوه. لذلك وجدت boost::format التي تأخذ الشكل من printf و القوة من الـ streams :) تحياتي...