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

مساعدة بسيطة في باقي القسمة

بدأه Er za في 2 فبراير 2012 · 25 رد · 5,327 مشاهدة · في الأسئلة المجابة
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

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

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

مثال: برنامج یدخل المستخدم اي رقم ویقوم البرنامج بحساب عدد مراتب الرقم ومجموع ارقامھ

(٨=٢+٣+٢+ متلا اذا ادخل المستخدم1232 فعدد مراتب الرقم ھي اربعة ( 4) ومجموع ارقامھ ( ١

تحلیل: تكمن فكرة ھذا السؤال في المراتب اي لو جمعنا باقي قسمة الرقم على عشرة كل مرة سنحصل في النھایة

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

الرقم مرتبھ مرتبھ

اللي مش فاهمه هو يعني فكرة ايجاد مجموع مراتب الرقم باستغلال باقي القسمة اتمنى التوضيح و شكرا

#2

السلام عليكم

أخي الفكرة كما يلي

باقي قسمة أي عدد صحيح على العشرة هو رقم الآحاد : مثال : باقي قسمة ال 156 على العشرة هو ال 6 ..

وبذلك يمكننا الحصول على الآحاد دوما بعملية باقي القسمة على عشرة

ومن أجل الخصول على المئات نطرح من الرقم الأصلي آحاده ونقسم على عشرة .. مثال 859 نطرح منه 9 فيصبح 850 ثم نقسمه على عشرة فيصبح 85 وعندها نوجد باقي قسمته على عشرة وهو 5 فهذا رقم العشرات

وبالمثل نحصل على المئات ..

وهكذا

وإذا كنا نتعامل مع أعداد صحيحة فقط فيكفي أن نقسم الرقم على عشرة ثم نوجد باقي قسمته على عشرة حتى نحصل على العشرات مثال: 456 نريد الحصول على العشرات نقسمه على عشرة 45 ونلاحظ أنه لايوجد فواصل ثم نوجد

باقي قسمته على عشرة وهو 5 وهو العشرات ...

وإليك مثال برمجي :


#include<iostream.h>
void main(){
int i;
cin>>i;
int first_digit=i%10;
int second_digit=(i/10)%10;
int third_digit=(i/100)%10;
cout<<first_digit+second_digit+third_digit;
}

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

#3

لتكن فكرتك أكثر شمولية .

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

post-15367-027053900%201340345097.gifpost-15367-087183200%201340344597.gif
post-247365-0-10080400-1379403554_thumb.

#4

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

تقصد بمثل تلك الطريقة أخ محمد ابوزايد :

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
int *digitNumbers(int Num);
int main(void){
	int Num,Sum=0;
    scanf("%d",&Num);
    int *PointerNum=digitNumbers(Num);
    for(int i=*PointerNum;i>=1;i--){
    Sum+=*(PointerNum+i);
	}
    printf("\n%d\n",Sum);
return 0;
}

// هذه الدالة تعود بعدد المراتب فى أول مكان فى المؤشر وتعود بقيم المراتب فى باقى الأماكن المحجوزة للمؤشر
int *digitNumbers(int Num){
	int NumberOfDigit=0,intNum=0,DNum;// DNum save Num toget the number of digits "NumberOfDigit" ,intNum to convert double to int
    DNum=Num; // set Num to DNum
	// get the number of digits by using while loop
  while(DNum/10 >= 1){
		DNum=DNum/10;
        NumberOfDigit++;
	 }
	// NumberOfDigit + 1 to complete number of digits
   NumberOfDigit++;
	// allocation memory
 int *PNum=(int *)malloc((NumberOfDigit+1)*sizeof(int));
	// set the number of digits to *(PNum+0)
 *PNum=NumberOfDigit;
	// set the digit in Num to PNum from *(PNum+1) to *(PNum+NumberOfDigit)
	for(int i=0;i<NumberOfDigit;i++){
         intNum=Num/pow(10,i);
		*(PNum+i+1)=intNum%10;
	}
	// return PNum pointer
	return PNum;
}

عذراً لكتابة الكود بلغة C فلا أعلم كيفية التعامل مع المؤشرات فى لغة ++C

sumDigitsOfNumber.c

تم تعديل هذه المشاركة بواسطة ahmedsaoud31 في 5 فبراير 2012 في 02:19

لاتحسبن العلم ينفع وحده مالم يتوج ربه بخلاق

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

#6

حتى الآن لا توجد سوى محاولة واحدة ؟

... يبدوا أن الإخوة غير متحمسين للمؤشرات :huh:

طيب, ها هي محاولتي :

int* digitNumbers(int Nbr)
{
     int NbR = Nbr, Digit, NumberOfDigit = 0, Counter = 0;
     int * pARR, *arr;
     //حساب عدد خانات العدد من أجل حجز مصفوفة ديناميكية بنفس الحجم
     while(NbR/10 >= 1)
     {
         NbR/=10;
         NumberOfDigit++;
     }
     //حجز المصفوفة الديناميكية
     pARR = new int [NumberOfDigit + 1];
     //تقطيع العدد و إسناد كل رقم إلى خانة من المصفوفة
     while(Nbr>0)
     {
         Digit = int(Nbr % 10);
         *(pARR + Counter) = Digit;
         Counter++;
         Nbr /= 10;
     }
     //ألآن أصبح المؤشر arr يشير إلى نفس المكان الذي يشير إليه pARR
     arr = pARR;
     //تحرير المؤشر pARR
     delete pARR;
     //إعادة المؤشر arr الذي يحتوي على نسخة من المر الأصلي
     return arr;   
}

ما هي ملاحظاتكم ؟؟

#7

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

ولا يهمك أخى سأراعى تحرير الذاكرة فى المرات القادمة :)

كود جميل ومختصر أخى الكريم

:happy: بس شكل الكود مكتوب بلغة c++

pARR = new int [NumberOfDigit + 1];

لاتحسبن العلم ينفع وحده مالم يتوج ربه بخلاق

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

#8

شكرا أخى ahmedsaoud31 على محاولتك الجميلة بلغة السي ... .

اقتباس
حتى الآن لا توجد سوى محاولة واحدة ؟

... يبدوا أن الإخوة غير متحمسين للمؤشرات :huh:

طيب, ها هي محاولتي :

رائع أخى khaled_prg على أضافتك الرائعة بلغة سي++

تقبل منى هذا:


  • تم أضافة العناصر الى المصفوفة بترتيب معكوس . وتبدو مشكلة بسيطة يمكن السيطرة عليها.
  • اﻻهم. انا كمبرمج عندما ترجع الدالة مؤشر لمصوفة من نوع int واريد طباعة عناصرها فكيف لى أن اعرف كم عدد عناصرها؟
  • وهناك نقطة صغيورة
    1. عند تمرير القيمة صفر للدالة فأنها ترجع صفر؟
    2. وعندما تمرر لها 1 فانها ترجع 0 ايضاً؟
    3. وعندما تمرر القيمة 12 ترجع صفر و 1 ؟
    4. ارجو ان تنظر الى هذة النقاط بعين المبرمج. افدنا وافادك الله ... .

تقبل مرورى

تحياتى العطرة والله الموفق ... .

post-15367-027053900%201340345097.gifpost-15367-087183200%201340344597.gif
post-247365-0-10080400-1379403554_thumb.

#9
اقتباس
بس شكل الكود مكتوب بلغة c++

نعم هو كذلك :) أردت ان تكون الفكرة مُبرمجة بأكثر من لغة و إن كان هناك تقارب بين اللغتين.

