إرشادات لتحسين التعليمات البرمجية الخاصة بك

StackOverflow https://stackoverflow.com/questions/60673

  •  09-06-2019
  •  | 
  •  

سؤال

ما هي الإرشادات التي تتبعها لتحسين الجودة العامة للتعليمات البرمجية الخاصة بك؟لدى العديد من الأشخاص قواعد حول كيفية كتابة تعليمات برمجية C++ والتي (من المفترض) تجعل من الصعب ارتكاب الأخطاء.لقد رأيت الناس يصر أن كل if البيان يتبعه كتلة قوسية ({...}).

أنا مهتم بالإرشادات التي يتبعها الآخرون والأسباب الكامنة وراءها.أنا مهتم أيضًا بالمبادئ التوجيهية التي تعتقد أنها هراء، ولكنها شائعة.يمكن لأي شخص أن يقترح عدد قليل؟

ولبدء الأمر، سأذكر بعضًا منها للبدء بها:

  • استخدم دائمًا الأقواس بعد كل مرة if / else البيان (المذكور أعلاه).الأساس المنطقي وراء ذلك هو أنه ليس من السهل دائمًا معرفة ما إذا كانت عبارة واحدة هي في الواقع عبارة واحدة، أو ماكرو معالج مسبق يتوسع إلى أكثر من عبارة واحدة، لذلك قد ينقطع هذا الرمز:
    // top of file:
    #define statement doSomething(); doSomethingElse

    // in implementation:
    if (somecondition)
        doSomething();

ولكن إذا كنت تستخدم الأقواس فسوف يعمل كما هو متوقع.

  • استخدم وحدات ماكرو المعالج المسبق للترجمة الشرطية فقط.يمكن أن تسبب وحدات ماكرو المعالج المسبق كل أنواع الجحيم، لأنها لا تسمح بقواعد تحديد النطاق في لغة C++.لقد جنحت عدة مرات بسبب وحدات الماكرو للمعالج المسبق ذات الأسماء الشائعة في ملفات الرأس.إذا لم تكن حذرًا، فقد تتسبب في كل أنواع الفوضى!

الآن إليك.

هل كانت مفيدة؟

المحلول

بعض من مفضلاتي الشخصية:

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

اخرج من أعمال إدارة الذاكرة.تعلم كيفية استخدام المؤشرات الذكية: std::auto_ptr, std::tr1::shared_ptr (أو boost::shared_ptr) و boost::scoped_ptr.تعرف على الاختلافات بينهما ومتى تستخدم واحدًا مقابل الآخر.آخر.

من المحتمل أنك ستستخدم مكتبة النماذج القياسية.إقرأ ال كتاب جوسوتيس.لا تتوقف بعد الفصول القليلة الأولى عن الحاويات معتقدًا أنك تعرف المحكمة الخاصة بلبنان.ادفع إلى الأشياء الجيدة:الخوارزميات والكائنات الوظيفية.

نصائح أخرى

  1. حذف التعليمات البرمجية غير الضرورية.

هذا كل شيء.

  • استخدام وتنفيذ أسلوب وإرشادات ترميز مشتركة. الأساس المنطقي: يستطيع كل مطور في الفريق أو في الشركة قراءة التعليمات البرمجية دون تشتيت الانتباه الذي قد يحدث بسبب أنماط الأقواس المختلفة أو ما شابه ذلك.
  • قم بانتظام بإعادة بناء قاعدة المصدر بالكامل (أي.قم بإجراء عمليات إنشاء أو إنشاءات يومية بعد كل تسجيل وصول) والإبلاغ عن أي أخطاء! الأساس المنطقي: يكون المصدر دائمًا في حالة صالحة للاستخدام، ويتم اكتشاف المشكلات بعد وقت قصير من "تنفيذها"، حيث يكون حل المشكلات رخيصًا.

قم بتشغيل كافة التحذيرات التي يمكنك الوقوف عليها في برنامج التحويل البرمجي الخاص بك (gcc: -Wall هي بداية جيدة ولكنها لا تتضمن كل شيء، لذا تحقق من المستندات)، وارتكب أخطاء فيها لذا يتعين عليك إصلاحها (gcc: -Werror).

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

