سؤال

بدأت تعلم c++ حوالي 3 أسابيع بعد 2 سنوات من جافا.يبدو مختلف جدا ولكن ايم الحصول على هناك.لي المحاضر هو رجل جميل ولكن في أي وقت أنا أسأل سؤال لماذا شيئا من هذا الطريق أو هذا الطريق.لقد يستجيب "لأنه".

هناك الكثير من التعليقات في التعليمات البرمجية أدناه مع عدد قليل من الأسئلة العشوائية, ولكن المشكلة الرئيسية هي ايم الحصول على اثنين من أخطاء بناء واحد يقول arraytotal لم تتم تهيئة (على الرغم من أنني وجدت قيمة ذلك) والآخر يقول مرجعية خارجية في الرئيسية.

أن أي شخص قراءة العقل رمز الإجابة على بعض التعليقات داخل و ربما المشكلة الشاملة im ؟

#include<string>
#include<fstream>
#include<ostream>

using namespace std;

//double decimals[5] ={2,4,6,8,10};

const int arraySize = 5;
// does an arraySize have to be const always? is it so it doesnt channge after the array has been created?

//double decimals[arraySize];

/*
   this array is being created in the function averageN() but why?
   cant i just create it up top and reference it in?
 */

// why do you have to write the name of the function up here before you even create it?
double averageN();

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

// why does the array have to be created here?
double averageN(double decimals[arraySize])
{

    double average;
    double arrayTotal;
    for (int i = 0; i<5;i++)
    {
        // fills with random numbers from 0 - 10
        decimals[i] = (0+(rand()%10));
    }

    // find the total of all the elements in the array
    for (int i = 0; i < arraySize;i++)
    {
        double currentElement = decimals[i];
        arrayTotal = (currentElement+arrayTotal);
        //arrayTotal +=decimals[i]) ;
    }
    // return the average
    average = (arrayTotal/arraySize);
    return 0.0;
}
هل كانت مفيدة؟

المحلول

إجاباتي السريعة دون فحص مزدوج (كانت لحظة منذ أن تطورت في C ++) هي:

  1. لم تتم تهيئة ArrayTotal

    أظن أن المترجم الخاص بك يعلق هذا كخطأ للتأكد من قيامك بذلك. إذا لم تقم بذلك ، فلا يمكنك التأكد من تهيئته إليه. تقليديًا لبناء التصحيح ، قام C/C ++ بتوزيع الذاكرة لبعض قيمة التصحيح للمساعدة في تحديد المتغيرات غير المخصصة. قم بتعيين ArrayTotal = 0 عند تهيئته ويجب أن يزول ذلك. (افضل تمرين)

    على سبيل المثال arraytotal = 0 ؛

  2. مرجع خارجي في الرئيسي

    أظن أن هذا لأن النموذج الأولي الخاص بك لـ Averagen لا يتطابق مع الطريقة المحددة لاحقًا. يحتاج النموذج الأولي إلى تضمين أنواع المعلمات وكذلك نوع الإرجاع. تغيير النموذج الأولي من Double Averagen () ؛ إلى double averagen (double []) ؛ وأعتقد أن هذا سيصلح هذه المشكلة.

  3. هل يجب أن تكون صفائفها دائمًا؟ هل هو كذلك لا القنوات بعد إنشاء الصفيف؟

    نظرًا لأنك تستخدمه لتحديد حجم الصفيف الذي تم تمريره إلى Averagen ، نعم. يتطلب تحديد حجم الصفيف مثل هذا قيمة ثابتة.

  4. يتم إنشاء هذه الصفيف في الوظيفة Averagen () ولكن لماذا؟ لا أستطيع فقط إنشائها من أعلى والرجوع إليها؟

    لا يتم إنشاؤه في Averagen. إنها معلمة رسمية إلى Averagen. يحتاج المتصل في Averagen إلى توفير المتغير المناسب وتمريره. ثم من داخل الطريقة ، يمكنك الوصول إليه من خلال العشرية.

  5. لماذا عليك أن تكتب اسم الوظيفة هنا قبل أن تنشئها؟

    هذا هو النموذج الأولي للوظيفة. من الضروري إذا تمت الإشارة إلى الوظيفة في التعليمات البرمجية قبل تعريف الوظيفة. يمكن حل ذلك بطرق أخرى أيضًا ، مثل تحريك تعريف Averagen قبل كل استخداماته.

