можно ли использовать #define для печати информации?

Я наткнулся на заявление, которое я не понял. Кто-нибудь может объяснить мне, пожалуйста. Это программа C++ для сортировки данных.

#define PRINT(DATA,N) for(int i=0; i<N; i++) { cout<<"["<<i<<"]"<<DATA[i]<<endl; } cout<<endl;

А также, когда я попытался изменить оператор в следующем формате, я получил ошибку компиляции!

#define PRINT(DATA,N)
for(int i=0; i<N; i++)
{
   cout<<"["<<i<<"]"<<DATA[i]<<endl;
}
cout<<endl;

person neodev    schedule 26.07.2013    source источник
comment
Вам нужно сказать ему, что следующая строка является его частью, если вы собираетесь разделить их.   -  person chris    schedule 26.07.2013
comment
@neodev Вот так: stackoverflow.com/questions/6281368/   -  person Chris    schedule 26.07.2013
comment
Нет причин использовать макрос. Следует использовать функцию. При необходимости тип данных может быть параметром шаблона.   -  person Neil Kirk    schedule 02.09.2013


Ответы (3)


Его можно использовать, если правильно его определить. Но .... только потому, что его можно использовать, не означает, что его следует использовать.

Используйте 1_:

std::copy_n(data, n, std::stream_iterator<X>(std::cout, " "));

Это напечатает все элементы n из data в стандартный вывод, каждый из которых разделен пробелом. Обратите внимание, что в приведенном выше коде X является типом data[i].

Или напишите правильную функцию (не макрос) для печати в определенном вами формате. Предпочтительно шаблон функции с begin и end в качестве параметров функции. Посмотрите, как работают и реализуются алгоритмы из стандартной библиотеки. Это поможет вам придумать хороший общий дизайн вашего кода. Исследуйте и экспериментируйте с универсальными функциями библиотеки!

person Nawaz    schedule 26.07.2013
comment
Да, определенно лучшее решение. Его можно легко адаптировать под формат. - person chris; 26.07.2013

  1. Это макрос, каждый раз, когда вы пишете PRINT(DATA,N), препроцессор заменяет им весь цикл for, включая переменные.
  2. Вам не хватает знаков \ в конце каждой строки. Это говорит о том, что макрос переходит на следующую строку. (Посмотрите Макросы с несколькими операторами в C++.
  3. Если вы используете макрос, используйте скобки вокруг любых переменных (DATA) и (N). Замена является буквальной, и это позволит использовать такие варианты использования, как PRINT(data, x+1), которые в противном случае приводят к неожиданным результатам.
  4. Не используйте макрос, если вы ДЕЙСТВИТЕЛЬНО не должны, из-за этого может возникнуть много проблем, у него нет области действия и так далее. Вы можете написать встроенный метод или использовать std::copy_n, как предложил Наваз.
person Vadim    schedule 26.07.2013
comment
Конечно. Я действительно не могу не подчеркнуть, как вы должны стараться избегать использования макросов, если в этом нет необходимости. Подумайте, что произойдет, если вы напишете что-то вроде PRINT(Data, x++). Вы ожидаете, что ++ произойдет только один раз, когда на самом деле это будет происходить каждый раз, когда N используется в макросе. - person Vadim; 26.07.2013

Это не то, для чего вы хотите использовать макрос.

Напишите шаблонную функцию, которая делает то же самое:

template<typename T>
void PRINT(const T &data, size_t n){
    for (size_t i=0;i<n;++i)
        cout << "["<<i<<"]"<<data[i]<<endl;
}

Вам действительно следует избегать использования макросов. Единственная причина, по которой я считаю, что вам НУЖНЫ макросы, — это когда вам нужно использовать имя ввода (в виде строки) или местоположение (LINE или FILE), например:

#define OUT(x) #x<<"="<<x<<"; "
#define DEB std::cerr<<"In "<<__FILE__<<":"<<__LINE__<<": "

для использования в печати следующим образом:

DEB << OUT(i)<<OUT(val[i])<<OUT(some_func(val[i],3))<<endl;

Который будет печатать

In file.cc:153: i=4; val[i]=10; some_func(val[i],3)=4.32; 

Это функциональность, которую вы не можете сделать без макросов. Все, что вы МОЖЕТЕ сделать без макросов, вы ДОЛЖНЫ

person rabensky    schedule 26.07.2013