24 декабря 2006 г.

О кино...

Как я уже говорил, редко попадаются хорошие фильмы. "Хорошие" — это такие, чтоб вспомнить можно было с удовольствием, или с удовольствием посмотреть второй раз. А вот вчера удалось посмотреть сразу два! :)

Первый — "Мемуары гейши". К сожалению, не оставил в душе феерического искрящегося следа, как пишут в некоторых рецензиях, но фильм очень понравился. Понравился и сюжетом, и актерами и тем, как это все снято. А снято красиво. Особенно торкнула сцена, где главная героиня танцует на сцене в синем свете под падающим снегом... Очень красиво. Вообще очень хорошо показана японская культура, вернее, ее отличия от европейской, глазами европейского человека. Качественный, интересный и ненудный фильм. С удовольствием посмотрю фильм еще раз, если представится такая возможность.

Второй фильм — это фильм Павла Лунгина "Остров". Тут, честно говоря, подходящих слов подобрать не могу... Фильм зацепил, и зацепил сильно. Думаю, что этот фильм нужно смотреть всем, и атеистам в том числе (конечно, я не имею в виду представителей религиозных конфессий, отличных от православного христианства). Даже, если фильм не понравится или останется непонятым, то, все равно, какой-то след оставит. Самое поразительное, что фильм от начала до конца наполнен религиозным содержанием, но при этом смотрится на одном дыхании. Совсем не хочется заснуть или переключится на какое-то другое дело. Пять баллов.

ЗЫ. Моя мама тоже посмотрела "Остров". На вопрос "ну, как?", она вздохнула и с грустной улыбкой ответила: "Эх... Если бы все в жизни было действительно так...". Я маме ничего не сказал, но про себя подумал, что фильм-то как раз об этом — о нашем маловерии.

20 ноября 2006 г.

Отступники, или Идите в жопу, эстеты

Стоял в пробке, краем глаза заметил рекламный щит с невзрачной картинкой и надписью "Отступники". Пригляделся — фильм с Николсоном, ДиКаприо и Деймоном в главных ролях. Хм, рекламка так себе... Попахивало очередным г...

В сети опять промелькнула афиша "Отступников". Теперь уже совершенно сознательно ткнул на ссылку. Оказалось, типа рецензия. "Слабенький римейк гонконгского фильма...", "утерян глубокий смысл...", "не дотягивает до эстетства и философии оригинала...", "Скорсезе работает на автопилоте, без искры..." Скорсезе?! Прочитали повнимательней — этому фильму в вину ставилось только "отсутствие эстетики оригинала"... Мы поняли, что обязательно сходим посмотреть.

Я улыбался весь фильм. Не потому, что было смешно — фильм совсем не смешной. Улыбался потому, что после первых же двух минут понял — мне нравится этот фильм :) За последнее время еще ни один фильм не казался мне наполненным таким количеством позитивной энергии. Даже не смотря на то, что это фильм, в котором все время кого-то убивают. Причем, это показано с изрядной долей цинизма, иногда гротескного. Все равно улыбался :) Потому что, фильм у Скорсезе получился отличный. Действительно, не зашибись какой сюжет. Якобы скрытый философский смысл, раскрывается тут же в одной из фраз главных героев фильма. Даже простота — и та гротескная :) Но дело не в глубокой философии или эстетике. Скорсезе смог показать все то, что хотел :) Плюс офигительно драйвовый саундтрек и очень хорошие актеры, которые не расслабляются, а играют на полную катушку... Браво!

После просмотра, вышел из кинотеатра с мыслью, что хочется посмотреть еще раз :) Видимо, я — не эстет, и слава Богу ;)

22 сентября 2006 г.

В поисках истины

Недавно, при создании небольшой утилитки, столкнулся с проблемой инициализации указателей на массивы char. Точнее, не с самой инициализацией, а последующим использованием такого указателя. Дело было под Linux Slackware, компилятором выступал gcc.

Проблема выглядела примерно так:

#include <stdlib.h>

void myfunc (char *p)
{
  *p = 'X';
}

int main ()
{
  char *str0 = "Hello";
  char str1[] = "Hello2";

  printf("str1 => %s\n", str1);
  myfunc(str1);
  printf("str1 => %s\n", str1);

  printf("str0 => %s\n", str0);
  myfunc(str0);
  printf("str0 => %s\n", str0);

  return 0;
}


