Перейти к содержимому

Как сделать отступ в c

  • автор:

Оформление программ и отступы

Паскаль, как и многие другие языки программирования, допускает достаточно свободное оформление программ. Вы можете ставить пробелы и переводы строк как вам угодно (за исключением, конечно, ряда понятных требований типа пробелов в выражении if a mod b=c then ).

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

Основная цель форматирования программы — чтобы была лучше видна ее структура, то есть чтобы были лучше видны циклы, if’ы и прочие конструкции, важные для понимания последовательности выполнения действий. Должно быть легко понять, какие команды в каком порядке выполняются в программе, и в первую очередь — какие команды относятся к каким циклам и if’ам (циклы, if’ы и подобные конструкции ниже я буду называть управляющими конструкциями).

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

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

Обязательные требования

  • Используйте здравый смысл. Любое из указанных ниже правил можно нарушать, если здравый смысл подсказывает вам, что лучше сделать не так — но такие ситуации скорее исключение, чем правило.
  • На каждой строке должно быть не более одной команды и/или управляющей конструкции.
    • Исключение: очень тесно связанные между собой по смыслу команды типа assign и reset.
    • Исключение: управляющая конструкция, внутри которой находится только одна короткая команда, например:
    if a>0 then inc(i);
    for i:=a to b do if x[i]<>0 then begin // больше кода тут быть не должно!
    if a=0 then begin b:=2; // в этой строке отступ c:=c+2; // и в этой тоже end;

    Основной принцип отступов — программу можно представить себе как последовательность вложенных блоков. Основной блок — сама программа. В нем могут быть простые команды, а также сложные блоки — if’ы, циклы и т.д. Код внутри if’а или внутри цикла — это отдельный блок, вложенный в основной блок. Код внутри цикла внутри if’а — это блок, вложенный в другой блок, вложенный в третий. Пример: следующему коду:

    read(n); for i:=1 to n do begin read(a[i]); if a[i]>0 then begin writeln(a[i]); k:=k+1; end; end; if n>0 then writeln('!');

    соответствует следующая структура блоков:

    +--------------------+ | основная программа | | +-----------+ | | | цикл for | | | | +-------+ | | | | | if | | | | | +-------+ | | | +-----------+ | | +------+ | | | if | | | +------+ | +--------------------+
    for i:=1 to n do begin read(a); s:=s+a; end; // end сразу виден if s>2 then writeln(s) else begin // else сразу виден и разрывает последовательность строк: writeln('Error'); // видно, что это две ветки halt; end; // видно, что end есть и не потерян
    if dir='North' then . else if dir='South' then . else if dir='East' then . else if dir='West' then . else writeln('Error!');

    По смыслу программы это — многовариантное ветвление, здесь все случаи равноправны или почти равноправны. Тот факт, что в программе каждый следующий if вложен в предыдущий — это просто следствие того, что в паскале нет возможности сделать многовариантное ветвление. Поэтому такой код надо оформлять именно так, как указано выше, т.е. все ветки else if делать на одном отступе. (Не говоря уж о том, что если на каждый такой if увеличивать отступ, то программа очень сильно уедет вправо.) Но отличайте это от слудеющего варианта:

    if a=0 then writeln(-1); else begin if b=0 then begin x:=1; else x:=b/a; writeln(x); end;
    read(a); b:=0; c:=0; for i:=1 to a do begin b:=b+i*i; c:=c+i; end;

    Все равно неправильно (for всегда выполняется после c:=0, поэтому отступы должны быть одинаковыми):

    read(a); b:=0; c:=0; for i:=1 to a do begin b:=b+i*i; c:=c+i; end;
    read(a); b:=0; c:=0; for i:=1 to a do begin b:=b+i*i; c:=c+i; end;
    if a=0 then // условие короткое, лучше в одну строку . for i:=1 to 10 do // аналогично . if (((sum+min=min2+min3) or (sqrt(sumSqr)<30)) and (abs(set1-set2)+eps>thershold)) or (data[length(s)-i+1]=data[i]) or good then.
    if a=0 then . for i:=1 to 10 do . if ( ( (sum+min=min2+min3) or (sqrt(sumSqr)<30) ) and (abs(set1-set2)+eps>thershold) ) or (data[length(s)-i+1]=data[i]) or good then.
    type int=integer; float=extended; var i:integer; s:string;

    Не столь обязательные требования, но которые я настоятельно рекомендую соблюдать

    • Пишите begin на той же строке, что и управляющая конструкция, ну или хотя бы на том же отступе, что и управляющая конструкция:
      Совсем плохо:
    for i:=1 to n do begin read(a[i]); .

    Более-менее:

    for i:=1 to n do begin read(a[i]); .
    for i:=1 to n do begin read(a[i]); .

    Пример хорошо отформатированной программы:

    function sum(a, b: longint): longint; begin sum := a + b; end; var i, a, b, s: longint; x, y: double; arr: array [1..1000] of boolean; begin read(a, b); arr[1] := true; for i := 2 to 1000 do if ((a > 0) and (arr[i-1])) then arr[i] := true; for i := 1 to 1000 do arr[i] := false; s := 0; if (a < 0) then begin a := -a; if (b < 0) then begin b := -b; s := a + b; end else begin while (s 
    
    

    Хороший стиль программирования

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

    Ясность кода

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

    Пробелы и форматирование

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

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

    Отступ

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

    if ( true ) < // блок кода >
    Стили скобок

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

    if ( true ) < // блок кода >

    Есть и другие стили:

    if ( true ) < // блок кода >
    if ( true ) < // блок кода >

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

    Ширина отступа

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

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

    Табы и пробелы

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

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

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

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

    if ( long_term_one && long_term_two ) < // код >

    Если второе условие было отформатировано с помощью таба с отступом в четыре пробела с последующим пробелом, то при открытии в другом редакторе с шириной табов в восемь пробелов, код будет выглядеть некрасиво:

    if ( long_term_one && long_term_two ) < // код в теле оператора выбора >

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

    if ( long_term_one && long_term_two ) < // код оператора if >
    Неправильное использование пробелов

    Сколько пробелов вы используете зависит только от вас. Но, стоит быть в курсе некоторых вопросов. Во-первых, чем больше пробелов помогает подчеркнуть логику вашей программы, тем лучше. Но вы не хотите, чтобы ваши пробелы дезориентировали вас. Это может не запутать вас в данный момент, но может сбить с толку вас в будущем, или кого-то еще, кто будет читать ваш код. Как же выглядит ошибочное форматирование?

    if ( true ) ++i; ++j;

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

    Практическое руководство. Задание отступов, выступов и маркеров абзацев с помощью элемента управления RichTextBox в Windows Forms

    Элемент управления RichTextBox в Windows Forms поддерживает разнообразные варианты форматирования отображаемого в нем текста. Вы можете форматировать выбранные абзацы в виде маркированного списка, устанавливая свойство SelectionBullet. Вы также можете использовать свойства SelectionIndent, SelectionRightIndent и SelectionHangingIndent, чтобы задавать отступы абзацев относительно левого или правого края элемента управления, а также левую границу других строк текста.

    Форматирование абзаца в виде маркированного списка

    1. Установите свойство SelectionBullet в значение true .
    RichTextBox1.SelectionBullet = True 
    richTextBox1.SelectionBullet = true; 
    richTextBox1->SelectionBullet = true; 

    Чтобы задать отступ абзаца

    1. Задайте в свойстве SelectionIndent целое число, представляющее расстояние в пикселях между левым краем элемента управления и левой границей текста.
    2. Задайте в свойстве SelectionHangingIndent целое число, представляющее расстояние в пикселях между левой границей первой строки текста в абзаце и левой границей последующих строк в том же абзаце. Значение свойства SelectionHangingIndent влияет только на строки в абзаце, расположенные под первой строкой.
    3. Задайте в свойстве SelectionRightIndent целое число, представляющее расстояние в пикселях между правым краем элемента управления и правой границей текста.
    RichTextBox1.SelectionIndent = 8 RichTextBox1.SelectionHangingIndent = 3 RichTextBox1.SelectionRightIndent = 12 
    richTextBox1.SelectionIndent = 8; richTextBox1.SelectionHangingIndent = 3; richTextBox1.SelectionRightIndent = 12; 
    richTextBox1->SelectionIndent = 8; richTextBox1->SelectionHangingIndent = 3; richTextBox1->SelectionRightIndent = 12; 

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

    См. также

    • RichTextBox
    • Элемент управления RichTextBox
    • Элементы управления для использования в Windows Forms

    Совместная работа с нами на GitHub

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

    Как осуществить ввод списка с отступом от края

    Опишите подробнее, что вы имеете в виду. Вы хотите, чтобы при вводе с клавиатуры каждой строки курсор находился не в первой (как обычно бывает после нажатия на ENTER) позиции строки а в заданной (скажем, 10-й)?

    18 фев 2018 в 9:05
    Да, именно так.
    18 фев 2018 в 10:16
    Тогда печатайте в цикле ввода перед gets (только замените его на fgets) нужное число пробелов.
    18 фев 2018 в 15:36

    А в каком кокретно место вставлять пробелы перед gets, я уже все препробовал, везде появляется ошибка при компиляции.

    18 фев 2018 в 22:16

    2 ответа 2

    Сортировка: Сброс на вариант по умолчанию

    std::vector vs(29); std::string s; size_t i = vs.size(); while ( std::cin >> s && i--)

    как хотите так и вводите - фамилии будут в вашем векторе

    Отслеживать
    ответ дан 17 фев 2018 в 20:46
    AR Hovsepyan AR Hovsepyan
    15.9k 3 3 золотых знака 14 14 серебряных знаков 30 30 бронзовых знаков
    На счет fgets понял, не понял куда всунуть нужное число пробелов. Можно, наверное, вставить "\t"
    18 фев 2018 в 16:35
    вы хотите вводить фамилии через пробелы?
    18 фев 2018 в 18:45

    Сделал всавку for (i=0;i Все получилось. Вот только после " Вводим список класса:" первая фамилия пробивается в два раза дальше, чем вторая

    18 фев 2018 в 23:50

    Вот почти ваша программа.
    Я просто оставил в ней все относящееся к вводу-выводу данных, добавил вычитывание символов, оставшихся после ввода количества фамилий, заменил gets() на С++-ный ввод строки .getline() и выбросил "сортировку" (она в таком виде все равно не работает, но это уж вы сами сделайте)

    #include #include #include #include using namespace std; int main(int argc, char *argv[]) < int i, a, n; char str_spisok[29][19]; cout > n; while ((a = cin.get()) != '\n') if (a == EOF) exit(1); cout cout 

    Проверка в Linux:

    avp@avp-ubu1:hashcode$ g++ t1.cpp -Wall && ./a.out Введите число фамилий в списке (29 или меньше): 3 Вводим список класса: Иванов Петров Sidorov Список отсортирован: Иванов Петров Sidorov avp@avp-ubu1:hashcode$ 

    Как видите с отступами все нормально.

    В Win-7 (MinGW и окошко консоли) я тоже попробовал и с печатью отступов также нет проблем.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *