#define
делает буквальную замену строки символов, которые вы определили. Таким образом, выражение:
a = 2*(s-u*t)/SQUARE(t*t)
расширится:
a = 2*(s-u*t)/t*t
Который, данный оператор порядок оценки будет оценивать как:
a = (2*(s-u*t)/t)*t
Не то, что вы хотите. Вы, наверное, очень хочется a = 2*(s-u*t)/(t*t)
, так что вы должны иметь:
#define SQUARE(x) (x*x)
или даже лучше, так как @Jongware указывает, так как x
сама может быть выражением:
#define SQUARE(x) ((x)*(x))
Таким образом, такие выражения, как, SQUARE(a+b)
будет правильно оценивают ((a+b)*(a+b))
, а не (a+b*a+b)
.
Также, как указано в комментариях, вы должны остерегаться результатов макрорежима, когда у вас есть побочные эффекты в ваших аргументах. Например, что делает SQUARE(x++)
, и каково значение x
, когда это будет сделано? В этом случае это дало бы (x++)*(x++)
, причем значение x
было бы приращенным дважды, а результаты могут быть неопределенными (зависит от порядка приращения приращения в этом случае).
'# define' делает * буквальную замену строки *. Таким образом, вы получите 'a = 2 * (s-u * t)/t * t', который, учитывая операторный порядок оценки, будет оцениваться как: a = (2 * (s-u * t)/t) * t'. Вы, вероятно, действительно хотите 'a = 2 * (su * t)/(t * t)', поэтому вы должны иметь '#define SQUARE (x) ((x) * (x))' – lurker
FWIW, [см. Это] http://en.cppreference.com/w/c/language/operator_precedence). –
Лучший способ узнать: 'cpp your_file.c' – nouney