مقدمة عن C++

ما هي C++؟

C++ هي لغة برمجة متعددة النماذج طورها Bjarne Stroustrup في Bell Labs كامتداد للغة C. تدعم البرمجة الإجرائية والكائنية والوظيفية.

تاريخ C++:

تم تطوير C++ في أوائل الثمانينيات. كانت تسمى في البداية "C with Classes" ثم أصبحت C++ في عام 1983. الاسم C++ يأتي من معامل الزيادة ++ في C.

مميزات C++:
  • أداء عالي: كود مترجم مباشرة إلى machine code
  • البرمجة الكائنية: دعم كامل لـ OOP
  • مرونة: تدعم عدة نماذج برمجية
  • قوية: تحكم كامل بالذاكرة والأجهزة
  • مكتبة قياسية غنية: STL (Standard Template Library)
مجالات استخدام C++:
  • أنظمة التشغيل
  • الألعاب (Game Development)
  • أنظمة الوقت الفعلي (Real-time Systems)
  • قواعد البيانات
  • المتصفحات
  • الذكاء الاصطناعي
الفرق بين C و C++:
  • C++ تدعم البرمجة الكائنية، C لا تدعم
  • C++ تحتوي على namespace و classes
  • C++ تحتوي على string class، C تستخدم char arrays
  • C++ تدعم function overloading، C لا تدعم

تثبيت بيئة العمل

متطلبات بيئة العمل:

لبدء البرمجة بـ C++، تحتاج إلى مترجم (Compiler) وبيئة تطوير (IDE).

1. المترجمان:
  • GCC/G++: الأكثر استخداماً، مجاني
  • MinGW: نسخة Windows من GCC
  • Clang: مترجم حديث من LLVM
  • MSVC: من Microsoft (جزء من Visual Studio)
2. بيئات التطوير:
  • Code::Blocks: مجاني ومفتوح المصدر
  • Visual Studio: من Microsoft (مجاني للاستخدام الشخصي)
  • CLion: من JetBrains (مدفوع)
  • Dev-C++: بسيط للمبتدئين
  • VS Code: محرر نصوص مع إضافات C++
3. تثبيت MinGW على Windows:
  1. قم بتحميل MinGW-w64
  2. ثبت الملفات
  3. أضف مسار bin إلى PATH
  4. تحقق: g++ --version
4. التحقق من التثبيت:
g++ --version
g++ -v

أول برنامج C++

بنية برنامج C++:

كل برنامج C++ يبدأ من دالة main() وهي نقطة البداية لتنفيذ البرنامج.

مثال Hello World:
#include <iostream>
using namespace std;

int main() {
    cout << "مرحباً بكم في C++!" << endl;
    cout << "هذا أول برنامج لي" << endl;
    return 0;
}
شرح الكود:
  • #include <iostream>: تضمين مكتبة الإدخال/الإخراج
  • using namespace std;: استخدام namespace القياسي
  • int main(): دالة رئيسية، نقطة البداية
  • cout: للطباعة (console output)
  • <<: معامل الإدخال
  • endl: نهاية السطر (end line)
  • return 0;: إنهاء البرنامج بنجاح
بدون using namespace:
#include <iostream>

int main() {
    std::cout << "مرحباً!" << std::endl;
    return 0;
}
خطوات التشغيل:
  1. احفظ الكود في ملف hello.cpp
  2. افتح Terminal
  3. قم بالتجميع: g++ hello.cpp -o hello
  4. قم بالتشغيل: ./hello (Linux/Mac) أو hello.exe (Windows)

المتغيرات وأنواع البيانات

أنواع البيانات في C++:

C++ تدعم أنواع بيانات أساسية (Primitive) وأنواع بيانات مرجعية (Reference).

أنواع البيانات الأساسية:
النوع الحجم الوصف مثال
int 4 bytes عدد صحيح int age = 25;
float 4 bytes عدد عشري (دقة بسيطة) float price = 99.99f;
double 8 bytes عدد عشري (دقة عالية) double salary = 5000.50;
char 1 byte حرف واحد char grade = 'A';
bool 1 byte true أو false bool isActive = true;
string متغير نص (من مكتبة string) string name = "أحمد";
تعريف المتغيرات:
#include <iostream>
#include <string>
using namespace std;

int main() {
    // تعريف متغيرات
    int age = 25;
    float price = 99.99f;
    double salary = 5000.50;
    char grade = 'A';
    bool isActive = true;
    string name = "أحمد";
    
    // عرض القيم
    cout << "الاسم: " << name << endl;
    cout << "العمر: " << age << endl;
    cout << "السعر: " << price << endl;
    cout << "الراتب: " << salary << endl;
    cout << "الدرجة: " << grade << endl;
    cout << "نشط: " << (isActive ? "نعم" : "لا") << endl;
    
    return 0;
}
Type Modifiers:
  • short: عدد صحيح قصير
  • long: عدد صحيح طويل
  • unsigned: بدون إشارة (موجب فقط)
  • signed: مع إشارة (افتراضي)