Если откомпилировать этот код и попытаться выполнить, то результат будет плачевным:

> gcc a.c
> ./a.out
str1 => Hello2
str1 => Xello2
str0 => Hello
Segmentation fault

Хм, странно... Что-то не помню я, чтобы такая проблема у меня раньше возникала. А в чем же причина?

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

> gcc -S a.c
> cat a.s

Смотрим, что там получилось. Ага, вот оно:

...
LC0:
        .ascii "Hello\0"
LC1:
        .ascii "Hello2\0"
...
        movl    $LC0, -12(%ebp)
        movl    LC1, %eax
        movl    %eax, -40(%ebp)
        movzwl  LC1+4, %eax
        movw    %ax, -36(%ebp)
        movzbl  LC1+6, %eax
        movb    %al, -34(%ebp)
...

При компиляции место для обеих строк резервируется в секции .rdata. Но при инициализации указателя str0 в память стека просто записывается адрес размещения строки "Hello" (LC0), а при инициализации str1 в стеке резервируется нужное количество байт и туда полностью копируется содержимое второй строки (LC1). Когда мы пытаемся изменить вторую строку (которая скопирована в стек), то она без проблем меняется. А при попытке изменить первую — мы лезем в сегмент данных. Вот тут-то нас и поджидает Seqmentation fault. Неплохо...

Немного странно, что выражение char *str0 = "..." в результате дает константную строку. Ну, да ладно.

Интересно, что Seqmentation fault, как правило, возникает в системах с защитой памяти. А ну-ка, проверим, что там у нас в других системах: Solaris, gcc — то же самое; Windows, MSYS, gcc — то же... Ну, что ж, все понятно. Ура.

Стоп. Раз уж я полез в другие системы, может быть и компилятор другой попробовать. Что у нас там в Windows есть? Компилятор cl.exe от Microsoft:

> cl.exe a.c
> a.exe
str1 => Hello2
str1 => Xello2
str0 => Hello
str0 => Xello

Ой... :-/ Это что такое? А где же "unexpected exception" или "memory access denied"?.. Неужели cl генерирует принципиально другой код? Ну-ка, cl, покажи, что там у тебя в ассемблере:

...
$SG829  DB 'Hello', 00H
        ORG $+2
$SG831  DB 'Hello2', 00H
        ORG $+1
...
        mov DWORD PTR _str0$[ebp], OFFSET FLAT:$SG829
        mov eax, DWORD PTR $SG831
        mov DWORD PTR _str1$[ebp], eax
        mov cx, WORD PTR $SG831+4
        mov WORD PTR _str1$[ebp+4], cx
        mov dl, BYTE PTR $SG831+6
        mov BYTE PTR _str1$[ebp+6], dl
...

Странно, но все то же самое — для первой строки в стек загоняется только указатель, а вторая полностью копируется в стек. Получается, что система тут не при чем? Все дело в компиляторе?

Пришлось лезть в MSDN и читать документацию. После недолгих поисков был найден некий ключ /GF, который, помимо прочего, заставляет компилятор размещать строковые константы в read-only memory. "If you try to modify strings under /GF, an application error occurs." Да, это обеспечит защиту строковых "констант" от модификации, но только если указать нужный ключ компилятора.

А что же gcc? Внимательно просмотрев документацию, обнаружил раздел "Incompatibilities of GCC", первый пункт которого гласил: "GCC normally makes string constants read-only." Вот так. То есть и gcc и cl могут сгенерировать код с одинаковым поведением, но первый делает это по умолчанию, а второй — только, если указать нужную опцию.

Вот тут-то и пришла в голову идея заглянуть, наконец-таки, в стандарт языка Си. Параграф 6.7.8 стандарта гласит:
"...the declaration char *p = "abc"; defines p with type 'pointer to char' and initializes it to point to an object with type 'array of char' with length 4 whose elements are initialized with a character string literal. If an attempt is made to use p to modify the contents of the array, the behavior is undefined."

Эээ... И что?

Читаем внимательней — "behavior is undefined". Именно эти три слова являются причиной такого поведения моего кода под разными компиляторами. "Поведение неопределено" — этого должно быть вполне достаточно для нормальных людей, чтобы не использовать конструкции вида char *p = "abc".

Мда... Я зачем-то провел "масштабное исследование" проблемы, которое все равно меня привело туда, куда я должен был пойти в самом начале. К Стандарту. Стыдно? Да.

