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

خطأ في الكود

مغلق
بدأه maas في 14 يونيو 2005 · 18 رد · 1,473 مشاهدة · في الأسئلة المجابة
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم

يا شباب انه سويت برنامج انه المستخدم يدخل أي رقم

و هو يقوم بتحويله إلى binary باستخدام الrecursion مطلوب حله بالrecursion و لكن هناك خطأ و أرجو مساعدتكم

#include <iostream.h>
int bin(int);
int main()
{
	int n;
	cout<<"Enter any number ";
	cin>>n;
	cout<<bin(n);
	return 0;
}
int bin(int x)
{
	int s[100],a[100];
    a=x%2;
	return 1;
	s=bin(a%2);
	return s;
}

تم تعديل هذه المشاركة بواسطة maas في 14 يونيو 2005 في 15:34

#2

أنا ما فاهم الكود ما هو عمله في دالة bin

int s[100],a[100];
	a=x%2;
	return 1;
	s=bin(a%2);
	return s;

ليش ترجع واحد بدون شرط هل هناك شرط ؟؟؟؟

وليش تستخدم array int ؟؟؟؟

كود غير مفهوهم

#3

يعني لتخزين الأرقام 1 و 0 و عقب يطبعهم

#4

كلمة return تخرجك من الـ function ..

جرب بدل من ذلك ان تكتب 1 عالشاشة ...

#5

حاولت أجرب الطرق و لكن ما صار البرنامج

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

تم تعديل هذه المشاركة بواسطة maas في 14 يونيو 2005 في 18:11

#6

هذي اخر حل توصلت له و لكن خطأ

#include <iostream.h>
int bin(int);
int main()
{
int n;
cout<<"Enter any positive number ";
cin>>n;
cout<<bin(n);
return 0;
}
int bin(int x)
{
int s,r;
if(x<=1)
return x;
s=x%2;
r=bin(s%2);
bin( x >> 1);
return r;
}
#7

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

السلام عليكم

كل ما فهمتة انك تريد عمل كود للتحويل من decimal الى binary

وأدى الكود اهوة سهل وبسيط

#include<iostream.h>
#include<conio.h>
void main(){
     clrscr();
     cout<<"Enter a decimal:";
int num;cin>>num;
     cout<<"\nBinary:";
int *prt;
int pos=0;
     do{
	ptr[pos]=num%2;
	num=num/2;
	pos++;
       }while(num>0);
     for(int count=pos-1;count>=0;count--)
	cout<<ptr[count];
     getch();
}

Muhammad Allam

Computer Science

@Resource(MappedURL="My Blog" )

#8

مشكور أخوي على الكود

و لكن باستخدام الrecursion

#9

السلام عليكم

برنامج يحول العدد من decimal إلى binary بإستخدم recursion هكذا من المفروض ان يكون عنوان الموضع اما ان تسمية الموضوع خطاء فى كود فهناك مواضيع كثيره هى عباره عن اخطاء فى كود..

على كل حال البرنامج يكتب هكذا:

#include "stdafx.h"
#include <iostream.h>
int bin(int);
int s=0;
int r=0;
int main(int argc, char* argv[])
{
	int n;
	cout<<"Enter any positive number ";
	cin>>n;
	cout<<bin(n);
	return 0;
}

int bin(int x)
{
	if (x==0)
  return s;
	bin( x >> 1);
	r=x & 1;
	s=s * 10 + r;
	return s;
}

البرنامج معقد قليلاً ولكن الفكره الاساسيه هى قسمة العدد على 2 وذلك فى السطر

bin( x >> 1);

وكما نعلم نقل العدد خطوه إلى اليمن تقسمه على 2 بدلاً من إستخدام

bin( x /2);

الخطوه التاليه هى التاكد إذا كان الرقم زوجى ام فردى وذلك بإستخدم خدعه بسيطه وهى التحقق من اخر رقم

r=x & 1;

لمن لايعرف هذه المعلومه جميع الاعداد الفرديه تنتهى بواحد , واخيراُ نقوم بضرب العدد فى 10 حتى ياخذ كل رقم خانته الاصليه ثم نضيف العدد الموجود فى r وهو إما 1 او 0..

ارجو تكون المسئله واضحه...

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

