• 0
هاني الأتاسي

سلسلة - شغل مخك (20)

سؤال

ماهو الكود اللازم من أجل طباعة الرقم الصحيح integer وليكن 32 بت إذا كان المتوفر لدينا فقط هو تابع اخراج حرف واحد .. أي مثلا التابع putc أو PutChar ..

أريد أفضل وأكفئ طريقة مع مراعاة الاشارة السالبة .. :)

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

19 إجابة على هذا السؤال .

  • 0

السلام عليكم ورحمة الله وبركاته

هذه أول مشاركة لي في هذا المنتدى الرائع

وأود أن أشكر كل القائمين على هذا المنتدى الذي يمثل انجازا عربيا شامخا

هذا هو ما توصلت إليه لحل هذه المسألة

أتمنى أن أجد حلا افضل من هذا


PrintInt(int x)
{
int iReminder;
char szTemp[20];
int Index = 0;

if (x < 0)
{
putc('-', stdout);
x *= -1;
}
while (x > 0)
{
iReminder = x%10 + 0x0000000000000030;
szTemp[Index] = iReminder;
x /= 10;
Index++;
}
for(Index;Index > 0; Index--)
putc(szTemp[Index - 1], stdout);

return 0;
}

جملة if لاختبار هل العدد سالب أم موجب

عبارة while لوضع الأعداد في مصفوفة

عبارة for لطباعة المصفوفة بالترتيب الصحيح

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

good solution but I don't need to use an array.. :)

and wellcome Seven to ur site.

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

السلام عليكم أخي هاني ..

سؤالك حلو وذكي ..

وهذا حل صغير وحلو بعد .. بس أرجو انك ماتقول لي انه يستهلك الذاكرة زي السؤال اللي راح .. ;) ..

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

void PrintIntNumber( int num )

{

if ( num :):)

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

أخ أبو فيصل أنا جاوبتك على هذاك السؤال أني كنت مخطئ وراجع الوصلة التالي :

http://www.arabteam2000.com/vb/showthread....01&pagenumber=2

كودك جميل وهو المطلوب بس كودك مابيطبع الرقم 0 ... :)

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

أعتقد أنه يمكنك تعديل الكود السابق ..

الطلب الآخر هو أريد أن أبني التابع itoa أي الذي يحول الرقم إلى سلسلة وهو على الصورة التالية :


char *itoa(int val, char* str);

حيث يقوم التباع بارجاع قيمة str و str عبارة عن مؤشر لمصفوفة حرفية من أجل أن نضع فيها المحارف و val هو الرقم الذي نريد تحويله .. :)

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

معليش أخي هاني .. يظهر اني ما انتبهت لردك ..

كيف ؟ الكود ما يطبع الرقم ؟؟

لاحظ انني استخدمت التابع putchar عشان أطبع الرقم ..

void PrintIntNumber( int num )

{

if ( num :)

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

وين وين!!!:'(

أصبت بإكتئاب عند رؤية الحل البسيط!!!

لقد بدأت في عملية معقدة لحل هذا السؤال.. وضعت دالة لتحديد عدد الخانات.. ثم ثمت بقسمة العدد على عدد الخانات-1 وعملت تقريب لكي أحصل على الخانة اليمنى ثم أطبعها.. وأحذف الخانة اليمنى من العدد وأكرر العملية حتى يصل العدد الى صفر أكون قد طبعته بالترتيب الصحيح!!! (شو هالتعقيد :o )

ممكن يا أخي تشرح حلك خاصة أنك تستدعي الدالة نفسها قبل بلوغ سطر الطباعة!! فهمني دنا غلبااان!

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

أخي هاني .. حاولت اجيب الحل الثاني بدالة Recursive لكن ما رضى يجي معي الحل !!

المهم هذا الحل ,, وعساه يكون المطلوب ..

char * itoa( int val, char *str )
{
int revVal = 0 ; char *temp = str ;
//now I will reverse the number
while( val != 0 )
{
revVal = revVal * 10 + (val % 10) ;
val /= 10 ;
}
// then I will save the number in 'str'
if( revVal < 0 )
{
revVal *= -1 ;
*temp = '-' ;
temp++ ;
}
while( revVal != 0 )
{
*temp = (revVal % 10) + '0' ;
*(++temp) = 0 ;
revVal /= 10 ;
}
return str ;
}

بالنسبة لك يا أخي اسماعيل .. فالحل بالطريقة الأولى يسمى بـ Recursive ..

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

يعني لو قمت بطباعة الرقم قبل استدعاء الدالة لأصبح الرقم معكوسا ..

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

أخ أبوفهد أنا قصدي إذا كان الرقم 0 من البداية فإنه لن ينطبع أبد ..

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

يا ابو فهد

بالنسبة لحلك الثاني لو تشرحه الله لا يهينك

عندما تقوم بالدخول لل while loop الاولى تقوم بعكس الرقم لكن في نفس الوقت تقوم بجمعه وحفظه في revVal

!!

؟؟

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

بالنسبة للسؤال الثاني

هذا افضل ما توصلت اليه ةلكني اتمنى ان اجد افضل منه :)