كتب سوتر وألكساندرسكو كتابًا جيدًا حول هذا الموضوع بعنوان معايير الترميز C++.

إليك بعض النصائح العامة من ليل أولي:

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

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

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

كانت تلك عامة جدًا.للحصول على نصائح محددة، لا يمكنني القيام بعمل أفضل بكثير من سوتر وألكساندرسكو.

في حالة وضع العبارات الثابت على اليسار، أي.

if( 12 == var )

لا

if( var == 12 )

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

أستخدم الأقواس في حالة عدم وجودها على نفس الخط.

if( a == b ) something();
if( b == d )
{
    bigLongStringOfStuffThatWontFitOnASingleLineNeatly();
}

دائمًا ما يكون للأقواس المفتوحة والمغلقة خطوط خاصة بها.لكن هذه بالطبع اتفاقية شخصية.

قم بالتعليق فقط عندما يكون من الضروري فقط شرح ما يفعله الكود، حيث لا يمكن لقراءة الكود أن تخبرك بنفس الشيء.

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

  1. استخدم التنسيق المتسق.
  2. عند العمل على التعليمات البرمجية القديمة، استخدم النمط الحالي للتنسيق، خاصة.أسلوب هدفين.
  3. احصل على نسخة من كتاب سكوت ماير لـ C++ الفعالة
  4. احصل على نسخة من كتاب ستيف ماكونيل Code Complete.

هناك أيضا لطيفة دليل أسلوب C++ يتم استخدامها داخليًا بواسطة Google، والتي تتضمن معظم القواعد المذكورة هنا.

ابدأ بكتابة الكثير من التعليقات - ولكن استخدم ذلك كفرصة لإعادة صياغة الكود بحيث يكون واضحًا بذاته.

أي:

for(int i=0; i<=arr.length; i++) {
  arr[i].conf() //confirm that every username doesn't contain invalid characters
}

كان ينبغي أن يكون شيء أشبه

for(int i=0; i<=activeusers.length; i++) {
  activeusers[i].UsernameStripInvalidChars()
}
  • استخدم علامات التبويب للمسافات البادئة ، ولكن محاذاة البيانات مع المسافات ، وهذا يعني أن الأشخاص يمكن أن يقرروا مقدار المسافة البادئة عن طريق تغيير حجم علامة التبويب ، ولكن أيضًا تظل الأمور محاذاة (على سبيل المثال ، قد ترغب بنية)

  • استخدم دائمًا الثوابت أو الوظائف المضمنة بدلاً من وحدات الماكرو حيثما أمكن ذلك

  • لا تستخدم أبدًا "استخدام" في ملفات الرأس، لأن كل ما يتضمن تلك التكملة سيتأثر أيضًا، حتى لو كان الشخص الذي يقوم بتضمين رأسك لا يريد كل الأشياء القياسية (على سبيل المثال) في مساحة الاسم العامة الخاصة به.

  • إذا كان هناك شيء أطول من حوالي 80 عمودًا، فقم بتقسيمه إلى عدة أسطر، على سبيل المثال

    if(SomeVeryLongVaribleName != LongFunction(AnotherVarible, AString) &&
       BigVaribleIsValid(SomeVeryLongVaribleName))
    {
        DoSomething();
    }
    
  • فقط مشغلي التحميل الزائد لجعلهم يفعلون ما يتوقعه المستخدم، على سبيل المثال، التحميل الزائد لمشغلي + و - لـ 2dVector أمر جيد

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

  1. اصطلاح ترميز الإعداد وجعل جميع المشاركين يتبعون الاصطلاح (لن ترغب في قراءة التعليمات البرمجية التي تتطلب منك معرفة مكان العبارة/التعبير التالي لأنه لم يتم وضع مسافة بادئة له بشكل صحيح)
  2. إعادة هيكلة التعليمات البرمجية الخاصة بك باستمرار (احصل على نسخة من إعادة البناء، بقلم مارتن فاولر، الإيجابيات والسلبيات مفصلة في الكتاب)
  3. كتابة تعليمات برمجية مقترنة بشكل غير محكم (تجنب كتابة التعليق عن طريق كتابة تعليمات برمجية تشرح نفسها بنفسها، تميل التعليمات البرمجية غير المتماسكة إلى أن تكون أسهل في الإدارة/التكيف مع التغيير)
  4. إذا كان ذلك ممكنًا، قم باختبار الكود الخاص بك (أو إذا كنت مفتول العضلات بما فيه الكفاية، TDD.)
  5. الافراج في وقت مبكر، الافراج في كثير من الأحيان
  6. تجنب التحسين المبكر (يساعد التنميط في التحسين)