يبدو أن الملكة المُدللة جافا بدأت تُنسيني في المؤشرات .. :lol:

اقتباس
  • تم أضافة العناصر الى المصفوفة بترتيب معكوس . وتبدو مشكلة بسيطة يمكن السيطرة عليها.
  • اﻻهم. انا كمبرمج عندما ترجع الدالة مؤشر لمصوفة من نوع int واريد طباعة عناصرها فكيف لى أن اعرف كم عدد عناصرها؟

يمكن حل هاتين المشكلتين عن طريق استخدام دالة أخرى تأخذ كوسيط المؤشر الناتج عن الدالة السابقة و متغير آخر يحوي طول السلسلة ثم تقوم بإظهار العناصر بشكل معكوس, هكذا :

void Affiche(int *ptr, int length)
{
     for(int i=length-1;i>=0;i--)
         cout<<*(ptr + i)<<" ";
     cout<<endl;
}

اقتباس
عند تمرير القيمة صفر للدالة فأنها ترجع صفر؟

وعندما تمرر لها 1 فانها ترجع 0 ايضاً؟

وعندما تمرر القيمة 12 ترجع صفر و 1 ؟

بصراحة لم أفهم قصدك أخي محمد ! :blush:

قمتُ ببرمجة الدالة بغض النظر عن الحالات الخاصة