نصائح أخرى

  1. // هل يجب أن يكون Carrayize Const دائمًا؟ هل هو كذلك لا القنوات بعد إنشاء الصفيف؟ نعم ، يجب أن يكون const ، علاوة على ذلك ، يجب أن يكون تعبيرًا مستمرًا ، مما يعني أن حجمه يجب أن يكون معروفًا في وقت الترجمة (وليس في وقت التشغيل). إذا كنت ترغب في تغيير حجم المصفوفات ، فإن الأفضل هو استخدام ناقل الحاوية القياسية std ::. أو استخدم المصفوفات المخصصة ديناميكيًا إذا كنت تريد صفيفًا ثابتًا ، لكن الحجم غير معروف حتى وقت التشغيل

  2. /* يتم إنشاء هذه الصفيف في وظيفة Averagen () ولكن لماذا؟ لا أستطيع فقط إنشائها من أعلى والرجوع إليها؟ */ إذا كنت تتحدث عن العشرية ، فلا ، فهو متغير عالمي ، يمكنك استخدامه من أي مكان.

  3. // لماذا يجب عليك كتابة اسم الوظيفة هنا قبل أن تنشئها؟ يجب أن تعلن أي اسم في C ++ قبل استخدامه. نظرًا لأنك تسمي هذه الوظيفة بشكل رئيسي ، يجب إعلانها مسبقًا على الأقل. يمكنك أيضًا توفير التعريف (الجسم) قبل الرئيسي.

  4. // لماذا يجب إنشاء الصفيف هنا؟

عفوًا ، يبدو أن هناك مزيجًا كبيرًا في الكود الخاص بك. في الواقع ، لديك وظيفتان مسماة Averagen ، إحداها هي Averagen التي لا تأخذ أي معلمات ، والآخر هو Averaen يأخذ مجموعة من المزدوجة. لم تحدد أبدًا أول واحد ، تم الإعلان عنه للتو.

الأخطاء:

  1. لم يتم تهيئة doubletotal. حسنًا ، ليس كذلكdouble arrayTotal; التغيير إلى

    arraytotal مزدوج = 0.0 ؛

  2. Extenal لم يتم حلها في Main - هذه هي وظيفة Averagen في Main التي تهدئها. أنت لم تكتب جسدا لذلك. قمت بإنشاء وظيفة تأخذ صفيفًا ، لم تكن مفيدة لأن صفيفك عالمي. ما عليك سوى حذف معلمة الصفيف من تعريف Averagen.

HTH

PS اقرأ S. Lippmann's C ++ Primer. إنه أفضل كتاب للمبتدئين في C ++. IMO :)

  • يعطي Const المترجم فكرة مفادها أنه لا ينبغي تغيير العنصر وإذا حاول الرمز ذلك ، فيمكن للمترجم أن يعلق خطأ.

  • تم ذكر اسم الوظيفة قبل الإعلان الفعلي ، تحتاج الوظيفة الرئيسية () إلى الرجوع إليها قبل أن يأتي المترجم فعليًا لتجميعه (كما هو الحال لاحقًا في ملف الكود). يمكنك تحريك الوظيفة بأكملها قبل Main () لتجنب ذلك.

  • يقول Averagen المزدوج (العشرية المزدوجة [صفائف]) إن هذه الوظيفة تأخذ صفيفًا. لا يقول أنه يخلق الصفيف. إذا نظرت في الوظيفة ، فسيأخذ الصفيف ، ويضيف القيم المحسوبة فيها (decimals[i] = (0+(rand()%10))). تحسب هذه الوظيفة أيضًا متوسطًا على الصفيف ويعيد ذلك بمثابة مزدوج.

للإجابة على سؤالك الكبير ، ما هو الخطأ - اقرأ النقطة الأخيرة وانظر إلى المكالمة التي تجريها -averageN(); - هل يمكنك أن ترى كيف ليست هذه المكالمة الصحيحة؟

حسنًا ، إليك مهمتك الوحيدة في ArrayTotal:

 arrayTotal = (currentElement+arrayTotal);

الآن ، ما هي قيمة arrayTotal بعد هذه المهمة؟ حسنًا ، يعتمد ذلك على قيمته قبل المهمة. ما هي قيمتها قبل المهمة الأولى؟ أنت لا تعرف. يمكن ان تكون اى شئ لأنك لم تقدم لها قيمة أولية.

  const int arraySize = 5;
// does an arraySize have to be const always? is it so it doesnt channge after the array has been created?

