Макрос в C, чтобы заменить 0 на 1

0

У меня есть пара определений в моей программе, которые дают размер массиву. Теперь вы не можете инициализировать массив с размером 0. Поэтому мне нужно проверить это значение, и если он равен нулю, поставьте 1. Я никогда раньше не использовал макрос, но это то, что я придумал:

#define MINIMUMONE(i)  do{if(i == 0){return 1;}else{return i;}}while(0)

а затем инициализировать мои массивы так:

int directIn[MINIMUMONE(NRDIRECTINPUTS)] = {0};

с NRDIRECTINPUTS определенными в отдельном файле. Теперь я получаю ожидаемое первичное выражение ошибки до 'do', ожидаемое '' 'до' do 'и ожидаемое'} 'в конце ввода. Поскольку я раньше не использовал макрос, я в первую очередь не уверен, что это возможно.

Теперь, набрав этот вопрос, я пришел к откровению о том, что это совсем не то, как работают макросы, но они просто заменяют его на то, что приходит после него. Есть ли способ сделать то, что я желаю? Я использую Arduino, поэтому он C/C++, если это может быть полезно.

  • 1
    C или C ++? Это приводит к различным ответам, поскольку C99 поддерживает массив переменной длины, поэтому MININUMONE может возвращать переменную вместо константы, в то время как C ++ 03 не поддерживает ее.
  • 0
    Могу ли я предложить использовать std::array<T, N> вместо T[N] ? Они позволяют размер 0.
Теги:
macros

3 ответа

2
Лучший ответ

#define MINIMUMONE(i) ( (i)? (i): 1 )

  • 0
    Я бы даже сделал (i) || 1 , чтобы избежать побочных эффектов , если таковые имеются, с осознанием того, что вы должны оценить i , по крайней мере один раз, так что любой побочный эффект происходит ровно один раз.
  • 1
    @NitzanShaked: Проблема, (i) || 1 всегда возвращает 1 , даже если i было 2 .
Показать ещё 2 комментария
6

Зачем использовать макрос, когда вы можете использовать constexpr -functions?

constexpr std::size_t minimumone( std::size_t i )
{
    return i == 0? 1 : i;
}

Ради комментаторов, это нераспространяемая версия вышеприведенного кода:

constexpr std::size_t minimumone( std::size_t i )
{
    return i + (i == 0); // Becomes at least 1 whatever value i has.
}

И, конечно, версия шаблона:

template< std::size_t N >
constexpr std::size_t minimumone()
{
    return N == 0? 1 : N;
}

А поскольку С++ 1y, он становится еще лучше:

template< std::size_t N >
std::size_t minimumone = (N == 0? 1 : N);
  • 0
    Хороший выбор, но я бы посоветовал избегать условных.
  • 1
    Условия не имеют никакого значения во время компиляции!
Показать ещё 6 комментариев
2

Здесь версия без условного:

#define MINIMUMONE(i) ((i) + !(i))

Ещё вопросы

Сообщество Overcoder
Наверх
Меню