العمليات والمعاملات

المعاملات في C++:

1. المعاملات الحسابية:
int a = 10, b = 3;
cout << a + b << endl;  // 13 (الجمع)
cout << a - b << endl;  // 7 (الطرح)
cout << a * b << endl;  // 30 (الضرب)
cout << a / b << endl;  // 3 (القسمة)
cout << a % b << endl;  // 1 (الباقي)
2. معاملات التعيين:
int x = 10;
x += 5;  // x = x + 5
x -= 3;  // x = x - 3
x *= 2;  // x = x * 2
x /= 4;  // x = x / 4
3. معاملات المقارنة:
int x = 5, y = 10;
cout << (x == y) << endl;  // 0 (false)
cout << (x != y) << endl;  // 1 (true)
cout << (x < y) << endl;   // 1 (true)
cout << (x > y) << endl;   // 0 (false)
4. معاملات منطقية:
bool a = true, b = false;
cout << (a && b) << endl;  // 0 (AND)
cout << (a || b) << endl;  // 1 (OR)
cout << (!a) << endl;      // 0 (NOT)

عبارات التحكم

عبارات if-else:

int age = 18;
if (age >= 18) {
    cout << "يمكنك التصويت" << endl;
} else {
    cout << "لا يمكنك التصويت" << endl;
}
if-else if-else:
int score = 85;
if (score >= 90) {
    cout << "ممتاز" << endl;
} else if (score >= 80) {
    cout << "جيد جداً" << endl;
} else if (score >= 70) {
    cout << "جيد" << endl;
} else {
    cout << "يحتاج تحسين" << endl;
}
عبارة switch-case:
int day = 3;
switch (day) {
    case 1:
        cout << "الاثنين" << endl;
        break;
    case 2:
        cout << "الثلاثاء" << endl;
        break;
    case 3:
        cout << "الأربعاء" << endl;
        break;
    default:
        cout << "يوم آخر" << endl;
}

الحلقات

حلقة for:

for (int i = 1; i <= 10; i++) {
    cout << i << " ";
}
// الناتج: 1 2 3 4 5 6 7 8 9 10
حلقة while:
int i = 1;
while (i <= 10) {
    cout << i << " ";
    i++;
}
حلقة do-while:
int i = 1;
do {
    cout << i << " ";
    i++;
} while (i <= 10);
break و continue:
for (int i = 1; i <= 10; i++) {
    if (i == 5) break;  // يخرج من الحلقة
    if (i % 2 == 0) continue;  // يتخطى التكرار الحالي
    cout << i << " ";
}
// الناتج: 1 3

المصفوفات

تعريف المصفوفات:

int numbers[5] = {1, 2, 3, 4, 5};
int arr[10];  // مصفوفة فارغة
الوصول للعناصر:
int arr[5] = {10, 20, 30, 40, 50};
cout << arr[0] << endl;  // 10
cout << arr[2] << endl;  // 30
arr[1] = 25;  // تعديل قيمة
حلقة مع المصفوفات:
int arr[5] = {1, 2, 3, 4, 5};
for (int i = 0; i < 5; i++) {
    cout << arr[i] << " ";
}
مصفوفات متعددة الأبعاد:
int matrix[3][3] = {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9}
};
cout << matrix[1][1] << endl;  // 5

النصوص

استخدام string class:

#include <string>
using namespace std;

string name = "أحمد";
string greeting = "مرحباً";
عمليات على النصوص:
string str1 = "مرحباً";
string str2 = " العالم";
string result = str1 + str2;  // "مرحباً العالم"

cout << result.length() << endl;  // طول النص
cout << result[0] << endl;  // أول حرف
دوال مفيدة:
string text = "Hello World";
text.append("!");  // إضافة نص
text.insert(5, " C++");  // إدراج نص
text.erase(0, 6);  // حذف جزء
text.replace(0, 5, "Hi");  // استبدال

الدوال

تعريف الدوال:

int add(int a, int b) {
    return a + b;
}

int main() {
    int result = add(5, 3);
    cout << result << endl;  // 8
    return 0;
}
دوال void:
void greet(string name) {
    cout << "مرحباً " << name << endl;
}

int main() {
    greet("أحمد");
    return 0;
}
Default Parameters:
void print(int x = 10) {
    cout << x << endl;
}

int main() {
    print();  // 10
    print(20);  // 20
    return 0;
}

Overloading

Function Overloading:

يمكن تعريف عدة دوال بنفس الاسم ولكن بمعاملات مختلفة.

int add(int a, int b) {
    return a + b;
}

double add(double a, double b) {
    return a + b;
}

