👨🏻💻 Задача по программированию на языке C от нашего подписчика
Будет ли корректно скомпилирован (без ошибок и ворнингов) следующий код? И если — да, то что будет выведено при его запуске?
💡 Постарайтесь подумать самостоятельно и напишите свои ответы в комментариях. Чуть позже опубликуем разбор.
#задачи #cpp #C #си #программирование
Будет ли корректно скомпилирован (без ошибок и ворнингов) следующий код? И если — да, то что будет выведено при его запуске?
#include <stdio.h>⚙️ Обсуждение этой задачи в группе Physics.Math.Code в VK
int main(void) {
const int value = 111;
printf("init value: %d\n", value);
*((int*) &value) = 222;
printf("new value: %d\n", value);
return(0);
}
💡 Постарайтесь подумать самостоятельно и напишите свои ответы в комментариях. Чуть позже опубликуем разбор.
#задачи #cpp #C #си #программирование
👍54👎16🤔3❤1
🧩 Задача на C++: "Таинственная конкатенация"
🖥 Что выведет следующая программа? Будьте внимательны!
Варианты:
1. Обе строки выведут "Hello, World!"
2. Ошибка компиляции
3. Первая выведет мусор, вторая — "Hello, World!"
4. Первая вызовет ошибку, вторая скомпилируется
Задумайтесь на минутку, прежде чем запускать код...
🔍 Разбор проблемы
Правильный ответ: 2 (Ошибка компиляции) или, если точнее, ошибка возникнет уже на строке с result1.
🖥 Код с решением и комментариями:
📚 Малоизвестный факт:
В C++ есть специальная фаза трансляции, где соседние строковые литералы объединяются в один. Например:
Но этот процесс происходит до раскрытия макросов, поэтому MERGE("Hello, ", "World!") не работает как ожидается.
Ключевые моменты:
1. Оператор ## в макросах выполняет сращивание токенов, а не строк
2. Строковые литералы автоматически конкатенируются на фазе трансляции
3. Макросы раскрываются на более поздней фазе, когда уже слишком поздно для "правильной" конкатенации строк
Будьте осторожны с оператором ## при работе со строковыми литералами! Для их конкатенации лучше использовать обычное расположение рядом или constexpr функции в современном C++.
Чем токен отличается от строки?
1. Токен (в контексте препроцессора C++) — это минимальная единица текста программы, которую распознает препроцессор ( )
Препроцессор работает именно на уровне токенов. Оператор ## сращивает именно токены, а не их значение
2. Строковый литерал — это конкретный тип токена, который представляет строку в кавычках. Пример: "Hello" — это один токен типа "строковый литерал"
Ещё по теме: Задачки по программированию для наших подписчиков [ C/C++ ]
#C #cpp #cplusplus #программирование #задачи
💡 Physics.Math.Code // @physics_lib
#include <iostream>
#define MERGE(a, b) a ## b
int main() {
const char* result1 = MERGE("Hello, ", "World!");
const char* result2 = MERGE("Hello, ", "World" "!");
std::cout << result1 << std::endl;
std::cout << result2 << std::endl;
return 0;
}
Варианты:
1. Обе строки выведут "Hello, World!"
2. Ошибка компиляции
3. Первая выведет мусор, вторая — "Hello, World!"
4. Первая вызовет ошибку, вторая скомпилируется
Задумайтесь на минутку, прежде чем запускать код...
🔍 Разбор проблемы
#include <iostream> #define MERGE(a, b) a ## b
int main() {
// Эта строка НЕ скомпилируется:
// const char* result1 = MERGE("Hello, ", "World!");
// После раскрытия макроса получим: "Hello, ""World!"
// Это два отдельных строковых литерала без оператора конкатенации
// А вот эта строка скомпилируется и выведет "Hello, World!":
const char* result2 = MERGE("Hello, ", "World" "!");
// После раскрытия макроса получим: "Hello, ""World""!"
// А благодаря фазе трансляции, соседние строковые литералы
// сливаются в один: "Hello, World!!"
// Правильный способ через макрос:
const char* result3 = "Hello, " "World!";
std::cout << result2 << std::endl; // Выведет: Hello, World!!
std::cout << result3 << std::endl; // Выведет: Hello, World!
return 0;
}
В C++ есть специальная фаза трансляции, где соседние строковые литералы объединяются в один. Например:
const char* s = "Hello, " "World!"; // Эквивалентно "Hello, World!"Но этот процесс происходит до раскрытия макросов, поэтому MERGE("Hello, ", "World!") не работает как ожидается.
Ключевые моменты:
1. Оператор ## в макросах выполняет сращивание токенов, а не строк
2. Строковые литералы автоматически конкатенируются на фазе трансляции
3. Макросы раскрываются на более поздней фазе, когда уже слишком поздно для "правильной" конкатенации строк
Будьте осторожны с оператором ## при работе со строковыми литералами! Для их конкатенации лучше использовать обычное расположение рядом или constexpr функции в современном C++.
Чем токен отличается от строки?
1. Токен (в контексте препроцессора C++) — это минимальная единица текста программы, которую распознает препроцессор (
int, main, (, ), {, "Hello", 123, +, ;Препроцессор работает именно на уровне токенов. Оператор ## сращивает именно токены, а не их значение
2. Строковый литерал — это конкретный тип токена, который представляет строку в кавычках. Пример: "Hello" — это один токен типа "строковый литерал"
Ещё по теме: Задачки по программированию для наших подписчиков [ C/C++ ]
#C #cpp #cplusplus #программирование #задачи
💡 Physics.Math.Code // @physics_lib
Please open Telegram to view this post
VIEW IN TELEGRAM
❤41👍16🤷♂14🤯6🔥4👾4👏1👻1