|
|
  |
Си |
|
|
|
Mar 24 2013, 07:09
|

Профессионал
    
Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581

|
Цитата(Буратино @ Mar 24 2013, 10:33)  Скажите, а нужны скобки в этом коде? Код return (!x && y) || (x && !y); формально - не нужны. боюсь, меня заплюют, как обычно, но я ставлю скобки везде, где они позволяют визуально выделить "полезные" части выражения, чтобы, как обычно, никто не напрягал лишний раз голову, вспоминая о приоритетах операций. в пользу моего подхода задайте вопрос любому своему знакомому: сколько будет два плюс два умножить на два? почти 99% с первой попытки отвечают 8, хотя правила арифметики знают даже двоечники...
--------------------
Я бы взял частями... но мне надо сразу.
|
|
|
|
|
Mar 24 2013, 07:52
|

Универсальный солдатик
     
Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362

|
Цитата(igorle @ Mar 23 2013, 23:02)  Затем Вам показали, что В УЧЕБНЫХ целях полезно ПОНЯТЬ, почему 5[a] эквивалентно a[5]. ... Такой код НУЖНО использовать при обучении, для демонстрации области дейстия автоматических переменных. И... почему? Кто бы объяснил "на пальцах", как работает 5[a]. У классиков я такого не нашел. Про "зачем" не спрашиваю, считаю "незачем".  Насчет скобок - стараюсь не писать лишние. Мне интереснее в список приоритетов заглянуть. И писать лаконично, "красиво". Но вот последний Keil в своем редакторе выдает предупреждающие знаки, когда из-за приоритета операций, возможно, получится не то, чего я желаю.
|
|
|
|
|
Mar 24 2013, 08:06
|
Местный
  
Группа: Свой
Сообщений: 338
Регистрация: 14-07-12
Пользователь №: 72 753

|
Цитата(ARV @ Mar 24 2013, 08:56)  никто на планете Земля не желает, чтобы бацилла чумы существовала наравне с человеком, хотя это естественный биологический вид, теоретически имеющий право на существование. бациллу чумы уничтожили - и все стали только счастливее. Вот смотрите до чего вы докатились. Вы уже говорите о знаниях как о бацилле. Приравняли ЗНАНИЯ к ЧУМЕ. Средневековье какое-то. Завтра вы начнете книгу K&R жечь на кострах. Интересно, а как вы, не обремененный лишними знаниями, будете писать несложные, но выходящие за рамки банальных знаний функции. Как вы и ваши ученики будут писать прототип функции с одним аргументом, получающей 1) указатель на массив типа int a[10][10]; 2) указатель на массив типа int *a[10]; 3) указатель на функцию, получающую в качестве аргумента указатель из первого вопроса, а возвращающую указатель из второго вопроса. Надеюсь вы не считаете, что подобные функции никому не нужны? Цитата(ViKo @ Mar 24 2013, 11:52)  И... почему? Кто бы объяснил "на пальцах", как работает 5[a]. У классиков я такого не нашел. Про "зачем" не спрашиваю, считаю "незачем". :) Совсем на пальцах a[5] эквивалентно *(a+5) От перемены мест слагаемых...
Сообщение отредактировал igorle - Mar 24 2013, 09:49
|
|
|
|
|
Mar 24 2013, 08:20
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
QUOTE (XVR @ Mar 23 2013, 22:27)  По поводу a[5] vs 5[a] - зтого специально никто не добивался. Это всего лишь побочное следствие определения семантики языка. Очевидно использовать это в реальных программах смысла никакого нет. Согласился бы с более мягкой формулировкой: "...использовать это в реальных программах настоятельной необходимости нет". Потому что, иногда такая запись, имхо, лучше акцентирует замысел. Например, есть несколько массивов, и надо пройтись по энному - скажем, пятому - элементу всех массивов: CODE #include <stdio.h>
int A1[10] = { 1,2,3,4,5,6,7,8,9,0 }; int A2[10] = { 11,22,33,44,55,66,77,88,99,10 }; int A3[10] = { 111,222,333,444,555,666,777,888,999,100 };
int *p[] = { A1, A2, A3 };
int main() { for(int i = 0; i < sizeof(p)/sizeof(p[0]); ++i) { printf("%d\n", 5[p[i]]); printf("%d\n", p[i][5]); } return 0; } Вывод, очевидно, работает одинаково: 6 6 66 66 666 666 но запись 5[p[i]], имхо, заметно выразительнее в данном контексте, чем p[i][5] - мы именно подчёркиваем, что выбираем конкретный элемент всех массивах, а не просто перебираем массивы с какой-то дальнейшей целью - выбор какого-то элемента, как в данном примере. Когда я вижу такую запись, я полагаю, что программист именно хотел сделать акцент этой особенности алгоритма. Мелочь, но к месту. Совершенно согласен, что профессиональный квалифицированный программист должен безо всякого напряжения и ломки воспринимать такого рода конструкции. Признаюсь, что на заре освоения С, когда столкнулся в первый раз с такой записью, испытал лёгкий культурный шок.  Это мотивировало помедитировать над этой темой, через некоторое время всё встало на свои места.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Mar 24 2013, 09:00
|
Местный
  
