Я программист с небольшим стажем, но уже делаю свои первые робкие шаги по карьерной лестнице. Я много читаю и самообучаюсь, иногда что-то пробую в своей практике. И теперь я готов поделиться с вами несколькими советами по программированию которые очень помогают мне в моей каждодневной работе. Ко всем советам я пришел сам и они многократно опробованы в моих проектах.

1) Бесконечный цикл


Все мы знаем, что в компьютере многое может произойти по принципу «Оно само». Где-то будет скачек напряжения или магнитные наводки. Поэтому легко в нашей программе может произойти инверсия бита. И мы вместо true получим false. А это говорит о том, что цикл вида:

while ( true ) {
  doSome();
}

совершенно ненадежен! В любой момент может true поменяться на false и мы выйдем из цикла. Как этого избежать? Очень легко. Мы легко можем повысить надежность бесконечного цикла вот таким «куском» кода.

while(true) {
  do {
    for(;;) {
      doSome();
    }
  } while(1);
}

Многие могут сказать, что кол-во кода увеличилось. Но на помощь приходит препроцессор.

#define FOREVER_CYCLE_START while(true){do{for(;;){
#define FOREVER_CYCLE_END }}while(1);}

И теперь мы легко можем написать

FOREVER_CYCLE_START
	foreverYoung();
FOREVER_CYCLE_END

Великолепно и всё сразу понятно. А новичок не будет думать, что же значит for(;;){ }. и почему условие в for похоже на плачущую рожицу.

2) Установка фигурной скобки


Бесконечные споры. Что же лучше?

if ( COND ) {
  doSome();
}

или

if ( COND ) 
{
  doSome();
}

Хватит! Представляю вариант который устроит ВСЕХ!

if ( COND ) {
{
  doSome();
}}

Все счастливы и довольны. О холиваре можно забыть… Хотя… стоит ли писать последние две закрывающиеся фигурные скобки на одной строке или стоит разнести на две? Но это уже отдельный вопрос требующий привлечения специалистов и дополнительных обсуждений.

3) Ассемблерные вставки


Никогда не бойтесь вставлять ассемблерный код в свои программы. Такие вставки показывают, что вы знаете не только высокоуровневый С++, но и в ладах с языком машины. Да, иногда, придётся переписывать или подправлять ассемблерный код, что бы перенести программу на другую архитектуру. Но за эту работу вам дополнительно заплатят и в очередной раз ваше начальство убедится, что вы хороший сотрудник. И никто другой не может справится с вашими обязанностями. Есть ещё маленькая хитрость. Вы можете вставлять бесполезные ассемблерные вставки, которые ничего не делают. Например вы можете по вспомнить, разные способы обмена информацией в регистрах:

mov  bx, ax
mov  ax, cx
mov  cx, bx
xchg ax, cx
push ax
mov  ax, cx
pop  cx
xor  ax, cx 
xor  cx, ax 
xor  ax, cx

Этот код придаст важности вашей программе. А люди которые будут с ним работать освежат свои знания. С вами может работать неопытный программист, который только что пришел из университета. А мы знаем, что студенты не очень охотно учат ассемблер. Таким образом он сразу же побежит к вам за разъяснением. У него создастся впечатление, что вы гуру, раз можете так легко манипулировать языками программирования. А начальство будет радо видеть, что новые сотрудники бегают к вам за новыми знаниями и вы ими охотно делитесь. Что может повлиять на вашу зарплату. Да и все же знают, что на ассемблере — быстрее!

4) Никогда не используйте const


Программисты как никто другой знает, что мы живём в бурном и быстро развивающемся мире, где все меняется очень быстро. А значит и использовать const смысла нет. Даже когда объект очевидно const, например кол-во спутников земли (у нас всего одна луна), то все равно по какой-то причине луна может расколоться на две. И придётся делать:

const int moons = 1;
moons++;

Что к вашему разочарованию забракует компилятор. Да и к тому же вы можете случайно сделать const, то что вы бы не хотели. Как вам понравится, если кто-то сделать вашу зарплату const? Всё! Прощай карьерный рост и повышение зарплаты.

const salary = 100; // $ в год

Да и к тому же это просто лишняя растрата байт кода. За эти 5 символов можно было бы сделать что-то полезное. Например, foo++.