حيثما أمكنك، استخدم الزيادة المسبقة بدلاً من الزيادة اللاحقة.

أستخدم PC-Lint في مشاريعي الخاصة بـ C++، وأعجبني بشكل خاص الطريقة التي يشير بها إلى المنشورات الموجودة مثل إرشادات MISRA أو "Effective C++" و"Moreeffactive C++" لسكوت مايرز.حتى إذا كنت تخطط لكتابة مبررات مفصلة للغاية لكل قاعدة تتحقق منها أداة التحليل الثابت، فمن الجيد الإشارة إلى المنشورات الراسخة التي يثق بها المستخدم.

فيما يلي أهم نصيحة قدمها لي أحد خبراء C++، وقد ساعدتني في بعض المناسبات الهامة في العثور على الأخطاء في الكود الخاص بي:

  • استخدم أساليب const عندما تكون الطريقة ليس من المفترض لتعديل الكائن.
  • استخدم مراجع ومؤشرات const في المعلمات عندما يكون الكائن ليس من المفترض لتعديل الكائن.

باستخدام هاتين القاعدتين، سيخبرك المترجم مجانًا بمكان الخلل في المنطق في التعليمات البرمجية الخاصة بك!

أيضًا، بالنسبة لبعض التقنيات الجيدة التي قد تتبعها مدونة Google "الاختبار على المرحاض".

انظر إليها بعد ستة أشهر

تأكد من وضع مسافة بادئة بشكل صحيح

حسنًا - ربما كان ينبغي علي أن أكون أكثر تحديدًا بعض الشيء.

أنا لا أبحث كثيرًا عن النصائح لنفسي - فأنا أكتب أداة لتحليل التعليمات البرمجية الثابتة (العروض التجارية الحالية ليست جيدة بما يكفي لما أريده)، وأبحث عن أفكار للمكونات الإضافية لتسليط الضوء على الإمكانات الممكنة أخطاء في الكود.

لقد ذكر العديد من الأشخاص أشياء مثل صحة الثبات واستخدام المؤشرات الذكية - وهذا هو نوع التفكير الذي يمكنني التحقق منه.يعد التحقق من المسافة البادئة والتعليق أمرًا أصعب قليلاً (من وجهة نظر البرمجة على أي حال).

تتمتع المؤشرات الذكية بطريقة لطيفة للإشارة إلى الملكية بوضوح شديد.إذا كنت فئة أو وظيفة:

  • إذا حصلت على المؤشر الخام, ، أنت لا تملك أي شيء.يُسمح لك باستخدام النقطة، بفضل المتصل بك، الذي يضمن بقاء النقطة على قيد الحياة لفترة أطول منك.
  • إذا حصلت على ضعيف_ptr, ، أنت لا تملك النقطة، وفوق ذلك يمكن أن تختفي النقطة في أي وقت.
  • إذا حصلت على Shared_ptr, ، أنت تمتلك الكائن مع الآخرين، لذلك لا داعي للقلق.ضغط أقل، ولكن أيضًا تحكم أقل.
  • إذا حصلت على auto_ptr, ، أنت المالك الوحيد للكائن.إنها لك، أنت الملك.لديك القدرة على تدمير هذا الشيء، أو إعطائه لشخص آخر (وبالتالي فقدان الملكية).

أجد حالة auto_ptr قوية بشكل خاص:في التصميم، إذا رأيت auto_ptr، أعلم على الفور أن هذا الكائن سوف "يتجول" من جزء من النظام إلى الآخر.

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

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