#cpp
Задача стоит написать функцию-макрос. Сама функция написано и даже один раз корректно
срабатывает.
Вот она:
#define maximum(x, y, r) int aa=x; int bb=y; r = ((aa) > (bb) ? (aa) : (bb))/* присвойте
в r максимум из x и y */
Но при повторном вызове компилятор выдает ошибки вида:
error: redeclaration of 'int aa'
error: 'int aa' previously declared here
Помогите разобраться в причине, пожалуйста
Ответы
Ответ 1
Прежде всего мне представляется, что вы имели в виду что-то подобное: #define maximum(x, y, r) \ do { int aa = ( x ); int bb = ( y ); ( r ) = bb < aa ? aa : bb; } while ( false ) Предвидя ваш вопрос, почему используется конструкция do-while, скажу, чтобы, например, этот макрос можно было бы использовать в if-else предложении: if ( x > 0 && y > 0 ) maimum( x, y, r ); else maximum( x = -x, y = -y, r ); Ниже представлена демонстрационная программа #include#define maximum(x, y, r) \ do { int aa = ( x ); int bb = ( y ); ( r ) = bb < aa ? aa : bb; } while ( false ) int main() { int x = -10, y = -5, r; if ( x > 0 && y > 0 ) maximum( x, y, r ); else maximum( x = -x, y = -y, r ); std::cout << "x = " << x << ", y = " << y << ", r = " << r << std::endl; } Ее вывод на консоль: x = 10, y = 5, r = 10 Что касается вашего определения макроса, то он постоянно определяет переменные aa и bb в той области видимости, где макрос вызывается. #define maximum(x, y, r) int aa=x; int bb=y; r = ((aa) > (bb) ? (aa) : (bb)) Поэтому компилятор выдает сообщение об ошибке, что эти переменные были уже определены, если макрос вызывается более одного раза. Использование макросов в C++ - это анахронизм. Лучше использовать встраиваемые функции, то есть функции со спецификатором inline. Более того в C++ уже есть стандартная функция std::max. Поэтому вы могли бы просто написать r = std::max( x, y ); Имейте в виду, что поведение вашего макроса отличается от поведения аналогичной стандартной функции std::max. Ваш макрос в случае равенства x и y возвращает y, тогда как стандартная функция std::max возвращает x. И кроме того вы используете оператор > тогда как стандартная функция использует оператор <. Для фундаментальных типов это может не играть существенной роли, тогда как для определенных пользователем типов это имеет важное значение. А самое главное - ваш макрос нельзя использовать в выражениях. Это ограничивает его применение. Ответ 2
Причина однозначно описана в сообщении об ошибке: множественное объявление переменной. Макрос заменяется (грубо говоря) на его содержимое препроцессором и у вас второй раз появляется объявление переменной как только появляется второе вхождение макроса.Ответ 3
#define SET_MAX(r,a,b) do \ { \ auto aa=(a); \ auto bb=(b); \ (r) = aa>bb ? aa : bb; \ } while(0) Но вообще, лучше сделать функцию: templatetyped & set_max(typed &r, const typed &a, const typed &b) { return r = a > b ? a : b; } Ответ 4
Добавлю и свои 5 копеек. Для GNU (g++/gcc) я бы написал этот макрос следующим образом: #define maximum(x, y, r) ({typeof(x) _x = x; typeof(y) _y = y; \ (r) = ( _x > _y ? _x : _y);}) Компиляторы g++/gcc позволяют использовать блоки {...}, в которых можно определять локальные для блока переменные, в скобочных выражениях. В таком виде у макроса будет такое же поведение как у функции, если его аргументы "самомодифицирующиеся", т.е. Вы пишете что-то типа maximum(++a, b--, *t++); Поскольку тело макроса заключено в скобки, то его можно использовать в коде всюду, где допустимо выражение, например, в операторе if if (maximum(a, b, t[i++]) > 0)) .... или в качестве аргумента функций, в объявлении переменных (инициализация) и т.п. как функцию с побочным эффектом. Значением такого выражения будет значение последнего оператора, т.е. то, что в данном случае присваивается аргументу r макроса. Понятно, что r в этом макросе д.б. lvalue. P.S. Между прочим, тип выражений (переменных) x, y и r может быть и разным.Ответ 5
Макрос - это не функция. Проще сделать так: #define maximum(x, y, r) r = ((x) > (y) ? (x) : (y)) И не забудь добавить ; после maximum при использовании. Но обычно делают так: #define maximum(x, y) ((x) > (y) ? (x) : (y)) А используют так: int r = maximum( a, b ); Но раз уж мы говорим о С++, то я бы использовал функцию. templateT & maximum( T & a, T & b ) { return a > b ? a : b; } Ответ 6
#define maximum(x, y) []() { auto aa=(x), bb=(y); return ((aa) > (bb) ? (aa) : (bb)); }() :)
Комментариев нет:
Отправить комментарий