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

 
 
19 страниц V  « < 12 13 14 15 16 > »   
Reply to this topicStart new topic
> Си
ARV
сообщение Mar 24 2013, 07:09
Сообщение #196


Профессионал
*****

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



Цитата(Буратино @ Mar 24 2013, 10:33) *
Скажите, а нужны скобки в этом коде?

Код
return (!x && y) || (x && !y);
формально - не нужны. боюсь, меня заплюют, как обычно, но я ставлю скобки везде, где они позволяют визуально выделить "полезные" части выражения, чтобы, как обычно, никто не напрягал лишний раз голову, вспоминая о приоритетах операций.

в пользу моего подхода задайте вопрос любому своему знакомому: сколько будет два плюс два умножить на два? почти 99% с первой попытки отвечают 8, хотя правила арифметики знают даже двоечники...




--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Mar 24 2013, 07:52
Сообщение #197


Универсальный солдатик
******

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



Цитата(igorle @ Mar 23 2013, 23:02) *
Затем Вам показали, что В УЧЕБНЫХ целях полезно ПОНЯТЬ, почему 5[a] эквивалентно a[5].
...
Такой код НУЖНО использовать при обучении, для демонстрации области дейстия автоматических переменных.

И... почему? Кто бы объяснил "на пальцах", как работает 5[a]. У классиков я такого не нашел. Про "зачем" не спрашиваю, считаю "незачем". sm.gif

Насчет скобок - стараюсь не писать лишние. Мне интереснее в список приоритетов заглянуть. И писать лаконично, "красиво".
Но вот последний Keil в своем редакторе выдает предупреждающие знаки, когда из-за приоритета операций, возможно, получится не то, чего я желаю. sm.gif
Go to the top of the page
 
+Quote Post
igorle
сообщение Mar 24 2013, 08:06
Сообщение #198


Местный
***

Группа: Свой
Сообщений: 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
Go to the top of the page
 
+Quote Post
dxp
сообщение Mar 24 2013, 08:20
Сообщение #199


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] - мы именно подчёркиваем, что выбираем конкретный элемент всех массивах, а не просто перебираем массивы с какой-то дальнейшей целью - выбор какого-то элемента, как в данном примере. Когда я вижу такую запись, я полагаю, что программист именно хотел сделать акцент этой особенности алгоритма. Мелочь, но к месту. Совершенно согласен, что профессиональный квалифицированный программист должен безо всякого напряжения и ломки воспринимать такого рода конструкции. Признаюсь, что на заре освоения С, когда столкнулся в первый раз с такой записью, испытал лёгкий культурный шок. sm.gif Это мотивировало помедитировать над этой темой, через некоторое время всё встало на свои места.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
ViKo
сообщение Mar 24 2013, 08:47
Сообщение #200


Универсальный солдатик
******

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



Цитата(igorle @ Mar 24 2013, 11:06) *
Совсем на пальцах
a[5] эквивалентно *(a+5)
От перемены мест слагаемых...

... получаем *(5+a). А дальше? "Еще нежнее..."
Go to the top of the page
 
+Quote Post
igorle
сообщение Mar 24 2013, 09:00
Сообщение #201


Местный
***

Группа: Свой
Сообщений: 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 дают одинаковый результат, то и получается, что конструкции эквивалентны.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Mar 24 2013, 09:08
Сообщение #202


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 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] нельзя, а использовать можно. И где логика? sm.gif
P.S. начинаю относиться к K & R, как к шарлатанам. sm.gif
Go to the top of the page
 
+Quote Post
igorle
сообщение Mar 24 2013, 09:35
Сообщение #203


Местный
***

Группа: Свой
Сообщений: 338
Регистрация: 14-07-12
Пользователь №: 72 753



Цитата(ViKo @ Mar 24 2013, 12:08) *
Да, так понятно. И понятно, что так вычисляется при работе компилятора. Непонятно, почему это допускается, ради простоты реализации? Ведь a[] - это массив, а 5[] - бред. Можно задать массив a[5], но нельзя задать 5[a]. Это - что-то, именуемое "хаком".
Таким образом, задать 5[a] нельзя, а использовать можно. И где логика? sm.gif
P.S. начинаю относиться к K & R, как к шарлатанам. sm.gif

Исходный код делится на "кирпичики". Оператор "[]" при использовании описывается где-то так:
операнды должны быть один - типа поинтер, другой - целое
Сложить операнды. (результатом будет поинтер)
выполнить опрацию разыменовывания.

Это логика, но отнюдь не шарлатанство. Объявление переменной и применение переменной - разные вещи.
Вас не смущает, что звездочка может означать и умножение, и указатель, и разыменовывание в зависимости от контекста.

Кстати, недостаток логики повергает многих в задумчивость, когда просишь сказать чему равен (-11)%10. А у классиков здесь все четко и просто.


Цитата
...Ведь a[] - это массив, а 5[] - бред...

