Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Си
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
Страницы: 1, 2, 3, 4, 5, 6
demiurg_spb
Цитата(Herz @ Mar 26 2013, 13:58) *
Если честно, то тогда это недоразумение. Мы говорили о записи, в которой используется остаток от деления. Именно эту запись я предлагал Вам произнести.
Хорошо. Мы поговорим о
Код
с = (!a + !b) % 2;

Тут я виду солжение двух булов по модулю 2.
ИМХО, написано самым выразительным образом из всех возможных.
Herz
Цитата(demiurg_spb @ Mar 26 2013, 13:17) *
Хорошо. Мы поговорим о
.....

Нет, видимо, не получится. Мы с Вами на слишком разных языках говорим, как оказывается.
Цитата
Тут я виду солжение двух булов по модулю 2.
ИМХО, написано самым выразительным образом из всех возможных.


Ну, если это - самый выразительный... laughing.gif

А я тут вижу присваивание переменной с остатка от деления (что, кстати, не является логической операцией!) на два суммы двух аргументов, в данном случае приведенных к булам.
О том, что результат является логическим и что он соответствует "исключающему ИЛИ", можно догадаться, лишь расшифровав эту запись и поняв, что же происходит в ходе выполнения последовательности, описанной столь причудливо.
Не пойму, для чего Вы привели ссылку, ибо там как раз говорится противоположное тому, что Вы доказываете:

Цитата
В естественном языке операция «сложение по модулю» эквивалентна двум выражениям:

«результат истинен (равен 1), если A не равно B (A≠B)»;
«если A не равно B (A≠B), то истина (1)».

Часто указывают на сходство между сложением по модулю 2 и конструкцией «либо … либо …» в естественном языке.


Как по-Вашему, можно таким, естественным языком прочесть обсуждаемую запись?
Впрочем, вопрос риторический. Я, кажется, Вашу позицию хорошо понял. Тоже не стану больше спорить.
demiurg_spb
Цитата(Herz @ Mar 26 2013, 17:19) *
Просто когда знешь термин сложение по модулю два то это читается очень просто (видишь сложение и видишь взятие модуля 2).
Если этого не знаешь никто не мешает написать так как предлагаете вы.
Код
с = (!a != !b);
Никакой принципиальной разницы тут нет.
Лично я, да и многие другие программисты, стараются минимизировать количество условных операций в своих программах.
Т.к. линейный код (без ветвлений) зачастую выполняется быстрее и ложиться оптимальнее на большинство платформ (особенно старых).
Поэтому я на автомате уже пишу конструкции подобные
Код
с = !a ^ !b;

Также, как следствие применения максимально линейного кода уменьшается джиттер и программа становится более детерминированная, что иногда бывает критически важным.
Поймите, есть разные подходы к программированию и разные задачи.
У меня за более чем 15-ти летний стаж фактически ежедневного программирования было много различных задач: от промышленных приборов и автоматики, до комплексов искробезопасных ПЛК для горнорудной промышленности и приборов для военных применений на флоте и в авиации.
Как это не пафосно звучит, но когда от твоего софта зависят жизни людей привычки писать надёжный и детерминированный код вырабатываются сами-собой.
toweroff
Цитата(demiurg_spb @ Mar 26 2013, 15:17) *
Тут я виду солжение двух булов

то есть приведенных к ближайшему целому типу 0 и 1?
и опять в этом случае мы уходим от как такового bool к целочисленному типу

я не говорю, что это непонятно. Я никоим образом не утверждаю, что это абсурд, ибо машиное слово - оно и есть машинное, и процессор оперирует только ими. Также все "логические" типы - это только приведение в некий машинный вид операнда. Но ARV ратует именно за интуитивно по-человечески понятную запись, стиль Pascal не дает покоя sm.gif
XVR
Напишу еще немного. sm.gif Во первых, я хочу сказать, что несмотря на бурную дискуссию с ARV я согласен с почти всеми его высказываниями. Различие я вижу лишь в том, что считать 'естественным, логичным и интуитивно понятным', а что таковым не является.

