---
title: Inline Functions in C++
localeTitle: وظائف مضمنة في C ++
---
## وظائف مضمنة في C ++

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

يوفر C ++ وظائف مضمّنة لتقليل الحمل المكالمة الدالة. دالة مضمنة هي دالة يتم توسيعها في السطر عندما يتم استدعاؤها. عندما يتم استدعاء الدالة المضمنة يتم إدخال رمز كامل للدالة المضمنة أو استبدالها في نقطة استدعاء دالة مضمنة. يتم تنفيذ هذا الاستبدال بواسطة برنامج التحويل البرمجي C ++ في وقت التحويل البرمجي. وظيفة مضمنة قد تزيد من الكفاءة إذا كانت صغيرة. إن صيغة تعريف الدالة المضمنة هي:

 `inline return-type function-name(parameters) 
 { 
    // function code 
 } 
` 

تذكر أن التضمين هو مجرد طلب إلى المحول البرمجي وليس أمرًا. يمكن تجاهل المحول البرمجي طلب forlining. قد لا يؤدّي المحول البرمجي inlining في حالات مثل:

*   إذا احتوت إحدى الدالات على حلقة. (ل ، بينما ، لا أثناء)
*   إذا كانت الدالة تحتوي على متغيرات ثابتة.
*   إذا كانت الوظيفة متكررة.
*   إذا كان نوع إرجاع الدالة مختلفًا عن الفراغ ، ولا يوجد بيان الإرجاع في نص الدالة.
*   إذا احتوت الدالة على مفتاح تبديل أو عبارة goto.

### توفر الوظائف المضمنة المزايا التالية:

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

### عيوب وظيفة مضمنة:

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

يوضح البرنامج التالي هذا المفهوم:

 `#include <iostream> 
 using namespace std; 
 class operation 
 { 
    int a,b,add,sub,mul; 
    float div; 
 public: 
    void get(); 
    void sum(); 
    void difference(); 
    void product(); 
    void division(); 
 }; 
 inline void operation :: get() 
 { 
    cout << "Enter first value:"; 
    cin >> a; 
    cout << "Enter second value:"; 
    cin >> b; 
 } 
 
 inline void operation :: sum() 
 { 
    add = a+b; 
    cout << "Addition of two numbers: " << a+b << "\n"; 
 } 
 
 inline void operation :: difference() 
 { 
    sub = ab; 
    cout << "Difference of two numbers: " << ab << "\n"; 
 } 
 
 inline void operation :: product() 
 { 
    mul = a*b; 
    cout << "Product of two numbers: " << a*b << "\n"; 
 } 
 
 inline void operation ::division() 
 { 
    div=a/b; 
    cout<<"Division of two numbers: "<<a/b<<"\n" ; 
 } 
 
 int main() 
 { 
    cout << "Program using inline function\n"; 
    operation s; 
    s.get(); 
    s.sum(); 
    s.difference(); 
    s.product(); 
    s.division(); 
    return 0; 
 } 
` 

انتاج:

 `Enter first value: 45 
 Enter second value: 15 
 Addition of two numbers: 60 
 Difference of two numbers: 30 
 Product of two numbers: 675 
 Division of two numbers: 3 
`