Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Вопрос(ы) по коду
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
Jenya7
Я тут перевожу чужой код на новую платформу. Встретился такой код
Код
if(g_sPreset[g_uiCounterPush] < g_sPreset_max[g_uiCounterPush])
    g_sPreset[g_uiCounterPush]++;
как компилятор это увидит g_sPreset++ или g_sPreset[g_uiCounterPush++] ?

gosha-z
Цитата(Jenya7 @ Jun 14 2018, 17:12) *
Я тут перевожу чужой код на новую платформу. Встретился такой код
Код
if(g_sPreset[g_uiCounterPush] < g_sPreset_max[g_uiCounterPush])
    g_sPreset[g_uiCounterPush]++;
как компилятор это увидит g_sPreset++ или g_sPreset[g_uiCounterPush++] ?

Первое. Что логично.
Jenya7
Цитата(gosha-z @ Jun 14 2018, 19:14) *
Первое. Что логично.


я понял. спасибо. судя по коду этот п...рограмист хотел таки приращивать g_uiCounterPush. хотя это то же самое.
gosha-z
Цитата(Jenya7 @ Jun 14 2018, 17:25) *
я понял. спасибо. судя по коду этот п...рограмист хотел таки приращивать g_uiCounterPush. хотя это то же самое.

Ээээ... Что "то же самое"?
Jenya7
еще такой вопрос
в aaa.h файле определено
Код
#if _MENU_C
char *s_MainMenu[] =
{
    "MAINT ",
    " AUTO ",
    "MANUAL",
    "FAILS ",
};
#else
extern char *s_MainMenu[];
#endif

а в aaa.c файле
#define _MENU_C
есть шанс что дефайн будет виден в aaa.h файле?

Цитата(gosha-z @ Jun 14 2018, 19:49) *
Ээээ... Что "то же самое"?

результат будет тот же. мы сместимся на один адрес вперед. .... ах да. ошибся. не то же самое.
gosha-z
Цитата(Jenya7 @ Jun 14 2018, 17:55) *
еще такой вопрос
в aaa.h файле определено
Код
#if _MENU_C
char *s_MainMenu[] =
{
    "MAINT ",
    " AUTO ",
    "MANUAL",
    "FAILS ",
};
#else
extern char *s_MainMenu[];
#endif

а в aaa.c файле
#define _MENU_C
есть шанс что дефайн будет виден в aaa.h файле?

Да, в случае
#define _MENU_C
#include "aaa.h"
Цитата(Jenya7 @ Jun 14 2018, 17:55) *
результат будет тот же. мы сместимся на один адрес вперед.


Нет, a[b]++ и a[b++] разные по смыслу


Jenya7
Цитата(gosha-z @ Jun 14 2018, 20:00) *
Да, в случае
#define _MENU_C
#include "aaa.h"

Нет, a[b]++ и a[b++] разные по смыслу
а можно узнать что имел в виду писавший это? a[b]++ или таки a[b++]
k155la3
Цитата(Jenya7 @ Jun 14 2018, 18:10) *
а можно узнать что имел в виду писавший это? a[b]++ или таки a[b++]
sm.gif интеллектуалам не понятно.
Переписываем
a[b]++;
в виде a[b] = a[b] +1;
По приоритету [] существенно выше чем оператор инкримента.
Forger
Цитата(Jenya7 @ Jun 14 2018, 17:12) *
Я тут перевожу чужой код на новую платформу. Встретился такой код
Код
if(g_sPreset[g_uiCounterPush] < g_sPreset_max[g_uiCounterPush])
    g_sPreset[g_uiCounterPush]++;
как компилятор это увидит g_sPreset++ или g_sPreset[g_uiCounterPush++] ?

См. приоритеты операторов. Оператор "[]" имеет приоритет, равный приоритету оператора "++".
При равных приоритетах работает правило "слева направо". Т.е. сначала выполнится оператор [], а затем ++.
Однако, в подобных не очевидных ситуациях, имхо, лучше писать явно: g_sPreset[g_uiCounterPush] = g_sPreset[g_uiCounterPush] + 1;

Цитата(k155la3 @ Jun 14 2018, 19:10) *
По приоритету [] существенно выше чем оператор инкримента.

Это не так, приоритеты у них одинаковые ))
Я тоже так думал, пока не глянул в "табличку" (см. ссылку выше)
Jenya7
Цитата(Forger @ Jun 15 2018, 00:11) *
См. приоритеты операторов. Оператор "[]" имеет приоритет, равный приоритету оператора "++".
При равных приоритетах работает правило "слева направо". Т.е. сначала выполнится оператор [], а затем ++.
Однако, в подобных не очевидных ситуациях, имхо, лучше писать явно: g_sPreset[g_uiCounterPush] = g_sPreset[g_uiCounterPush] + 1;