يدعم C ++ أساسًا نوعين من المصفوفات: المصفوفات ذات الحجم الثابت ، والتي يتم إعلانها باسم type name[size], ، والصفائف الديناميكية التي يتم تخصيصها new[].
بالنسبة لصفيف الحجم الثابت ، يجب توفير حجمها للمترجم حتى يتمكن من تخصيص ذاكرة كافية للمصفوفة. نظرًا لأن الحجم يجب أن يكون معروفًا للمترجم ، يمكنك فقط تحديده بـ const متغير أو حرفي.
على الرغم من أنه من الممكن إنشاء صفائف مخصصة ديناميكيًا بنفسك ، من خلال التذرع new[], ، سيعطيك هذا بعض الصداع للحصول على إدارة الذاكرة بشكل صحيح. من الأفضل استخدام الفئات الحالية التي تفعل ذلك من أجلك ، مثل std::vector.

 //double decimals[arraySize];

/*
 this array is being created in the function averageN() but why?
 cant i just create it up top and reference it in?
 */

يمكنك إنشائها هنا ، ولكن هذا من شأنه أن يمنح أي شخص الوصول إلى الصفيف. بالنسبة لبرنامج صغير مثل هذا ليس مشكلة كبيرة ، ولكن ضع في اعتبارك أن هناك عشرات الملفات الأخرى التي يمكنها أيضًا الوصول إلى المصفوفة وتغييرها في لحظات غير متوقعة.

إنه في الأساس نفس السؤال عن سبب عدم جعل جميع الفصول والأفراد علنًا في جافا: الحد من من لديه الوصول.

// why do you have to write the name of the function up here before you even create it?
double averageN();

عليك أن تعلن الوظيفة قبل أن تتمكن من استخدامها. لدى C ++ شرط أن جميع الأسماء التي تستخدمها يجب أن تكون قد تم الإعلان عنها في برنامج التحويل البرمجي قبل استخدامها الأول ، وسيقوم برنامج التحويل البرمجي بقراءة ملف بترتيب متتابع من الأعلى إلى الأسفل.