Disclamer: Все нижеслдующее никоим образом не связанно ни с какими участниками этой дискуссии

Что же такое 'естественое и огичное'? Давайте споросим у бубульки возле подъезда - нужно ли разделять логические и арифметические операции? Как думаете, что она вам ответит? wink.gif Ладно, согласен - не та целевая аудитория. Давайте спросим у программиста, но тут есть загвоздка - у какого именно? Не бывает 'сферического программиста в ваккуме'. Каждый язык програмирования построен вокруг некоторого набора принципов и правил, и наборы эти разные. И не надо аппелировать к математической логике - она напрямую не применима к языкам програмирования, т.к. они строились не для доказательства математических теорем, а для написания программ.

Как вы думаете, эти коды согласуются с 'здравым смыслом и математической логикой'?

Код
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)


Код
select: aBlock
| newCollection |
newCollection := self species new.
self do: [:each |
    (aBlock value: each)
        ifTrue: [newCollection add: each]].
^newCollection


Код
gcd2(A, 0, A).
gcd2(A, B, G) :- A>0, B>0, N is mod(A, B), gcd2(B, N, G).

gcdn(A, [], A).
gcdn(A, [B|Bs], G) :- gcd2(A, B, N), gcdn(N, Bs, G).
gcdn([A|As], G) :- gcdn(A, As, G).

:- initialization(main).

str2int([], []).
str2int([S|St], [N|Nt]) :- number_atom(N, S), str2int(St, Nt).

main :-
    argument_list(Args),
    str2int(Args, Numbers),
    gcdn(Numbers, G),
    write(G), nl.


Код
(~R∊R∘.×R)/R←1↓⍳R


На возможный ответ 'что это за бред' сразу отвечу - вполне законные куски программ на разных языках, а именно - Haskel, Smalltalk, Prolog, APL

Давайте возмем более близкие языки - С и Pascal. Несмотря на их внешнюю схожесть (по сравнению с вышеизложенными кусками кода), они очень разные. И как это пародоксально не звучит, С более простой язык. В С уменьшено количество сущностей языка и практически убраны какие либо ограничения на использование конкретных конструкций в конкретных местах. Все описывается именно на уровне сущностей.
Например - в Pascal'е операция сравнения, присваивание и арифметика это разные сущности и используются они в разных, строго определенных контекстах. В С это все выражения, и использоваться они могут везде, где ожидается выражение. В Pascal'е все очень строго оговорено и определено. Шаг влево, шаг вправо - расстрел sm.gif
Поэтому запись на С
Код
int a=b==c;
вызывает у Pascal'иста взрыв мозга - как так, тут же сравнение, значит должен быть if!
И не надо аппелировать к логике и здравому смыслу - у програмистов на С и Pascal'е они будут разными. Более того, они и должны быть разными - языки же разные!
Так же становится понятными жалобы со стороны Pascal'истов на сложность С. На самом деле они жалуются не на сложность, а на то, что способы применения вроде бы понятных и тривиальных конструкций порой оказываются совершенно другими. Так же понятно, почему с Pascal'я неохотно переходят на С - не хочется вылезать из песочницы, там все так просто и безопасно wink.gif И понятно, почему все же перейдя на С обратно уже не возвращаются - мир интереснее, чем песочница.