Это не так, приоритеты у них одинаковые ))
Я тоже так думал, пока не глянул в "табличку" (см. ссылку выше)


это не я писал. писал начинающий програмист. я не знаю что он имел ввиду. но сдается мне он далек от таких изысков g_sPreset[g_uiCounterPush] = g_sPreset[g_uiCounterPush] + 1;хотя...черт его душу разберет...
Forger
Цитата(Jenya7 @ Jun 14 2018, 21:21) *
это не я писал. писал начинающий програмист
А сам этот "программист" куда-то пропал?
ViKo
Цитата(Forger @ Jun 14 2018, 21:11) *
Это не так, приоритеты у них одинаковые ))
Я тоже так думал, пока не глянул в "табличку" (см. ссылку выше)

Приоритеты у них разные, а табличка у вас неправильная. rolleyes.gif
Не "существенно выше" sm.gif , а на одну позицию.
Forger
Цитата(ViKo @ Jun 14 2018, 22:05) *
Приоритеты у них разные, а табличка у вас неправильная. rolleyes.gif

Значит msdn тоже врет, все врут! Но коли так, покажите свою "правильную" табличку cool.gif
gosha-z
Народ, вы чего? Там все однозначно безо всяких толкований. a[b++] - инкрементим индекс, не трогая элемент массива, a[b]++ - инкрементим элемент, не трогая индекс. Любой другой вариант уже начинает попахивать нарушением MISRA C Rule 12.2
Forger
Цитата(gosha-z @ Jun 14 2018, 22:36) *
Народ, вы чего?

И то верно blink.gif

Честно говоря, я решил, что речь идет про трактовку компилятором g_sPreset[g_uiCounterPush]++: либо (g_sPreset[g_uiCounterPush])++ либо (g_sPreset++)[g_uiCounterPush]. blush.gif


Если все же по теме, то ясен пень, что сначала выполнится то, что внутри оператора [ ], а потом и сам оператор [].
ViKo
Цитата(Forger @ Jun 14 2018, 22:12) *
Значит msdn тоже врет, все врут! Но коли так, покажите свою "правильную" табличку cool.gif

Посмотрите у Кернигана с Ричи, и у Шилда в книгах.
Forger
Цитата(ViKo @ Jun 15 2018, 07:52) *
Посмотрите у Кернигана с Ричи, и у Шилда в книгах.
Чтобы не быть голословным, приведите сюда конкретные цитаты из этих книг, а конкретно приоритеты оператора постфиксного инкремента ++ и оператора [].
k155la3
Цитата(Forger @ Jun 14 2018, 21:11) *
. . . Оператор "[]" имеет приоритет, равный приоритету оператора "++". . .
Это не так, приоритеты у них одинаковые ))
Да, надо будет перечитать "классику". И делать это постоянно sm.gif
+ порядок "разбора" строки компилятором слева направо, как обычные операторы +-*/
Ни у кого не возникает вопроса в результате выражения A/B*C



ViKo
Цитата(Forger @ Jun 15 2018, 08:01) *
Чтобы не быть голословным, приведите сюда конкретные цитаты из этих книг, а конкретно приоритеты оператора постфиксного инкремента ++ и оператора [].

Я думаю, вы в состоянии самостоятельно полистать книги. Стр. примерно 66 - 69. Для пост- и пре- ++ и - - там нет различий, это, видимо, позже придумали словоблуды (стандартизаторы) и шарлатаны из MS. Кстати, в стандарте что на этот счет?
P.S. в стандарте на C99 я не нашел слова priority
k155la3
? z1 = ++ms[10] - синтаксис оператора для двух приведенных вариантов один. Тут могут быть грабли ?

динамический массив
Цитата
int ms[100], z0, z1;
. . .
z = ms[10]++;
z1 = ++ms[10];

указатель на массив
Цитата
int *ms = new int(100);
int z0, z1, z3;
. . .
z = ms[10]++;
z1 = ++ms[10];
z3 = (++ms)[10];
aiwa
Цитата(Jenya7 @ Jun 14 2018, 18:10) *
а можно узнать что имел в виду писавший это? a[b]++ или таки a[b++]

Чтобы узнать что имел ввиду писавший лучше спросить у самого писавшего.
Но написал он инкремент элемента массива, а не индекса.

