إعلان
دورة تطوير التطبيقات باستخدام لغة JavaScript في هذه الدورة ستتعلم لغة جافا سكريبت, استخدام مكتبة React.js, بناء API الموقع بواسطة Node.js, تطوير تطبيق جوال باستخدام React Native, و في نهاية الدورة ستتعلم تطوير تطبيق محادثة شبيه بتطبيق WhatsApp. تعلم الآن
دورة تطوير واجهات المستخدم في هذه الدورة ستتعلم لغة HTML و لغة CSS و لغة JavaScript. من ناحية التطبيق العملي ستتعلم طريقة بناء واجهة متجر إلكتروني مكون من ست صفحات, تحويل خمسة تصاميم PSD إلى صفحات ويب, بناء واجهة مستخدم تشبه موقع يوتيوب, بناء لوحة تحكم إحترافية. تعلم الآن
تطوير تطبيقات باستخدام لغة بايثون في هذه الدورة ستتعلم أساسيات البرمجة بلغة بايثون وصولاً إلى التعامل مع أشهر أطر العمل (Flask و Django) و ستتعلم كيف تبني متجر إلكتروني يمكن للمستخدمين البيع و الشراء من خلاله. تعلم الآن
دورة تطوير تطبيقات الويب باستخدام لغة PHP في هذه الدورة ستتعلم لغة PHP من الصفر, استخدام إطار العمل Laravel بشرح مفصّل و عملي, كيفية تطوير شبكة اجتماعية تشبه Instagram, بناء API لتطبيق جوال وفق أسلوب RESTful, تطوير موقع إعلانات مبوبة, تطوير نظام إدارة محتوى CMS كامل. تعلم الآن
دورة تطوير تطبيقات الويب باستخدام لغة Ruby في هذه الدورة ستتعلم البرمجة بلغة Ruby إنطلاقاً من أبسط المفاهيم وحتى بناء تطبيق حقيقي, إستخدام إطار العمل Ruby on Rails بشرح مفصّل و عملي, بناء تطبيق حقيقي عبارة عن شبكة اجتماعية تشبه تويتر, تطوير مجتمع الكتروني يشبه حسوب I/O. تعلم الآن
دورة علوم الحاسوب هذه الدورة معدة لتكون مدخل لعلوم الحاسوب و لغات البرمجة حيث ستتعرف فيها على أنظمة التشغيل و ستتعمق في نظام لينكس و في كيفية التعامل معه من خلال موجه الأوامر, بالإضافة إلى قواعد البيانات و أساسيات الشبكات و الخوادم و مبادئ الحماية والأمان في الويب. تعلم الآن

    الخوارزميات و هياكل البيانات التحدي الأول - الحل بلغة C++

    فكرة المشروع

    لنفترض أننا نريد إنشاء برنامج الهدف منه تخزين مجموعة كتب و من ثم عرضها بشكل مرتب.
    البيانات التي نريد تخزينها هي التالية:

    • المؤلفين: بيانات كل مؤلف ستتضمن (رقم تعرفة, الإسم الكامل, الهاتف, البريد الإلكتروني).
    • الكتب: بيانات كل كتاب ستتضمن (رقم تعرفة, العنوان, تاريخ النشر, رقم الإصدار, مؤلف الكتاب).

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


    الشكل العام لأقسام المشروع


    شرح أقسام المشروع

    Author يمثل أي مؤلف يتم إنشاؤه.
    Book يمثل أي كتاب يتم إنشاؤه.
    Library سيحتوي على كل المؤلفين و الكتب و الدوال التي تسمح بإضافة و حذف مؤلف و كتب.
    add_author(): مهمتها إضافة مؤلف جديد.
    remove_author(): مهمتها حذف مؤلف من خلال id المؤلف الذي نمرره لها عند استدعائها.
    print_author(): مهمتها عرض كل معلومات المؤلف من خلال id المؤلف الذي نمرره لها عند استدعائها.
    print_author_books(): مهمتها عرض إسم المؤلف و أسماء كتبه من خلال id المؤلف الذي نمرره لها عند استدعائها.
    add_book(): مهمتها إضافة كتاب جديد.
    remove_book(): مهمتها حذف كتاب من خلال id الكتاب الذي نمرره لها عند استدعائها.
    print_book(): مهمتها عرض كل معلومات الكتاب و إسم مؤلفه من خلال id الكتاب الذي نمرره لها عند استدعائها.

    قم بتحويل الرسم إلى كود. ثم قم بإنشاء مجموعة كتب و مؤلفين. و قم بتجربة جميع الدوال في البرنامج.


    إرشادات

    المشروع يجب أن يحتوي على 3 كلاسات أساسية هي Author, Book و Library.

    كل كلاس منهم سيكون هناك ملفين في المشروع من أجله:
    - ملف إمتداده .h يمثل الشكل العام لما يحتويه الكلاس.
    - و ملف إمتداده .cpp يمثل طريقة عمل كل شيئ تم وضعه في الملف .h و هذا من قواعد لغة C++.

    ملاحظة: سنقوم بوضع كود الملفين التابعين لنفس الكلاس ( ملف الـ .h و ملف الـ .cpp ) تحت بعضهما حتى نسهّل عليك قراءة الشرح.


    معلومة

    لإعطاء رقم id موحد لكل كائن يتم إنشاؤه, يمكنك تعريف متغير ثابت ( static ) في الكلاس و جعله أيضاً private حتى لا يمكن تعديل قيمته بشكل يدوي من خارج هذا الكلاس. بعدها تقوم فقط بجعل قيمته تزيد 1 كلما قمت بإنشاء كائن من هذا الكلاس و من ثم تضع قيمته في المتغير id.

    ملاحظة: سنقوم بإنشاء متغير نوعه private static إسمه idIncrementer في الكلاس Author و الكلاس Book من أجل هذا الهدف فقط.


    الحل بلغة ++C

    Author.h
    #ifndef AUTHOR_H
    #define AUTHOR_H
    
    #include <string>
    using namespace std;
    
    // الذي يمثل المؤلف Author هنا قمنا بذكر الخصائص, الدوال و الكونستركتور الذي يحتويه الكلاس
    class Author
    {
        public:
    		// هنا قمنا بتحديد شكل كونستركتور الكلاس و الذي سنستخدمه لإسناد قيم للكائن الذي ننشئه من هذا الكلاس بشكل مباشر
            Author(string name, string phone, string email);
    
            // هنا قمنا بتعريف الخصائص الأساسية التي يجب أن يملكها المؤلف
            int id;
            string name;
            string phone;
            string email;
    
        private:
            // لأننا بنفس الوقت نريده أن يكون موحداً private و static قمنا بتعريفه كـ idIncrementer المتغير
            // لجميع الكائنات التي ننشئها من هذا الكلاس و لا يمكن التعامل معه بشكل مباشر من أي كلاس آخر
            static int idIncrementer;
    };
    
    #endif
    		

    Author.cpp
    #include "Author.h"
    
    // idIncrementer هنا قمنا بتحديد القيمة الأولية للثابت
    int Author::idIncrementer = 0;
    
    // Author هنا قمنا بتحديد كيف سيتم إسناد القيم الأولية عند إنشاء كائن من الكلاس
    // id تزيد 1 في كل مرة و من ثم يتم وضعها في الخاصية idIncrementer لاحظ أننا جعلنا قيمة
    // الخاصة بالكائن القيم الأخرى التي سيتم تمريرها للكائن سيتم تخزينها بشكل مباشر في خصائص الكائن
    Author::Author(string name, string phone, string email)
    {
    	idIncrementer++;
    	this->id = idIncrementer;
    	this->name = name;
    	this->phone = phone;
    	this->email = email;
    }
    		

    Book.h
    #ifndef BOOK_H
    #define BOOK_H
    
    #include "Author.h"    // Author حتى نستطيع إنشاء كائن من الكلاس Author.h لاحظ أننا قمنا بتضمين الملف
    #include <string>
    using namespace std;
    
    // الذي يمثل الكتاب Book هنا قمنا بذكر الخصائص, الدوال و الكونستركتور الذي يحتويه الكلاس
    class Book
    {
        public:
    		// هنا قمنا بتحديد شكل كونستركتور الكلاس و الذي سنستخدمه لإسناد قيم للكائن الذي ننشئه من هذا الكلاس بشكل مباشر
            Book(string title, string publishingDate, int version,const Author& author);
    		
            // هنا قمنا بتعريف الخصائص الأساسية التي يجب أن يملكها الكتاب
            int id;
            string title;
            string publishingDate;
            int version;
            Author author;
    
        private:
            // لأننا بنفس الوقت نريده أن يكون موحداً private و static قمنا بتعريفه كـ idIncrementer المتغير
            // لجميع الكائنات التي ننشئها من هذا الكلاس و لا يمكن التعامل معه بشكل مباشر من أي كلاس آخر
            static int idIncrementer;
    };
    
    #endif
    		

    Book.cpp
    #include "Book.h"
    
    // idIncrementer هنا قمنا بتحديد القيمة الأولية للثابت
    int Book::idIncrementer = 0;
    
    // Book هنا قمنا بتحديد كيف سيتم إسناد القيم الأولية عند إنشاء كائن من الكلاس
    // id تزيد 1 في كل مرة و من ثم يتم وضعها في الخاصية idIncrementer لاحظ أننا جعلنا قيمة
    // الخاصة بالكائن القيم الأخرى التي سيتم تمريرها للكائن سيتم تخزينها بشكل مباشر في خصائص الكائن
    Book::Book(string title, string publishingDate, int version, const Author& author):
        author(Author(author.name, author.phone, author.email))
    {
        idIncrementer++;
        this->id = idIncrementer;
        this->title = title;
        this->publishingDate = publishingDate;
        this->version = version;
    }
    		

    Library.h
    #ifndef LIBRARY_H
    #define LIBRARY_H
    
    #include <vector>
    #include "Author.h"    // Author حتى نستطيع إنشاء كائن من الكلاس Author.h لاحظ أننا قمنا بتضمين الملف
    #include "Book.h"      // Book حتى نستطيع إنشاء كائن من الكلاس Book.h كما أننا قمنا بتضمين الملف
    
    // يمثل كل ما تحتويه المكتبة من كتب و مؤلفين و الدوال التي يمكن استخدامها للتعامل معهم Library الكلاس
    class Library
    {
        public:
            // سنضع فيه كل معلومات الكتب books سنضع فيه كل معلومات المؤلفين, و الكائن authors الكائن
            vector<Author> authors;
            vector<Book> books;
    
            void addAuthor(const Author& author);
            void removeAuthor(int id);
            void printAuthor(int id);
            void printAuthorBooks(int id);
            void addBook(const Book& book);
            void removeBook(int id);
            void printBook(int id);
    };
    
    #endif
    		

    Library.cpp
    #include "Library.h"
    #include <iostream>
    #include <stdbool.h>
    
    vector<Author> authors;
    vector<Book> books;
    
    // authors بداخل المصفوفة Author يمكن استخدامها لإضافة كائن من الكلاس addAuthor() الدالة
    void Library::addAuthor(const Author& author)
    {
        authors.push_back(author);
    }
    
    // الخاص به id بالإعتماد على رقم الـ authors موضوع بداخل المصفوفة Author يمكن استخدامها لإلغاء كائن من الكلاس removeAuthor() الدالة
    void Library::removeAuthor(int id)
    {
        // authors بواسطة هذه الحلقة سنمر على جميع الكائنات المخزنة بداخل المصفوفة
        for (unsigned i = 0; i < authors.size(); i++)
        {
            // الذي مررناه للدالة سيتم حذفه و من ثم الخروج من الدالة id الحالي يملك نفس رقم الـ author في حال كان الكائن
            if (authors[i].id == id)
            {
                authors.erase(authors.begin() + i);
                return;
            }
        }
    
        // الذي تم تمريره للدالة سيتم طباعة الجملة التالية id يملك نفس رقم الـ authors في حال لم يتم إيجاد أي كائن في المصفوفة
        cout << "Author with id " << id << " is not found!\n";
        cout << "----------------------\n";
    }
    
    // الخاص به id بالإعتماد على رقم الـ authors يمكن استخدامها لطباعة كل المعلومات المتوفرة حول مؤلف موضوع بداخل المصفوفة printAuthor() الدالة
    void Library::printAuthor(int id)
    {
        // authors بواسطة هذه الحلقة سنمر على جميع الكائنات المخزنة بداخل المصفوفة
        for (unsigned i = 0; i < authors.size(); i++)
        {
            // الذي مررناه للدالة سيتم طباعة كل معلوماته و من ثم الخروج من الدالة id الحالي يملك نفس رقم الـ author في حال كان الكائن
            if (authors[i].id == id)
            {
                cout << "Author with id " << id << " info.\n";
                cout << "Name: " << authors[i].name << "\n";
                cout << "Phone: " << authors[i].phone << "\n";
                cout << "Email: " << authors[i].email << "\n";
                cout << "----------------------\n";
                return;
            }
        }
    
        // الذي تم تمريره للدالة سيتم طباعة الجملة التالية id يملك نفس رقم الـ authors في حال لم يتم إيجاد أي كائن في المصفوفة
        cout << "Author with id " << id << " is not found!\n";
        cout << "----------------------\n";
    }
    
    // الخاص به id بالإعتماد على رقم الـ authors يمكن استخدامها لطباعة كل أسماء الكتب التي قام بتأليفها مؤلف موضوع بداخل المصفوفة printAuthorBooks() الدالة
    void Library::printAuthorBooks(int id)
    {
        // الذي تم تمريره للدالة id يملك رقم الـ authors بهدف التأكد ما إن كان يوجد كاتب في المصفوفة isAuthorExist سنستخدم المتغير
        // من إعداد هذا الكاتب لأن ذلك سيكون غير منطقي books لأنه إن لم يكن هناك كاتب أصلاً فلن نقوم بالبحث عن كتب في المصفوفة
        bool isAuthorExist = false;
        string authorName = "";
    
         // authors بواسطة هذه الحلقة سنمر على جميع الكائنات المخزنة بداخل المصفوفة
        for (unsigned i = 0; i < authors.size(); i++)
        {
            // authorName الذي مررناه للدالة سيتم تخزين إسم المؤلف في المتغير id الحالي يملك نفس رقم الـ author في حال كان الكائن
            // authors و إيقاف الحلقة لأننا تأكدنا أن هذا المؤلف موجود في المصفوفة true إلى isAuthorExist و من ثم تغيير قيمة
            if (authors[i].id == id)
            {
                isAuthorExist = true;
                authorName = authors[i].name;
                break;
            }
        }
    
        // authors فهذا يعني أنه لم يتم إيجاد أي كائن في المصفوفة false تساوي isAuthorExist في حال بقيت قيمة
        // الذي تم تمريره للدالة سيتم طباعة الجملة التالية و الخروج من الدالة id يملك نفس رقم الـ
        if (!isAuthorExist)
        {
            cout << "Author with id " << id << " is not found!\n";
            cout << "----------------------\n";
            return;
        }
    
        // هنا سيتم طباعة إسم المؤلف
        cout << "Books of author " << authorName << ":\n";
    
        // books بواسطة هذه الحلقة سنمر على جميع الكائنات المخزنة بداخل المصفوفة
        for (unsigned i = 0; i < books.size(); i++)
        {
            // الذي تم تمريره id يملك نفس رقم الـ book ( أي المؤلف ) الحالي الموضوع في الكائن author في حال كان الكائن
            // و بالتالي سيتم طباعة إسم هذا الكتاب book للدالة فهذا يعني أنه هو مؤلف الكتاب الحالي المخزن في الكائن
            if (books[i].author.id == id)
            {
                cout << "- " << books[i].title << "\n";
            }
        }
    
        cout << "----------------------\n";
    }
    
    // books بداخل المصفوفة Book يمكن استخدامها لإضافة كائن من الكلاس addBook() الدالة
    void Library::addBook(const Book& book)
    {
        books.push_back(book);
    }
    
    // الخاص به id بالإعتماد على رقم الـ books موضوع بداخل المصفوفة Book يمكن استخدامها لإلغاء كائن من الكلاس removeBook() الدالة
    void Library::removeBook(int id)
    {
        // books بواسطة هذه الحلقة سنمر على جميع الكائنات المخزنة بداخل المصفوفة
        for (unsigned i = 0; i < books.size(); i++)
        {
            // الذي مررناه للدالة سيتم حذفه و من ثم الخروج من الدالة id الحالي نفس رقم الـ book في حال كان الكائن
            if (books[i].id == id)
            {
                books.erase(books.begin() + i);
                return;
            }
        }
    
        // الذي تم تمريره للدالة سيتم طباعة الجملة التالية id يملك نفس رقم الـ books في حال لم يتم إيجاد أي كائن في المصفوفة
        cout << "Book with id " << id << " is not found!\n";
        cout << "----------------------\n";
    }
    
    // الخاص به id بالإعتماد على رقم الـ books يمكن استخدامها لطباعة كل المعلومات المتوفرة حول كتاب موضوع بداخل المصفوفة printBook() الدالة
    void Library::printBook(int id)
    {
        // books بواسطة هذه الحلقة سنمر على جميع الكائنات المخزنة بداخل المصفوفة
        for (unsigned i = 0; i < books.size(); i++)
        {
            // الذي مررناه للدالة سيتم طباعة كل معلوماته و من ثم الخروج من الدالة id الحالي يملك نفس رقم الـ book في حال كان الكائن
            if (books[i].id == id)
            {
                cout << "Book with id " << id << " info.\n";
                cout << "Title: " << books[i].title << "\n";
                cout << "Version: " << books[i].version << "\n";
                cout << "Publishing date: " << books[i].publishingDate << "\n";
                cout << "Author: " << books[i].author.name << "\n";
                cout << "----------------------\n";
                return;
            }
        }
    
        // الذي تم تمريره للدالة سيتم طباعة الجملة التالية id يملك نفس رقم الـ books في حال لم يتم إيجاد أي كائن في المصفوفة
        cout << "Book with id " << id << " is not found!\n";
        cout << "----------------------\n";
    }
    		

    main.cpp
    #include <iostream>
    
    // هنا قمنا بتضمين كل الكلاسات التي أنشأناها لأننا سننشئ كائنات منها
    #include "Author.h"
    #include "Book.h"
    #include "Library.h"
    
    using namespace std;
    
    int main()
    {
    	// أي كأننا قمنا بإنشاء 3 مؤلفين Author هنا قمنا بإنشاء 3 كائنات من الكلاس
    	Author author1("Mhamad", "+96170123456", "mhamad@gmail.com");
    	Author author2("Salem",  "+9664021833",  "salem@gmail.com");
    	Author author3("Rola",   "+9631249392",  "rola@gmail.com");
    
    	// أي كأننا قمنا بإنشاء 4 كتب Book هنا قمنا بإنشاء 4 كائنات من الكلاس
    	// Book وضعناه لكائنين من الكلاس author1 لاحظ أننا وضعنا الثلاث مؤلفين بداخل الكتب التي أنشأناها. و لاحظ أن الكائن
    	// book2 و book1 يعتبر مؤلف الكتابين اللذين يمثلهما الكائنين author1 إذاً المؤلف الذي يمثله الكائن
    	Book book1("Learn Java", "12-20-2019", 1, author1);
    	Book book2("Learn HTML", "8-5-2018", 3, author1);
    	Book book3("PHP for beginners", "10-2-2019", 1, author2);
    	Book book4("C# for dummies", "12-20-2019", 1, author3);
    
    	// لأننا نريد تخزين الكتب و المؤلفين بشكل مرتب بداخله Library هنا قمنا بإنشاء كائن من الكلاس
    	Library library;
    
    	// addAuthor() بواسطة الدالة library التي يمكلها الكائن authors هنا قمنا بإضافة المؤلفين في المصفوفة
    	library.addAuthor(author1);
    	library.addAuthor(author2);
    	library.addAuthor(author3);
    
    	// addBook() بواسطة الدالة library التي يمكلها الكائن books هنا قمنا بإضافة الكتب في المصفوفة
    	library.addBook(book1);
    	library.addBook(book2);
    	library.addBook(book3);
    	library.addBook(book4);
    
    	// printAuthor() الخاص بهم و بواسطة الدالة id هنا قمنا بطباعة معلومات كل المؤلفين بالإعتماد على رقم التعرفة
    	// تذكر: رقم التعرفة الخاص بكل مؤلف تم إنشاؤه بشكل تلقائي عند إنشاء كل مؤلف بداخل الكونستركتور
    	library.printAuthor(1);
    	library.printAuthor(2);
    	library.printAuthor(3);
    
    	// printBook() الخاص بهم و بواسطة الدالة id هنا قمنا بطباعة معلومات كل الكتب بالإعتماد على رقم التعرفة
    	// تذكر: رقم التعرفة الخاص بكل كتاب تم إنشاؤه بشكل تلقائي عند إنشاء كل كتاب بداخل الكونستركتور
    	library.printBook(1);
    	library.printBook(2);
    	library.printBook(3);
    	library.printBook(4);
    
    	// printAuthorBooks() الخاص بهم و بواسطة الدالة id هنا قمنا بطباعة الكتب التي يملكها كل مؤلف بالإعتماد على رقم التعرفة
    	library.printAuthorBooks(1);
    	library.printAuthorBooks(2);
    	library.printAuthorBooks(3);
    
    	// removeAuthor() هنا قمنا بحذف المؤلف الذي يملك رقم التعرفة 2 بواسطة الدالة
    	// printAuthorBooks() و printAuthor() بعدها حاولنا طباعة معلوماته و الكتب التي قام بتأليفها بواسطة الدالة
    	// لاحظ أنه لم يحدث أي خطأ عند محاولة طباعة معلومات مؤلف لم يعد موجوداً لأن الدوال مصممة للتأكد قبل المحاولة الحذف
    	library.removeAuthor(2);
    	library.printAuthor(2);
    	library.printAuthorBooks(2);
    
    	char end; std::cin >> end;
        return 0;
    }
    		

    سنحصل على النتيجة التالية عند التشغيل.

    Author with id 1 info.   --> الموضوعة في السطر 41 printAuthor() تم عرض هذا المحتوى بسبب استدعاء الدالة
    Name: Mhamad
    Phone: +96170123456
    Email: mhamad@gmail.com
    ----------------------
    Author with id 2 info.   --> الموضوعة في السطر 42 printAuthor() تم عرض هذا المحتوى بسبب استدعاء الدالة
    Name: Salem
    Phone: +9664021833
    Email: salem@gmail.com
    ----------------------   --> الموضوعة في السطر 43 printAuthor() تم عرض هذا المحتوى بسبب استدعاء الدالة
    Author with id 3 info.
    Name: Rola
    Phone: +9631249392
    Email: rola@gmail.com
    ----------------------
    Book with id 1 info.   --> الموضوعة في السطر 47 printBook() تم عرض هذا المحتوى بسبب استدعاء الدالة
    Title: Learn Java
    Version: 1
    Publishing date: 12-20-2019
    author in Mhamad
    ----------------------
    Book with id 2 info.   --> الموضوعة في السطر 48 printBook() تم عرض هذا المحتوى بسبب استدعاء الدالة
    Title: Learn HTML
    Version: 3
    Publishing date: 8-5-2018
    author in Mhamad
    ----------------------
    Book with id 3 info.   --> الموضوعة في السطر 49 printBook() تم عرض هذا المحتوى بسبب استدعاء الدالة
    Title: PHP for beginners
    Version: 1
    Publishing date: 10-2-2019
    author in Salem
    ----------------------
    Book with id 4 info.   --> الموضوعة في السطر 50 printBook() تم عرض هذا المحتوى بسبب استدعاء الدالة
    Title: C# for dummies
    Version: 1
    Publishing date: 12-20-2019
    author in Rola
    ----------------------
    Books of author Mhamad:   --> الموضوعة في السطر 53 printAuthorBooks() تم عرض هذا المحتوى بسبب استدعاء الدالة
    - Learn Java
    - Learn HTML
    ----------------------
    Books of author Salem:   --> الموضوعة في السطر 54 printAuthorBooks() تم عرض هذا المحتوى بسبب استدعاء الدالة
    - PHP for beginners
    ----------------------
    Books of author Rola:   --> الموضوعة في السطر 55 printAuthorBooks() تم عرض هذا المحتوى بسبب استدعاء الدالة
    - C# for dummies
    ----------------------
    Author with id 2 is not found!   --> الموضوعة في السطر 61 printAuthor() تم عرض هذا المحتوى بسبب استدعاء الدالة
    ----------------------
    Author with id 2 is not found!   --> الموضوعة في السطر 62 printAuthorBooks() تم عرض هذا المحتوى بسبب استدعاء الدالة
    ----------------------
    إعلان

    Eqla3Tech.com

    شروحات مكتوبة حول لغات البرمجة و تقنية المعلومات باللغة العربية مقدمة من إقلاع تك.

    لغة جافا لغة ++C قواعد البيانات نظام ويندوز نظام لينكس الشبكات تقنية المعلومات الأمن السيبراني

    الدورات

    أدوات مساعدة

    الأقسام

    دورات
    مقالات أسئلة مشاريع كتب