5) Давайте переменным максимально короткие имена


Ведь запомнить переменную x куда проще чем position_of_object_on_x_axis. Например, этот код выглядит лаконичным и удобно читаемым:

if ( x < y ) {
  z++;
} else if ( c > q ) {
  c += f;
} else {
  r = z + c;
}

Код легко умещается в пределах видимости глаз. И его легко проанализировать просто бросив на него взгляд.

6) CamelCase или snake_case


Еще один вечный холивар. Такой же, как полезна ли венгерская нотация или является пережитком прошлого! Достаточно. Мы программисты должны писать код, а не выяснять кто прав, а кто нет.

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

Примеры этого стиля:
float float_charPositionX;
int int_moneySpent
char* charPointer_nameOfPerson;

7) Имена переменных


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

int int_kolichestvoBukv;
float float_glubinaBasseina;
bool bool_estLiZhiznNaMarse;

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

int int_koJIu4ecTBo6ykB;
float float_rJly6uHa6acceuHA;
bool bool_ectbJIu7Ku3HbHaMapce;

8) DEFINE'ы


Препроцессор существует уже очень давно и перешел в наследство от языка С. А раз он передался по наследству, значит он представляет из себя некоторую ценность, проверен временем и перенесен на С++, как неотъемлемая часть программирования. Возьмем типичную ситуацию. На 1-ом курсе университета вы изучали pascal. А на 2-ом вам начали преподавать C++. Новые синтаксис может ввести в замешательство. Но не беда. На помощь спешит препроцессор C++.

Вы всегда можете написать:

#define BEGIN {
#define END }

И всё. Процесс перехода на новый язык будет менее болезненным и более понятным.

9) Глобальные переменные


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

10) Исходники


Помните, что все исходные коды программы лучше хранить в одном файле. Это облегчает поиск интересующих вас переменных и функций. Ведь простой поиск по тексту одновременно становится и поиском по всему проекту. Все функции перед глазами, все переменные доступны в паре движений скроллом. Разбиение кода на несколько файлов приводит к тому, что за ним уже надо следить, что бы файлы не потерялись, разруливать обращения к глобальным переменным из каждого модуля компиляции и т. д. Зачем все эти сложности? Когда всё компактно находится рядом куда проще разобраться в исходных кодах, нежели скакать по куче разных файлов.

Эпилог


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