На самом деле есть гораздо более опасная связка - переход с С на С++. Несмотря на их внешнюю практически идентичность, эти языки отличаются горадо больше, чем С и Pascal. А если неофиту еще скажут, что в настоящей ООП программе все должно быть в виде классов, то получаются жуткие классовые монстры, такие, что не в сказке сказать не вслух произнести wink.gif
ARV
да при чем тут паскаль-style... вы посмотрите: везде и всюду логические переменные обособлены от числовых, и только Си стоит особняком... ну 40 лет назад это имело какое-то оправдание - каждый бит был на счету, каждый герц и т.д. и т.п., можно было жертвовать частью логичности в пользу какой-то "оптимальности", но сейчас это уже атавизм какой-то... есть же средства в Си, чтобы избежать этой странности? почему бы не сделать правилом хорошего тона их активное использование?
=AK=
Цитата(XVR @ Mar 27 2013, 15:15) *
Давайте возмем более близкие языки - С и Pascal. Несмотря на их внешнюю схожесть (по сравнению с вышеизложенными кусками кода), они очень разные. И как это пародоксально не звучит, С более простой язык. В С уменьшено количество сущностей языка и практически убраны какие либо ограничения на использование конкретных конструкций в конкретных местах. Все описывается именно на уровне сущностей.

С точностью до наоборот. Более простой язык имеет более простую (т.е компактную, короткую) БНФ. Как известно, БНФ Паскаля в разы меньше БНФ С. А БНФ Форта в разы меньше БНФ Паскаля, вот он и впрямь простой язык.
ARV
об одном я всех умоляю: не надо холивара C vs PASCAL!

Цитата(XVR @ Mar 27 2013, 08:45) *
Поэтому запись на С
Код
int a=b==c;
вызывает у Pascal'иста взрыв мозга - как так, тут же сравнение, значит должен быть if!
И не надо аппелировать к логике и здравому смыслу - у програмистов на С и Pascal'е они будут разными. Более того, они и должны быть разными - языки же разные!
все без исключения люди в своей жизни руководствуются абсолютно одинаковой логикой если-то-иначе-и-или-не и т.д. и т.п., не взирая на более чем 160 различных языков, на которых они говорят! разница в языках программирования может объяснять разницу в подходах к решению задачи, но не разницу в логике!


взрыва мозга вызывает не присваиваивание результата сравнения переменной, а тот факт, что этот результат присваивается переменной целочисленного типа! вот в чем коренная проблема, показанная на этом простом примере. в паскале абсолютно допустимо написать bool_var := a = b; - с учетом синтаксиса это совершенно полный эквивалент вашего примера, но переменная bool_var должна быть описана как boolean, то есть булева переменная. и для этой переменной выражения not bool_var не имеет никаких противоречий со здравым смыслом, т.к. ни при каких условиях не может подменять множество вариантов одним, как в случае семантически идентичной записи Си !var

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

но главное не это: ведь есть же способ исключить любые парадоксы в тексте программ на Си! для этого надо пользоваться принципом бритвы Оккама: не плоди сущности без нужды. если нужны логические действия, делаем их при помощи имеющихся в Си ЛОГИЧЕСКИХ манипуляций над логическими же данными. если уж а=25 признается стандартом за эквивалент логической истины, то для приведения этого в соответствии с настоящей логикой следовало бы применять не !!a, но a != 0 - только и всего! на 1 значащий символ длиннее запись, но на стопицот процентов ЛОГИЧНЕЕ!!!
MrYuran
Все очень просто.
Си изначально разрабатывался как структурированный макроассемблер, соответственно и методики сходные.
Как в ассемблере оценивается результат логических операций? Обычно через флаг Z.
Собственно, вот и оно.
Всего два состояния - ноль и неноль.
ARV
Цитата(MrYuran @ Mar 27 2013, 10:35) *
Все очень просто.
Си изначально разрабатывался как структурированный макроассемблер, соответственно и методики сходные.
Как в ассемблере оценивается результат логических операций? Обычно через флаг Z.
Собственно, вот и оно.
Всего два состояния - ноль и неноль.
да-да-да, все в кусре. а зачем тогда вообще Си? давайте все на ассемблере, или лучше в машинных кодах, к чему полумеры?