int add(int a, int b, int c) {
    return a + b + c;
}

int main() {
    cout << add(5, 3) << endl;  // 8
    cout << add(5.5, 3.2) << endl;  // 8.7
    cout << add(1, 2, 3) << endl;  // 6
    return 0;
}

البرمجة الكائنية - المقدمة

مفاهيم OOP:

  • Class: قالب لإنشاء الكائنات
  • Object: مثال من الكلاس
  • Encapsulation: إخفاء البيانات
  • Inheritance: الوراثة
  • Polymorphism: تعدد الأشكال
مثال بسيط:
class Car {
public:
    string brand;
    int year;
    
    void display() {
        cout << brand << " " << year << endl;
    }
};

int main() {
    Car myCar;
    myCar.brand = "Toyota";
    myCar.year = 2023;
    myCar.display();
    return 0;
}

Classes و Objects

تعريف Class:

class Student {
private:
    string name;
    int age;
    
public:
    void setName(string n) {
        name = n;
    }
    
    void setAge(int a) {
        age = a;
    }
    
    void display() {
        cout << "الاسم: " << name << ", العمر: " << age << endl;
    }
};

int main() {
    Student s1;
    s1.setName("أحمد");
    s1.setAge(20);
    s1.display();
    return 0;
}

Constructors و Destructors

Constructor:

class Person {
private:
    string name;
    int age;
    
public:
    Person(string n, int a) {
        name = n;
        age = a;
        cout << "تم إنشاء كائن" << endl;
    }
    
    ~Person() {
        cout << "تم حذف الكائن" << endl;
    }
    
    void display() {
        cout << name << " " << age << endl;
    }
};

int main() {
    Person p("أحمد", 25);
    p.display();
    return 0;
}

Inheritance

الوراثة:

class Animal {
public:
    void eat() {
        cout << "الحيوان يأكل" << endl;
    }
};

class Dog : public Animal {
public:
    void bark() {
        cout << "الكلب ينبح" << endl;
    }
};

int main() {
    Dog d;
    d.eat();  // من Animal
    d.bark();  // من Dog
    return 0;
}

Polymorphism

Virtual Functions:

class Shape {
public:
    virtual void draw() {
        cout << "رسم شكل" << endl;
    }
};

class Circle : public Shape {
public:
    void draw() override {
        cout << "رسم دائرة" << endl;
    }
};

class Rectangle : public Shape {
public:
    void draw() override {
        cout << "رسم مستطيل" << endl;
    }
};

int main() {
    Shape* s1 = new Circle();
    Shape* s2 = new Rectangle();
    s1->draw();  // رسم دائرة
    s2->draw();  // رسم مستطيل
    return 0;
}

Encapsulation

Access Modifiers:

class BankAccount {
private:
    double balance;
    
public:
    void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
        }
    }
    
    double getBalance() {
        return balance;
    }
};

int main() {
    BankAccount account;
    account.deposit(1000);
    cout << account.getBalance() << endl;
    return 0;
}

Friend Functions

Friend Keyword:

class Box {
private:
    int width;
    
public:
    Box(int w) : width(w) {}
    
    friend void printWidth(Box b);
};

void printWidth(Box b) {
    cout << "العرض: " << b.width << endl;
}

int main() {
    Box b(10);
    printWidth(b);
    return 0;
}

Operator Overloading

Overloading Operators:

class Vector {
private:
    int x, y;
    
public:
    Vector(int x, int y) : x(x), y(y) {}
    
    Vector operator+(const Vector& other) {
        return Vector(x + other.x, y + other.y);
    }
    
    void display() {
        cout << "(" << x << ", " << y << ")" << endl;
    }
};

int main() {
    Vector v1(1, 2);
    Vector v2(3, 4);
    Vector v3 = v1 + v2;
    v3.display();  // (4, 6)
    return 0;
}

Templates

Function Templates:

template <typename T>
T getMax(T a, T b) {
    return (a > b) ? a : b;
}

int main() {
    cout << getMax(10, 20) << endl;  // 20
    cout << getMax(3.5, 2.8) << endl;  // 3.5
    return 0;
}
Class Templates:
template <class T>
class Stack {
private:
    T items[100];
    int top;
    
public:
    Stack() : top(-1) {}
    
    void push(T item) {
        items[++top] = item;
    }
    
    T pop() {
        return items[top--];
    }
};

int main() {
    Stack<int> intStack;
    intStack.push(10);
    cout << intStack.pop() << endl;
    return 0;
}

STL - المقدمة

Standard Template Library:

STL هي مجموعة من القوالب الجاهزة في C++ توفر هياكل بيانات وخوارزميات.

مكونات STL:
  • Containers: vector, list, map, set
  • Iterators: للتنقل في الحاويات
  • Algorithms: sort, find, count

Vector و List

Vector:

