تضمين التوجيه
يُوجّه أمر التضمين معالج ملفات النصوص لاستبدال نص الأمر بمحتوى ملف مُحدد.
قد تكون عملية التضمين منطقية بطبيعتها. قد يقوم المعالج ببساطة بمعالجة محتوى ملف التضمين في موقع التوجيه دون إنشاء ملف مدمج.
قد تستخدم المعالجات المختلفة صيغًا مختلفة. يُعرّف مُعالج C المُسبق (المستخدم مع C و C++ وفي سياقات أخرى) توجيه التضمين على أنه سطر يبدأ #includeويتبعه تحديد ملف. يُعرّف COBOL توجيه تضمين يُشار إليه بـ copyلتضمين ملف نسخ .
في لغة C/C++، يُستخدم توجيه التضمين عادةً لتضمين ملف رأس ، ولكنه يُمكن استخدامه لتضمين أي ملف. على الرغم من ندرة استخدامه، إلا أنه يُستخدم أحيانًا لتضمين ملف نصي مثل ملف بامتداد .c .
يدعم توجيه التضمين التغليف وإعادة الاستخدام . يمكن فصل أجزاء النظام المختلفة إلى مجموعات منطقية مع الحفاظ على اعتمادها المتبادل عبر تضمين الملفات. صُممت لغتا C و C++ للاستفادة من التضمين مع تحسين وقت البناء من خلال السماح بفصل التصريح عن التنفيذ . يمكن تقليص المعلومات المُضمنة إلى التصريحات فقط.
نظرًا لأن تضمين محتوى الملفات مباشرةً ينطوي على عيوب كبيرة، مثل كثرة التعليمات البرمجية المتكررة أو عدم إدراك أنواع البيانات/بنية اللغة، فقد صُممت اللغات الحديثة بدون توجيه تضمين. تدعم لغات مثل Go و Python و Haskell التجزئة المعيارية عبر عبارة استيراد ، مما يجعل المُترجم/المفسر يُحمّل وحدة نمطية، ويُحلل التعليمات البرمجية من خلال الوحدة النمطية المرتبطة، وليس عن طريق تضمين النص. أما اللغات المُترجمة، مثل Rust و D ، فتربط جميع ملفات الكائنات ببساطة في وقت الترجمة. وبالمثل، قدمت لغة C++ أيضًا importاستيراد وحدات C++ النمطية ، والتي تستخدم ملفات .pcm للتخزين كملفات وسيطة، على غرار كيفية عمل الرؤوس المُترجمة مسبقًا . على الرغم من أن Java و C# تحتويان على عبارات استيراد، إلا أنها لا تُعادل توجيه التضمين. في الواقع، في هذه اللغات، يتم تحميل الفئات عند الطلب بواسطة مُحمّل الفئات ، ويمكن الوصول إليها ببساطة عن طريق تحديد الفئة بالكامل مع مساحات أسمائها . تُستخدم عبارات الاستيراد في هذه اللغات فقط لإضافة فئة إلى النطاق الحالي.importusing
على الرغم من أن لغة C# لديها القدرة على استخدام بعض توجيهات المعالج المسبق المشابهة لتلك الخاصة بالمعالج المسبق للغة C، إلا أنها لا تحتوي على #includeالتوجيه.
الدعم اللغوي
لغة C/C++
تُستخدم لغتا C و C++ (قبل C++20) عادةً مع مُعالج C المُسبق الذي يستبدل #includeسطر التوجيه بمحتوى الملف المُحدد. يُحاط مسار الملف إما بعلامات اقتباس مزدوجة (مثل "Header.h" ) أو بأقواس زاوية (مثل <Header.h> ). [ 1 ] تُحدد بعض المُعالجات المُسبقة موقع ملف التضمين بشكل مختلف بناءً على الفواصل المُحيطة؛ حيث تُعامل المسار بين علامتي اقتباس مزدوجتين على أنه نسبي إلى ملف التضمين، بينما يُعامل المسار بين قوسين زاوية على أنه موجود في أحد أدلة مسار بحث النظام المُكوّن. [ 2 ]
تتضمن الأمثلة العبارات التالية:
// تضمين ملف الرأس القياسي للغة C المسمى 'stdio.h'؛ من المحتمل أن يكون ملفًا بهذا الاسم #include <stdio.h> // تضمين ملف الرأس القياسي للغة C++ المسمى 'vector'؛ قد يكون ملفًا أو لا #include <vector> // تضمين ملف رأس مخصص باسم 'MyHeader.h' #include "MyHeader.h"يسمح توجيه التضمين بتطوير مكتبات برمجية تقوم بما يلي:
- يساعد على ضمان استخدام الجميع لنفس إصدار تعريف تخطيط البيانات أو التعليمات البرمجية الإجرائية في جميع أنحاء البرنامج
- سهولة الرجوع إلى أماكن استخدام المكونات في النظام
- برامج تغيير مركزية/عامة بسهولة عند الحاجة (يجب تعديل ملف واحد فقط)
- وفر الوقت عن طريق إعادة استخدام تخطيطات البيانات
لا تدعم توجيهات التضمين أنماط المطابقة ، لذلك على سبيل المثال لن يتم تضمين جميع ملفات *.h في الدليل الحالي.#include"*.h"
مثال
لنفترض وجود ملفي مصدر C. أحدهما يُعرّف دالة add()والآخر يستخدمها. بدون استخدام توجيه تضمين، يمكن للملف المستخدم تعريف الدالة محليًا كنموذج أولي للدالة :
دبراغما مرة واحدةint add ( int , int );دالة ثلاثية ( عدد صحيح x ) { تُرجع دالة الجمع ( x ، الجمع ( x ، x )); }من عيوب هذا الأسلوب ضرورة وجود نموذج الدالة في كل ملف يستدعيها add(). ومن عيوبه أيضًا أنه في حال تغيير توقيع الدالة، يجب تحديث كل ملف مستخدم. يُجنّب وضع النموذج في ملف واحد منفصل هذه المشاكل. إذا نُقل النموذج إلى ملف رأس Add.h ، يصبح ملف المصدر المستخدم كما يلي:
#include "Add.h"دالة ثلاثية ( عدد صحيح x ) { تُرجع دالة الجمع ( x ، الجمع ( x ، x )); }ملف رأس الصفحة
في لغتي C و C++، ملف الرأس هو ملف كود مصدر يسمح للمبرمجين بمشاركة وإعادة استخدام تعريفات قاعدة التعليمات البرمجية - وغالبًا ما يتم تنفيذها في مجموعات منفصلة ومترابطة منطقيًا.
يُعرّف ملف الرأس عناصر البرمجة مثل الدوال ، والفئات ، والمتغيرات ، ووحدات المعالجة المسبقة . يسمح ملف الرأس للمبرمج باستخدام عناصر البرمجة في ملفات متعددة بناءً على التعريف المشترك في ملف الرأس. تُمكّن التعريفات في ملف الرأس ملفات الجسم من استخدام التطبيقات دون تضمين كود التطبيق مباشرةً. يحافظ ملف الرأس على فصل الواجهة عن التطبيق . [ 3 ]
قد تحدث أخطاء في عملية الترجمة إذا احتوت ملفات رأسية متعددة على نفس الملف. أحد الحلول هو تجنب تضمين الملفات في ملفات الرأس ، مما قد يتطلب استخدام توجيهات تضمين زائدة في ملفات الجسم. حل آخر هو استخدام حارس تضمين في كل ملف رأسي. [ 4 ]
تُعرَّف مكتبة C القياسية على أنها مجموعة من ملفات الرأس. أما مكتبة C ++ القياسية فهي مشابهة، ولكن يمكن للمترجم توفير التصريحات دون قراءة ملف فعلي.
تُسمى ملفات رأس لغة C القياسية بامتداد .h ، كما في المثال .hpp. عادةً ما تحمل ملفات رأس C المخصصة نفس الامتداد. أما ملفات رأس C++ المخصصة، فتميل إلى امتلاك امتدادات متنوعة، تشمل .hpp و .hh و .h++ و .hxx، بالإضافة إلى الامتداد .h الذي قد يكون غامضًا .#include<stdio.h>
يؤدي استخدام اسم مكتبة C++ القياسية بين قوسين زاويين (مثل <vector> ) إلى تضمين التصريحات، ولكن قد لا يكون مصدرها ملفًا. [ 5 ]
وحدة رأسية
منذ إصدار C++20 ، يدعم C++ دلالات الاستيراد عبر وحدة الرأس ، أي وحدات الترجمة المنفصلة المُصنّعة من ملف رأس. [ 6 ] وهي مصممة لتكون بمثابة مرحلة انتقالية نحو التبني الكامل للوحدات النمطية.
importاعتبارًا من C++26 ، لا يُعدّ هذا الأمر توجيهًا للمعالج المسبق. وبالتالي، لا يتعامل معه معالج C المسبق. importفهو لا ينسخ التعليمات البرمجية إلى ملف مثل #include، بل يربط وحدة الترجمة أثناء وقت الترجمة.
مثال:
import < stdio.h > ; // دعم هذا اختياري import <vector> ; // دعم هذا إلزامي بموجب معيار التصدير import " MyHeader.h " ;يتم توفير وحدات رأسية لجميع رؤوس مكتبة C++ القياسية. [ 7 ]
الوحدات
منذ C++20، تم إدخال الوحدات النمطية ويتم استيرادها باستخدام import`.`. تتمتع هذه الوحدات بنفس دلالات استيراد وحدات الرأس، ولكنها توفر تحكمًا أدق في الصادرات. منذ C++26 ، لم يعد المعالج المسبق يتعامل معها على الإطلاق. يجب وضع علامة عليها module، ويجب وضع علامة على كل رمز exportأو وضعه في exportكتلة ``` حتى يمكن الوصول إليه عن طريق الاستيراد. دلالات عبارة ``` importهي:
تصدير اختياري استيراد اسم_الوحدة؛
اعتبارًا من C++23 ، يمكن استيراد مكتبة C++ القياسية كوحدة نمطية عن طريق كتابة .importstd;
// يستورد مكتبة C++ القياسية import std ;// يستورد وحدة باسم "acme.project.math.BigInteger" import acme . project . math . BigInteger ;// يستورد وحدة باسم "wikipedia.util.logging.Logger " ، ويعيد تصديرها // أي ملف يستورد هذه الوحدة سيستوردها بشكل غير مباشر wikipedia.util.logging.Logger export import wikipedia.util.logging.Logger ;تضمين
تمت إضافة هذا التوجيه في C23 و C++26 ، #embedوهو مشابه للتوجيه #includeالسابق ولكنه أكثر ملاءمة لتضمين/إدراج الموارد الثنائية في التعليمات البرمجية المصدرية.
constexpr char ICON_DISPLAY_DATA [] = { #embed "art.png" };// حدد أي نوع يمكن تهيئته من خلال تعبيرات الثوابت العددية الصحيحة constexpr char RESET_BLOB [] = { #embed "data.bin" };// تعمل السمات بنفس الكفاءة alignas ( 8 ) constexpr char ALIGNED_DATA_STRING [] = { #embed "attributes.xml" };int main () { return #embed </dev/urandom> limit(1) ; }أوبجكتيف سي
تستخدم لغة Objective-C ، مثل لغة C، ملفات الرأس ولديها #includeتوجيهة `#include`. ومع ذلك، فهي تحتوي أيضًا على #importتوجيهة `#pragma once`، والتي تعمل بنفس طريقة `#include` #include، والفرق الوحيد هو أن ` #import#pragma once` تضمن عدم تضمين الملف أكثر من مرة، دون استخدام حراس `#include` أو `#pragma once` .
#import <Foundation/Foundation.h> #import "MyClass.h"#importلا ينبغي الخلط بين توجيه Objective-C importوالعبارة في C++ (التي تستورد وحدة نمطية)، أو توجيه Microsoft Visual C++#import ، الذي يستورد مكتبة أنواع. [ 8 ]
كوبول
تتيح لغة كوبول (وكذلك لغة آر بي جي 4 ) للمبرمجين نسخ ملفات النسخ إلى مصدر البرنامج ، وهو ما يشبه تضمين النصوص ولكنه يسمح باستبدالها. الكلمة المفتاحية للتضمين في كوبول هي `include` COPY، ويتم الاستبدال باستخدام REPLACING ... BY ...عبارة `include`. كانت توجيهة `include` موجودة في كوبول منذ الإصدار 60، ولكنها تغيرت من الصيغة الأصلية INCLUDE[ 9 ] إلى الصيغة الجديدة COPYبحلول عام 1968. [ 10 ]
فورتران
لا تتطلب لغة فورتران ملفات رأسية بالمعنى الحرفي . مع ذلك، تتميز فورتران 90 والإصدارات الأحدث بميزتين مرتبطتين: includeالعبارات والوحدات. يمكن استخدام العبارات لمشاركة ملف مشترك يحتوي على واجهات الإجراءات، تمامًا مثل ملف رأس لغة C، مع العلم أن تحديد الواجهة ليس إلزاميًا لجميع أنواع إجراءات فورتران. هذا الأسلوب غير شائع الاستخدام؛ فبدلًا من ذلك، تُجمّع الإجراءات عادةً في وحدات يمكن الرجوع إليها باستخدام useعبارة ضمن أجزاء أخرى من الكود. بالنسبة للوحدات، يُنشئ المُصرّف معلومات واجهة من نوع ملف الرأس تلقائيًا، وتُوضع عادةً في ملفات وحدات منفصلة، مع أن بعض المُصرّفات تضع هذه المعلومات مباشرةً في ملفات الكائنات. لا يُلزم مُواصفات اللغة نفسها بإنشاء أي ملفات إضافية، على الرغم من أن واجهات إجراءات الوحدات تُنشر بهذه الطريقة بشكل شبه عالمي.
هاسكل
لغة هاسكل ، التي يمكنها استخدام المعالج المسبق للغة سي عن طريق كتابة {-# LANGUAGE CPP #-}، لديها إمكانية الوصول إلى #includeالتوجيه.
باسكال
تدعم معظم مترجمات لغة باسكال$i توجيه المترجم or $include، حيث يأتي توجيه $ior $includeمباشرةً بعد بداية كتلة التعليق بالشكل التالي:
{$i ''filename.pas''}(*$i ''filename.inc''*){$include ''filename.inc''}(*include ''filename.pas''*)
حيث لا يُميّز التوجيه $i/ $Iأو $include/ بين الأحرف الكبيرة والصغيرة ، ويكون اسم الملف المراد تضمينه هو filename.pas أو filename.inc . (من الشائع تسمية ملفات التضمين في لغة باسكال بالامتداد .inc ، ولكن هذا ليس شرطًا). بعض المترجمات، لمنع الاستدعاء الذاتي غير المحدود، تحدّ من استدعاء ملف التضمين إلى عدد معين، أو تمنع استدعاء نفسه أو أي ملف مفتوح حاليًا، أو تقتصر على ملف تضمين واحد كحد أقصى في كل مرة، على سبيل المثال، لا يمكن لملف التضمين تضمين نفسه أو ملف آخر. مع ذلك، يمكن للبرنامج الذي يُضمّن ملفات أخرى تضمين عدة ملفات، واحدًا تلو الآخر.$INCLUDE
PHP
في لغة PHP ، includeيؤدي التوجيه إلى تضمين ملف PHP آخر وتقييمه. [ 11 ] توجد أوامر مشابهة require، منها `<file>`، والتي في حال فشل التضمين، تُنتج استثناءً خطيرًا وتوقف البرنامج النصي، [ 12 ] و` <file>` include_onceو` require_once<file>`، والتي تمنع تضمين ملف أو استدعائه مرة أخرى إذا تم تضمينه أو استدعاؤه مسبقًا، متجنبةً بذلك مشكلة التضمين المزدوج في لغة C.
الصدأ
تحتوي لغة Rustinclude! على ماكرو، يعمل بشكل أساسي بنفس طريقة عمله #includeفي لغة C. يقوم بتحليل العنصر إما كتعبير أو كعنصر، اعتمادًا على السياق. [ 13 ]
include! ( "generated_code.rs" );fn main () { // ... استخدم العناصر من generated_code.rs }لكن على عكس لغة C، فإن هذه ليست الطريقة المعتادة لفصل وتضمين التعليمات البرمجية. بدلاً من ذلك، تستخدم لغة Rust الوحدات النمطية ، التي تحافظ على مساحات الأسماء والتغليف.
يدعم Rust أيضًا include_str!ماكرو يسمح بتضمين ملف كامل وتخزينه في سلسلة نصية. [ 14 ] يوجد include_bytes!ماكرو مماثل.
let my_str : & ' static str = include_str! ( "spanish.in" ); let bytes : & ' static [ u8 ] = include_bytes! ( "spanish.in" );لغات أخرى
لغات أخرى بارزة تحتوي على توجيه تضمين:
include...( فورتران ، ماسم )<!--#include ...-->(HTML SSI )var...=require("...");(جافا سكريبت مع CommonJS )<%@include...%>( JSP )%include ...( PL/I )/COPY QCPYLESRC,QBC(لعبة RPG IV - الوسيط الأول هو اسم الملف، والوسيط الثاني هو دفتر النسخ)local...=require("...")( لوا )
تميل اللغات الحديثة (مثل هاسكل وجافا ) إلى تجنب استخدام توجيهات التضمين، مفضلةً الوحدات النمطية ودلالات الاستيراد/التصدير. بعض هذه اللغات (مثل جافا وسي شارب ) لا تستخدم التصريحات المسبقة، وبدلاً من ذلك، يتم التعرف على المعرفات تلقائيًا من ملفات المصدر وقراءتها مباشرةً من رموز المكتبة الديناميكية (التي يُشار إليها عادةً باستخدام توجيهات التضمين importأو usingالاستيراد).
انظر أيضاً
- واجهة برمجة التطبيقات – اتصال بين أجهزة الكمبيوتر أو البرامج. صفحات تعرض أوصافًا مختصرة لأهداف إعادة التوجيه.
- ملف تنفيذ الفئة – ملف يُنفذ أساليب الفئة
- مكتبة C/C++ تعتمد على ملفات الرأس فقط – متوفرة في ملفات رأسية خالصة
- لغة تعريف الواجهة - لغة حاسوبية تُستخدم لوصف واجهة مكون برمجي. صفحات تعرض أوصافًا مختصرة لأهداف إعادة التوجيه.
- ثغرة تضمين الملفات – نوع من أنواع الثغرات الأمنية على الويب
- البرمجة المعيارية – تنظيم الكود في وحدات
- قاعدة التعريف الواحد – قاعدة لغة البرمجة C++
- #pragma once – توجيه C/C++ لمنع تضمين ملفات الرأس بشكل متكرر
- رأس مُجمَّع مسبقًا – نوع مُحسَّن من الملفات في برمجة الحاسوب
- الوحدات (C++) – وحدة ترجمة معيارية في لغة C++
- التضمين – تضمين مجموعة بيانات داخل مجموعة بيانات أخرى تلقائيًا
- بناء Unity – تقنية لتسريع بناء مشاريع C/C++
مراجع
- ↑ معيار C11، 6.10.2 تضمين ملف المصدر، الصفحات 164-165
- ↑ ستالمان، ريتشارد م. (يوليو 1992). "معالج لغة سي المسبق" (ملف PDF) . مؤرشف من الأصل (ملف PDF) في 4 سبتمبر 2012. تم الاطلاع عليه في 19 فبراير 2014 .
- ↑ آلان غريفيث (2005). "فصل الواجهة والتنفيذ في لغة C++" . ACCU . تم الاسترجاع في 7 مايو 2013 .
- ↑ بايك، روب (21 فبراير 1989)، ملاحظات حول البرمجة بلغة C ، أرشيف وثائق Cat-v ، تم استرجاعه في 9 ديسمبر 2011
- ↑ معيار C11، 7.1.2 رؤوس قياسية، ص 181، الحاشية 182: "الرأس ليس بالضرورة ملف مصدر، كما أن
<المحددة>في أسماء الرؤوس ليست بالضرورة أسماء ملفات مصدر صالحة. - ↑ "دمج الوحدات - P1103R3" (PDF) .
- ↑"P1502R1 - Standard library header units for C++20".
- ↑Microsoft Corporation. "#import directive (C++)". learn.microsoft.com. Microsoft Learn. Retrieved 6 December 2025.
- ↑"COBOL Initial Specifications for a COmmon Business Oriented Language"(PDF). Department of Defense. April 1960. p. IX-9. Archived from the original(PDF) on 12 February 2014. Retrieved 11 February 2014.
- ↑"The COPY Statement". CODASYL COBOL Journal of Development 1968. July 1969. LCCN 73601243.
- ↑"include". php.net. The PHP Group. Retrieved 20 February 2014.
- ↑"require". php.net. The PHP Group. Retrieved 20 February 2014.
- ↑"include in std - Rust". doc.rust-lang.org. Retrieved 8 September 2025.
- ↑"include_str in std - Rust". doc.rust-lang.org. Retrieved 4 July 2025.
External links
- Programming constructs
- Source code
- C (programming language) headers
- C (programming language)
- C++
