🔄 Цикли, Вложени цикли, Функции и Низове в езика C++
🔄 Цикли
Циклите в C++ позволяват изпълнението на един и същи блок от код множество пъти. Те се използват за работа с повторения и итерации върху структури от данни.
Видове цикли:
- for цикъл:
Използва се, когато броят на итерациите е известен предварително.
#include <iostream>
using namespace std;
int main() {
for (int i = 0; i < 5; i++) {
cout << "Итерация: " << i << endl;
}
return 0;
}
-
while цикъл: Използва се, когато не знаем предварително колко итерации ще са нужни.
-
do-while цикъл: Гарантира изпълнението на блока поне веднъж, дори ако условието е невярно.
🔁 Вложени цикли
Вложените цикли са цикли, които се намират вътре в други цикли. Те са полезни за работа с двумерни структури, като матрици. Пример:
#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;
}
Резултат:
🔧 Функции в 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;
}
Видове функции:
-
Функции без аргументи и връщана стойност:
-
Функции с аргументи:
-
Функции с връщана стойност:
📝 Низове
Низовете са последователности от символи. В 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;
}
Основни операции с низове:
-
Конкатенация:
-
Дължина на низ:
-
Достъп до символи:
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;
}
💡 Съвети за оптимизация
- Използвайте правилния цикъл:
forза известен брой итерации,whileза неизвестен - Избягвайте излишни проверки: Поставяйте условия извън цикъла, където е възможно
- Внимавайте с вложени цикли: Сложността расте бързо (O(n²), O(n³))
- Предавайте низове по референция:
void func(const string& s)за да избегнете копиране - Резервирайте памет предварително:
string.reserve()ако знаете приблизителния размер
🏁 Заключение
Циклите, функциите и низовете са основни градивни блокове на програмирането. Овладяването на тези концепции е критично за решаване на алгоритмични задачи. Практикувайте редовно с различни задачи, експериментирайте с различни подходи и постепенно ще развиете интуиция за ефективно използване на тези инструменти! 🚀