#include <vector>
#include <list>

vector<int> vec;
vec.push_back(10);
vec.push_back(20);
vec.push_back(30);

for (int i = 0; i < vec.size(); i++) {
    cout << vec[i] << " ";
}
List:
list<int> myList;
myList.push_back(1);
myList.push_front(0);

for (auto it = myList.begin(); it != myList.end(); it++) {
    cout << *it << " ";
}

Map و Set

Map:

#include <map>
#include <set>

map<string, int> ages;
ages["أحمد"] = 25;
ages["محمد"] = 30;

cout << ages["أحمد"] << endl;  // 25
Set:
set<int> numbers;
numbers.insert(10);
numbers.insert(20);
numbers.insert(10);  // لن يُضاف (مكرر)

for (int n : numbers) {
    cout << n << " ";
}

File Handling

قراءة وكتابة الملفات:

#include <fstream>

// الكتابة
ofstream outFile("data.txt");
outFile << "مرحباً بالعالم" << endl;
outFile.close();

// القراءة
ifstream inFile("data.txt");
string line;
while (getline(inFile, line)) {
    cout << line << endl;
}
inFile.close();

Exception Handling

try-catch:

#include <stdexcept>

int divide(int a, int b) {
    if (b == 0) {
        throw runtime_error("القسمة على صفر!");
    }
    return a / b;
}

int main() {
    try {
        int result = divide(10, 0);
        cout << result << endl;
    } catch (exception& e) {
        cout << "خطأ: " << e.what() << endl;
    }
    return 0;
}

Smart Pointers

unique_ptr و shared_ptr:

#include <memory>

// unique_ptr
unique_ptr<int> ptr1 = make_unique<int>(10);

// shared_ptr
shared_ptr<int> ptr2 = make_shared<int>(20);
shared_ptr<int> ptr3 = ptr2;  // مشاركة نفس الكائن

cout << *ptr1 << endl;
cout << *ptr2 << endl;

Lambda Expressions

Lambda Functions:

auto add = [](int a, int b) {
    return a + b;
};

cout << add(5, 3) << endl;  // 8

// مع capture
int x = 10;
auto multiply = [x](int y) {
    return x * y;
};

cout << multiply(5) << endl;  // 50

مشروع متوسط

نظام إدارة طلاب:

#include <iostream>
#include <vector>
#include <string>

class Student {
private:
    string name;
    int id;
    double gpa;
    
public:
    Student(string n, int i, double g) : name(n), id(i), gpa(g) {}
    
    void display() {
        cout << "الاسم: " << name << ", الرقم: " << id << ", المعدل: " << gpa << endl;
    }
    
    double getGPA() { return gpa; }
};

class StudentManager {
private:
    vector<Student> students;
    
public:
    void addStudent(Student s) {
        students.push_back(s);
    }
    
    void displayAll() {
        for (auto& s : students) {
            s.display();
        }
    }
};

int main() {
    StudentManager manager;
    manager.addStudent(Student("أحمد", 1, 3.5));
    manager.addStudent(Student("محمد", 2, 3.8));
    manager.displayAll();
    return 0;
}

Best Practices

أفضل الممارسات:

  • استخدم const: للقيم التي لا تتغير
  • تجنب using namespace std: في ملفات الـ headers
  • استخدم Smart Pointers: بدلاً من raw pointers
  • استخدم STL: بدلاً من المصفوفات العادية
  • معالجة الأخطاء: استخدم try-catch
  • التعليقات: اكتب تعليقات واضحة
  • أسماء متغيرات: استخدم أسماء وصفية

مشروع تطبيقي كامل

نظام مكتبة:

#include <iostream>
#include <vector>
#include <string>
#include <map>

class Book {
private:
    string title;
    string author;
    bool available;
    
public:
    Book(string t, string a) : title(t), author(a), available(true) {}
    
    string getTitle() { return title; }
    bool isAvailable() { return available; }
    void borrow() { available = false; }
    void returnBook() { available = true; }
};

class Library {
private:
    map<string, Book> books;
    
public:
    void addBook(string isbn, Book b) {
        books[isbn] = b;
    }
    
    void borrowBook(string isbn) {
        if (books.find(isbn) != books.end() && books[isbn].isAvailable()) {
            books[isbn].borrow();
            cout << "تم استعارة الكتاب" << endl;
        } else {
            cout << "الكتاب غير متاح" << endl;
        }
    }
    
    void displayAvailable() {
        for (auto& pair : books) {
            if (pair.second.isAvailable()) {
                cout << pair.second.getTitle() << endl;
            }
        }
    }
};

int main() {
    Library lib;
    lib.addBook("001", Book("C++ Programming", "Author1"));
    lib.addBook("002", Book("Data Structures", "Author2"));
    lib.borrowBook("001");
    lib.displayAvailable();
    return 0;
}