إذا مررنا للدالة 0 أو 1 فسيتم حجز جدول من خانة واحدة و لكن كيف عرفت أن هذه الخانة تحتوي على صفر ؟؟ :blink:

هل لأن المعامل new يقوم بتصفير الذاكرة بعد الحجز (كما تفعل ابنة خالته memset في لغة السي :D ) أم ماذا ؟

عموما, يمكننا معاجلة هذه الحالة كما يلي : إذا كان العدد المُستقبل يحتوي على رقم واحد فسيتم إرجاع مؤشر يشير إلى نفس العدد.

تحياتي لك.

تم تعديل هذه المشاركة بواسطة khaled_prg في 6 فبراير 2012 في 13:13

#10

لحظة معى لقد استخدمت دالتك كما يلى:

#include <iostream>
using namespace std;
int* digitNumbers(int Nbr);

int main()
{
    int numsCounts;
    int *plist;
    // فى حالة قيمة مكونة من رقمين
    numsCounts = 2;
    plist = digitNumbers(12);
    cout << "12 is: ";
    for(int i=0; i<2; i++)
        cout << *(plist+i) << " ";

    // فى حالة قيمة مكونة من رقمين
    numsCounts = 1;
    plist = digitNumbers(1);
    cout << endl << "1 is: ";
    for(int i=0; i<1; i++)
        cout << *(plist+i) << " ";

    return 0;
}
int* digitNumbers(int Nbr)
{
     int NbR = Nbr, Digit, NumberOfDigit = 0, Counter = 0;
     int * pARR, *arr;
     //حساب عدد خانات العدد من أجل حجز مصفوفة ديناميكية بنفس الحجم
     while(NbR/10 >= 1)
     {
         NbR/=10;
         NumberOfDigit++;
     }
     //حجز المصفوفة الديناميكية
     pARR = new int [NumberOfDigit + 1];
     //تقطيع العدد و إسناد كل رقم إلى خانة من المصفوفة
     while(Nbr>0)
     {
         Digit = int(Nbr % 10);
         *(pARR + Counter) = Digit;
         Counter++;
         Nbr /= 10;
     }
     //ألآن أصبح المؤشر arr يشير إلى نفس المكان الذي يشير إليه pARR
     arr = pARR;
     //تحرير المؤشر pARR
     delete pARR;
     //إعادة المؤشر arr الذي يحتوي على نسخة من المر الأصلي
     return arr;
}

المخرجات

caster@caster:~/projects/bin$ ./fff
12 is: 0 1
1 is: 0 
caster@caster:~/projects/bin$

تم تعديل هذه المشاركة بواسطة محمد ابوزايد في 6 فبراير 2012 في 15:14

post-15367-027053900%201340345097.gifpost-15367-087183200%201340344597.gif
post-247365-0-10080400-1379403554_thumb.

#11
اقتباس
لقد استخدمت دالتك كما يلى

لم أقم باختبار الدالة و إنما كتبت فكرتي على ورقة ثم نقلتها هنا :)

لكن عندما قمت باختبار الدالة فووووجئت !! :wacko: :blink: :wacko:

....

مرحبا بكم في عالم السحر و الشعوذة !! :D

حتى يتأكد لبقية المبرمجين أننا نتعاطى السحر :D إليك النتاائج التالية :

تنفيذ الكود في الــ Borland :

02oephw6.png

تنفيذ الكود في الــ CodeBlocks :

02qmnzr6.png

تنفيذ الكود في Dev :

02qzmui6.png

ما ذا يمكننا أن نقول ؟؟ طبعا اختلاف العلماء رحمة :lol:

....

بصراحة .. أشم في الكود رائحة Undefined Behavior و لكنني لا أعلم أين !! :blush:

ما رأيكم ؟؟

#12

اهلا اخ خالد

