реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> приоритеты математических и логических операций
demiurg_spb
сообщение Aug 20 2009, 16:31
Сообщение #1


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Код
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

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


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
zltigo
сообщение Aug 20 2009, 16:51
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(demiurg_spb @ Aug 20 2009, 18:31) *
Кому не сложно прокомментируйте. Спасибо!

Не вижу никаких причин комментировать. Операция условия имеет самый низкий приоритет из перечисленных ниже только у присваивания. Возьмите букварь K&R, ознакомьтесь, и примите принятые Авторами языка уровни приоритета, как даденность.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Aug 20 2009, 17:03
Сообщение #3


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Спасибо! Покопался сам и тоже нашёл. Чем выше строчка, тем выше приоритет:
Цитата
( ) Вызов функции
[ ] Выделение элемента массива
. Выделение элемента записи
-> Выделение элемента записи
! Логическое отрицание
~ Поразрядное отрицание
- Изменение знака
++ Увеличение на единицу
-- Уменьшение на единицу
& Взятие адреса
* Обращение по адресу
(тип) Преобразование типа (т.е. (float) a)
sizeof( ) Определение размера в байтах
* Умножение
/ Деление
% Определение остатка от деления
+ Сложение
- Вычитание
<< Сдвиг влево
>> Сдвиг вправо
< Меньше, чем
<= Меньше или равно
> Больше, чем
>= Больше или равно
= = Равно
!= Не равно
& Поразрядное логическое "И"
^ Поразрядное исключающее "ИЛИ"
| Поразрядное логическое "ИЛИ"
&& Логическое "И"
|| Логическое "ИЛИ"
?: Условная (тернарная) операция
= Присваивание
+=, - =, *=, /=, %=, <<=,>>=, &=, |=, ^= Составные операции присваивания.
, Операция запятая


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
Dima_G
сообщение Aug 21 2009, 08:53
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 279
Регистрация: 2-07-08
Из: Новосибирск
Пользователь №: 38 699



Цитата(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

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


Используй всегда скобки для определения порядка выполнения операций. Код будет более наглядным, и меньше вероятность посадить багу
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Aug 21 2009, 09:10
Сообщение #5


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Dima_G @ Aug 21 2009, 11:53) *
Используй всегда скобки для определения порядка выполнения операций. Код будет более наглядным, и меньше вероятность посадить багу
a = b + c * d; - в таких выражениях тоже?


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Sep 2 2009, 17:31
Сообщение #6


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Вот наткнулся на очередное своё заблуждение
Код
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*?


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
rezident
сообщение Sep 2 2009, 17:58
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(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
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Sep 2 2009, 18:03
Сообщение #8


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Из Вашего ответа следует, что sizeof(void)==1. так?
Да я проверил STATIC_ASSERT(sizeof(void)==1) - компилится нормально.
Я просто думал, что sizeof(void)==sizeof(int), а это оказалось не так и что-то объясняет.

С указателями у меня кристальная ясность. А вот с приоритетностью и размером типа void - нет (пока).
ПС: Пример на пальцах Вам удалсяsmile.gif


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
rezident
сообщение Sep 2 2009, 18:23
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



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

Update. Вот страничку из K&R специально вырезал. Красным выделил те операции, которые вы применяете. Обратите внимание на порядок их разыменования.

Сообщение отредактировал rezident - Sep 2 2009, 18:41
Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Sep 2 2009, 19:47
Сообщение #10


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Спасибо за табличку! А с размером объекта типа void очень неожиданно для меня получилось...
Проясните пожалуйста последнее - что имеется в виду под ассоциативностью (это порядок разбора выражения справа налево ну или наоборот)?


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
rezident
сообщение Sep 2 2009, 20:10
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Да, правильно. Ассоциативность определяет порядок разбора выражения компилятором.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 23:05
Рейтинг@Mail.ru


Страница сгенерированна за 0.02198 секунд с 7
ELECTRONIX ©2004-2016