char* itoascii(int val, char* str)

{

static int i = 0; // static var

if (val<0) {val*= -1; str[i]='-'; i++;} // to handle '-' sign

if (val > 0)

itoascii(val/10,str); // recursive call

str[i] =val%10+'0'; // put char in string

str[i+1]='

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

شكرا للجميع على المحاولات ..

بالنسبة لحل أخي أبو فيصل بصراحة جدا طويل وفي حلقات غير لازمة متل قلب الرقم .. أرجو أن تفكر أكثر بالحل التعاودي ..

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

في جميع الحلول السابقة يوجد أمر جدا مهم نسيتوه .. :)

أرجو التفكير بحل تعاودي من غير استخدام متحول static ..

بالنسبة لسؤالك أخي Seven أنه ماهو الأفضل :


val *= -1

ام الافضل

val = ~val +1

أعتقد أن الأولى أفضل لأن السي يقوم بشكل آلي بعملية optimization لها من أجل تنفيذها في المعالج .. حيث تحتوي معظم المعالجات على تعليمة قلب الاشارة .. الثانية غير مفهومة في العادة لمترجم السي أنا الأولى فهي مفهومة أنها لقلب الاشارة ..

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

أخي semelak ..

الكود يقوم بعكس الرقم ويضع الرقم المعكوس في revVal ..

بعد ذلك يقوم بتخزين المتغير revVal في مصفوفة حرفية ..

وطريقة عكس الرقم .. بواسطة عملية loop في كل مرة اخذ خانة الآحاد ثم أقسمه على 10 ثم أقوم بضرب العدد revVal بـ 10 ثم أضيف الرقم اللي أخذته من العملية السابقة .. وهكذا ..

ثم الخطوة الثانية أسوي نفس العملية لكن بدل التخزين في متغير عددي أخزنه في مصفوفة حرفية ...

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

أخي هاني لو تلاحظ ان اسمي أبوفهد مو أبو فيصل :)

وأرجو ان يكون هالكود جيد

char * IntToAscii( int val, char *str )
{
char tmp[2] = "" ; // to join the tmp with str
if( val < 0 ) { *str = '-' ; *(str+1) = 0 ; val *= -1 ; }
if( !val ) {
if (*str != '-' ) *str = 0 ;
return str ;
}
IntToAscii( val / 10, str ) ;
*tmp = (val % 10) + '0' ;
return strcat( str, tmp ) ;
}

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

حل جيد لكني لا أريد استخدام strcat أو أي شئ مشابهها لأنها بطيئة ... :)

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

طيب هل لك أخي هاني أن تعطينا حل لهذه المسألة ؟

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

اشكركم جميعا على المشاركة .. سوف أضع الحل هنا الآن ..:

اولا لماذا رأيت الجميع يتبعون حل يحتوي على تابع واحد ؟؟ كان بالامكان تسريع الحلول باستخدام تابعين ..

ثانيا معظم الحلول لم تراعي حالة أن يكون الرقم الأولي 0 .. ففي معظم الحلول التابع لن يحول الرقم 0 إلى السلسلة وكأن شيئا لم يكن .

ثالثا معظم الحلول لم تنهي السلسة بالمحرف null .. وهو شئ أساسي لانهاء السلسلة .

الحل هو التالي وسوف أشرحه سريعا بعد ذلك :

char *_itoa(int n, char *str)

{

int nVal;

char *p;

if (n == 0)

return str;

nVal = n % 10;

p = _itoa(n / 10, str);

*p = nVal + '0';

return p + 1;

}

char *itoa(int n, char *str)

{

char *p;

if (n == 0) {

*str = '0';

p = str + 1;

}

else if (n ;) ..

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

جميل ..

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

يعني في حلك الدالة الأولى ما راح ترجع مصفوفة الأحرف ..

لكنك حافظت عليها في الدالة الثانية ..

أما في حلي لكي أتفادى اشكالية ان مصفوفة الأحرف راح يضيع المؤشر تبعها تستخدمت الدالة strcat وقلت انها بطيئة :) .

أما في مسألة الصفر فما فيه حل الا دالة أخرى تقوم باستدعاء الدالة الثانية .

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

ماشاء الله عليك اخي/Seven

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
زوار
This topic is now closed to further replies.

  • يستعرض القسم حالياً   0 members

    لا يوجد أعضاء مسجلين يشاهدون هذه الصفحة .