لماذا تنسخ العنوان الموجود بالمؤشر pARR داخل المؤشر arr ثم تحذف pARR

ما الفرق بين pARR و arr :wacko: كان يجب ان تعيد عنوان pARR مباشرة

اقتباس

بصراحة .. أشم في الكود رائحة Undefined Behavior و لكنني لا أعلم أين !! :blush:

لاحظ انك تعيد من الدالة مؤشر داخلى local ينتهى بازالة الدالة من المكدس stack

تحياتى

1


﴿وَمَا كَانَ اللَّهُ لِيُعَذِّبَهُمْ وَأَنْتَ فِيهِمْ ۚ وَمَا كَانَ اللَّهُ مُعَذِّبَهُمْ وَهُمْ يَسْتَغْفِرُونَ﴾

الأنفال ۳۳                                  
 

#13
اقتباس
سأحاول تدقيق الكود ليعمل على بيئات التطوير بدون مشاكل ان شاء الله ....

بانتظارك أخي :)

اقتباس
اهلا اخ خالد

أهلا بك :)

+1

اقتباس
لماذا تنسخ العنوان الموجود بالمؤشر pARR داخل المؤشر arr ثم تحذف pARR

ما الفرق بين pARR و arr :wacko: كان يجب ان تعيد عنوان pARR مباشرة

قمت بنسخ العنوان الموجود بالمؤشر pARR داخل المؤشر arr لكي أستطيع تحرير المؤشر الأول دون أن أفقد ما يشير إليه.

اقتباس
لاحظ انك تعيد من الدالة مؤشر داخلى local ينتهى بازالة الدالة من المكدس stack

إذا كانت المشكلة تكمن هنا فيمكننا الإعلان عن المؤشر arr كمتغير عام, ما رأيك ؟

#14
اقتباس

إذا كانت المشكلة تكمن هنا فيمكننا الإعلان عن المؤشر arr كمتغير عام, ما رأيك ؟

لا يجوز لاحظ انك تكتب دالة ليستعملها مبرمج اخر غيرك :cool:

هل تعرف كيف تستخدم الدالة itoa ؟

http://www.cplusplus.com/reference/clibrary/cstdlib/itoa/

اظن لو ان ما تقوم به فى دالتك صحيح لما اجبرتك الدالة itoa على ادخال المرسل parameter الثانى لتحفظ فيه النتيجة

اقتباس

Parameters

value

Value to be converted to a string.

str

Array in memory where to store the resulting null-terminated string.

base

Numerical base used to represent the value as a string, between 2 and 36, where 10 means decimal base, 16 hexadecimal, 8 octal, and 2 binary.

لاحظ str ووظيفته

تحياتى

تم تعديل هذه المشاركة بواسطة MOHAMED FATHEI في 7 فبراير 2012 في 16:48


﴿وَمَا كَانَ اللَّهُ لِيُعَذِّبَهُمْ وَأَنْتَ فِيهِمْ ۚ وَمَا كَانَ اللَّهُ مُعَذِّبَهُمْ وَهُمْ يَسْتَغْفِرُونَ﴾

الأنفال ۳۳                                  
 

#15
اقتباس
اظن لو ان ما تقوم به فى دالتك صحيح لما اجبرتك الدالة itoa على ادخال المرسل parameter الثانى لتحفظ فيه النتيجة

لا يمكننا القياس في هذه الحالة ! :)

str عبارة عن مصفوفة حرفية كبيرة الحجم (ألا تلاحظ معي أن مصطلح كبيرة الحجم يعني الهروب من الحجز الديناميكي :D )