Группа: Свой
Сообщений: 338
Регистрация: 14-07-12
Пользователь №: 72 753

|
Цитата(dxp @ Mar 24 2013, 11:20)  Согласился бы с более мягкой формулировкой: "...использовать это в реальных программах настоятельной необходимости нет". Потому что, иногда такая запись, имхо, лучше акцентирует замысел. Например, есть несколько массивов, и надо пройтись по энному - скажем, пятому - элементу всех массивов: Очень красивый пример. Действительно, такой код читабельнее. Как и в случае с ксором - взгляд сразу выхватывает суть. Цитата(ViKo @ Mar 24 2013, 11:47)  ... получаем *(5+a). А дальше? "Еще нежнее..." Инкремент указателя сдвигает указатель на следующий элемент массива. Написав a[5], мы говорим сложи a и 5, и верни нам значение, которое хранится в полученом адресе Написав 5[a], мы говорим сложи 5 и a, и верни нам значение, которое хранится в полученом адресе Поскольку 5+a и a+5 дают одинаковый результат, то и получается, что конструкции эквивалентны.
|
|
|
|
|
Mar 24 2013, 09:08
|

Универсальный солдатик
     
Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362

|
Цитата(igorle @ Mar 24 2013, 12:00)  Написав a[5], мы говорим сложи a и 5, и верни нам значение, которое хранится в полученом адресе Написав 5[a], мы говорим сложи 5 и a, и верни нам значение, которое хранится в полученом адресе Да, так понятно. И понятно, что так вычисляется при работе компилятора. Непонятно, почему это допускается, ради простоты реализации? Ведь a[] - это массив, а 5[] - бред. Можно задать массив a[5], но нельзя задать 5[a]. Это - что-то, именуемое "хаком". Таким образом, задать 5[a] нельзя, а использовать можно. И где логика?  P.S. начинаю относиться к K & R, как к шарлатанам.
|
|
|
|
|
Mar 24 2013, 09:35
|
Местный
  
Группа: Свой
Сообщений: 338
Регистрация: 14-07-12
Пользователь №: 72 753