Цитата(k155la3 @ Jun 15 2018, 10:30) *
? z1 = ++ms[10] - синтаксис оператора для двух приведенных вариантов один. Тут могут быть грабли ?


В простых выражениях ++a[b] (или a[b]++) никаких грабель не будет, причем независимо от порядка разбора.

В обоих случах "int *ms = new int(100);" и "int *ms = new int(100);" для компилятора различия сводятся
лишь к проверке типа, а сама переменная ms является по сути указателем в обоих случаях.



Forger
Цитата(ViKo @ Jun 15 2018, 10:15) *
Для пост- и пре- ++ и - - там нет различий, это, видимо, позже придумали словоблуды (стандартизаторы) и шарлатаны из MS. Кстати, в стандарте что на этот счет?

В стандарте С99 нет деления между постфиксным и префиксным инкрементом. Приоритет этих операций равен приоритету оператора [].
В стандартах C++ префиксный операторы перенесли в группу приоритетов ниже. Постфиксные остались на прежнем месте.

Т.е. как я и говорил постфиксный ++ имеет равный приоритет как и []. Не зависимо от стандарта. Не путайте народ!

Вот ссылки для сравнения:
http://ru.cppreference.com/w/c/language/operator_precedence
http://ru.cppreference.com/w/cpp/language/...ator_precedence
ViKo
Из Шилдта
Цитата
Order of Evaluation
C does not specify the order in which the subexpressions of an expression are evaluated. This leaves
the compiler free to rearrange an expression to produce more
Highest ( ) [ ] –>.
! ~ ++ – – – (type) * & sizeof
* / %
+ –
<< >>
< <= > >=
== !=
&
^
|
&&
| |
?:
= += –= *= /= etc.
Lowest ,
Table 2 -8. Precedence of C Operators


Из К&R
Цитата
Operators Associativity
() [] -> . left to right
! ~ ++ -- + - * (type) sizeof right to left
* / % left to right
+ - left to right
<< >> left to right
< <= > >= left to right
== != left to right
& left to right
^ left to right
| left to right
&& left to right
|| left to right
?: right to left
= += -= *= /= %= &= ^= |= <<= >>= right to left
, left to right
Forger
Цитата(ViKo @ Jun 15 2018, 10:15) *
в стандарте на C99 я не нашел слова priority

Там используется другой термин: precedence

Вот любопытная ссылка:
https://www.geeksforgeeks.org/difference-between-p-p-and-p/
По сути a[b] есть (*( a + b ))
Herz
Автор! В этом разделе 99% вопросов "по коду". Вы же не новичок, Вам должно быть это известно. Придумайте, пожалуйста, для темы более чёткое название.
ViKo
Цитата(Forger @ Jun 15 2018, 13:16) *
Там используется другой термин: precedence

Я по всякому искал, не нашел. Это удивляет.
P.S. но не очень усердно
k155la3
IMHO: Использование постфиксных, и тем более - префиксных ++ в составе выражения ухудшает читабельность кода.
Смысла особого в такой "упаковке" не вижу. Компилятору - это филоетово, Будет ли оптимизация у исполнимого кода,
и к чему она приведет при таком написании - вопрос. Имело смысл, когда тактовая процессора измерялась килогерцами.
Хотя если задача - запутать читающего - то "самое-то" sm.gif
Forger
Цитата(ViKo @ Jun 15 2018, 13:51) *
Я по всякому искал, не нашел. Это удивляет.

Увы, в стандарте нет явной precedence table, есть только жалкие крохи, которые еще больше запутывают.
Я пришел к выводу, что каждый компилятор может некоторые нюансы трактовать по-своему. Другими словами стандарт "отдает это на откуп" разработчику компилятора.
Поэтому подобные "мутные дела" лучше проверять на конкретном компиляторе.
Хотя, имхо, правильнее вообще избегать таких мутных дел и писать код более явно, чтобы любой компилятор правильно понял это. Да и читать такой код намного проще ))
ViKo
Цитата(Forger @ Jun 15 2018, 13:58) *
Хотя, имхо, правильнее вообще избегать таких мутных дел и писать код более явно, чтобы любой компилятор правильно понял это. Да и читать такой код намного проще ))

Это верно. Но я имею таблицу приоритетов в файле, куда складываю "умные мысли", примеры на C (преимущественно с этого сайта). И периодически к ней обращаюсь, чтобы не писать лишних скобок. Увы, наизусть не выучил. Да и не хочу доверять памяти то, что можно доверить компьютеру.
Forger
Цитата(ViKo @ Jun 15 2018, 14:38) *
Но я имею таблицу приоритетов в файле, куда складываю "умные мысли",