لا إله إلا الله محمد رسول الله

busbar : يجب ان تدرك انه هناك حد ادنى للمعرفة المطلوبة قبل البدء في عمل أي شئ.

#10

السلام عليكم

اليك ايضاً نفس البرنامج بطريقه مبسطه جداً

#include "stdafx.h"
#include <iostream.h>
int bin(int);
int s=0;
int r=0;
int main(int argc, char* argv[])
{
	int n;
	cout<<"Enter any positive number ";
	cin>>n;
	cout<<bin(n);
	return 0;
}

int bin(int x)
{
	if (x==0)
  return s;
	bin( x / 2);
	r=x % 2;
	s=s * 10 + r;
	return s;
}

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

ولكن وضعت هذه الطريقه ايضاً حتى يسهل الفهم..

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

لا إله إلا الله محمد رسول الله

busbar : يجب ان تدرك انه هناك حد ادنى للمعرفة المطلوبة قبل البدء في عمل أي شئ.

#11

مشكور أخوي على الكود و على الشرح

بس يا ريت لو في طريقة أسهل من هذي الطريقة و لكن باستخدام الrecursion

لأني شوي ما فهمت

#12

العفو اخى بس انا وضعت طريقتين والطريقه الثانيه ليست صعبه, ياريت تقولى إلى إنتا مش فاهمه وإن شاء الله اشرح لك

لا إله إلا الله محمد رسول الله

busbar : يجب ان تدرك انه هناك حد ادنى للمعرفة المطلوبة قبل البدء في عمل أي شئ.

#13

اعتقد عدم فهمك للكود ليس لانه معقد ولكن لانك لا تعرف مكانيكيه عمل الـstack , لكى تفهم الـRecursion لابد ان تكون على علم تام بما يحدث عند إستدعاء function وماذا يحدث فى الـstack لو كانت هذه هى المشكله إن شاء الله احاول ان اشرحها بطريقه مبسطه غداً, ولكن الموضوع طويل, واعتقد جميع مبرمجى السى لديهم نفس المشكله, مهم جداً معرفه ما يحدث فى الـstack ولو لاحظت انا قمت بوضع المتغيرات s و r خارج الداله bin حتى لا تستهلك المكدس (stack) ولو فى احد الاعضاء يستطيع ان يشرح الـStack فياريت يفيدنا, وإلا ساقوم إن شاء الله بشرحه غداً

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

لا إله إلا الله محمد رسول الله

busbar : يجب ان تدرك انه هناك حد ادنى للمعرفة المطلوبة قبل البدء في عمل أي شئ.

#14
اقتباس
اعتقد عدم فهمك للكود ليس لانه معقد ولكن لانك لا تعرف مكانيكيه عمل الـstack , لكى تفهم الـRecursion لابد ان تكون على علم تام بما يحدث عند إستدعاء function وماذا يحدث فى الـstack لو كانت هذه هى المشكله إن شاء الله احاول ان اشرحها بطريقه مبسطه غداً, ولكن الموضوع طويل, واعتقد جميع مبرمجى السى لديهم نفس المشكله, مهم جداً معرفه ما يحدث فى الـstack ولو لاحظت انا قمت بوضع المتغيرات s و r خارج الداله bin حتى لا تستهلك المكدس (stack) ولو فى احد الاعضاء يستطيع ان يشرح الـStack فياريت يفيدنا, وإلا ساقوم إن شاء الله بشرحه غداً

ممكن توضح العمليات التى تقوم ف الstack

هل انت تقصد عندما يجيى متغير يضعة ف الstack وعند دخول أخر يضعة ولكن عند دخول اى opertator

يخرج كل اللى ف الstack ويعمل العملية عليهم ثم يضع الناتج ف الstack

ولا الstack الذى ينشأ خصيصا للmethod عمل copy للمتغيرات ويبدأ العمل معهم (ودة يأخد وقت أطول)

هل هذا ما تقصدة باأخ أحمد ولا اية ولو كان خطأ ممكن تصحح المعلومة لكى كلنا نستفيد

وشكرا لك

Muhammad Allam

Computer Science

@Resource(MappedURL="My Blog" )

#15

Stack عبارة عن هيكل بيانات .