|
Цитата(ViKo @ Mar 24 2013, 12:08)  Да, так понятно. И понятно, что так вычисляется при работе компилятора. Непонятно, почему это допускается, ради простоты реализации? Ведь a[] - это массив, а 5[] - бред. Можно задать массив a[5], но нельзя задать 5[a]. Это - что-то, именуемое "хаком". Таким образом, задать 5[a] нельзя, а использовать можно. И где логика?  P.S. начинаю относиться к K & R, как к шарлатанам.  Исходный код делится на "кирпичики". Оператор "[]" при использовании описывается где-то так: операнды должны быть один - типа поинтер, другой - целое Сложить операнды. (результатом будет поинтер) выполнить опрацию разыменовывания. Это логика, но отнюдь не шарлатанство. Объявление переменной и применение переменной - разные вещи. Вас не смущает, что звездочка может означать и умножение, и указатель, и разыменовывание в зависимости от контекста. Кстати, недостаток логики повергает многих в задумчивость, когда просишь сказать чему равен (-11)%10. А у классиков здесь все четко и просто. Цитата ...Ведь a[] - это массив, а 5[] - бред... Ээээ. Дело привычки. Вспомнил, как давным давно (а я весьма стар), когда мы начинали изучать программирование, мой однокурсник возмущался, что нельзя писать x=x+10, потому что это бред и не может быть верным ни при каком значении x  Уже сегодня вечером вы, не задумываясь, будете думать Ведь a[] - это массив, а 5[] - это шестой элемент массива.
Сообщение отредактировал igorle - Mar 24 2013, 10:00
|
|
|
|
|
Mar 24 2013, 10:40
|

Универсальный солдатик
     
Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362

|
Цитата(igorle @ Mar 24 2013, 12:35)  Вас не смущает, что звездочка может означать и умножение, и указатель, и разыменовывание в зависимости от контекста. Не смущало. Но, после прочтения данной темы, возникла мысль - а почему для взятия адреса не использовали, например, символ @. @a - красота. Цитата(igorle @ Mar 24 2013, 12:35)  Кстати, недостаток логики повергает многих в задумчивость, когда просишь сказать чему равен (-11)%10. А у классиков здесь все четко и просто. Цитирую классиков K&R, 2-е издание, белая, с синей буквой C, стр. 55 Цитата Направление округления при операции / или знак результата при операции % для отрицательных аргументов зависят от системы... Так чему равен результат?  Боюсь ошибиться, 1? -1? Цитата(igorle @ Mar 24 2013, 12:35)  Уже сегодня вечером вы, не задумываясь, будете думать Ведь a[] - это массив, а 5[] - это шестой элемент массива. Прекращайте шутить, и без того все страньше и страньше. Хотя... смотря как считать, начиная с "нулевого" или с "первого". Здесь и классики иногда путаются в терминах. Цитата(igorle @ Mar 24 2013, 12:35)  операнды должны быть один - типа поинтер, другой - целое Сложить операнды. (результатом будет поинтер) И чему равен поинтер на 5?
|
|
|
|
|
Mar 24 2013, 11:00
|
Местный
  
Группа: Свой
Сообщений: 338
Регистрация: 14-07-12
Пользователь №: 72 753

|
Цитата(ViKo @ Mar 24 2013, 13:40)  Цитирую классиков K&R, 2-е издание, белая, с синей буквой C, стр. 55 Вот видите как полезно читать классиков. Суть в том, что сумма результата деления умноженного на делитель и остатка от деления дают исходное число. Таким образом результат будет или -1, или 9. В зависимости от платформы. Кстати, мне пока не попадалась платформа, где округление для отрицательных чисел шло в минус. В смысле -11/10 может на рекоторых платформах давать -2. Тогда остаток от деления будет 9. Но на всех платформах, где я проверял, результат от деления был -1, соответственно остаток от деления - тоже -1. Цитата(ViKo @ Mar 24 2013, 13:40)  И чему равен поинтер на 5?  5 - это не указатель. Это целое. Которое будет складываться с указателем.
|
|
|
|
|
Mar 24 2013, 15:29
|

Профессионал
    
Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581

