Skip to content

🔄 Цикли, Вложени цикли, Функции и Низове в езика C++

🔄 Цикли

Циклите в C++ позволяват изпълнението на един и същи блок от код множество пъти. Те се използват за работа с повторения и итерации върху структури от данни.

Видове цикли:

  1. for цикъл:
    Използва се, когато броят на итерациите е известен предварително.
#include <iostream>
using namespace std;

int main() {
    for (int i = 0; i < 5; i++) {
        cout << "Итерация: " << i << endl;
    }
    return 0;
}
  1. while цикъл: Използва се, когато не знаем предварително колко итерации ще са нужни.

    #include <iostream>
    using namespace std;
    
    int main() {
        int i = 0;
        while (i < 5) {
            cout << "Итерация: " << i << endl;
            i++;
        }
        return 0;
    }
    

  2. do-while цикъл: Гарантира изпълнението на блока поне веднъж, дори ако условието е невярно.

        #include <iostream>
        using namespace std;
    
        int main() {
            int i = 0;
            do {
                cout << "Итерация: " << i << endl;
                i++;
            } while (i < 5);
            return 0;
        }
    

🔁 Вложени цикли

Вложените цикли са цикли, които се намират вътре в други цикли. Те са полезни за работа с двумерни структури, като матрици. Пример:

#include <iostream>
using namespace std;

int main() {
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            cout << "i: " << i << ", j: " << j << endl;
        }
    }
    return 0;
}

Резултат:

i: 0, j: 0
i: 0, j: 1
i: 0, j: 2
...
i: 2, j: 2

🔧 Функции в C++

Функциите позволяват разделяне на програмата на по-малки модули, което прави кода по-организиран и лесен за поддръжка.

Дефиниране на функция:

#include <iostream>
using namespace std;

// Дефиниране на функция
int add(int a, int b) {
    return a + b;
}

int main() {
    int result = add(5, 7);
    cout << "Резултат: " << result << endl;
    return 0;
}

Видове функции:

  • Функции без аргументи и връщана стойност:

    void greet() {
        cout << "Здравей, свят!" << endl;
    }
    

  • Функции с аргументи:

    void printNumber(int num) {
        cout << "Число: " << num << endl;
    }
    

  • Функции с връщана стойност:

      int square(int x) {
          return x * x;
      }
    

📝 Низове

Низовете са последователности от символи. В C++ има два основни типа низове:

C-style низове (масиви от символи):

#include <iostream>
using namespace std;

int main() {
    char str[] = "Здравей";
    cout << str << endl;
    return 0;
}

Стандартни низове (std::string):

    #include <iostream>
    #include <string>
    using namespace std;

    int main() {
        string greeting = "Здравей, свят!";
        cout << greeting << endl;
        return 0;
    }

Основни операции с низове:

  • Конкатенация:

    string first = "Здравей";
    string second = " свят";
    string result = first + second;
    cout << result << endl; // Здравей свят
    

  • Дължина на низ:

    string text = "Програмиране";
    cout << "Дължина: " << text.length() << endl;
    

  • Достъп до символи:

    string word = "C++";
    cout << word[0] << endl; // C
    

4. Range-based for цикъл (C++11)

Модерен и удобен синтаксис за обхождане на контейнери:

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> numbers = {1, 2, 3, 4, 5};

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

    // За модификация на елементите използваме референция
    for (int& num : numbers) {
        num *= 2;
    }

    return 0;
}

5. break и continue

  • break: Прекратява изпълнението на цикъла
  • continue: Пропуска текущата итерация и преминава към следващата
// Пример с break
for (int i = 1; i <= 10; i++) {
    if (i == 5) break; // Спира при i = 5
    cout << i << " ";
}
// Изход: 1 2 3 4

// Пример с continue
for (int i = 1; i <= 5; i++) {
    if (i == 3) continue; // Пропуска 3
    cout << i << " ";
}
// Изход: 1 2 4 5

🎯 Практически задачи с цикли

Сума на числата от 1 до N

int sumToN(int n) {
    int sum = 0;
    for (int i = 1; i <= n; i++) {
        sum += i;
    }
    return sum;
    // По-бързо: return n * (n + 1) / 2;
}

Факториел

long long factorial(int n) {
    long long result = 1;
    for (int i = 2; i <= n; i++) {
        result *= i;
    }
    return result;
}

Числа на Фибоначи

void fibonacci(int n) {
    long long a = 0, b = 1;

    for (int i = 0; i < n; i++) {
        cout << a << " ";
        long long next = a + b;
        a = b;
        b = next;
    }
}

Проверка за палиндром (с цикли)

bool isPalindrome(string s) {
    int left = 0, right = s.length() - 1;

    while (left < right) {
        if (s[left] != s[right]) {
            return false;
        }
        left++;
        right--;
    }
    return true;
}

🔁 Вложени цикли - Разширени приложения

Отпечатване на шаблони (Pattern printing)

// Триъгълник от звездички
void printTriangle(int n) {
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= i; j++) {
            cout << "* ";
        }
        cout << endl;
    }
}