تستخدمه السي في تخزين البارمترات للدوال و المتغيرات المحلية Local variables .

لاحظ ان Local variables تدمر بعد استدعاء الدالة يعني مش هتبقي موجودة بعد الاستدعاء ; لذا استخدم الاخ احمد غريب بالاعلان و تعريف متغيرات محلية Global .

ممكن وضع الكلمة static داخل الدالة و استخدام متغيرات محلية ; للتبسيط ـ تعويضاً عن المتغيرات المحلية .

int bin(int x)
{

static int s=0;
static int r=0;

 if (x==0)
 return s;
bin( x / 2);
r=x % 2;
s=s * 10 + r;
return s;
}

إذن Stack او مكدس وظيفتة هي عمل Push او ضخ للبارمترات و المتغيرات المحلية عند الاستدعاء , و عند رجوع الدالة يقوم بعمل Pop لهذه المكونات .

BEng , Electronics and communications.

Embedded systems engineer.

Graphics Programmer

عالم الكومبيوتر هو من لديه المعرفة في علوم الكومبيوتر ، الرياضيات ، هندسة الالكترونيات -احمد صالح

#16

وأدى الكود بعد التصحيح لو يوجد بة اى خطأ قولى لكى اعدلة ولكى نستفيد

#include<iostream.h>
#include<conio.h>

class a
{
  private:
  int pos;
  int *ptr;

   public:
   a():pos(0),ptr(new int[0])
   {}

 inline  void bi(int num)
{

 	 ptr[pos]=num%2;
	num=num/2;
	pos++;
    if(num>0)
   {
     bi(num);
   }

  for(int count=pos-1;count>=0;count--)
     {cout<<ptr[count];    }
     cout<<"\n";
}
};



void main(){
     a  A;
     clrscr();
     cout<<"Enter a decimal:";
     int num;
     cin>>num;

     A.bi(num);
     getch();
}

Muhammad Allam

Computer Science

@Resource(MappedURL="My Blog" )

#17

السلام عليكم

احمد صالح كتب:
Stack عبارة عن هيكل بيانات .

تستخدمه السي في تخزين البارمترات للدوال و المتغيرات المحلية Local variables . 

لاحظ ان Local variables تدمر بعد استدعاء الدالة يعني مش هتبقي موجودة بعد الاستدعاء ; لذا استخدم الاخ احمد غريب بالاعلان و تعريف  متغيرات محلية Global .

ممكن وضع الكلمة static داخل الدالة و استخدام متغيرات محلية ; للتبسيط  ـ تعويضاً عن المتغيرات المحلية .

int bin(int x)
{

static int s=0;
static int r=0;

 if (x==0)
 return s;
bin( x / 2);
r=x % 2;
s=s * 10 + r;
return s;
}

إذن Stack او مكدس وظيفتة هي عمل Push او ضخ للبارمترات و المتغيرات المحلية عند الاستدعاء , و عند رجوع الدالة يقوم بعمل Pop لهذه المكونات .

كلام جميل اخى احمد ولكن ولكن هناك جزئيه بسيطه لابد من توضيحها وهى ماذا يحدث عندما تستدعى function من داخل function هل الدوال التى فى داخل الfunction الاول تدمر ؟؟

هذه الجزئيه مهمه جداً لفهم مايحدث عند إستخدام الrecursion..

النقطه الثانيه وهى المتغيرات من نوع static داخل الـfunction , اشكرك جزيل الشكر للتطرق لهذه المسئله, بالنسبه للمتغيرات الـstatic فهى بالظبط مثل الglobal معى فرق بسيط الا وهو ان المتغير من نوع static تستطيع ان تراه فقط داخل الـFunction ولكنه موجود فى الذاكره حتى بعد إنتهاء الـfunction...

اقتباس
ممكن توضح العمليات التى تقوم ف الstack

هل انت تقصد عندما يجيى متغير يضعة ف الstack وعند دخول أخر يضعة ولكن عند دخول اى opertator

يخرج كل اللى ف الstack ويعمل العملية عليهم ثم يضع الناتج ف الstack

ولا الstack الذى ينشأ خصيصا للmethod عمل copy للمتغيرات ويبدأ العمل معهم (ودة يأخد وقت أطول)