لاحظ أن هذا الإعلان لا يتطابق مع تعريف الوظيفة الذي تقدمه أدناه. نظرًا لأن C ++ يدعم التحميل الزائد للوظيفة ، فإن الاثنين يعتبران وظائف مختلفة ، لأنهما يقبلان معلمات مختلفة (لا شيء مقابل مؤشر)

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

 // why does the array have to be created here?
 double averageN(double decimals[arraySize])
     {

هذا لا ليس إنشاء صفيف. بدلاً من ذلك ، يحدد أن الوظيفة تتوقع أن يتم استدعاؤها مع وسيطة مؤشر ( arraySize يتم تجاهله تمامًا ولا يمكنك تمرير صفيف إلى وظيفة في C ++ ، لذلك يتم ضبط المعلمة للقراءة double *decimals).

للحصول على برنامج عمل ، تحتاج إلى تغيير الخطين أعلاه إلى

 double averageN()
     {
    double decimals[arraySize];

double average;
double arrayTotal;

كلاهما average و arrayTotal لم يتم تهيئة. هذا يعني أنهم سيبدأون ببعض القيمة غير المعروفة.
إلى عن على average, ، هذا ليس مشكلة ، لأن أول شيء تفعله به هو تعيين قيمة جديدة. لكن ل arrayTotal, ، أنت تضيف قيمًا إليها ، لذلك يجب أن تدعها تبدأ بقيمة معروفة.

for (int i = 0; i<5;i++)
{
    // fills with random numbers from 0 - 10
    decimals[i] = (0+(rand()%10));
}

// find the total of all the elements in the array
for (int i = 0; i < arraySize;i++)
{
    double currentElement = decimals[i];
    arrayTotal = (currentElement+arrayTotal);
    //arrayTotal +=decimals[i]) ;
}
// return the average
average = (arrayTotal/arraySize);
return 0.0;
 }

زوجان من المشاكل:

  • إعلانك الأمامي عن Averagen غير صحيح

شفرة:

double averageN();

النسخة الموردة أدناه تأخذ معلمة.

  • إن إعلانك عن Averagen لا يعمل تمامًا
    إعلان المعلمات من نوع مجموعة ليست واضحة بشكل حدسي.
    عادةً ما يترك الناس الصفيف يتحلل إلى مؤشر إلى الصفيف ويمرون طولًا كمعلمة ثانية.

شفرة:

double averageN(double *decimals, int arraySize)

إذا كنت تريد فقط تمرير صفائف بحجم معين ، فيجب عليك القيام بذلك بالرجوع إليه:

double averageN(double (&decimals)[arraySize])
  • مكالمتك إلى Averagen () بشكل رئيسي.
    أنت تمر معلمات الصفر. الآن هذا يتطابق مع الإعلان الأمامي ولكن ليس التعريف الفعلي.

نتيجة سأقوم بتغيير الرمز مثل هذا:

extern double averageN(double (&decimals)[arraySize]);

int main()
{
    double data[arraySize];
    averageN(data);
    return 0;
}

// why does the array have to be created here?
double averageN(double (&decimals)[arraySize])
{

بالإضافة إلى التفاصيل الفنية للإجابات الأخرى ، بدلاً من ذلك ، الإجابة على الشكوى في فقرتك الأولى: إحدى الطرق للحصول على إجابات عالية الجودة على "لماذا" أسئلة C ++ هي طرحها في إحدى مجموعات Usenet ، لأنه ، كما هو الحال مع Stackoverflow هناك الخبراء يتسكعون هناك ، ولكن على عكس Stackoverflow ، فإن سؤال المبتدئين هو المحتمل أن للحصول على إجابة من أحد أعضاء لجنة التقييس ، وإذا كنت محظوظًا حتى من أولئك الذين صاغوا المعيار (مثل أندرو كوينيج أو بيت بيكر حاليًا). في الأوقات السابقة كان بيارن هناك أيضًا. لكن السنوات الأخيرة لم ينشر الكثير.

أسئلة المبتدئ الأساسية "لماذا":alt.comp.lang.learn.c-c ++. فرانسيس جلاسبورو معلقة هناك. إنه عضو في اللجنة ومؤلف العديد من الكتب التمهيدية C ++ الناجحة. إنه يعرف أيضًا القليل من الرياضيات ، وبما أن تردد النشر هناك منخفض (ما هو مع Stackoverflow!) ، فأنت متأكد تقريبًا من أنه سيتم الرد على أي سؤال مثير للاهتمام على الفور تقريبًا - وبشكل صحيح - من قبل فرانسيس ، في لعبة Snap. :-)

أسئلة عامة حول لغة C ++: comp.lang.c ++و/أو comp.lang.c ++. المعتدل. المجموعة الأخيرة خاضعة للإشراف ولها ميثاق. الاعتدال يقلل من الضوضاء - على سبيل المثال لا البريد العشوائي - ولكنه يضيف التأخير. يفضل بعض أعضاء اللجنة النشر في الغالب في المجموعة غير المعتمدة (EG James Kanze) ، وبعضها ، مثل Pete Becker و Howard Hinnant ، في المنشور في كلا المجموعتين ، وبعض الخبراء المعروفين ، على سبيل المثال أندريه ألكسندريسكو ، على ما يبدو على ما يبدو فقط في المجموعة المعتدلة.

أسئلة حول معنى المعيار ، والتقارير حول الأخطاء في المعيار وما إلى ذلك (في الأوقات السابقة ، كان هذا أيضًا حيث أبلغت عن عيوب رسميًا في المعيار): [comp.std.c ++]. هذه أيضًا مجموعة خاضعة للإشراف ، وللأسف ، أصبح تأخير وزارة الدفاع الآن طويلًا تقريبًا. ولكن بصفتك مبتدئًا ، ربما تكون أقل اهتمامًا بالتفاصيل الرسمية ، وأكثر اهتمامًا بالأسس والتفسيرات ، والتي [comp.lang.c ++] و [comp.lang.c ++. المعتدل] هي مجموعات رائعة (أعتقد أن Stackoverflow Main's الميزة هي عندما تتساءل "ما هو الخطأ في هذا الرمز" أو الأسئلة التي يمكن حلها من حيث المبدأ بمجرد قراءة الوثائق ذات الصلة).

أخيرًا ، لقد ارتبطت بمجموعات Google التي توفر واجهة على الويب ، ولكن يمكنك الوصول إلى هذه المجموعات بشكل مباشر أكثر من عميل Usenet مثل Thunderbird (أو على سبيل المثال متصفح الأوبرا ، الذي يحتوي على عميل مدمج). كل ما عليك فعله للوصول إلى USENET عبر عميل محلي هو تكوين العميل ، وإخباره عن الخادم ، مثل EternalSeptember المجاني. أو aioe.

هتاف و هول. ،

- ألف

شيء واحد يبدو أن لا أحد علق على:عودتك بيان في نهاية averageN هو الخطأ.تقول أنك العودة متوسط ، ثم حساب نصف قطر ثم return 0.0;.محاولة return average; أو return arrayTotal/arraySize;.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top