لو افترضنا في التمرين أن عدد أرقام العدد لا يتجاوز عدد معين وليكن MAX فستكون المشكلة بسيطة لأننا لا نحتاج إلى حجز ديناميكي .. فقط سنرسل مصفوفة (ثابتة الحجم) إلى الدالة و سنقوم بالتعديل على خانات المصفوفة بحيث نُسند لكل خانة أحد أرقام العدد. أما في الحالة العكسية فسيلزمنا الحجز الديناميكي .. و هنا تكمن المشلكة !! : (

#16

أهلا بك أخى محمد فتحى:

MOHAMED FATHEI كتب:

لاحظ انك تعيد من الدالة مؤشر داخلى local ينتهى بازالة الدالة من المكدس stack

مسموح لك بأرجاع متغير مؤشر يشير الى ذاكرة ديناميكية تم حجزها داخل الدالة كما فى أقتباس من مشاركة سابقة

محمد ابوزايد كتب:

مع التخصيص الديناميكي لا يتم حذف الذاكرة التي خصصت عندما تنتهى الدالة من عملها، أو عندما يخرج التنفيذ من كتلة الكود الحالي

يمكنك اﻻطلاع علىكل التفاصيل من هنــــــــــــا

أو رابط مشاركة قمت بطرح نقاش حول تلك المشكلة من هنـــا.

ونرجع للخطأ الذى تم بالكود وهو حذف الذاكرة الديناميكية التى تم حجزها فى الدالة عن طريق حذف المؤشر

 delete pARR;

وبعد استدعاء الدالة نقوم بحذف الذاكر من داخل الدالة الرئيسية حتى تظل الذاكرة محجوز حتى نهاية البرنامج ....

وبذلك الكود يعمل بنجاح كما يلى:

/* 
 * File:   main.cpp
 * Author: Mohammed Abu Zayed ..
 *
 * Created on February 7, 2012, 5:18 PM
 */

#include <iostream>
using namespace std;
int* digitNumbers(int Nbr);

int main() {
    int numsCounts;
    int *plist;
    numsCounts = 0;
    // فى حالة صفر
    cout << "case 0: ";
    numsCounts = 0;
    plist = digitNumbers(0);
    for (int i = 0; i < numsCounts; i++)
        cout << *(plist + i) << " ";
    delete plist;
    // فى حالة 1
    cout << "case 1: ";
    numsCounts = 1;
    plist = digitNumbers(1);
    for (int i = 0; i < numsCounts; i++)
        cout << *(plist + i) << " ";
    delete plist;
    // فى حالة 12 والخ ...
    cout << "case 12: ";
    numsCounts = 2;
    plist = digitNumbers(12);
    for (int i = 0; i < numsCounts; i++)
        cout << *(plist + i) << " ";
    delete plist;
    return 0;
}

int* digitNumbers(int Nbr) {
    int NbR = Nbr, Digit, NumberOfDigit = 1, Counter = 0;
    int * pARR;
    while (NbR / 10 >= 1) {
        NbR /= 10;
        NumberOfDigit++;
    }

    pARR = new int [NumberOfDigit];

    while (Nbr > 0) {
        Digit = int(Nbr % 10);
        *(pARR + Counter) = Digit;
        Counter++;
        Nbr /= 10;
    }
    return pARR;
}

// name='' كتب:

نأتى الى الجزء اﻻهم:

MOHAMED FATHEI كتب:

اظن لو ان ما تقوم به فى دالتك صحيح لما اجبرتك الدالة itoa على ادخال المرسل parameter الثانى لتحفظ فيه النتيجة

لاحظ str ووظيفته

لقد سبقتى يا اخى ان الهدف اساسا من سؤالى فى تطوير الكود الى دالة مستقلة هو دفع اخى خالد الى استخدام مصفوفة حرفية ليس ﻻن الحجز الديناميكى ﻻ يعمل بل حتى نتمكن من عرض محتويات المصفوفة وايجاد عدد عناصرها

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

اﻵن اخى خالد عليك التفكير فى النقطتين التاليتن وايجاد حلى زكى:

-استخدام مصفوفة حرفة بدلا من الحجز الديناميكى

-حل مشكلة عكس ترتيب اﻻرقام

ارجو ان تكون تفهمت وجهت نظرى

تقبل تحياتى والله الموفق ... .

تم تعديل هذه المشاركة بواسطة محمد ابوزايد في 7 فبراير 2012 في 20:23

post-15367-027053900%201340345097.gifpost-15367-087183200%201340344597.gif
post-247365-0-10080400-1379403554_thumb.

#17

+1

اقتباس
اﻵن اخى خالد عليك التفكير فى النقطتين التاليتن وايجاد حلى زكى:

-استخدام مصفوفة حرفة بدلا من الحجز الديناميكى

-حل مشكلة عكس ترتيب اﻻرقام

شبيك لبيك .. خدامك بين أيديك :D

أحم .. أحم ... أظنني سأستعين قليلا بالعصا السحرية itoa :lol: ( ألم تقل إنك تريد استخدام مصفوفة حرفية ؟ :D) :

#include <iostream>
#include <cstdlib>
using namespace std;
int main() {
    int x;
    cin>>x;
    char buffer [33];
    itoa (x,buffer,10);
    cout<<buffer<<endl;
    return 0;
}

بلاش وجع الراس يعني ^_^

... المؤشرات هي السبب الرئيسي و الوحيد لتضخم الخلايا الدماغية !! :D (معا من أجل القضاء على المؤشرات :lol: )

تم تعديل هذه المشاركة بواسطة khaled_prg في 7 فبراير 2012 في 21:22

#18
MOHAMED FATHEI كتب:

اظن لو ان ما تقوم به فى دالتك صحيح لما اجبرتك الدالة itoa على ادخال المرسل parameter الثانى لتحفظ فيه النتيجة

لاحظ str ووظيفته

وترجع تلك المشكلة لعدم مقدرة الدالة إعادة مؤشر لمصفوفة معرفة داخلياً فى الدالة وبالتالى يتم إدخال المصفوفة كباراميتر لتعمل عليها الدالة

ولكن يمكن إعادة مؤشر لذاكرة معرفة ديناميكياً كما أشار الأخ محمد أبوزايد

فلا سبيل فى لغة السي " إن لم يكن هناك حلول أخرى فى لغة ++c " لأن تأخذ باراميتر عدد صحيح وتعود بمصفوفة من نوع char أو أى مصفوفة أخرى أو حتى عنوان المصفوفة , فإما تعريف مصفوفة عامةلتعمل عليها الدالة أو إدخالها للدالة كباراميتر .

- فلتطبيق هذا على المثال السابق لن نحتاج مصفوفة ذات عدد كبير ولكن فقط مصفوفة من نوع char عدد عناصرها 10 لأن مدى العدد الصحيح من نوع int لا يتعدى 10 خانات

- ويتبقى لنا أننا نريد أن نعيد عدد مراتب العدد مع مصفوفة المراتب فلنذيد عدد عناصر المصفوفة من نوع char عنصرين لإرجاع عدد المراتب بهما .

- إذا فيجب أن لايقل عدد عناصر المصفوفة المدخلة عن 12 عنصر .

لاتحسبن العلم ينفع وحده مالم يتوج ربه بخلاق

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

#19
اقتباس
إما تعريف مصفوفة عامةلتعمل عليها الدالة أو إدخالها للدالة كباراميتر

لا أظن انه بإمكانك إعادة مؤشر يشير إلى مصفوفة تم الإعلان عنها محليا .. لأنه مع انتهاء تنفيذ الدالة سيتم مسح كافة المعلومات (العناوين) :)