Комментарии (65)


  1. TimsTims
    19.11.2015 16:49
    -45

    int int_kolichestvoBukv;
    float float_glubinaBasseina;
    bool bool_estLiZhiznNaMarse;

    int int_koJIu4ecTBo6ykB;
    float float_rJly6uHa6acceuHA;
    bool bool_ectbJIu7Ku3HbHaMapce;

    Что-то не увидел тэг «сарказм». Он тут есть?

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

    и в очередной раз ваше начальство убедится, что вы хороший сотрудник

    Начальству, которое не разбирается особо в коде — вообще пофиг, на чем вы пишете и как пишете


    1. TimsTims
      19.11.2015 18:10
      -15

      Полезные НЕ советы программисту

      И теперь я готов поделиться с вами несколькими советами по программированию

      Последняя фраза сбила с толку. Понял, что это всё-же НЕ_СОВЕТЫ, а не «советы, которыми делится автор». Стоило добавить во вторую цитату «готов поделиться несколькими несоветами»…
      Количество голосов у так-же запутавшегося zodchiy подтверждают путаницу в трактовках
      Подавлю в себе хомяка)


      1. mc_dir
        19.11.2015 22:24
        +19

        Зато ты был первый!


        1. TimsTims
          20.11.2015 22:28

          Зато видно, что с чувством юмора на хабре всё в порядке(почти все поняли шуточный посыл поста, кэп)


    1. ishua
      20.11.2015 14:17
      +4

      То есть другие советы не смутили?


    1. Draku1a
      25.11.2015 03:24

      Тут тэг сарказм — на всю статью.


  1. zodchiy
    19.11.2015 16:52
    +29

    Я так понимаю это была ирония?


  1. amarao
    19.11.2015 17:01
    -39

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

    Для всего остального цивилизованного мира флип бита во-первых ни к чему критическому не приведёт (привет, ECC), во-вторых, кто вам сказал, что бит флипнется на вашем «true», а не на адресе перехода?

    Неверно работающее оборудование — это проблема сисадминов. Выглядит она так:

    CPU_SrcID#0_Channel#3_DIMM#0 (channel:3 slot:0 page:0x379c86 offset:0xdc0 grain:32 syndrome:0x0 — area:DRAM err_code:0001:0093 socket:0 channel_mask:8 rank:0)

    И мы точно знаем, что с этим делать.

    А вот вам (программистам) надо подумать, а что вы будете делать, когда все биты в памяти компьютера инвертируются? (hint: распределённость и отказоустойчивость).


    1. fshp
      20.11.2015 00:09
      +16

      то вам сказал, что бит флипнется на вашем «true», а не на адресе перехода
      Да вы просто не шарите. while(true) скомпилируется в безусловный переход. Там не будет никакой проверки, будет простой jmp. Goto, если так понятнее. Так что флип бита в этом куске может лишь изменить инструкцию, но не условие (его там попросту нет). А это уже совсем другая проблема.

      В конец статьи пропущена картинка с Леонардом Хофстедтером.


      1. vsespb
        20.11.2015 02:33

        Наверняка в jmp можно поменять один бит, так чтобы оно превратилось во что-нибудь безобидное и длина инструкции совпала


        1. fshp
          20.11.2015 03:03
          +2

          Так я и говорю. Изменится инструкция. А от этого уже ничего не спасёт. Хоть в 10 циклов оберните. jmp сменится на hlt (хотя для этого 3 бита флипнуть нужно как минимум, но это для примера). И привет.


  1. maaGames
    19.11.2015 17:20
    +8

    Если нужно беспокоиться о «перевёрнутом бите», то используется память с ECC.
    Но я догадался, что это юморной пост, но не догадался, что он вообще делает на хабре?


    1. FSA
      20.11.2015 09:53

      Кстати, отличная идея программе продолжать работе если что-то пошло не так и true вдруг стало false :)


      1. Alexeyslav
        20.11.2015 10:35

        Не очень смешно…
        на абапе(SAP R/3) иногда встречается проверка в программах «IF 1 = 0.» а на форумах говорят что в некоторых ситуациях это условие срабатывает!


        1. FSA
          20.11.2015 10:36

          Ну я бы в таком случае после цикла вызвал бы исключительную ситуацию.


        1. postgree
          20.11.2015 12:06

          А можно описание этих ситуаций. Я хоть и не абапер, но интересно такое узнать. Да и саперов в очередной раз потролить можно будет.


          1. Alexeyslav
            20.11.2015 14:40

            Давно дело было. Это в основном неисправляемые баги в версиях с экзотическими языками где разные символы могут неожиданно быть равны.
            Да дело давно было, уже и не помню этого форума. Но суть сводилась примерно к тому что такие условия могли срабатывать на корейских версиях сервера приложений. Видимо когда идёт сравнение двух символов в юникоде сравниваются только первые их байты и получается подобная фигня. Может, этот баг уже исправили, а может и нет. Кто знает где там ещё они зарыты остались.


    1. RolexStrider
      20.11.2015 22:01
      +1

      Если нужно беспокоиться о «перевёрнутом бите», то используется

      Созданный Минобороны США «максимально безопасный» язык Ada получил антипода – язык paranoid, который, как следует из названия, доводит стремление к «безопасному выполнению» до паранойи. Некоторые его конструкции достойны немедленного цитирования (с синхронным переводом):

      //типы данных:
      х: сомнительное целое;
      а: мало_похоже_на массив [x..y а_может_быть z] каких_нибудь символов;
      L: безнадежно_поврежденный список слишком_маленьких целых;
      //присвоение значения переменной:
      x ТОЧНО 3;
      x ЧЕСТНОЕ_СЛОВО 3;
      x МАМОЙ_КЛЯНУСЬ 3;


      1. maaGames
        21.11.2015 06:30

        Назвали бы язык Рая.)
        Перехожу в режим зануды.
        Проблемы со слишком_маленькими целыми быть не может, так что там массив слишком маленьких вещественных циселок.)


  1. affka
    19.11.2015 17:27
    +4

    У вас опечатка в заголовке… Нужно «НЕ» убрать :)


    1. masai
      21.11.2015 17:03
      +1

      HE = Highly Efficient


      1. Bronx
        24.11.2015 11:55

        High-Explosive


  1. robert_ayrapetyan
    19.11.2015 17:27
    +18

    Низкий поклон за проделанный труд! Можно добавить еще один совет — пользуйтесь копипастой, где только возможно, ведь вызов процедуры\функции — это дополнительные инструкции и пустой расход ресурсов процессора.


    1. Mrrl
      19.11.2015 20:22
      +5

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


    1. fshp
      20.11.2015 00:16

      А вот бывают случаи, когда без копипасты не обойтись. Например, большой switch, в котором несколько веток изменить нужно. Как красиво это сделать я не понимать.


      1. nochkin
        20.11.2015 06:39
        +8

        Сделать красиво достаточно просто — надо переписать этот участок кода на ассемблере.


        1. macseem_327
          20.11.2015 14:37

          Или заменить на множество вложенных if elseif elseif else, это даст возможность больше кастомизировать условие, да и вообще switch — это же моветон!


  1. danl
    19.11.2015 18:03
    +12

    Еще один совет — писать больше серьёзных и полезных постов.


  1. leremin
    19.11.2015 18:11
    +8

    Еще добавлю:

    • Проверяйте выбранный элемент в ComboBox через if… else if… else if… со строками. Это облегчает написание кода и сразу видно, что имеется ввиду.
    • Всегда создавайте велосипеды для контейнеров из std. Их разработчики — теоретики и ничего не понимают в написании реальных программ. Ваша реализация будет быстрее и лучше
    • Пишите методы по три, а лучше по пять тысяч строк. Читателю вашего кода будет гораздо проще в нем разобраться, ведь нет нужды лазить по множеству файлов и классов.

    Было бы смешно, не будь этого в проекте, который мне достался в наследство.


    1. khim
      20.11.2015 01:15

      Как выглядит контейнер с методами в три тысячи строк я даже боюсь себе представить. Один метод «Do» с 25ю аргументами???

      А если серьёзно, то долгое время и вариантов-то не было: STL начал прилично поддерживаться всякими GCC не так давно (по историческим меркам).


      1. leremin
        20.11.2015 06:43

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


    1. trigger_af
      27.11.2015 14:34

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


  1. Mrrl
    19.11.2015 18:34
    +23

    Лучше такое публиковать в пятницу — тогда люди быстрее разберутся, в чём дело.


  1. kamazee
    19.11.2015 19:24
    +19

    int int_koJIu4ecTBo6ykB;
    float float_rJly6uHa6acceuHA;
    bool bool_ectbJIu7Ku3HbHaMapce;


    Так Вы же сами пишете, что программист может не знать английского! Предлагаю однозначно более лучший универсальный вариант, который подойдет действительно всем:

    int LIeJIoe_koJIu4ecTBo6ykB;
    float Dpo6Hoe_rJly6uHa6acceuHA;
    bool JIOru4eckoe_ectbJIu7Ku3HbHaMapce;
    


    1. leremin
      19.11.2015 19:28
      +3

      А боярское программирование для не знающих английского на что?


      1. RolexStrider
        20.11.2015 22:07

        О! Точно, это пункт 8 же, только наоборот!


    1. Mrrl
      19.11.2015 20:15
      +52

      Нет, надо сначала написать

        typedef int LIeJIoe;
        typedef float Dpo6Hoe;
        typedef bool JIOru4eckoe;
      

      а уже потом честно описывать переменные:
      LIeJIoe LIeJIoe_koJIu4ecTBo6ykB;
      Dpo6Hoe Dpo6Hoe_rJly6uHa6acceuHA;
      JIOru4eckoe JIOru4eckoe_ectbJIu7Ku3HbHaMapce;
      



      1. leremin
        19.11.2015 20:22

        Сделайте меня развидеть это. Люто плюсанул бы, да не могу.


        1. Mrrl
          19.11.2015 20:23
          +1

          «Доктор, смените кодировку!»


      1. maaGames
        19.11.2015 20:48
        +5

        Так вот ты какой, человек-обфускатор…


      1. xotta6bl4
        20.11.2015 16:13

        Тогда уж лучше писать на джаве.

        Целое целое_количествоБукв;
        Дробное дробное_глубинаБассейна;
        Логическое логическое_естьЛиЖизньНаМарсе;
        


      1. Draku1a
        25.11.2015 03:34

        Как будто бывший 1С-ник начал пытаться кодить на Cи ))


        1. Mrrl
          25.11.2015 21:04

          Бывших 1С-ников не бывает! Как и бывших С-шников и прочих :)


          1. Draku1a
            26.11.2015 02:10

            «Программист — это не профессия, это ­диагноз...»


  1. AllexIn
    19.11.2015 20:17
    +34

    image


  1. novoxudonoser
    20.11.2015 00:00
    +1

    Статья на хабр это хорошо, но можт стоит указать язык в тегах?


    1. achekalin
      20.11.2015 00:38
      +9

      Русский, батенька, тут больше за русский ратуют.

      Ассемблер, C и Паскаль упоминаются, но все же автор заботится о русскоязычной аудитории, за что ему нижайший (не) поклон!


      1. khim
        20.11.2015 01:06
        +3

        Да ладно вам. Какая же это «забота о русскоязычной аудитории» если все русские буквы куда-то пропали? Что за низкопоклонство перед западом? Возьмите КОИ-7 и будет вам щястя!

        ТЫПЕДЕФ ИНТ Целое;
        ТЫПЕДЕФ ФЛОАТ Дробное;
        ТЫПЕДЕФ БООЛ Условие;

        Целое ВместимостьВБуквах;
        Дробное ГлубинаБассейнаВМетрах;
        Условие ЕстьЛиЖизньНаМарсеДаНет;
        И нет проблем!

        Правда придётся отказаться от любимного «универсального стиля» в связи с отсуствием подчёркивания, но и так хорошо смотрится.


        1. Mrrl
          20.11.2015 01:12
          +2

          Не пройдёт. При обратном переключении эти надписи, конечно, останутся корректными, но на какое-нибудь

          Drobnoe Drobnoe_dlina[osseW[agah^eloweka;

          С++ будет ругаться.


          1. khim
            20.11.2015 07:34

            Ерунда. Мы что — хуже американцев? Они могут писать романы без буквы «E», а мы не можем обойтись без нескольких букв? Наоборот — это только добавит остроты!


  1. FiresShadow
    20.11.2015 07:50
    +2


  1. Koshelenok
    20.11.2015 08:11
    +5

    Чуть было не изошелся на «Ассемблерные вставки» прямо в автобусе пока дочитал! Пять с плюсом за сарказм, если это он.


  1. olekl
    20.11.2015 13:06
    +2

    По-моему, после «ассемблерных вставок» не догадаться, что тут ирония, странно. Спасибо, статья заставила поулыбаться! Особенно про имена переменных.


    1. Myosotis
      20.11.2015 15:36

      По-моему, уже на первом пункте понятно, что это пост-шутка)


      1. olekl
        20.11.2015 15:46

        Ну все-таки «параноик программинг» в некоторых случаях имеет место быть)


      1. Mrrl
        20.11.2015 16:45

        пост-шутка — это то, что с человеком сделают после такой шутки?


  1. gaelpa
    20.11.2015 13:28
    +1

    Как-то в статье смешаны обычные «вредные советы» и «истинное безумие». Имхо, первого добра навалом, можно было бы оставить только второе.


    1. Aclz
      20.11.2015 13:38

      Навалом и первого и второго.


  1. ssneg
    20.11.2015 15:32
    +1


  1. vlivyur
    20.11.2015 16:06

    Суперкласс — объектно-ориентированное и процедурное программирования в одном флаконе.
    <Зануда>
    Венгерская нотация это не про типы переменных, а про характер хранимого значения в ней (зарплата, цена продукта — всё в рублях, decimal, но складывать или перемножать их нельзя, на это и должен указывать префикс).
    </Зануда>


  1. LeX_KaR
    20.11.2015 17:06

    Просто поржал от души. Спасибо.


  1. fareloz
    20.11.2015 18:04

    Остер, вредные советы для программистов прям


  1. Ryder95
    24.11.2015 13:31

    Я не понял, половина советов кажется реально полезной


    1. Myosotis
      25.11.2015 15:48
      +1

      Значит, карьерная лестница вас ждет!


  1. Dark_Purple
    26.11.2015 10:12

    Адовый ад.