// Диамант
void printDiamond(int n) {
    // Горна половина
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n - i; j++) cout << " ";
        for (int j = 1; j <= 2 * i - 1; j++) cout << "*";
        cout << endl;
    }
    // Долна половина
    for (int i = n - 1; i >= 1; i--) {
        for (int j = 1; j <= n - i; j++) cout << " ";
        for (int j = 1; j <= 2 * i - 1; j++) cout << "*";
        cout << endl;
    }
}

Таблица за умножение

void multiplicationTable(int n) {
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            cout << i * j << "\t";
        }
        cout << endl;
    }
}

🔧 Функции - Разширени концепции

Предаване по стойност vs по референция

// По стойност - създава копие
void incrementValue(int x) {
    x++; // Променя само копието
}

// По референция - работи с оригинала
void incrementReference(int& x) {
    x++; // Променя оригиналната променлива
}

int main() {
    int a = 5;
    incrementValue(a);
    cout << a << endl; // 5 (не се променя)

    incrementReference(a);
    cout << a << endl; // 6 (променена)
}

Функции с подразбиращи се стойности

int power(int base, int exp = 2) {
    int result = 1;
    for (int i = 0; i < exp; i++) {
        result *= base;
    }
    return result;
}

int main() {
    cout << power(5) << endl;    // 25 (5^2)
    cout << power(5, 3) << endl; // 125 (5^3)
}

Претоварване на функции (Function Overloading)

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

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

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

Рекурсивни функции - Основи

// Факториел рекурсивно
int factorialRecursive(int n) {
    if (n <= 1) return 1;
    return n * factorialRecursive(n - 1);
}

// Степенуване рекурсивно
int powerRecursive(int base, int exp) {
    if (exp == 0) return 1;
    return base * powerRecursive(base, exp - 1);
}

📝 Низове - Разширени операции

Обхождане на низ

string text = "Програмиране";

// Класически начин
for (int i = 0; i < text.length(); i++) {
    cout << text[i] << " ";
}

// Range-based for
for (char c : text) {
    cout << c << " ";
}

Сравняване на низове

string s1 = "abc";
string s2 = "abd";

if (s1 == s2) cout << "Еднакви" << endl;
if (s1 < s2) cout << "s1 е лексикографски по-малък" << endl;

Търсене в низ

string text = "Програмиране на C++";

// Намиране на подниз
size_t pos = text.find("на");
if (pos != string::npos) {
    cout << "Намерен на позиция: " << pos << endl;
}

// Проверка дали започва/завършва с подниз
if (text.substr(0, 4) == "Прог") {
    cout << "Започва с 'Прог'" << endl;
}

Модификация на низове

string s = "hello";

// Главни букви
for (char& c : s) {
    c = toupper(c);
}
// s = "HELLO"

// Малки букви
for (char& c : s) {
    c = tolower(c);
}

// Обръщане
reverse(s.begin(), s.end());

// Вмъкване
s.insert(2, "XYZ"); // Вмъква на позиция 2

// Изтриване
s.erase(2, 3); // Изтрива 3 символа от позиция 2

Разделяне на низ (tokenization)

#include <sstream>

string text = "apple banana cherry";
stringstream ss(text);
string word;

while (ss >> word) {
    cout << word << endl;
}

Числа и низове

// Низ към число
string numStr = "12345";
int num = stoi(numStr);        // string to int
long long bigNum = stoll(numStr); // string to long long
double d = stod("3.14");       // string to double

// Число към низ
int x = 42;
string str = to_string(x);

🎯 Практически задачи с низове

Броене на гласни и съгласни

int countVowels(string s) {
    int count = 0;
    string vowels = "aeiouAEIOU";

    for (char c : s) {
        if (vowels.find(c) != string::npos) {
            count++;
        }
    }
    return count;
}

Премахване на интервали

string removeSpaces(string s) {
    string result = "";
    for (char c : s) {
        if (c != ' ') {
            result += c;
        }
    }
    return result;
}

Броене на думи

int countWords(string s) {
    int count = 0;
    bool inWord = false;

    for (char c : s) {
        if (c != ' ' && !inWord) {
            count++;
            inWord = true;
        } else if (c == ' ') {
            inWord = false;
        }
    }
    return count;
}

Проверка за анаграм

bool areAnagrams(string s1, string s2) {
    if (s1.length() != s2.length()) return false;

    sort(s1.begin(), s1.end());
    sort(s2.begin(), s2.end());

    return s1 == s2;
}

💡 Съвети за оптимизация

  1. Използвайте правилния цикъл: for за известен брой итерации, while за неизвестен
  2. Избягвайте излишни проверки: Поставяйте условия извън цикъла, където е възможно
  3. Внимавайте с вложени цикли: Сложността расте бързо (O(n²), O(n³))
  4. Предавайте низове по референция: void func(const string& s) за да избегнете копиране
  5. Резервирайте памет предварително: string.reserve() ако знаете приблизителния размер

🏁 Заключение

Циклите, функциите и низовете са основни градивни блокове на програмирането. Овладяването на тези концепции е критично за решаване на алгоритмични задачи. Практикувайте редовно с различни задачи, експериментирайте с различни подходи и постепенно ще развиете интуиция за ефективно използване на тези инструменти! 🚀