|
|
  |
приоритеты математических и логических операций |
|
|
|
Aug 20 2009, 16:31
|

неотягощённый злом
     
Группа: Свой
Сообщений: 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 Первый и второй варианты верны, третий - нет. Видимо играют роль приоритеты математических и логических операций. Кому не сложно прокомментируйте. Спасибо!
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Aug 20 2009, 17:03
|

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

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

неотягощённый злом
     
Группа: Свой
Сообщений: 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*?
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Sep 2 2009, 17:58
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(demiurg_spb @ Sep 2 2009, 23:31)  Первый вариант очищает память как решето через промежутки равные sizeof(rtc_t) пишет нолики. А второй и третий вариант делают то, что нужно (байт в байт асмовый листинг). Гм. Странно, а что вы хотели-то? Как написали так он и делает. Цитата(demiurg_spb @ Sep 2 2009, 23:31)  Что тут происходит с приоритетностью и как её меняет void*? У вас какое-то недопонимание сути указателей? Может стоит стандарт Си или K&R почитать? В ваших примерах типы указателей разные, т.е. они указывают на разные (по размеру) объекты. Попробую привести пример "на пальцах". Есть небольшая деталька в виде винта М3. Винты фасуют по кулечкам по 100 штук в каждом. А потом кулечки пакуют в картонную коробку. А теперь представьте, что кладовщику, на складе которого хранятся эти винты, указывают: отгрузи покупателю №1 50 винтиков, покупателю №2 - 50 упаковок винтиков, а покупателю №3 - 50 коробок винтиков. Как вы считаете, каждый из покупателей получит одинаковое количество винтов?
|
|
|
|
|
Sep 2 2009, 18:03
|

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

|
Из Вашего ответа следует, что sizeof(void)==1. так? Да я проверил STATIC_ASSERT(sizeof(void)==1) - компилится нормально. Я просто думал, что sizeof(void)==sizeof(int), а это оказалось не так и что-то объясняет. С указателями у меня кристальная ясность. А вот с приоритетностью и размером типа void - нет (пока). ПС: Пример на пальцах Вам удался
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Sep 2 2009, 18:23
|
Гуру
     
Группа: Свой
Сообщений: 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
Эскизы прикрепленных изображений
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|