هل هذا ما تقصدة باأخ أحمد ولا اية ولو كان خطأ ممكن تصحح المعلومة لكى كلنا نستفيد

وشكرا لك

انت تتحدث عن التحويل بين الinfix ,و الـpostfix مثلاُ وفى هذه الحاله نستخدم stack وهمى, انا هنا اتحدث عن النوع الثانى والذى سميته ب stack للـmethods او بمسماه الحقيقى وهو stack frame ..

طبعاُ كما وعدت ساقوم بشرح الstack وما يحدث عند إستدعاء function معين, وفى الحاله الخاصه عند إستخدام الrecursion , ولكن فى مداخله جديده إن شاء الله..

وبما ان الموضوع طويل فسياخذ منى قرابة الساعه لاكتبه فانتظرونى....

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

ملاحظه :

تعقيباُ على كلام الاخ احمد صالح, فى لغة الاسمبلى لا يوجد ما يسمى بstatic variable إنما هو جزء من لغة السى وعندما يحول البرنامج للغة الاله فإنه يصبح متغير عادى من نوع Global .

تم تعديل هذه المشاركة بواسطة احمد غريب في 15 يونيو 2005 في 20:06

لا إله إلا الله محمد رسول الله

busbar : يجب ان تدرك انه هناك حد ادنى للمعرفة المطلوبة قبل البدء في عمل أي شئ.

#18
اقتباس
تعقيباُ على كلام الاخ احمد صالح, فى لغة الاسمبلى لا يوجد ما يسمى بstatic variable إنما هو جزء من لغة السى وعندما يحول البرنامج للغة الاله فإنه يصبح متغير عادى من نوع Global .

كنت سأوضح هذه النقطة ، لكن خفت من التعقيد بذكر الاسيمبلي :)

BEng , Electronics and communications.

Embedded systems engineer.

Graphics Programmer

عالم الكومبيوتر هو من لديه المعرفة في علوم الكومبيوتر ، الرياضيات ، هندسة الالكترونيات -احمد صالح

#19

السلام عليكم

ساحاول تبسيط الموضوع على قدر المستطاع ولن ادخل فى تفاصيل لها علاقه بالسمبلى حتى لا يحدث تشويش للفكره, وطبعاُ ساضطر لإخفاء جزء كبير من ما يحدث فى المكدس حتى لا ندخل فى تفاصيل كثيره ودقيقه تبعدنا عن الهدف الا وهو فهم مكانيكيه الـrecursion .

بسم الله نبداء

مثال من الحياة العامه

إفترض انك عاكف على قرائة كتاب معين ووصلت للصفحه رقم 100 ثم قاطعك شخص ما وطلب منك عمل شيئ معين يستغرق بعض الوقت, ثم بعد ان انتهيت من هذا العمل عدت لتكمل القرائه كيف ستعرف اين توقفت, وهل ستبداء القرائه من اول الكتاب ام انك ستبحث عن المكان الذى توقفت فيه؟؟؟

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

البرامج ايضاً تفعل ذلك تخيل ان لديك برنامج يكتب Hello World وفى السطر الثانى يكتب This is the end of my program دعنا نكتب البرنامج ونتابع ما سيحدث..

int main(int argc, char* argv[])
{
	cout<<"Hello World ";
	cout<<"This is the end of my program ";
	return 0;
}

كيف يعمل مثل هذا البرنامج ؟؟

البرنامج لديه مؤشر إسمه PC يرمز لكمة Program counter اي عداد الشفره, هذا العداد يبداء باول سطر فى البرنامج وهو كتابة Hello World , ولكن لكتابة هذا السطر لابد ان يستدعى الداله cout لانها هى المسؤله عن الكتابه , فى هذه الحاله سيضطر المؤشر للإنتقال إلى مكان اخر خارج الشفره, ولكن إذا إنتقل إلى مكان خارج الشفره لابد ان يعرف المكان التى توقف عنها التنفيذ لكى يتمكن من المواصله.

هنا ياتى دور المكدس Stack البرنامج لابد ان يحفظ العنوان الذى توقفنا عنده قبل ان ينتقل إلى مكان اخر, ثم بعد عودته يواصل من حيث إنتها التنفيذ, وافضل مكان يمكنه ان يضع العنوان هو المكدس, وعندما يعود يسترجع العنوان من المكدس ويواصل التنفيذ من حيث توقف.. وهكذا..

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