|
Цитата(igorle @ Mar 24 2013, 12:06)  Вот смотрите до чего вы докатились. Вы уже говорите о знаниях как о бацилле. Приравняли ЗНАНИЯ к ЧУМЕ. Средневековье какое-то. Завтра вы начнете книгу K&R жечь на кострах. как раз наоборот, это вы дальше сказанного К&R не желаете категорически поглядеть, это вы современные инквизиторы, готовые ради догмы закопать кого угодно! я показал нонсенс, когда ЛОГИЧЕСКИЕ операции делаются АРИФМЕТИЧЕСКИМИ операторами, причем для этого используется еще и ЛОГИЧЕСКАЯ операция. получается каша, названная красивым подходом. это по ВАШЕЙ догме. я предложил не путать теплое с мягким, и в ЛОГИЧЕСКИХ ВЫРАЖЕНИЯХ пользоваться ЛОГИЧЕСКИМИ операторами - это хоть и не выходит за рамки канонов, но почему-то вас возмутило со страшной силой. спустя некоторое время появляются люди, которые ОБОСНОВЫВАЮТ лучшим отражением ИДЕИ использование странных записей, и их слова все воспринимают "положительно". вопрос знатокам: почему, когда я предлагаю записывать выражения так, чтобы они лучше отражали суть, все поднимают меня на вилы?! ответ один - догма есть догма, а кто не с нею, тот против всех. что касается всяких загадочных функций со странными указателями, то я поступил бы очень просто: для каждого нужного места ввел бы новый тип, и все свелось бы к объявлению простой функции с нормально читаемым видом. я ведь просил вас, знактоков, изобразить вашу оптимальную запись для подобного примера - и где она?! игнорировать слабое место в собственной догме - это очень похоже на борцов за чистоту веры! приведенный пример с массивами показывает только полное непонимание пользы продемонстрированного подхода. запись, которая совершенно ничем не лучше, выдается за таковую. то есть возможность есть, даже применить ее порой удается, но зачем - оставется в тумане. объявив обычный многомерный массив, вы не сделали ничего такого, что сделает запись a[n][5] менее понятной - взяли 5-й элемент n-го массива. гораздо больше пользы в понимании закладываемого смысла сыграло бы нормальное поименование массивов и т.п. я привел реальный пример, что стремление к извращениям в кодировании приводит к ухудшению результатов - почему никто не среагировал? может у кого есть возможность протестировать аналогичный пример для ARMов - это принесло бы больше пользы в поднятом вопросе, чем все эти бредни про 5[a]... Цитата(igorle @ Mar 24 2013, 13:35)  Вас не смущает, что звездочка может означать и умножение, и указатель, и разыменовывание в зависимости от контекста. меня смущает. я вижу в этом одно из самых слабых мест Си - контекстнозависимая неоднозначность символов
--------------------
Я бы взял частями... но мне надо сразу.
|
|
|
|
|
Mar 25 2013, 05:51
|

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

|
Цитата(ARV @ Mar 24 2013, 08:56)  компилируем WinAVR 20100110 Вы бы ещё чего пораритетнее нашли... WinAVR почил 3 года назад. Так и будете его всю жизнь в пример ставить? Покажите как это сейчас выглядит например на gcc-(4.7.2 ... 4.8.0). И если не понравится результат, так заполните баг репорт и хоть как-то помогите развитию продукта вместо пустого хая. Или страшно? Профессионал млин...
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Mar 25 2013, 10:06
|
Гуру
     
Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847