Вот еще нашел любопытную таблицу: http://www.difranco.net/compsci/C_Operator...dence_Table.htm
Некоторые группы операторов тут имеют приоритет справа-налево, в отличие от большинства остальных групп.

Честно говоря, когда вижу в одном выражении смесь операторов "++/--" вместе с другими операторами, то стараюсь "от греха подальше" разделять их оператором ";" (на другую строку переносить).
Особенно это актуально при работе с указателями (операторы ->, *) - грабли с ними могут быть очень коварные smile3046.gif
esaulenka
Цитата(k155la3 @ Jun 15 2018, 13:57) *
IMHO: Использование постфиксных, и тем более - префиксных ++ в составе выражения ухудшает читабельность кода.

Что в данном конкретном примере нечитабельно?
Просто и наглядно: если значение в первом массиве меньше, чем соответствующее значение во втором, увеличиваем это значение.
Как это можно понять по-другому?!

А тема занятная получилась. Выяснилось, что приоритет операций в стандарте C99 явно не описан (наверное, его можно восстановить из форм Бэкуса-Наура, но уж больно лень) и он отличается (!) от приоритетов C++.
Хотя, конечно, стандарты C++ писали неглупые люди и про совместимость они подумали. Лично я ни разу не наступил на грабли, пользуясь им в этой части при написании сишного кода.
k155la3
Цитата(esaulenka @ Jun 15 2018, 15:42) *
Что в данном конкретном примере нечитабельно?
В данном и конкретном все понятно. (Если речь о том, что в первом посте)
Я в смысле применения к выражениям,
Цитата
a = b++ * 2 + b;

на что IAR выдает
Цитата
Warning[Pa081]: undefined behavior: the order of read and modification of variable "b" (declared 1at line 72) (or a value reached by some form of indirection through it) is undefined in this statement main.c 79
Оттранслировалось ли ЭТО в код не проверял.
Может кто более удачный пример "эффективного кода" приведет, не выдающего warning, error, но нечитабельного.



Forger
Цитата(k155la3 @ Jun 15 2018, 17:11) *
Может кто более удачный пример "эффективного кода" приведет, не выдающего warning, error, но нечитабельного.

За этим лучше сразу сюда: https://www.govnokod.ru biggrin.gif
aiwa
Цитата(k155la3 @ Jun 15 2018, 17:11) *
В данном и конкретном все понятно. (Если речь о том, что в первом посте)

Может кто более удачный пример "эффективного кода" приведет, не выдающего warning, error, но нечитабельного.


Неоднозначность результата компилирования и читабельность кода - суть вещи разные.
Приведенный Вами пример (a = b++ * 2 + b;) очень даже читабельный, хотя и неоднозначный.
Forger
Цитата(aiwa @ Jun 15 2018, 23:17) *
пример (a = b++ * 2 + b;) очень даже читабельный,

Неясно, что подразумевается под термином "читабельный": умение читать код или умение понимать прочитанное?
Второе подразумевает явное знание работы компилятора и его действий.
Если же поведение компилятора в том или ином случае сложно предсказать, то как ни старайся именовать курицу павлином , все равно курицей она так и останется sm.gif
aiwa
Цитата(Forger @ Jun 15 2018, 23:21) *
Неясно, что подразумевается под термином "читабельный": умение читать код или умение понимать прочитанное?
Второе подразумевает явное знание работы компилятора и его действий.

"Читабельность" - это совершенно субъективная инстанция, а работа компилятора - объективная.

Но если подразумевать под "читабельностью" предсказание работы компилятора, то - да, нечитабельный: компилятор даже вправе генерить различный код для такого оператора в разных местах.

Хотя пример лучше поменять на "а = b++ *2 + sin( b ); потому что старый можно оптимизировать в "а = b++ * 3;" воспользовавшись неоднозначностью порядка"
Forger
Цитата(aiwa @ Jun 16 2018, 00:44) *
...да, нечитабельный
Вот и я том же!
Применение винегрета (из разношерстных операторов при неоправданной экономии скобок () в пределах одного оператора ";") - любой код сделает нечитабельным, нечитаемым и т. п.
Озвучивать название такому "коду" тут запрещено правилами форума, но, я уверен, что все понимают о чем речь wink.gif

Потому возникает риторический вопрос: есть ли вообще смысл анализировать подобный "код", когда сходу сразу понятно, что нифига не понятно? ...

А всего-то достаточно добавить несколько пар скобок или операторов ";" с соотв. переносом строки, чтобы напрочь закрыть любую "необъективность" даже самого "упоротого" кода.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.