aam писал(а):Я что-то не понял насчет типов данных и порядка вычислений... Если это все считает препроцессор (или компилятор?), то какая разница какие там типы и порядок - результат один и тот же будет все равно.
U не определено с помощью define, но оно подставляется в виде числа (а не переменной) при вызове макроса:
if(adc==VOLTAGE_mV(1000))
...
т. е. в прошивке будет написано:
if(adc==163)
...
или
if(adc==163.84)
...
или
if(adc==1024*2*(1000-800)/2500)
...
?
разница будет и весьма существенная.
препроцессор - это всего лишь автоматический текстовый редактор, который выполняет поиск и замену текста. поэтому к компилятору попадет строчка
if(adc==1024*2*(1000-800)/2500), и никакая иная. затем компилятор начент во время компиляции вычислять все, чтот можно: в данном случае можно вычислить все выражение, т.к. все величины - константы. стандарт Си говорит, что вычисления должны быть сделаны, а порядок вычисления не определяется. чисто математически нет разницы, будет ли первым сделано вычисление 1024*2 или 2*(1000-800) или (1000-800)/2500, однако, результат в каждом случае будет немножко разным получаться.
если первым будет вычислено (1000-800)/2500, то мы получим (1000-800)/2500 == 0, т.к. деление целочисленное. разумеется, все прочие умножения нуля будут бесполезны - всегда получим
ноль.
если первым будет вычислено 1024*2*(1000-800), то получим 1024*2*(1000-800) == 2048*200 == 409600, что в
int никогда не вместится, а вместится только 16 младших бит, т.е. 1024*2*(1000-800) окажется равным
16384. далее это число будет поделено на 2500 и в итоге мы получим
6.
как видите, все варианты дают НЕПРАВИЛЬНЫЙ результат, точнее, результат правильный с точки зрения компилятора, но совсем НЕ ОЖИДАЕМЫЙ программистом (ожидается то
163,84, ну в крайнем случае
163).
удивлены? а все абсолютно в соответствии с языком Си, освоить который вы все никак не хотите... я устал уже твердить, что ВСЕ ЧИСЛА В ВЫРАЖЕНИЯХ СЧИТАЮТСЯ
int-ами, если не указано иное!!! поэтому просто запись 2*2 будет понята как умножение двух 16-битных чисел со знаком, и умножение 2000*2000 тоже самое, и, как это ни странно,
100000 тоже будет воспринято как
16-битное - с соответствующим усечением старших битов!!!!
поэтому всегда следует думать о том, какие числа используются в выражении, какой размер (т.е. тип) будет иметь результат вычислений и избегать только что рассмотренных подвохов.
P.S. я предполагаю, что компилятор
не станет вычислять выражение
справа налево, как я допустил в первом варианте рассуждений. однако, на 100% я в этом не уверен -
скорее всего - ДА, но может быть - и НЕТ