اقتباس
اﻵن اخى خالد عليك التفكير فى النقطتين التاليتن وايجاد حلى زكى:

-استخدام مصفوفة حرفة بدلا من الحجز الديناميكى

-حل مشكلة عكس ترتيب اﻻرقام

لا أملك الوقت الكافي لكتابة الكود و لكن لدي الآن الفكرة التالية :

  • نقوم بالإعلان عن مصفوفة حرفية dig عدد عناصرها 20 و لتكن global
  • الدالة digitNumbers ستأخذ وسيط واحد (وهو العدد المُراد تقسيم أرقامه) و تعيد مؤشر يشير إلى أول عنصر من عناصر dig أو لنقل أول أرقام العدد. طبعا محتوى المؤشر لن يتغير لأن المصفوفة لا زالت هي نفسها و لكن محتوى المصفوفة هو الذي تغير.
  • بالنسبة لتقسيم أرقام العدد سيكون هكذا, لنأخذ على سبيل المثال العدد 123 :
    int buffer[30]
    x = 123, n = (length(itoa(x,buffer,10))- 1)*10
    dig[0] = x/n;//dig[0] = 1
    x = x % n;//x = 23
    n = n/10


    n تساوي 10 إذا تختلف عن الصفر .. نكرر العملية :

    dig[1] = x/n;//dig[1] = 2
    x = x % n;//x = 3
    n = n/10


    n تساوي 1 إذا تختلف عن الصفر .. من جديد :

    dig[2] = x/n;//dig[2] = 3
    x = x %n;//x = 3
    n = n/10


  • نتوقف عندما تكون n تساوي 0, الناتج :
    dig[] = {1,2,3,\0}