|
Цитата(ARV @ Mar 24 2013, 08:56)  успехов вам в лаконизме!  Давайте возьмем другой проц, и уровень оптимизаций побольше Код typedef char boo;
boo var1(boo x, boo y){ return (!x && y) || (x && !y); }
boo var2(boo x, boo y){ return !x ^ !y; } Компилим gcc -O3 (версия gcc - gcc (GCC) 4.1.2 20070115 (SUSE Linux)) Платформа x64 - Код var1: .LFB2: testb %dil, %dil movl %edi, %edx movl %esi, %ecx jne .L2 testb %sil, %sil movl $1, %eax je .L2 rep; ret .p2align 4,,7 .L2: testb %dl, %dl setne %al testb %cl, %cl sete %dl andl %edx, %eax movzbl %al, %eax ret .LFE2:
var2: .LFB3: testb %dil, %dil sete %al testb %sil, %sil sete %dl xorl %edx, %eax movsbl %al,%eax ret .LFE3: Разницу в количестве команд видите? Если собрать под 32 бита (в x86) - то получается то же самое Код var1: pushl %ebp movl %esp, %ebp movzbl 8(%ebp), %edx movzbl 12(%ebp), %ecx testb %dl, %dl jne .L2 testb %cl, %cl movl $1, %eax je .L2 popl %ebp ret .p2align 4,,7 .L2: testb %dl, %dl setne %al testb %cl, %cl sete %dl popl %ebp andl %edx, %eax movzbl %al, %eax ret
var2: pushl %ebp movl %esp, %ebp cmpb $0, 8(%ebp) sete %al cmpb $0, 12(%ebp) popl %ebp sete %dl xorl %edx, %eax movsbl %al,%eax ret Цитата спустя некоторое время появляются люди, которые ОБОСНОВЫВАЮТ лучшим отражением ИДЕИ использование странных записей, и их слова все воспринимают "положительно". вопрос знатокам: почему, когда я предлагаю записывать выражения так, чтобы они лучше отражали суть, все поднимают меня на вилы?! ответ один - догма есть догма, а кто не с нею, тот против всех. Ответ неверный. 'лучше отражали суть' именно оригинал, а не ваш вариант. И 'странной записью' выглядит именно ваш вариант. А вы это упрямо игнорируете и с не меньшим упорством ищете заговор и догматиков. В общем как говорится 'на вкус и цвет товарищей нет'. У каждого может быть свой собственный взгляд на то, что наиболее естественно и правильно. Если хотите установить истину - сделайте опрос, какая версия этой конструкции покажется читателям более естественной PS. Собрал ваш тест на 4.7.2 (64 бита) Код var1: .LFB0: .cfi_startproc testb %sil, %sil jne .L11 .L5: testb %sil, %sil sete %al testb %dil, %dil setne %dl andl %edx, %eax ret .p2align 4,,10 .p2align 3 .L11: testb %dil, %dil movl $1, %eax jne .L5 rep ret .cfi_endproc .LFE0:
var2: .LFB1: .cfi_startproc testb %sil, %sil sete %al testb %dil, %dil sete %dl xorl %edx, %eax ret .cfi_endproc .LFE1: Код сильно потощал, но отношение размеров (не в пользу первого варианта) осталось
|
|
|
|
|
Mar 25 2013, 11:32
|

Профессионал
    
Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581

|
XVR, вы, пожалуйста, сообщите ВЕСЬ размер кода, потому как даже под WinAVR в моем варианте ассемблерный листинг функций давал ВАШ результат, а вот общий размер, который включает в том числе подготовительные действия по вызову функций, оказался совсем иным. что касается взгляда на логику, то по-моему, двух мнений тут быть не может: операция ^ арифметическая битовая, операция ! -логическая. в одном выражении смешаны два вида операций. математика такого не допускает: логические выражения не смешиваются с арифметическими. в Си этот принцип может быть нарушен (по стандарту), и в этом я вижу нарушение логики. запись выражения для ЛОГИЧЕСКОГО XOR только при помощи исключительно ЛОГИЧЕСКИХ операторов мне кажется абсолютно логичной, и позволяет привести математическую логику в русло стандарта Си. мой вариант как раз и отражает суть булевой алгебры преобразования логических функций - помните это? в моем варианте записи все сделано как раз в строгом соответствии с этим, и ни один пункт стандарта Си не нарушен - два плюса против одного вашего я бы мог сделать опрос, но в своей формулировке: какая из этих конструкций более соответствует здравому смыслу? я ведь не о Си пекусь, а том, как писать программы в соответствии со здравым смыслом, т.е. так, чтобы ни один закон не нарушить и при этом программу смог бы понять любой человек, обладаюсщий этим самым здравым смыслом, а не только вызубривший стандарт конкретного языка. хотя судя по уже состоявшемуся обмену мнений, результат опроса прогнозируем по причине нелюбви к логике здравого смысла у очень многих P.S. а что этоу вас за опкод какой-то странный в первом листинге второго варианта - rep? вроде как это префикс-повторитель, и тут он как бы неуместен...
--------------------
Я бы взял частями... но мне надо сразу.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|