1 int main(int argc, char* argv[])
2 {
3  print
4  return 0;
5 }
6 void print()
7 {
8  cout<<"Hello World ";
9  cout<<"This is the end of my program ";
10   return;
11 }


1 PC = 1
2 PC = 2
3 PC = 3 <= save PC+1 on stack & call print 
Here PC on stack = 4

4 PC = 6
5 PC = 7
6 PC = 8 <= save PC on Stac & call cout
on return from cout we get PC from stack

7 PC = 9 <= save PC on Stac & call cout
on return from cout we get PC from stack

8 PC = 10 <= now we are done get PC from stack 
9 PC = 4 <= we got it from the stack

10 PC = ?? <= return control to system

لاحظ السطر 6 فى عداد الشفره ترى انه وضع عنوان جديد فى المكدس رغم انه لدينا عنوان سابق وضعناه فى المكدس الا وهو عنوان العوده للداله main ولكن ذلك لن يؤثر لان طريقة عمل المكدس هى ان اخر داله وضعت فى المكدس هى اول داله نحصل عليها, وبذلك عندما نعود من cout سيكون عنوان العوده هو العنوان رقم 9 وليس العنوان رقم 4 , نفس الشيئ يحدث عندما نستدعى cout للمره الثانيه, العنوان رقم 10 يوضع فى المكدس وعند العوده نستانف البرنامج من هذا العنوان..

والان إلأ برنامج الـrecursion

int bin(int x)
{
 if (x==0)
return s;
bin( x / 2);
r=x % 2;
s=s * 10 + r;
return s;
}

,وهذا هو الجزء الذى يهمنا فى البرنامج, المكدس لا يحتفظ فقط بعنوان العوده وإنما يحتفظ ايضاً بقيم الدوال حتى يستطيع ان يستانف العمل بنفس القيم وفى نفس المكان الذى توقف عنده..

كما نلاحظ فى البرنامج فهناك إستدعاء للداله bin وطلما لم تصل قيمة x للصفر سنقوم بإٍتدعاء الداله bin , فى كل مره نستدعى فيها هذه الداله, لابد ان يحفظ البرنامج عنوان العوده, وفى هذه الحاله هو الامر :

r=x % 2;

ايضاً لابد ان يحفظ قيمة x وهى تتغير فى كل مره حيث تصبح x/2 حتى تصل للقيمه 0

كيف يصبح شكل المكدس لو مررنا العدد 5 بعد اخر إستدعاء للداله bin ??

عنوان العوده
1
عنوان العوده
2
عنوان العوده 
5

والان عندما نقوم بعملية return بعد لان الخطوه التى تلى x=1 هى x=0 وبذلك لن نستدعى الداله bin وإنما سنقوم بعملية return , والتى فى هذه الحاله ستاخذ عنوان العوده الموجود فى اعلى الـStack والداله x ستاخذ القيمه 1 . وبذلك يصبح السطر التالى

r=x % 2;

على النحو التالى

r=1 % 2;
و r=1
و s=s*10+1 =1

الreturn التاليه تعيدنا إلى عنوان العوده وهو السطر

r=x % 2;

و x تحصل على القيمه 2 ويصبح الكود بهذا الشكل

r=2 % 2;
و r=0
و s=1*10+0 =10

ثم نصل لاخر خطوه وبنفس الطريقه يصبح الكود على النحو التالى

r=5 % 2;
و r=1
و s=10*10+1 =101

طبعاً انا قمت بالتعويض فى المعادله s=s*10+r مباشرتاً والجواب كما هو واضح العدد 5 يحول إلى الbinary بالشكل التالى :

101

ارجو ان يكون الشرح واضح وإذا فى اى اسئله انا حاضر إن شاء الله , طبعاً هناك امور كثيره تحدث فى الـstack ولكنى لم اضعها هنا حتى لا تعقد الامور..

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

لا إله إلا الله محمد رسول الله

busbar : يجب ان تدرك انه هناك حد ادنى للمعرفة المطلوبة قبل البدء في عمل أي شئ.

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

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