#c #c 14 #preprocessor-directive #long-long
Вопрос:
#include <iostream>
using namespace std;
#define ll long long
int main() {
int a = 5;
ll maxi = 1;
maxi = max(maxi, maxi * ll(a));
cout<<maxi<<endl;
return 0;
}
Почему этот код выдает ошибку? Я не понимаю, что не так с #define ll long long .
Комментарии:
1. используйте int64_t вместо long long
2. Используйте вместо этого typedef ну, я тоже узнал кое-что новое, что #define ll long long недопустимо 🙂
3. Я бы просто напечатал
int64_t
вместоll
этого . Да, я знаю, что в нем несколько дополнительных символов, но это улучшает читабельность
Ответ №1:
Помните, что #define
выполняется текстовая подстановка. В итоге ты получаешь вот это:
maxi = max(maxi, maxi * long long(a));
Что недопустимо, поскольку имя типа для функционального приведения, грубо говоря, не может содержать пробелы на верхнем уровне. Итак, unsigned int(a)
, long double(a)
, и т. Д., Все они недействительны по той же причине.
Решение состоит в том, чтобы либо использовать using
вместо #define
:
using ll = long long;
или сделать (ll)a
, так как в этом случае пробелы разрешены.
Но на вашем месте я бы избавился ll
и использовал (long long)a
, так ll
как это довольно не описательное имя.
Обратите внимание, что #define ll long long
это неправильное использование макросов, и это плохо по многим причинам:
- Это сбивает с толку. Исходя из
ll maxi = 1;
этого , разумный человек ожидалll
бы, что он будет типом иll(a)
будет работать. И это сработало бы, если бы это не был макрос. - Короткое имя может вступать в конфликт с вещами. Если вы поместите это
#define
в заголовок, а затем включите другой заголовок, в котором это слово используетсяll
для любых целей, оно сломается.Чтобы избежать этого, макросы должны иметь длинные пугающие имена ALL_CAPS.
Макросы должны быть последним ядерным вариантом, используемым, когда все остальное терпит неудачу, а не только когда вам не хочется печатать лишние буквы.
Это то, что вы видите на сайтах конкурентного программирования, но если бы вы попытались сделать это на реальной работе, это провалило бы любой нормальный обзор кода.
Ответ №2:
В этом нет ничего плохого #define ll long long
(кроме возможности, с которой вы его спутаете 11
), он делает именно то, что должен делать.
Однако приведение ll(a)
, которое переводится long long(a)
как , недопустимо (в этой форме пробелы не допускаются).
Вам нужно использовать (ll)a
, что становится (long long)a
.
Я должен упомянуть, что для этого было бы лучше использовать определения типов, а не #define
операторы. Это было бы одним из:
typedef long long ll
using ll = long long;
Ответ №3:
Запомните метод приведения типов сначала мы должны написать имя типа сначала в фигурных скобках, а затем переменную, как это (int)a
.
В своем коде вы неправильно использовали макросы.Сначала вы должны написать ключевое слово, а затем то, что вы хотите назвать ключевым словом, как это #define long long ll
, затем вы можете использовать long long
как ll
. Это были все проблемы, которые у вас возникли с вашим кодом.
Комментарии:
1. «мы должны сначала написать имя типа» Не обязательно.
int(a)
компилируется, хотяlong long(a)
и не делает этого. «Сначала вы должны написать ключевое слово» Я не совсем понимаю идею, но#define long long ll
это неправильно. Это заменилоlong
бы наlong ll
, что имеет мало смысла. (Не говоря уже о том, что повторное использование ключевыхlong
слов, таких как имена макросов, незаконно, вы должны придумать свои собственные имена.) Оригинальный макрос OP имеет больше смысла.