Ээээ. Дело привычки.
Вспомнил, как давным давно (а я весьма стар), когда мы начинали изучать программирование, мой однокурсник возмущался, что нельзя писать x=x+10, потому что это бред и не может быть верным ни при каком значении x biggrin.gif
Уже сегодня вечером вы, не задумываясь, будете думать
Ведь a[] - это массив, а 5[] - это шестой элемент массива.

Сообщение отредактировал igorle - Mar 24 2013, 10:00
Go to the top of the page
 
+Quote Post
ViKo
сообщение Mar 24 2013, 10:40
Сообщение #204


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 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
Цитата
Направление округления при операции / или знак результата при операции % для отрицательных аргументов зависят от системы...

Так чему равен результат? sm.gif Боюсь ошибиться, 1? -1?

Цитата(igorle @ Mar 24 2013, 12:35) *
Уже сегодня вечером вы, не задумываясь, будете думать
Ведь a[] - это массив, а 5[] - это шестой элемент массива.

Прекращайте шутить, и без того все страньше и страньше. Хотя... смотря как считать, начиная с "нулевого" или с "первого". Здесь и классики иногда путаются в терминах.

Цитата(igorle @ Mar 24 2013, 12:35) *
операнды должны быть один - типа поинтер, другой - целое
Сложить операнды. (результатом будет поинтер)

И чему равен поинтер на 5? rolleyes.gif
Go to the top of the page
 
+Quote Post
igorle
сообщение Mar 24 2013, 11:00
Сообщение #205


Местный
***

Группа: Свой
Сообщений: 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? rolleyes.gif

5 - это не указатель. Это целое. Которое будет складываться с указателем.
Go to the top of the page
 
+Quote Post
ARV
сообщение Mar 24 2013, 15:29
Сообщение #206


Профессионал
*****

Группа: Свой
Сообщений: 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) *
Вас не смущает, что звездочка может означать и умножение, и указатель, и разыменовывание в зависимости от контекста.
меня смущает. я вижу в этом одно из самых слабых мест Си - контекстнозависимая неоднозначность символов


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Mar 25 2013, 05:51
Сообщение #207


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

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



Цитата(ARV @ Mar 24 2013, 08:56) *
компилируем WinAVR 20100110
Вы бы ещё чего пораритетнее нашли...
WinAVR почил 3 года назад. Так и будете его всю жизнь в пример ставить?
Покажите как это сейчас выглядит например на gcc-(4.7.2 ... 4.8.0).
И если не понравится результат, так заполните баг репорт и хоть как-то помогите развитию продукта вместо пустого хая.
Или страшно? Профессионал млин...


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
ARV
сообщение Mar 25 2013, 05:54
Сообщение #208


Профессионал
*****

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



Цитата(demiurg_spb @ Mar 25 2013, 09:51) *
Вы бы ещё чего пораритетнее нашли...
WinAVR почил 3 года назад. Так и будете его всю жизнь в пример ставить? Покажите как это сейчас выглядит (на gcc-(4.7.2 ... 4.8.0).
почил или нет, а я пользуюсь, и пока не сожалею. у вас есть свежак - вот вы и покажите, как стало хорошо и оптимально компилироваться то, что противоречит логике, об этом я и попросил


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
XVR
сообщение Mar 25 2013, 10:06
Сообщение #209


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



Цитата(ARV @ Mar 24 2013, 08:56) *
успехов вам в лаконизме! wink.gif
Давайте возьмем другой проц, и уровень оптимизаций побольше
Код
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


Цитата
спустя некоторое время появляются люди, которые ОБОСНОВЫВАЮТ лучшим отражением ИДЕИ использование странных записей, и их слова все воспринимают "положительно". вопрос знатокам: почему, когда я предлагаю записывать выражения так, чтобы они лучше отражали суть, все поднимают меня на вилы?! ответ один - догма есть догма, а кто не с нею, тот против всех.
Ответ неверный. 'лучше отражали суть' именно оригинал, а не ваш вариант. И 'странной записью' выглядит именно ваш вариант. А вы это упрямо игнорируете и с не меньшим упорством ищете заговор и догматиков.

В общем как говорится 'на вкус и цвет товарищей нет'. У каждого может быть свой собственный взгляд на то, что наиболее естественно и правильно. Если хотите установить истину - сделайте опрос, какая версия этой конструкции покажется читателям более естественной rolleyes.gif

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:

Код сильно потощал, но отношение размеров (не в пользу первого варианта) осталось biggrin.gif
Go to the top of the page
 
+Quote Post
ARV
сообщение Mar 25 2013, 11:32
Сообщение #210


Профессионал
*****

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



XVR, вы, пожалуйста, сообщите ВЕСЬ размер кода, потому как даже под WinAVR в моем варианте ассемблерный листинг функций давал ВАШ результат, а вот общий размер, который включает в том числе подготовительные действия по вызову функций, оказался совсем иным.

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

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

P.S. а что этоу вас за опкод какой-то странный в первом листинге второго варианта - rep? вроде как это префикс-повторитель, и тут он как бы неуместен...


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post

19 страниц V  « < 12 13 14 15 16 > » 
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 07:02
Рейтинг@Mail.ru


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