я вижу назначение языка программирования в том, чтобы быть мостом между человеческим мозгом и двоичными мозгами машины. и разумеется этот мост должен в идеале пропускать абсолютно все человеческие понятия без ограничений, т.е мало кого порадует мост, по которому можно только на одной ноге пропрыгать... это в идеале - я подчеркиваю. и заодно предлагаю, как из имеющегося материала Си (т.е. стандарта) путем простых действий расширить имеющийся мостик... не предлагаю ничего изымать из Си или прибавлять - всего-навсего думать чуть иначе, не так, как приучили себя в рамках "близости к железу", а так, как подсказывает человеческая логика. хотя бы до тех пор, пока экономия байта в коде не станет жизненно необходимой. ужимать поведение своего мозга в угоду машинному считаю не совсем правильным.
XVR
Цитата(ARV @ Mar 27 2013, 10:04) *
взрыва мозга вызывает не присваиваивание результата сравнения переменной, а тот факт, что этот результат присваивается переменной целочисленного типа!
Тут как раз все просто. Ну не было в С логического (boolean) типа, не было! Когда поняли, что он все же нужен, было уже поздно. Кстати, в С99 он все же появился, но какой то недоделанный, увы.
В С++ тип bool есть от рождения, и там он ведет себя именно так, как вы и хотите.

Цитата
но главное не это: ведь есть же способ исключить любые парадоксы в тексте программ на Си! для этого надо пользоваться принципом бритвы Оккама: не плоди сущности без нужды. если нужны логические действия, делаем их при помощи имеющихся в Си ЛОГИЧЕСКИХ манипуляций над логическими же данными.
Я уже устал вам объяснять - нет в С логических данных, а есть только числа. И логические операции - это всего лишь специальные псевдо-арифметические операции над целыми числами. И это не какие то тайные знания, которые доступны только ценителям и знатокам стандарта, а то, что было в этом языке всегда с самого его рождения.
Вместо того, что бы осознать базовые концепции языка С вы пытаетесь навязать всем свои собственные концепции, и заявляете, что все, что в С с ними не совпадает является ошибкой!

В общем вы когда переходили от Pascal'я к С видимо не вылезли из песочницы, а прихватили ее с собой, и теперь пытаетесь всех проходящих мимо в нее затянуть. 1111493779.gif
MrYuran
В общем, язык си писали программисты для самих себя, поэтому он позволяет множество различных вольностей.
Это его сильная и одновременно слабая сторона.
Для тех, кто привык к порядку, вояки изобрели MISRA C
ViKo
Цитата(XVR @ Mar 27 2013, 10:19) *
Тут как раз все просто. Ну не было в С логического (boolean) типа, не было! Когда поняли, что он все же нужен, было уже поздно. Кстати, в С99 он все же появился, но какой то недоделанный, увы.

И очень странно, что не было. И очень глупо, что нормального нет до сих пор.
Хотя... а в чем недоделанность _Bool ? Кроме ужасного названия?
XVR
Цитата(ViKo @ Mar 27 2013, 11:38) *
Хотя... а в чем недоделанность _Bool ? Кроме ужасного названия?
В том, что все логические операции в С до сих пор работают не с ним, а с int. Т.е. тип есть, но его никто не использует rolleyes.gif

ViKo
Я использую битовые поля. В них помещается сразу много битов. sm.gif
XVR
Цитата(ViKo @ Mar 27 2013, 11:59) *
Я использую битовые поля. В них помещается сразу много битов. sm.gif
И это правильно. А еще лучше использовать битовые шкалы rolleyes.gif Хотя нет, сейчас налетят поборники 'логичности' и заклюют за использование битовой операции '&' в условных выражениях wink.gif
ARV
Цитата(XVR @ Mar 27 2013, 11:19) *
Я уже устал вам объяснять - нет в С логических данных, а есть только числа. И логические операции - это всего лишь специальные псевдо-арифметические операции над целыми числами. И это не какие то тайные знания, которые доступны только ценителям и знатокам стандарта, а то, что было в этом языке всегда с самого его рождения.
Вместо того, что бы осознать базовые концепции языка С вы пытаетесь навязать всем свои собственные концепции, и заявляете, что все, что в С с ними не совпадает является ошибкой!

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