ما رأيكم بالفكرة ؟؟

تم تعديل هذه المشاركة بواسطة khaled_prg في 8 فبراير 2012 في 00:26

#20

كود :

char* digits(int value, char* arr) {
    int counter = 0;
    int temp = value;

    while (temp > 0) {
        temp /= 10;
        counter++;
    }

    *(arr + counter) = '\0';

    while (counter > 0) {
        *(arr + --counter) = (value % 10) + '0';
        value /= 10;
    }

    return arr;
}

int main(int argc, char** argv) {

    char nums[20] = {'0'};
    int index = 0;
    digits(503172, nums);

    while (*(nums + index) != '\0') {
        cout << *(nums + index++) << " ";
    }

    cout << endl << "=============================" << endl;

    return 0;

}

5 0 3 1 7 2

=============================

RUN SUCCESSFUL (total time: 32ms)

تم تعديل هذه المشاركة بواسطة MOHAMED FATHEI في 8 فبراير 2012 في 00:45

3


﴿وَمَا كَانَ اللَّهُ لِيُعَذِّبَهُمْ وَأَنْتَ فِيهِمْ ۚ وَمَا كَانَ اللَّهُ مُعَذِّبَهُمْ وَهُمْ يَسْتَغْفِرُونَ﴾

الأنفال ۳۳                                  
 

#21
اقتباس
لا أظن انه بإمكانك إعادة مؤشر يشير إلى مصفوفة تم الإعلان عنها محليا .. لأنه مع انتهاء تنفيذ الدالة سيتم مسح كافة المعلومات (العناوين) :)

هذا نص كلامى :

إما تعريف مصفوفة عامة لتعمل عليها الدالة أو إدخالها للدالة كباراميتر

وهذا هو البرنامج الذى أقصد فكرة عملة وبالنسبة للدالة سوف تأخذ باراميتر مصفوفة من نوع char لا تقل عدد عناصرها عن 12 ستكون وتأخذ عدد صحيح كالتالى :

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
void digitNumbers( int Num,char arr[]);
int main(void){
	int Num,Sum=0;
    scanf("%d",&Num);
    char arr[16];
	digitNumbers(Num , arr);
    for( int i=arr[10]+arr[11]-1;i>=0;i--){
    Sum+=arr;
	printf("%d",arr);
	}
    printf("\nThe Sum oF Digit of Number is :%d\n",Sum);
return 0;
}


void digitNumbers( int Num,char arr[]){
	int NumberOfDigit=0,intNum=0,DNum;// DNum save Num toget the number of digits "NumberOfDigit" ,intNum to convert double to int
    DNum=Num; // set Num to DNum
	// get the number of digits by using while loop
  while(DNum/10 >= 1)
	 {
		DNum=DNum/10;
        NumberOfDigit++;
	 }
	// NumberOfDigit + 1 to complete number of digits
    NumberOfDigit++;

	if(NumberOfDigit<10)
    {
		arr[10]=NumberOfDigit;
	    arr[11]=0;
	}
	else
    {
		arr[10]=9;
		arr[11]=1;
	}

	for( int i=0;i<NumberOfDigit;i++)
	{
         intNum=Num/pow(10,i);
		arr=intNum%10;
	}

}

طبعاً مدى مراتب العدد الصحيح من نوع int لن يتعدى 10 خانات

لاتحسبن العلم ينفع وحده مالم يتوج ربه بخلاق

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

#22
MOHAMED FATHEI كتب:

كود :

char* digits(int value, char* arr) {
    int counter = 0;
    int temp = value;

    while (temp > 0) {
        temp /= 10;
        counter++;
    }

    *(arr + counter) = '\0';

    while (counter > 0) {
        *(arr + --counter) = (value % 10) + '0';
        value /= 10;
    }

    return arr;
}

int main(int argc, char** argv) {

    char nums[20] = {'0'};
    int index = 0;
    digits(503172, nums);

    while (*(nums + index) != '\0') {
        cout << *(nums + index++) << " ";
    }

    cout << endl << "=============================" << endl;

    return 0;

}

مرحبا بك أخي محمد.