В чем мораль этого рассказа? Follow the standards.

16 сентября 2006 г.

Задачи на собеседованиях: строки и указатели

На собеседованиях частенько задают задачи на знание Си-строк и указателей.

  • Первый вариант. Нужно написать программу копирования строк без использования strcpy, strlen и прочих им подобным. Входные данные - только указатель на строку, оканчивающуюся нулем, и указатель на destination область.

  • Второй вариант: "развернуть" строку при копировании. То есть, если у нас есть "abcdef", то после выполнения программы мы должны получить "fedcba". В качестве входных данных - указатель на строку и можно воспользоваться strlen.

  • Третий вариант: "развернуть" строку на месте, не пользуясь дополнительными блоками памяти. Входные данные - как в варианте 2.

    Подобные задачи советует задавать на собеседованиях Джоэль Спольски. Какими бы простыми не казались эти задачи, именно на них отсеиваются большинство кандидатов.
  • 9 июля 2006 г.

    Немного о тестировании

    В процессе изучения разных подходов к тестированию программного обеспечения и многолетних попыток их практического применения, в голове сформировались некоторые мысли. Попытаюсь их сформулировать, пока не убежали... Вернее, это даже не мысли, а мои убеждения, основанные на результатах применения тех или иных подходов.
    1. Тестирование в проекте должно быть. Если тестирования нет — на проекте можно ставить крест. Еще лучше — даже не начинать такие проекты :)

    2. Разработчики должны сами тестировать свой код. Причем, тесты должны создаваться разработчиками до того, как они напишут свою первую строку кода ("test first" — этот подход описан в книге Кента Бека "Test Driven Development" и применяется в экстремальном программировании). Для чего:

      Во-первых, такой подход позволит создавать "чистый" код, то есть код, не содержащий ничего лишнего. Добавить в процессе кодирования пару-другую "кульных" фич, которые якобы обязательно будут использоваться — по-моему, этим болеют все разработчики. Пересилить себя и не делать этого очень трудно.

      Во-вторых, тестируя свой код, разработчики начнут задумываться о том, как они будут это делать. Иногда проблема невозможности тестирования доходит до крайности, когда нужно все выбрасывать и начинать заново. Разумеется, наличие толкового архитектора должно свести такие проблемы к минимуму, но опыт показывает, что разработчики, которым наплевать на тестирование, могут свести на нет все благие начинания. Да и толковых архитекторов не так уж легко найти... Как, впрочем, и разработчиков. Но это совсем другая история :)

      Третье, и самое главное достоинство этого подхода, — у разработчиков появится четкое понимание задачи, поставленной перед ними. Не редкость, когда разработчик приступает к реализации решения, не разобравшись толком, что же на самом деле требует ТЗ. Как результат — переделывание уже выполненной работы, иногда по нескольку раз, а значит, потеря драгоценного времени.

    3. Наличие в проекте команды тестеров. Это совсем необязательно на ранних этапах проекта, но, как говорится, "must be" уже со следующей итерации. Чем они должны заниматься: анализ существующих тестов на предмет актуальности и полноты (например, на основе статического анализа кода можно выяснить, что покрытие кода тестами не приближается и к 15%, даже несмотря на то, что разработчики старательно выписывают тесты, как написано в предыдущем пункте); создание новых сценариев и тестов, которые еще не были реализованы; вообще, стремиться всячески поставить разрабатываемую систему в такую позу, чтобы она (система) с перепугу начала делать что-нибудь не то, или выдала какой-нибудь непотребный Segmentation fault. Также эти ребята должны проводить и другие виды тестирования, например, динамическое, нагрузочное и стрессовое тестирование. При этом наличие тестеров предполагает, что разработчики будут продолжать создавать часть тестов самостоятельно.

    4. Тестирование должно быть автоматизированным! Как говорят военные, у продукта должно быть только две кнопки — "вкл." и "пуск ракеты". Этот очень логичный подход должен применяться и здесь. Существует множество фреймворков, чтобы облегчить реализацию этого пункта. Например, семейство xUnit — эффективные и простые в обращении продукты, к тому же совершенно бесплатные. Казалось бы, автоматизация тестов — вполне логичный подход, но, к сожалению, с ужасающей регулярностью приходится наблюдать тестирование "в живую". Это когда разработчик пишет, например, функцию сложения двух чисел и вместо того, чтобы запускать набор тестов, он каждый раз запускает свою программу, вводит с клавиатуры разные числа и смотрит, что же там его программулина наскладывала... Жуть!

    Фух! Ну вот, вроде бы удалось изложить мысли не сильно сумбурно :)

    1 июня 2006 г.

    Какая нах информатизация?..

    Продлевал сегодня ОСАГО. Я ж по осени устроил ДТП — пересчитать нужно. В страховой пересчитали — у меня волосики на голове зашевелились. Получилось существенно дороже. Так этот коэффициент еще 3 года будет действовать. Кошмар! :(

    Но мы же русские люди :) Мы ищем простые и эффективные решения. Развернулись и пошли в другую страховую. Там нам посчитали по старой цене, несмотря на то, что мы честно признались о ДТП. "Все так делают", сказали нам, "Единой базы нет, поэтому все и бегают по страховым". Ура информационному голоду и компьютерной безграмотности!!! :)

    Мне один профессор философии на экзамене в аспирантуру еще пять(!) лет назад с пеной у рта доказывал, что информатизация российского общества идет полным ходом и вот-вот закончится. Ню-ню... :-/

    10 мая 2006 г.

    2>&1

    Я долго пытался понять правила перенаправления потоков вывода в юниксовой оболочке bash. Действительно, вроде всё понятно, но...

    Например, было непонятно, почему работает команда, перенаправляющая stderr в stdout:
    ls *.txt *.err >file 2>&1

    Но при этом не работает вот так:
    ls *.txt *.err 2>&1 >file

    И уж совсем китайской грамотой казалась строка:
    cat file 3>&2 2>&1 1>&3

    Да, мне понятно, что эта команда меняет местами потоки вывода stderr и stdout. То, что выводилось в stdout, теперь будет выводиться в stderr и наоборот. Но почему именно так и никак иначе?..

    Всё оказалось не просто, а очень просто :) Спасибо замечательной книге "Unix Power Tools" издательства O'Reilly.

    Дело в том, что оболочка, при разборе параметров командной строки, читает параметры строго слева направо. Этот факт кажется совсем неудивительным, но оказывается именно это правило оказывает влияние на результат обработки командной строки.

    Разберем, как интерпретируется строка "ls *.txt *.err >file 2>&1":
    1. параметр ">file" — означает "перенаправить стандартный поток вывода (stdout) в файл c именем file";

    2. параметр "2>&1" — означает "перенаправить стандартный поток ошибок (2) в стандартный поток вывода (1). Но, так как стандартный поток вывода уже перенаправлен в файл, то и стандартный поток ошибок перенаправляется туда же.
    В результате оба потока будут перенаправлены в файл.

    А как интерпретируется строка "ls *.txt *.err 2>&1 >file"?
    1. параметр "2>&1" — означает "перенаправить стандартный поток ошибок в стандартный поток вывода". На этот момент поток вывода (1) направляется в терминал, а значит, что поток ошибок тоже перенаправится в терминал.

    2. параметр ">file" — означает "перенаправить стандартный поток вывода (stdout) в файл c именем file".
    Как результат — поток вывода будет направлен в файл, а поток ошибок — в терминал.

    После этого совсем не трудно понять, как работает команда "cat file 3>&2 2>&1 1>&3". Тут тоже все просто:
    1. поток вывода 3 перенаправить туда же, куда выводится поток вывода 2 — в stderr;

    2. поток вывода 2 перенаправить туда же, куда выводится поток 1 — в stdout;

    3. поток вывода 1 перенаправить туда же, куда выводится поток 3 — в stderr
    В результате, потоки вывода stderr и stdout как будто меняются местами — поток 1 идет в stderr, а поток 2 идет в stdout.

    25 апреля 2006 г.

    Размышления по поводу дополнительной работы

    Я много думал (и думаю) о второй работе. Ведь денег никогда не бывает много. Казалось бы, возьми вторую работу и работай дома, благо программистам такая возможность предоставляется намного чаще, чем представителям какой-то другой профессии.

    Однако, тут палка о двух концах. С одной стороны — не хватает денег, хочется найти дополнительный источник дохода. С другой — если у меня уже есть постоянная работа, то работать дома можно только по вечерам, а наличие семьи (я имею в виду жену и детей, а не родителей) этому никак не способствует. То есть, "домашняя" работа будет выполняться ближе к ночи или ночью. Это, в свою очередь, повлечет за собой хроническое недосыпание и потерю производительности на основной работе. А это уже приведет к нервозности, стрессу и падению производительности в "домашней работе".

    Результат: низкая производительность и снижение репутации на обеих работах (а, следовательно, падение уровня заработной платы), натяжение отношений с семьёй.

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

    21 марта 2006 г.

    Open Source — это не бесплатно!

    Жаль, но существует очень мало программистов, которые действительно понимают, что такое движение open source, лицензия GPL и вообще, как все это работает и какую преследует цель.

    Бытует мнение, что если программное обеспечение — open source, то это значит, что оно — бесплатно. К счастью, это не так. Open source — это не бесплатное программное обеспечение, это — продукты с открытым исходным кодом. Для многих это неочевидно, но это не одно и то же.

    Open Source вовсе не запрещает получать деньги за программное обеспечение. Вы можете назначать какую угодно цену за предлагаемый вами продукт, в том числе, распространять его бесплатно. Open source требует другого.

    Во-первых, исходные файлы продукта должны быть легко доступны. То есть, вы не можете скрывать исходные файлы от "покупателя".

    Во-вторых, какое-то лицо, получив бесплатно или купив у вас open source продукт, может модифицировать и/или рапространять этот продукт как ему заблагорассудится (в том числе за деньги), и вы не можете ни запретить ему это, ни требовать какой-то компенсации. Но такое распространение может быть только как open source и при этом сохраняются ваши авторские права.

    В open source есть и другие требования, но эти — основные, для того, чтобы понять: "open source" продукт — это не значит "бесплатный"!

    15 марта 2006 г.

    О дяде Билли, GPL и Open Source

    Наткнулся в сети на интервью с Биллом Гейтсом (CNET News.com, 25 июня, 2001):
    "...экосистема, в которой сосуществует бесплатное и коммерческое ПО, а заказчики всегда могут выбрать, что им удобнее. (...) Та часть движения open source, которая называется GPL, нарушает этот цикл, а именно, исключает для коммерческой компании возможность использовать результаты какой-либо из этих работ или опираться на такую работу. (...) есть люди, которые вообще отказывают в праве на существование коммерческому ПО, т.е. не допускают создания вокруг коммерческого ПО рабочих мест и налогов. Их немного, но лицензия GPL разработана именно такими людьми. (...) Когда говорят об открытом исходном коде, часто имеют в виду GPL. Open source и GPL — это разные вещи."


    Я не знаю, как выглядело "The Open Source Definition" в 2001 году, но то, что я вижу сейчас на www.opensource.org, а именно, "The Open Source Definition v1.9", вообще никак не противоречит GPLv2. Ни в одном пункте GPL нет противоречия правилам Open Source потому, что GPL — это одна из тех свободных лицензий, которые создавались на основе требований open source. Это первое.

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

    Совсем другое дело, что коммерческие компании хотят продавать продукты с закрытым исходным кодом, но при этом хотят использовать код открытых разработок. Э, так не пойдет! Существуют совершенно конкретные решения этой проблемы. Например, можно не использовать код открытых проектов, а создать свой, используя лишь идею, — это возможно и не запрещено. Или, например, сегодня многие open source-проекты распространяются под "двойной лицензией": хочешь использовать проект бесплатно — твой продукт должен быть открытым (повторяю, "открытый" — не значит "бесплатный"); хочешь закрыть доступ к своему исходному коду и/или ограничить свободу распространения твоего продукта — купи коммерческую лицензию и наслаждайся.

    Однако, ни Биллу Гейтсу, ни поддерживающим его лицам не выгодно рассматривать вопрос именно с этой стороны. Они специально питают дезинформацией умы пользователей/разработчиков, потому что идет целенаправленная информационная война против движения open source (а конкретно, Ричарда Столлмана). И эта война — обоюдная. Битва гигантов, так сказать, за господство в мире ИТ.

    Я не против этой битвы, скорее даже — "за", хотя я еще не решил, на чьей я стороне. Однако, поражает количество разработчиков, которые даже не удосуживаются просто прочитать GPL (не говоря уже о том, чтобы действительно разобраться в вопросе), прежде чем высказывать своё мнение касательно open source. Легко использовать информацию, которую ляпнул сосед дядя Вася. А самому разобраться — просто лень?

    3 марта 2006 г.

    О парном программировании и рабочем пространстве

    Я уже практиковал парное программирование на прошлой работе. Недавно снова попробовал. Еще раз убедился, что парное программирование дает реальный эффект и значительный прирост не только качества, но и, как бы это не казалось странным, производительности.

    Читая некоторые книги и статьи по организации процесса и рабочего пространства (например, Спольски, Рейнвотер) натыкаюсь на заявления о том, что у каждого программиста должен быть отдельный кабинет или хотя бы закуток, в котором программист мог бы единолично предаваться процессу программирования. Спольски, например, не отрицает парного программирования, но настаивает на отдельных кабинетах. Некоторые авторы вообще против парного программирования.

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

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

    Конечно, нельзя сказать, что если программисты будут сидеть в одной комнате, то они не будут отвлекаться на "различную ерунду". Но, во-первых, они будут это делать значительно реже — это проверенный факт. А во-вторых, в отдельных кабинетах программист лишается, так сказать, коллективного разума или коллективной базы знаний. В отдельном кабинете просто невозможно встать и сказать "Люди, у меня проблема в том-то. Кто мне поможет ее решить?" Максимум, что можно сделать в отдельном кабинете, это задать вопрос по почте или организовать поход по другим кабинетам, задавая каждому один и тот же вопрос.

    Более того, если у каждого программиста в кабинете будет полка с необходимыми книгами — это просто отлично. Но частенько одной и той же книгой пользуются несколько человек по несколько раз в день, а наличие в группе или отделе несколько экземпляров одной и той же книги — редкостный случай. Поэтому гораздо эффективнее организовать в помещении для программистов несколько книжных шкафов с необходимой литературой. В этом случае вместо того, чтобы идти к соседу или в библиотеку за нужной книгой, можно просто подъехать к шкафу на стуле, взять книгу и уехать на рабочее место, которое находится тут же, в паре метров от шкафа.

    Безусловно, такой подход по организации рабочего пространства не предусматривает наличие огромного зала с сотнями программистов. Этот подход эффективно работает с командами численностью около десяти человек. Думаю, никто не будет спорить, что управлять даже тремя десятками программистов (а тем более тысячей) ни одному нормальному руководителю не под силу. Все равно придется каким-то образом делиться на подгруппы и делегировать полномочия. Так что я за то, чтобы сформированную группу размещать в одной комнате, а не сажать каждого в отдельный кабинет.

    25 февраля 2006 г.

    Приоритеты операций в Си

    Давно искал нечто подобное, чтобы можно было повесить на стенку и пользоваться каждый день. По правде сказать, самому такую табличку сделать было лень. Все-таки, нашелся какой-то добрый человек и сделал эту таблицу, за что спасибо ему огромное. К сожалению, не знаю имени автора, ибо таблица попала ко мне в бумажном варианте. С удовольствием поставлю ссылку на автора, если таковой отыщется.

    Операции с одинаковым приоритетом выполняются слева направо в порядке следования.

    ПриоритетОператорОписание
    1++Префиксный инкремент
    --Префиксный декремент
    ()Вызов функции или подвыражение
    []Выделение элемента массива
    ->Указатель структуры
    .Член структуры
    2!Логическое отрицание
    ~Поразрядное логическое НЕ (двоичная инверсия)
    -Унарный минус (изменение знака)
    +Унарный плюс
    (type)Преобразование к типу
    *Разыменование указателя
    &Определение адреса переменной
    sizeofОпределение размера в байтах
    3*Умножение
    /Деление
    %Остаток от деления
    4+Сложение
    -Вычитание
    5>>Поразрядный сдвиг вправо
    <<Поразрядный сдвиг влево
    6<Меньше
    >Больше
    <=Меньше или равно
    >=Больше или равно
    7==Равно
    !=Не равно
    8&Поразрядное логическое И
    9^Поразрядное исключающее ИЛИ
    10|Поразрядное логическое ИЛИ
    11&&Логическое И
    12||Логическое ИЛИ
    13?:Оператор условия
    14=Присваивание
    +=Составное сложение
    -=Составное вычитание
    *=Составное умножение
    /=Составное деление
    %=Составное определение остатка от деления
    >>=Составной поразрядный сдвиг вправо
    <<=Составной поразрядный сдвиг влево
    &=Составное поразрядное логическое И
    ^=Составное поразрядное исключающее ИЛИ
    |=Составное поразрядное логическое ИЛИ
    15,Операция "запятая"
    ++Постфиксный инкремент
    --Постфиксный декремент