может 48 шрифтом это написать?

я просто поражаюсь: вы спорите не с моими утверждениями, а с приписываемыми вами мне... остановитесь, пожалуйста, это абсолютно бесплодно.
ViKo
Цитата(ARV @ Mar 27 2013, 11:08) *
я не предлагаю отказаться от стандартных положений языка Си, я предлагаю использовать их так, чтобы избавиться от присущих Си противоречий

А я люблю писать компактно, без лишних скобок, с минимальным количеством операторов. Считаю, что и компилируется более компактно, и работает чуть быстрее. Наверное, может оказаться и наоборот, в исключительных случаях. Если потребуется, можно проверить конкретно, что лучше.
Логика !a ^ !b мне понятна. Ради скорейшего понимания выражения кем-то посторонним или самим собой, когда-нибудь, "красотой" я жертвовать не буду.
sasamy
Цитата(ARV @ Mar 27 2013, 10:04) *
в соответствии с настоящей логикой следовало бы применять не !!a, но a != 0 - только и всего! на 1 значащий символ длиннее запись, но на стопицот процентов ЛОГИЧНЕЕ!!!


вы зря тратите нервы, тут контингент несколько специфичный, мозг на ассемблер заточен и на чем бы они ни писали и какой процессор не программировали - один фиг это будет ассемблер и ногодрыг, короче говоря искробезопасный код sm.gif
ARV
Цитата(MrYuran @ Mar 27 2013, 11:26) *
В общем, язык си писали программисты для самих себя, поэтому он позволяет множество различных вольностей.
Это его сильная и одновременно слабая сторона.
а как из этого следует категорическое нежелание программистов отказаться от использования слабых сторон Си? я вижу совсем немного моментов, которые явно не укладываются в обычные представления о мире:

1. возможность для автоматических переменных задавать одинаковые идентификаторы во вложенных блоках.


2. упомянутое назначение для обозначения логических значений 1 и !1 или 0 и !0

3. использование "для оптимальности" вариаций 5[a] и аналогичных "трюков".

по-моему, это все sm.gif всех делов - не пользоваться этими возможностями (кроме как под угрозой страшных бед), благо никаких титанических усилий для этого не потребуется, кроме собственного желания. все мои рекомендции из категории оформления кода "красиво" - типа давать переменным осмысленные имена, не применять магические числа и т.п.



Цитата(ViKo @ Mar 27 2013, 12:17) *
Ради скорейшего понимания выражения кем-то посторонним или самим собой, когда-нибудь, "красотой" я жертвовать не буду.
что ж, тогда вам неизбежно придется жертвовать своим временем и нервами ради понимания чужой "красоты" sm.gif
demiurg_spb
Цитата(ViKo @ Mar 27 2013, 11:38) *
Хотя... а в чем недоделанность _Bool ? Кроме ужасного названия?
Он размером с int.
И например на AVR от него никакого толку т.к. не помещается в байт.
ViKo
Надо в стандарте записать, чтобы одиночные битовые поля имели тип bool.

Цитата(demiurg_spb @ Mar 27 2013, 12:28) *
И например на AVR от него никакого толку т.к. не помещается в байт.

И в крынку битовое поле не лезет? Оно же имеет тип int. sm.gif
XVR
Цитата(ARV @ Mar 27 2013, 12:27) *
1. возможность для автоматических переменных задавать одинаковые идентификаторы во вложенных блоках.
Согласен, но с одним уточнением - намеренное использование одинаковых идентификаторов. Иначе программисту придется перед тем, как сделать например такое в какой то функции -
Код
{
int i;
for(i=0;i<10;++i) a[i]=i;
}
просмотреть весь остальной код функции, что бы убедится, что там нигде не используется i