اقتباس

char* digits(int value, char* arr)

عندي ملاحظة وحيدة في الكود :

مالفائدة من إعادة المؤشر في هذه الحالة ؟؟ عنوان المؤشر سيظل هو نفسه لذلك سيكون من الأحسن استخدام void

للتو لاحظت أنني وقعت في نفس التصور :D :

اقتباس
طبعا محتوى المؤشر لن يتغير لأن المصفوفة لا زالت هي نفسها و لكن محتوى المصفوفة هو الذي تغير.

.. هناك الكثير من الإختصارات في الكود بتاعك و قد أعجبتني كثيرا .. يا ريت لو تشرح الفكرة :)

اقتباس
إما تعريف مصفوفة عامة لتعمل عليها الدالة أو إدخالها للدالة كباراميتر

عفوا, ظننت أنك ستعيد مؤشر كما فعل الأخ محمد فتحي :)

#23
اقتباس

مالفائدة من إعادة المؤشر في هذه الحالة ؟؟ عنوان المؤشر سيظل هو نفسه لذلك سيكون من الأحسن استخدام void

لا انا اظن ان اعادة المؤشر افضل من void ففى النهاية ايهما استخدمت فسيقوم البرنامج بالمهمة بنجاح

علاوة على انى لاحظت هذه الطريقة فى الدالة itoa لهذا اظنها افضل

اقتباس

.. هناك الكثير من الإختصارات في الكود بتاعك و قد أعجبتني كثيرا .. يا ريت لو تشرح الفكرة :)

ما اخرنى اننى كنت احاول دمج عمليتى الدوران loop فى عملية واحدة :wacko: :wacko: :wacko:

وحتى الان لم انجح لكنى ساعيد المحاولة

تحياتى


﴿وَمَا كَانَ اللَّهُ لِيُعَذِّبَهُمْ وَأَنْتَ فِيهِمْ ۚ وَمَا كَانَ اللَّهُ مُعَذِّبَهُمْ وَهُمْ يَسْتَغْفِرُونَ﴾

الأنفال ۳۳                                  
 

#24
*(arr + --counter) = (value % 10) + '0';

ما الحكمة من جمع '0' على باقى القسمة

لاتحسبن العلم ينفع وحده مالم يتوج ربه بخلاق

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

#25

اولا مشكورين على تعليقاتكم الجميلة :)

اقتباس

ما اخرنى اننى كنت احاول دمج عمليتى الدوران loop فى عملية واحدة :wacko: :wacko: :wacko:

وحتى الان لم انجح لكنى ساعيد المحاولة

اظننى نجحت انظر الكود التالى :

char* getDigits(unsigned int value, char* arr) {
    int digit = 0;
    static int index = 0;
    *(arr + index) = '\0';

    if (value > 0) {
        digit = value % 10;
        getDigits(value / 10, arr);
    }

    *(arr + index++ -1) = digit + '0';

    return arr;
}

int main(int, char**) {

    char nums[20] = {'0'};
    int index = 0;
    char* ptr = getDigits(503172, nums);

    while (*(ptr + index) != '\0') {
        cout << *(ptr + index++) << " ";
    }

    cout << "[======End of Array======]" << endl;

    return 0;

}

اراها افضل من الاولى ما رأيكم ؟

اقتباس

ما الحكمة من جمع '0' على باقى القسمة

المصفوفة حرفية char ويمكن تسجيل الحرف بطريقتين اما بكتابته مباشرة مثل '9'

او بكتابة القيمة العددية له فى جدول Ascii مثلا الحرف 9 رقمه فى الجدول 57 والحرف 0 رقمه 48

وبدلا من كتابة الارقام فى كل مرة فان القيمة 48 ثابتة وهى قيمة الحرف 0

ونزيد عليها الرقم 9 فيصبح الناتج 57 وهو الحرف 9

على كل القى نظرة على جدول الاسكى وستعرف ما اقصده

تحياتى


﴿وَمَا كَانَ اللَّهُ لِيُعَذِّبَهُمْ وَأَنْتَ فِيهِمْ ۚ وَمَا كَانَ اللَّهُ مُعَذِّبَهُمْ وَهُمْ يَسْتَغْفِرُونَ﴾

الأنفال ۳۳                                  
 

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