Язык программирования Си для начинающих.
#0. Язык Си. Рождение легенды
#1. Этапы трансляции программы в машинный код. Стандарты
#2. Установка компилятора gcc и Visual Studio Code на ОС Windows
#3. Структура и понимание работы программы "Hello, World!"
#4. Двоичная, шестнадцатиричная и восьмиричная системы счисления
#5. Переменные и их базовые типы. Модификаторы unsigned и signed
#6. Операция присваивания. Числовые и символьные литералы. Операция sizeof
#7. Стандартные потоки ввода/вывода. Функции putchar() и getchar()
#8. Функция printf() для форматированного вывода
#9. Функция scanf() для форматированного ввода
#10. Арифметические операции: сложение, вычитание, умножение и деление
#11. Арифметические операции деления по модулю, инкремента и декремента
#12. Арифметические операции +=, -=, *=, /=, %=
#13. Булевый тип. Операции сравнения. Логические И, ИЛИ, НЕ
#14. Условный оператор if. Конструкция if-else
#15. Условное тернарное выражение ? :
#16. Оператор switch множественного выбора. Ключевое слово break
#17. Битовые операции И, ИЛИ, НЕ, XOR. Сдвиговые операции
#18. Генерация псевдослучайных чисел. Функции математической библиотеки
#19. Директивы макропроцессора #define и #undef
#20. Директива #define для определения макросов-функций. Операции # и ##
#21. Директивы #include и условной компиляции
#22. Оператор цикла while
#23. Оператор цикла for
#24. Цикл do-while с постусловием. Вложенные циклы
#25. Операторы break, continue и goto
#26. Указатели. Проще простого
#27. Указатели. Приведение типов. Константа NULL
Все видео доступны на youtube
#cpp #programming
👉 @cpp_lib
#0. Язык Си. Рождение легенды
#1. Этапы трансляции программы в машинный код. Стандарты
#2. Установка компилятора gcc и Visual Studio Code на ОС Windows
#3. Структура и понимание работы программы "Hello, World!"
#4. Двоичная, шестнадцатиричная и восьмиричная системы счисления
#5. Переменные и их базовые типы. Модификаторы unsigned и signed
#6. Операция присваивания. Числовые и символьные литералы. Операция sizeof
#7. Стандартные потоки ввода/вывода. Функции putchar() и getchar()
#8. Функция printf() для форматированного вывода
#9. Функция scanf() для форматированного ввода
#10. Арифметические операции: сложение, вычитание, умножение и деление
#11. Арифметические операции деления по модулю, инкремента и декремента
#12. Арифметические операции +=, -=, *=, /=, %=
#13. Булевый тип. Операции сравнения. Логические И, ИЛИ, НЕ
#14. Условный оператор if. Конструкция if-else
#15. Условное тернарное выражение ? :
#16. Оператор switch множественного выбора. Ключевое слово break
#17. Битовые операции И, ИЛИ, НЕ, XOR. Сдвиговые операции
#18. Генерация псевдослучайных чисел. Функции математической библиотеки
#19. Директивы макропроцессора #define и #undef
#20. Директива #define для определения макросов-функций. Операции # и ##
#21. Директивы #include и условной компиляции
#22. Оператор цикла while
#23. Оператор цикла for
#24. Цикл do-while с постусловием. Вложенные циклы
#25. Операторы break, continue и goto
#26. Указатели. Проще простого
#27. Указатели. Приведение типов. Константа NULL
Все видео доступны на youtube
#cpp #programming
👉 @cpp_lib
👍7🔥3
Перегрузка операторов в C++. Основы
https://metanit.com/cpp/tutorial/5.14.php
#cpp #programming
👉 @cpp_lib
#include <iostream>
class Counter
{
public:
Counter(int val)
{
value =val;
}
void print()
{
std::cout << "Value: " << value << std::endl;
}
Counter operator + (const Counter& counter) const
{
return Counter{value + counter.value};
}
private:
int value;
};
int main()
{
Counter c1{20};
Counter c2{10};
Counter c3 = c1 + c2;
c3.print(); // Value: 30
}
https://metanit.com/cpp/tutorial/5.14.php
#cpp #programming
👉 @cpp_lib
Metanit
C++ | Перегрузка операторов
Перегрузка операторов в языке програмирования C++, Operator Overloading, перегрузка операций сравнения, присвоения, инкремента и декремента
👍5🥱1🍓1
C++. Ограничение noexcept
Реализация обобщенного кода C++ может быть сложной, поскольку любая операция потенциально может выкинуть исключение.
Примечательно, что, когда требуется строгая гарантия исключений, это может значительно усложнить код и привести к накладным расходам во время выполнения (или даже к изменению сложности «O большого»).
К счастью, для обеспечения соблюдения гарантий noexcept во время компиляции концепты можно использовать C++20.
https://medium.com/@simontoth/daily-bit-e-of-c-constraining-on-noexcept-fe477cc2bbe1
#cpp #programming
👉 @cpp_lib
Реализация обобщенного кода C++ может быть сложной, поскольку любая операция потенциально может выкинуть исключение.
Примечательно, что, когда требуется строгая гарантия исключений, это может значительно усложнить код и привести к накладным расходам во время выполнения (или даже к изменению сложности «O большого»).
К счастью, для обеспечения соблюдения гарантий noexcept во время компиляции концепты можно использовать C++20.
#include <utility>
struct UnsafeType
{
UnsafeType() = default;
UnsafeType(UnsafeType&&) {}
UnsafeType& operator=(UnsafeType&&) { return *this; }
};
template <typename T>
void unsafe_swap(T& left, T& right)
{
auto tmp = std::move(left);
left = std::move(right); // Что будет, если этот move выкинет исключение?
// было выполнено перемещение значения из left,
// и перемещение этого значения в right снова может выкинуть исключение
right = std::move(tmp);
}
struct SafeType
{
SafeType() = default;
SafeType(SafeType&&) noexcept {}
SafeType& operator=(SafeType&&) noexcept { return *this; }
};
template <typename T>
requires requires (T& a, T& b)
{
// присваивание перемещением допустимо и не выкидывает исключение
{ a = std::move(b) } noexcept;
}
void safe_swap(T& left, T& right)
{
auto tmp = std::move(left);
left = std::move(right);
right = std::move(tmp);
}
SafeType a, b;
safe_swap(a, b); // OK
UnsafeType x, y;
// Не скомпилируется:
// safe_swap(x, y);
// UnsafeType не удовлетворяет требованию noexcept
https://medium.com/@simontoth/daily-bit-e-of-c-constraining-on-noexcept-fe477cc2bbe1
#cpp #programming
👉 @cpp_lib
👍4⚡2
C++. std::make_unique_for_overwrite, std::make_shared_for_overwrite и std::allocate_shared_for_overwrite
C++ 440. Набор функций создания умных указателей в C++20: std::make_unique_for_overwrite, std::make_shared_for_overwrite и std::allocate_shared_for_overwrite.
Стандарт C++20 представил новый набор функций создания умных указателей: std::make_unique_for_overwrite, std::make_shared_for_overwrite и std::allocate_shared_for_overwrite.
Эти варианты инициализируют выделенную память значениями по умолчанию, в отличие от предыдущих вариантов с инициализацией значениями.
Это позволяет избежать дублирующей инициализации POD типов при немедленной перезаписи памяти.
https://medium.com/@simontoth/daily-bit-e-of-c-std-make-unique-for-overwrite-std-make-shared-for-overwrite-and-34875c161fbd
#cpp #programming
👉 @cpp_lib
C++ 440. Набор функций создания умных указателей в C++20: std::make_unique_for_overwrite, std::make_shared_for_overwrite и std::allocate_shared_for_overwrite.
Стандарт C++20 представил новый набор функций создания умных указателей: std::make_unique_for_overwrite, std::make_shared_for_overwrite и std::allocate_shared_for_overwrite.
Эти варианты инициализируют выделенную память значениями по умолчанию, в отличие от предыдущих вариантов с инициализацией значениями.
Это позволяет избежать дублирующей инициализации POD типов при немедленной перезаписи памяти.
#include <memory>
#include <memory_resource>
auto p1 = std::make_unique_for_overwrite<int>();
// decltype(p1) == std::unique_ptr<int>, *p1 == неопределенное значение
auto p2 = std::make_shared_for_overwrite<int>();
// decltype(p2) == std::shared_ptr<int>, *p2 == неопределенное значение
std::pmr::monotonic_buffer_resource mr;
std::pmr::polymorphic_allocator<int> alloc{&mr};
auto p3 = std::allocate_shared_for_overwrite<int>(alloc);
// decltype(p3) == std::shared_ptr<int>, *p3 == неопределенное значение
// Перегрузки также поддерживают массивы, инициализируемые по умолчанию
auto p4 = std::make_unique_for_overwrite<int[]>(7); // 7 элементов
// decltype(p4) == std::unique_ptr<int[]>, p4[0] == неопределенное значение
auto p5 = std::make_shared_for_overwrite<int[]>(7);
// decltype(p5) == std::shared_ptr<int[]>, p5[0] == неопределенное значение
auto p6 = std::allocate_shared_for_overwrite<int[]>(alloc, 7);
// decltype(p6) == std::shared_ptr<int[]>, p6[0] == неопределенное значение
https://medium.com/@simontoth/daily-bit-e-of-c-std-make-unique-for-overwrite-std-make-shared-for-overwrite-and-34875c161fbd
#cpp #programming
👉 @cpp_lib
❤3👍3⚡1
Regular expressions library (since C++11)
Библиотека регулярных выражений предоставляет класс, представляющий регулярные выражения, которые являются своего рода мини-языком, используемым для выполнения сопоставления шаблонов в строках.
https://en.cppreference.com/w/cpp/regex
#cpp #programming
👉 @cpp_lib
Библиотека регулярных выражений предоставляет класс, представляющий регулярные выражения, которые являются своего рода мини-языком, используемым для выполнения сопоставления шаблонов в строках.
#include <iostream>
#include <iterator>
#include <regex>
#include <string>
int main()
{
std::string s = "Some people, when confronted with a problem, think "
"\"I know, I'll use regular expressions.\" "
"Now they have two problems.";
std::regex self_regex("REGULAR EXPRESSIONS",
std::regex_constants::ECMAScript | std::regex_constants::icase);
if (std::regex_search(s, self_regex))
std::cout << "Text contains the phrase 'regular expressions'\n";
std::regex word_regex("(\\w+)");
auto words_begin =
std::sregex_iterator(s.begin(), s.end(), word_regex);
auto words_end = std::sregex_iterator();
std::cout << "Found "
<< std::distance(words_begin, words_end)
<< " words\n";
const int N = 6;
std::cout << "Words longer than " << N << " characters:\n";
for (std::sregex_iterator i = words_begin; i != words_end; ++i)
{
std::smatch match = *i;
std::string match_str = match.str();
if (match_str.size() > N)
std::cout << " " << match_str << '\n';
}
std::regex long_word_regex("(\\w{7,})");
std::string new_s = std::regex_replace(s, long_word_regex, "[$&]");
std::cout << new_s << '\n';
}
https://en.cppreference.com/w/cpp/regex
#cpp #programming
👉 @cpp_lib
👍4
Библеотека CPR
C++ Requests - это простая обертка вокруг libcurl, вдохновленная отличным проектом Python Requests.
Несмотря на свое название, простой интерфейс libcurl - это еще не все, и ошибки, неправильное использование этого языка - частый источник ошибок и разочарований. Используя более выразительные языковые средства C++17 (или C++11, если вы используете cpr < 1.10.0), эта библиотека укладывает суть выполнения сетевых вызовов в несколько лаконичных идиом.
Вот быстрый GET-запрос:
https://github.com/libcpr/cpr
#cpp #programming
👉 @cpp_lib
C++ Requests - это простая обертка вокруг libcurl, вдохновленная отличным проектом Python Requests.
Несмотря на свое название, простой интерфейс libcurl - это еще не все, и ошибки, неправильное использование этого языка - частый источник ошибок и разочарований. Используя более выразительные языковые средства C++17 (или C++11, если вы используете cpr < 1.10.0), эта библиотека укладывает суть выполнения сетевых вызовов в несколько лаконичных идиом.
Вот быстрый GET-запрос:
#include <cpr/cpr.h>
int main(int argc, char** argv) {
cpr::Response r = cpr::Get(cpr::Url{"https://api.github.com/repos/whoshuu/cpr/contributors"},
cpr::Authentication{"user", "pass", cpr::AuthMode::BASIC},
cpr::Parameters{{"anon", "true"}, {"key", "value"}});
r.status_code; // 200
r.header["content-type"]; // application/json; charset=utf-8
r.text; // JSON text string
return 0;
}
https://github.com/libcpr/cpr
#cpp #programming
👉 @cpp_lib
👍11
Написание минимального JIT-компилятора для x86-64 на C++
В этой статье я покажу, как написать минимальный, базовый JIT-компилятор для x86-64 на C++, который работает на macOS, Linux и потенциально может работать на Windows через WSL.
Для наших целей JIT-компиляция — это техника, с помощью которой программа генерирует машинный код во время выполнения, основываясь на вводе пользователя. Программа на C++ компилируется заранее (AOT, ahead of time), что обычно означает, что после того, как исходный код был скомпилирован для конкретной машины, его нельзя изменить во время выполнения (и с точки зрения безопасности это желаемая функция). Простое и полезное применение JIT-компилятора на C++ — это компиляция новой функции на лету, основанной на других функциях, уже определенных в исходном коде.
https://solarianprogrammer.com/2018/01/10/writing-minimal-x86-64-jit-compiler-cpp/
#cpp #programming
👉 @cpp_lib
В этой статье я покажу, как написать минимальный, базовый JIT-компилятор для x86-64 на C++, который работает на macOS, Linux и потенциально может работать на Windows через WSL.
Для наших целей JIT-компиляция — это техника, с помощью которой программа генерирует машинный код во время выполнения, основываясь на вводе пользователя. Программа на C++ компилируется заранее (AOT, ahead of time), что обычно означает, что после того, как исходный код был скомпилирован для конкретной машины, его нельзя изменить во время выполнения (и с точки зрения безопасности это желаемая функция). Простое и полезное применение JIT-компилятора на C++ — это компиляция новой функции на лету, основанной на других функциях, уже определенных в исходном коде.
1 // hello_0.cpp
2 #include <iostream>
3 #include <string>
4
5 int main() {
6 // Get the user name
7 std::string name;
8 std::cout << "What is your name?\n";
9 std::getline(std::cin, name);
10 std::string hello_name = "Hello, " + name + "!\n";
11
12 // Greet the user
13 std::cout << hello_name;
14 }
https://solarianprogrammer.com/2018/01/10/writing-minimal-x86-64-jit-compiler-cpp/
#cpp #programming
👉 @cpp_lib
👍5🤷♂1🔥1
This media is not supported in your browser
VIEW IN TELEGRAM
🚀В этой статье рассматривается минималистичная реализация виртуальной машины (VM) на C, занимающая менее 125 строк кода! 🖥️
Основная идея — эмуляция простого процессора с регистровой архитектурой. Виртуальная машина поддерживает базовые операции, такие как загрузка значений в регистры, сложение, умножение и выполнение условных переходов.
🔹 Основные компоненты:
- Регистры (массив для хранения значений)
- Память (байтовый массив, хранящий инструкции и данные)
- Исполнительный цикл (разбор и выполнение инструкций)
🔹 Пример кода:
Основная идея заключается в том, чтобы хранить наши инструкции в массиве (
https://www.andreinc.net/2021/12/01/writing-a-simple-vm-in-less-than-125-lines-of-c
#cpp #programming
👉 @cpp_lib
Основная идея — эмуляция простого процессора с регистровой архитектурой. Виртуальная машина поддерживает базовые операции, такие как загрузка значений в регистры, сложение, умножение и выполнение условных переходов.
🔹 Основные компоненты:
- Регистры (массив для хранения значений)
- Память (байтовый массив, хранящий инструкции и данные)
- Исполнительный цикл (разбор и выполнение инструкций)
🔹 Пример кода:
Основная идея заключается в том, чтобы хранить наши инструкции в массиве (
uint16_t program[]
), а затем использовать функцию fwrite()
для создания бинарного файла, который мы в дальнейшем сможем загрузить с помощью ld_img()
.
#include <stdio.h>
#include <stdlib.h>
uint16_t program[] = {
/*mem[0x3000]=*/ 0xF026, // 1111 0000 0010 0110 TRAP trp_in_u16 ;read an uint16_t from stdin and put it in R0
/*mem[0x3002]=*/ 0x1220, // 0001 0010 0010 0000 ADD R1,R0,x0 ;add contents of R0 to R1
/*mem[0x3003]=*/ 0xF026, // 1111 0000 0010 0110 TRAP trp_in_u16 ;read an uint16_t from stdin and put it in R0
/*mem[0x3004]=*/ 0x1240, // 0001 0010 0010 0000 ADD R1,R1,R0 ;add contents of R0 to R1
/*mem[0x3006]=*/ 0x1060, // 0001 0000 0110 0000 ADD R0,R1,x0 ;add contents of R1 to R0
/*mem[0x3007]=*/ 0xF027, // 1111 0000 0010 0111 TRAP trp_out_u16;show the contents of R0 to stdout
/*mem[0x3006]=*/ 0xF025, // 1111 0000 0010 0101 HALT ;halt
};
int main(int argc, char** argv) {
char *outf = "sum.obj";
FILE *f = fopen(outf, "wb");
if (NULL==f) {
fprintf(stderr, "Cannot write to file %s\n", outf);
}
size_t writ = fwrite(program, sizeof(uint16_t), sizeof(program), f);
fprintf(stdout, "Written size_t=%lu to file %s\n", writ, outf);
fclose(f);
return 0;
}
https://www.andreinc.net/2021/12/01/writing-a-simple-vm-in-less-than-125-lines-of-c
#cpp #programming
👉 @cpp_lib
👍4❤1
🔥 C++: умные указатели – избавляемся от
Вы все еще вручную освобождаете память? Это уже не актуально! Разбираем умные указатели (
🔹 std::unique_ptr – для объектов, у которых один владелец. Память освобождается автоматически, когда указатель выходит из области видимости:
🔹 std::shared_ptr – для объектов, у которых несколько владельцев. Когда последний
❌ Забудьте про
А вы уже полностью отказались от
#cpp #programming
👉 @cpp_lib
delete
навсегда! Вы все еще вручную освобождаете память? Это уже не актуально! Разбираем умные указатели (
std::unique_ptr
, std::shared_ptr
) и их преимущества. 🔹 std::unique_ptr – для объектов, у которых один владелец. Память освобождается автоматически, когда указатель выходит из области видимости:
#include <memory>
#include <iostream>
int main() {
std::unique_ptr<int> ptr = std::make_unique<int>(42);
std::cout << *ptr << std::endl; // 42
}
🔹 std::shared_ptr – для объектов, у которых несколько владельцев. Когда последний
shared_ptr
уничтожается – объект тоже удаляется:
#include <memory>
#include <iostream>
int main() {
std::shared_ptr<int> sp1 = std::make_shared<int>(42);
std::shared_ptr<int> sp2 = sp1; // Теперь два владельца
std::cout << *sp1 << " " << *sp2 << std::endl; // 42 42
}
❌ Забудьте про
new
и delete
, используйте std::make_unique
и std::make_shared
. Это избавит вас от утечек памяти. А вы уже полностью отказались от
delete
? Пишите в комментариях! 👇 #cpp #programming
👉 @cpp_lib
👍14
Многопоточное программирование на C
Многопоточное программирование — это специализированная форма параллельного программирования, которая предполагает выполнение нескольких потоков в рамках одного процесса или приложения. Объясню - каждая система состоит из процессов, а процесс состоит из потоков. Потоков может быть как несколько так и один. То есть один процесс выполняет несколько действий одновременно. Многопоток нужен в основном для оптимизации использования ресурсов, для программирования интерфейсов - как упомянул раннее выполнение нескольких действийй одновременно. Многопоточность незаменима тогда, когда необходимо, чтобы графический интерфейс продолжал отзываться на действия пользователя во время выполнения некоторой обработки информации. Не будем тянуть, а перейдем к делу.
Тут я написал небольшое приложение которое создает поток и выводит с его помощью числа от одного до 10 с небольшой задержкой.
https://habr.com/ru/articles/881444/
#cpp #programming
👉 @cpp_lib
Многопоточное программирование — это специализированная форма параллельного программирования, которая предполагает выполнение нескольких потоков в рамках одного процесса или приложения. Объясню - каждая система состоит из процессов, а процесс состоит из потоков. Потоков может быть как несколько так и один. То есть один процесс выполняет несколько действий одновременно. Многопоток нужен в основном для оптимизации использования ресурсов, для программирования интерфейсов - как упомянул раннее выполнение нескольких действийй одновременно. Многопоточность незаменима тогда, когда необходимо, чтобы графический интерфейс продолжал отзываться на действия пользователя во время выполнения некоторой обработки информации. Не будем тянуть, а перейдем к делу.
Тут я написал небольшое приложение которое создает поток и выводит с его помощью числа от одного до 10 с небольшой задержкой.
#include <gtk-4.0/gtk/gtk.h>
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
static void *thread_function(void *data) {
for (int i = 1; i <= 10; i++) {
printf("Thread: %d\n", i);
sleep(1);
}
return NULL;
}
static void on_button_clicked(GtkWidget *widget, gpointer data) {
pthread_t thread;
if (pthread_create(&thread, NULL, thread_function, NULL) != 0) {
g_print("Ошибка создания потока\n");
}
pthread_detach(thread);
}
int main(int argc, char *argv[]) {
GtkWidget *window;
GtkWidget *button;
gtk_init(&argc, &argv);
window = gtk_window_new();
gtk_window_set_title(GTK_WINDOW(window), "Многопоточная программа");
gtk_window_set_default_size(GTK_WINDOW(window), 300, 200);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
button = gtk_button_new_with_label("Запустить поток");
g_signal_connect(button, "clicked", G_CALLBACK(on_button_clicked), NULL);
gtk_window_set_child(GTK_WINDOW(window), button);
gtk_widget_show(window);
gtk_main();
return 0;
}
//gcc threading.c -o thread_gui.o -lpthread Надо было добавить чтобы выводило и номер потока но что-то до меня не много не дошлоНадо было добавить чтобы выводило и номер потока но что-то до меня не много не дошло
https://habr.com/ru/articles/881444/
#cpp #programming
👉 @cpp_lib
👍9
🔥 Как правильно сравнивать
Доброй ночи! Давайте разберём важную тему – сравнение
✅ Способы сравнения строк
1️⃣ Оператор
Если вам нужно проверить точное совпадение строк:
Этот метод безопасен, читабелен и работает быстро.
2️⃣ Функция
Если нужно получить порядок строк в алфавитном сравнении:
🔹
-
-
-
3️⃣ Сравнение без учета регистра
В C++ нет встроенного метода, но можно использовать
4️⃣ Сравнение подстрок
Если нужно проверить, начинается ли строка с подстроки:
✅
🚀 Итоги
✔ Используйте
✔
✔ Для регистра –
✔ Для подстрок –
Какой метод вы чаще используете? Делитесь в комментариях!
#cpp #programming
👉 @cpp_lib
std::string
в C++? Доброй ночи! Давайте разберём важную тему – сравнение
std::string
в C++. Многие думают, что это просто (==
и всё), но есть нюансы! Давайте разберёмся. ✅ Способы сравнения строк
1️⃣ Оператор
==
Если вам нужно проверить точное совпадение строк:
std::string str1 = "hello";
std::string str2 = "hello";
if (str1 == str2) {
std::cout << "Строки равны!\n";
}
Этот метод безопасен, читабелен и работает быстро.
2️⃣ Функция
compare()
Если нужно получить порядок строк в алфавитном сравнении:
std::string str1 = "apple";
std::string str2 = "banana";
if (str1.compare(str2) < 0) {
std::cout << "apple идет перед banana\n";
}
🔹
compare()
возвращает: -
0
, если строки равны -
< 0
, если str1
меньше str2
-
> 0
, если str1
больше str2
3️⃣ Сравнение без учета регистра
В C++ нет встроенного метода, но можно использовать
std::transform
:
#include <algorithm>
#include <cctype>
#include <string>
bool caseInsensitiveCompare(const std::string& a, const std::string& b) {
return std::equal(a.begin(), a.end(), b.begin(), b.end(),
[](char c1, char c2) { return std::tolower(c1) == std::tolower(c2); });
}
std::string str1 = "Hello";
std::string str2 = "hello";
if (caseInsensitiveCompare(str1, str2)) {
std::cout << "Строки равны без учета регистра!\n";
}
4️⃣ Сравнение подстрок
Если нужно проверить, начинается ли строка с подстроки:
std::string text = "hello world";
std::string prefix = "hello";
if (text.rfind(prefix, 0) == 0) {
std::cout << "Строка начинается с 'hello'!\n";
}
✅
rfind(prefix, 0) == 0
проверяет, что prefix
стоит в начале строки.🚀 Итоги
✔ Используйте
==
для простого сравнения ✔
compare()
– если важно узнать порядок ✔ Для регистра –
std::tolower()
✔ Для подстрок –
rfind()
Какой метод вы чаще используете? Делитесь в комментариях!
#cpp #programming
👉 @cpp_lib
👍7👏4