Цитата
3. использование "для оптимальности" вариаций 5[a] и аналогичных "трюков".
Это не 'трюк', это вообще 'курьез'. Использовать это в программе можно только с явной целью всех запутать. rolleyes.gif Так что с этим пунктом тоже согласен.

ar__systems
Цитата(ViKo @ Mar 27 2013, 03:17) *
А я люблю писать компактно, без лишних скобок, с минимальным количеством операторов. Считаю, что и компилируется более компактно, и работает чуть быстрее

Вы еще без лишних пробелов пишите, вдруг более компактно компилироваться будет )))
ViKo
Цитата(ar__systems @ Mar 28 2013, 16:01) *
Вы еще без лишних пробелов пишите, вдруг более компактно компилироваться будет )))

Вот это в мое понятие о красоте и целесообразности не укладывается! Посмотрел, как в книжках пишут, на форуме, выработал свой стиль. Взял лучшее.
demiurg_spb
astyle рулит - за секунду переформатирует любой "страшный" си-код под свои предпочтения.
SyncLair
Цитата(demiurg_spb @ Mar 28 2013, 17:27) *
astyle рулит - за секунду переформатирует любой "страшный" си-код под свои предпочтения.

Может подскажите как заставить astyle переменные писать с начала строки а код с таба?
Код
int fn(int a,int b)
{
int c;
<TAB>c = a+ b;
<TAB>какой-то код
return c;
}
demiurg_spb
Цитата(SyncLair @ Mar 28 2013, 21:02) *
Может подскажите как заставить astyle переменные писать с начала строки а код с таба?
Не подскажу.
Никогда такого желания не возникало.
demiurg_spb
Вот пример макроса, используемого в исходниках Linux.
Тот кто сможет это осознать уже заслуживает медали;-)

Код
#define container_of(ptr, type, member) ({ \
                const typeof( ((type *)0)->member ) *__mptr = (ptr);
                (type *)( (char *)__mptr - offsetof(type,member) );})
sasamy
Цитата(demiurg_spb @ Apr 5 2013, 11:08) *
Вот пример макроса используемого в исходниках Linux.
Тот кто сможет это осознать уже заслуживает медали;-)

Код
#define container_of(ptr, type, member) ({ \
                const typeof( ((type *)0)->member ) *__mptr = (ptr);
                (type *)( (char *)__mptr - offsetof(type,member) );})


Вычисляет адрес структуры типа type по известному указателю ptr на ее элемент с именем member
neiver
Цитата(sasamy @ Apr 5 2013, 11:37) *
Вычисляет адрес структуры типа type по известному указателю ptr на ее элемент с именем member

Тому кто сможет сделать этот макрос без использования трёх применённых там GCC-шных расширений, используя только стандартный С99, тому можно сразу памятник нерукотворный sm.gif
SyncLair
Цитата(neiver @ Apr 5 2013, 14:20) *
Тому кто сможет сделать этот макрос без использования трёх применённых там GCC-шных расширений, используя только стандартный С99, тому можно сразу памятник нерукотворный sm.gif

как то я не вижу трёх расишрений -- вроде ведь только одно (TYPEOF()) ?
и TYPEOF() * на void * можно заменить ?


sasamy
Цитата(neiver @ Apr 5 2013, 14:20) *
Тому кто сможет сделать этот макрос без использования трёх применённых там GCC-шных расширений, используя только стандартный С99, тому можно сразу памятник нерукотворный sm.gif


А зачем ? Это - не для всех sm.gif
http://www.ibm.com/developerworks/ru/library/l-gcc-hacks/
Nixon
Код
#define CONTAINING_RECORD(address, type, field) ((type *)((unsigned char *)(address) - (unsigned char *)(&((type *)0)->field)))

Ставьте памятник sm.gif Авторам TNKernel sm.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.