2014-01-06 5 views
1

Я делаю программу, которая сдвигает значения влево или вправо в зависимости от значения второго аргумента. Если он положителен, он сдвигается влево, иначе он сдвигается вправо. N - количество сдвигов влево или вправо. У меня возникают проблемы с выполнением моих макросов.Использование инструкций препроцессора для макросов в C

#include <stdio.h> 

#define SHIFT(value, n) 

#if (n) > 0 
    (unsigned int value) <<= (int n); 
#else 
    ((unsigned int value)) >>= (int -n); 



int main() 
{ 
    printf("%d\n", SHIFT(1, 4)); 
} 

В настоящее время я получаю условную ошибку.

+0

Попробуйте '#define SHIFT (значение, п) \'. Обратная косая черта в конце указывает, что следующая строка является частью текущей строки. –

ответ

6

Препроцессор C на самом деле не работает так, как вы его намерены использовать. В частности, вы не можете использовать другие директивы CPP (например, #if, ...) в расширении макроса. Кроме того, поскольку макро расширение представляет собой статическая функция времени компиляции, то это не поможет в любом случае, когда фактические сдвиг-значения известно только во время выполнения:

int value_to_shift = read_some_integer_from_user(); 
int amount_to_shift_by = read_another_integer_from_user(); 
int shifted_value = SHIFT(value_to_shift, amount_to_shift_by); 

Если вы не возражаете, потенциал двойных -Оценка макро аргументов, идти с тройным оператором:

#define SHIFT(value, n) ((n) < 0? ((value) >> (-n)) : ((value) << (n))) 

Обратите внимание, что с помощью <<=>>=), как вы делаете в коде, наиболее вероятно, не то, что вы хотите, учитывая, что вы передаете буквальные числа как value аргументы для вашего SHIFT макроса.

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

static int 
shift(int value, int nbits) 
{ 
    return nbits < 0? (value >> -nbits) : (value << nbits); 
} 
+0

Хорошо. Есть ли способ сделать это с использованием типов данных в аргументах? –

+0

@XiJiaopin: И почему вы этого хотите? –

+0

Было бы уместно в этой конкретной программе, которая выводится из сдвига с целыми целыми знаками –

1

Ваш #define не делать то, что вы думаете, что он делает. Вам нужно продолжить линии с \. А так как п известно во время выполнения (предполагается, что ваш случай просто упрощением), вы можете использовать обычную функцию, и встраивать его в случае необходимости:

inline int shift(int value, int n) { 
    if (n < 0) { 
     return (unsigned int) value << n; 
    } 
    else { 
     return (unsigned int) value << -n; 
    } 
} 
+0

Синтаксис синтаксиса выглядит нечетным. Возможно, вы имели в виду '(unsigned int) value'? – Dirk

+0

@ Dirk Woops, исправлено, спасибо –

0

Вам нужно объединить строки с \. Вы также пропустили #endif Тед

INPLACE макросъемки:

#define SHIFT(value, n)  \ 
    value = ((n) > 0) ?  \ 
      value << (n) : \ 
      value >> -(n) 

Возврат сдвинут значение:

#define SHIFT(value, n)  \ 
    (((n) > 0) ?   \ 
      (value) << (n) : \ 
      (value) >> -(n)) 
+0

Я знаю, поэтому я написал, что это не сработает. Лучше его удалить. – egur

Смежные вопросы