Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: приоритеты математических и логических операций
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
demiurg_spb
Код
static const uint8_t X_MAX = 100;
uint8_t x;
uint8_t y;

y = (x < X_MAX)? (x+1):x;    // 1
y = x + ((x < X_MAX)? 1:0);  // 2
y = x + (x < X_MAX)? 1:0;    // 3

Первый и второй варианты верны, третий - нет.
Видимо играют роль приоритеты математических и логических операций.
Кому не сложно прокомментируйте. Спасибо!
zltigo
Цитата(demiurg_spb @ Aug 20 2009, 18:31) *
Кому не сложно прокомментируйте. Спасибо!

Не вижу никаких причин комментировать. Операция условия имеет самый низкий приоритет из перечисленных ниже только у присваивания. Возьмите букварь K&R, ознакомьтесь, и примите принятые Авторами языка уровни приоритета, как даденность.
demiurg_spb
Спасибо! Покопался сам и тоже нашёл. Чем выше строчка, тем выше приоритет:
Цитата
( ) Вызов функции
[ ] Выделение элемента массива
. Выделение элемента записи
-> Выделение элемента записи
! Логическое отрицание
~ Поразрядное отрицание
- Изменение знака
++ Увеличение на единицу
-- Уменьшение на единицу
& Взятие адреса
* Обращение по адресу
(тип) Преобразование типа (т.е. (float) a)
sizeof( ) Определение размера в байтах
* Умножение
/ Деление
% Определение остатка от деления
+ Сложение
- Вычитание
<< Сдвиг влево
>> Сдвиг вправо
< Меньше, чем
<= Меньше или равно
> Больше, чем
>= Больше или равно
= = Равно
!= Не равно
& Поразрядное логическое "И"
^ Поразрядное исключающее "ИЛИ"
| Поразрядное логическое "ИЛИ"
&& Логическое "И"
|| Логическое "ИЛИ"
?: Условная (тернарная) операция
= Присваивание
+=, - =, *=, /=, %=, <<=,>>=, &=, |=, ^= Составные операции присваивания.
, Операция запятая
Dima_G
Цитата(demiurg_spb @ Aug 20 2009, 20:31) *
Код
static const uint8_t X_MAX = 100;
uint8_t x;
uint8_t y;

y = (x < X_MAX)? (x+1):x;    // 1
y = x + ((x < X_MAX)? 1:0);  // 2
y = x + (x < X_MAX)? 1:0;    // 3

Первый и второй варианты верны, третий - нет.
Видимо играют роль приоритеты математических и логических операций.
Кому не сложно прокомментируйте. Спасибо!


Используй всегда скобки для определения порядка выполнения операций. Код будет более наглядным, и меньше вероятность посадить багу
Сергей Борщ
Цитата(Dima_G @ Aug 21 2009, 11:53) *
Используй всегда скобки для определения порядка выполнения операций. Код будет более наглядным, и меньше вероятность посадить багу
a = b + c * d; - в таких выражениях тоже?
demiurg_spb
Вот наткнулся на очередное своё заблуждение
Код
void rtc_clr(rtc_t* rtc) // no good
{    
    for (unsigned char i=0; i<sizeof(rtc_t); i++)
    {
        *(unsigned char*)rtc++ = 0;
    }
}

void rtc_clr(rtc_t* rtc) // good
{    
    unsigned char* p = (unsigned char*)rtc;

    for (unsigned char i=0; i<sizeof(rtc_t); i++)
    {
        *p++ = 0;
    }
}

void rtc_clr(void* rtc) // good with void* ???
{    
    for (unsigned char i=0; i<sizeof(rtc_t); i++)
    {
        *(unsigned char*)rtc++ = 0;
    }
}
Первый вариант очищает память как решето через промежутки равные sizeof(rtc_t) пишет нолики.
А второй и третий вариант делают то, что нужно (байт в байт асмовый листинг).
Что тут происходит с приоритетностью оператора ++ и оператора (unsigned char*) и как её меняет void*?
rezident
Цитата(demiurg_spb @ Sep 2 2009, 23:31) *
Первый вариант очищает память как решето через промежутки равные sizeof(rtc_t) пишет нолики.
А второй и третий вариант делают то, что нужно (байт в байт асмовый листинг).
Гм. Странно, а что вы хотели-то? Как написали так он и делает. laughing.gif
Цитата(demiurg_spb @ Sep 2 2009, 23:31) *
Что тут происходит с приоритетностью и как её меняет void*?
У вас какое-то недопонимание сути указателей? Может стоит стандарт Си или K&R почитать? В ваших примерах типы указателей разные, т.е. они указывают на разные (по размеру) объекты.
Попробую привести пример "на пальцах". Есть небольшая деталька в виде винта М3. Винты фасуют по кулечкам по 100 штук в каждом. А потом кулечки пакуют в картонную коробку. А теперь представьте, что кладовщику, на складе которого хранятся эти винты, указывают: отгрузи покупателю №1 50 винтиков, покупателю №2 - 50 упаковок винтиков, а покупателю №3 - 50 коробок винтиков. Как вы считаете, каждый из покупателей получит одинаковое количество винтов? wink.gif
demiurg_spb
Из Вашего ответа следует, что sizeof(void)==1. так?
Да я проверил STATIC_ASSERT(sizeof(void)==1) - компилится нормально.
Я просто думал, что sizeof(void)==sizeof(int), а это оказалось не так и что-то объясняет.

С указателями у меня кристальная ясность. А вот с приоритетностью и размером типа void - нет (пока).
ПС: Пример на пальцах Вам удалсяsmile.gif
rezident
Цитата(demiurg_spb @ Sep 3 2009, 00:03) *
Из Вашего ответа следует, что sizeof(void)==1. так?
Нет. Из моего ответа вы должны были сделать два вывода.
1. При операции ++ над указателем значение указателя (то бишь адреса) увеличивается на единицу размера объекта. Если размерность объекта 1 байт (и минимальная адресуемая единица тоже 1 байт), то значение указателя увеличится на 1. Если размер объекта, скажем 100 байт (с аналогичными возможностями адресации), то ++ увеличит значение указателя уже на 100, а не на 1.
2. При разборе синтаксиса компилятор действует так, как ему предписывают правила приоритета операций, применяя разыменование.

Update. Вот страничку из K&R специально вырезал. Красным выделил те операции, которые вы применяете. Обратите внимание на порядок их разыменования.
demiurg_spb
Спасибо за табличку! А с размером объекта типа void очень неожиданно для меня получилось...
Проясните пожалуйста последнее - что имеется в виду под ассоциативностью (это порядок разбора выражения справа налево ну или наоборот)?
rezident
Да, правильно. Ассоциативность определяет порядок разбора выражения компилятором.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.