el

РВН – Технология разработки программного кода

Данное руководство представляет собой профессиональную технологию и программный стандарт под условным названием Русско Венгерская Нотация – РВН.

РВН стандарт (или стиль) использовался при разработке ПО на 15-ти языках. Этот документ рассматривает аспекты его применения при программировании на С и С++.

Щёлкните по любой панели или подразделу для их раскрытия-закрытия Раскрыть панели меню
Раскрыть подразделы

Введение

РВН = snake_case + lowerCamelCase + CamelCase

РВН стиль – это смесь стандартов оформления кода, применяемых в C Linux, VC++, C#, Java, JS, PHP, Ruby, VB/Basic, Perl, Delphi/Pascal, SQL, EL76, ASM, Bash/Sh, NDOS.. Он разрешает все, что ведет к компактности и читабельности кода и подходит для разработчиков предпочитающих как snake_case, так и lowerCamelCase или CamelCase стили.

Стиль snake_case нагляднее, CamelCase компактнее, lowerCamelCase еще более компактен. В РВН вы сможете воспользоваться преимуществами все трех стилей одновременно там, где это выгодно.

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

Щёлкните по любому подразделу для его раскрытия-закрытия Раскрыть подразделы

Постановка задачи

Постановка задачи

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

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

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

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

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

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

Почему так важна стандартизация

Почему так важен стиль разработки?

Стиль разработки кода – это не мода, не каприз и не прихоть проджект-менеджеров, а актуальная необходимость, продиктованная существующей практикой. А именно:

1. Хороший стиль на порядок улучшает качество кода.

2. Одинаковость стиля повышает производительность разработки.

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

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

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

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

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

Суть РВН

Цели и задачи РВН

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

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

РВН – не просто стандарт или кодекс хороших манер программиста. Разработчики, пишущие в стиле РВН, находят в нём еще и мощную философскую подоплеку, которая обеспечивает РВН системность в реализации всех поставленных целей.

Суть технологии РВН состоит в соблюдении следующих ключевых концепций:
• модульность
DRY
• соглашения по программированию
• автодокументирование
• соглашения об именах
• соглашения по форматированию кода

Модульность позволяет изолировать независимые части кода друг от друга.

DRY означает: Don’t Repeat Yourself, то есть Не допускайте повторений. Другими словами, любая порция кода или сведений о системе должна быть размещена лишь в одном месте.

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

Автодокументирование (автоматическое документирование) обеспечивает механизм и поддерживает специальный синтаксис для генерации документации на ПО прямо из исходных текстов.

Определяющими являются соглашения об именах (включают соглашения по именованию и написанию). Их суть заключается в том, чтобы сделать код более коротким и ясным.

Целью соглашений по форматированию является достижение максимальной читабельности написанного кода.

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

У РВН есть вообще что-то такое, что трудно поддается описанию. У вас возникает чувство, что вы на правильном пути. Разумеется, пока вы не начнете писать код в стиле РВН , вам придется поверить нам на слово.

Если с помощью РВН добиться ясности кода не удаётся (код слишком сложен), то используйте комментарии. Если и это не помогает, то скорее всего алгоритм или код нужно пересмотреть и переписать заново.

Обзор технологии

Обзор РВН

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

При именовании РВН позволяет использовать (и/или не использовать) следующее:
• кодирование типа переменной в её идентификаторе (венгерская нотация)
• суффиксы и регистр символов (нижний, верхний, верблюжий CamelCase стиль)
• знаки подчёркивания для разделения слов

РВН стандарт подразумевает:
• модульность
• исключение дублирующего кода
• отсутствие магических чисел
• ограничение размера кода по горизонтали
• ограничение размера кода по вертикали (размер в один экран)
• и многое другое

Соглашения об именах

Щёлкните по любому подразделу для его раскрытия-закрытия Раскрыть подразделы

Соглашения по именованию

Выбирайте правильные имена

Выбирайте правильно имена

Имена – сердце программирования. Имя является результатом продолжительного осмысления среды, в котором живёт тот или иной объект. Только тот разработчик, который понимает систему в целом, может дать объекту имя, полностью вписывающееся в концепцию создаваемой системы.

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

В РВН допустимы имена в верблюжьей lowerCamelCase нотации. При этом lower можно опускать (CamelCase). Примеры:

В РВН допустимы имена в змеиной snake_case нотации. При этом snake можно опускать. Примеры:

В рамках РВН разрешено использовать так называемую венгерскую запись ( Hungarian Notation ). Венгерская запись позволяет обеспечить максимальную краткость имен идентификаторов при их же максимальной информативности.

Однако назвать переменную именем idx или даже i — это очень хорошо, но при условии, что будет понятно назначение этой переменной.

Имена могут включать общепринятые сокращения: или как часть имени, или в виде префикса/постфикса. При этом, имена должны быть наглядными. Если глобальной функции присвоить имя acpu(), то это может привести к путанице. Более подходящим будет имя:

Смешивать разные нотации в имени не рекомендуется. Примеры неправильных имен:

Венгерская нотация

Венгерская нотация

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

В РВН префиксы и постфиксы состоят из одного символа, к которому может добавляться знак подчеркивания. Обычно префиксы и постфиксы применяются для кодирования типа переменной в ее имени.

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

В РВН можно использовать не больше одного префикса в начале и не больше одного постфикса в конце имени. Имя не должно включать больше трех (а лучше двух) слов без учета префикса и постфикса.

Примеры неправильных имен:

Подбор имён переменных

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

Имя переменной должно полно и точно описывать сущность, представляемую переменной.

Имя следует выбирать читабельным, содержательным и по возможности коротким. В основе имени переменной должны лежать существительное (id, name, count, myID, last_name, coreCount).

Суть переменной Правильно Неправильно
Контрольная сумма check_sum KS, x, x1, x2, Temp
Число строк на странице lines_per_page LPP, x, x1, x2
Текущая дата current_date current, x, x1, x2
Скорость поезда train_velocity x, x1, x2
Идентификатор identifier, id x, x1, x2, idnt
Массив Идентификаторов aIdentifiers, aID ax, ax1, ax2, aidnt

 

Имена KS, LPP неудачны потому, что не являются общепринятыми сокращениями, вследствие чего не описывают сущность переменной.

Имя Current для переменной «Текущая дата» является неудачными, так как не полно и не точно описывает суть переменной.

Имена x, x1 и x2 традиционно представляют собой неизвестное количество чего-либо, что в данных случаях не является сутью переменной.

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

Суть переменной Правильно Неправильно
Код клавиши key_code knopka
Ширина width shirina
Высота height visota

 

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

Суть переменной Правильно Неправильно
Ствол орудия barrel tube, trunk
Подача в системе заряжания пушки feed supply
Подача электропитания power_supply feed

 

В качестве индексов простых циклов следует использовать переменные i, j и k и пр.

Если цикл является вложенным, индексу цикла рекомендуется присвоить полное осмысленное имя.

Правильный выбор имён индексов циклов позволяет избежать путаницы – использования i вместо j и наоборот. Кроме того, это облегчает понимание операций над массивами.

Например запись:

более информативна, чем запись:

Логическим переменным следует давать имена, подразумевающие значения true или false.

Такими типичными именами логических переменных являются:

Список примеров:

Суть переменной Правильно Неправильно
Операция завершена done flag
Операция завершена без ошибок success not_error

 

Следует использовать только утвердительные имена логических переменных, чтобы избежать появления инструкций типа

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

Правильно Но можно и так
typedef enum :
{
COLOR_RED,
COLOR_GREEN,
COLOR_BLUE
} Color;
typedef enum :
{
RED,
GREEN,
BLUE
} Color;

 

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

Правильно Неправильно

 

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

begin/end min/max visible/invisible
enabled/disabled next/previous source/target
first/last old/new up/down
locked/unlocked opened/closed add/delete

 

Подбор имён функций

Подбор имён функций

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

Рекомендуется начинать имя функции с глагола (выполняемого функцией действя).

Суть функции Правильно Но можно и так
Вычислить контрольную сумму
Вычислить контрольную сумму
Вычислить контрольную сумму
Вычислить КС и записать в БД

 

Если функция вычисляет контрольную сумму и записывает её в базу данных, то такой функции (по правилу выше) следует дать имя сalculateCheckSumAndSaveToDataBase().

Такое имя получается слишком длинным и несуразным. Следовательно, не стоит создавать функции с побочными эффектами.

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

В именах функций можно использовать описание возвращаемого значения.

Суть функции Имя функции
Вычислить косинус угла
Получить значение текущего цвета
Вычислить контрольную сумму

 

Для имен функций без возвращаемого значения (процедур) нужно обязательно использовать формат «глагол + объект». Глагол должен отражать выполняемое процедурой действие над объектом.

Суть процедуры Имя процедуры
Вывести документ на печать
Получить значение текущего цвета
Получить значение текущего цвета
Получить значение текущего цвета
Вычислить контрольную сумму
Вычислить контрольную сумму
Вычислить контрольную сумму

 

Если функция вычисляет какое-либо логическое выражение, то ей можно присвоить имя с префиксом Is.

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

 

Соглашения по написанию

Написание имён переменных

Написание имён переменных

Переменные следует писать либо строчными буквами, либо применять к ним lowerCamelCase и/или CamelCase стиль.

Имя переменной может включать:
• не больше трех слов
• тип переменной (обычно указывается в начале)
• общепринятые сокращения
• символы подчёркивания
• одни префикс
• один постфикс

При написании имён переменных, состоящих из нескольких слов, можно использовать символы подчёркивания для разделения отдельных слов в snake_case стиле. Также для разделения слов можно применять CamelCase стиль. После однобуквенного префикса имя переменной должно начинаться с заглавной буквы.

Примеры:

Правильно Неправильно

 

Написание макросов и констант

Написание макросов и констант

Константы, макроопределения или элементы перечислений следует писать заглавными буквами, а отдельные слова разделять символом подчёркивания “_”.

Написание имён функций

Написание имён функций

В именах функций и методов разрешено использовать все три нотации: snake_case + lowerCamelCase + CamelCase. Понятно, что при написании имён функций и методов в верблюжьей нотации каждое слово, входящее в состав имени, следует писать, начиная с заглавной буквы, остальные буквы имени должны быть строчными.

ВНИМАНИЕ ИСКЛЮЧЕНИЕ:
Для всех методов одного модуля можно использовать префикс в виде названия модуля в верхнем регистре (UPPER) и символа подчёркивания (префикс может быть в виде сокращённого имени модуля).

Правильно Неправильно

 

Написание литералов

Написание литералов

Шестнадцатеричные константы следует писать заглавными буквами. При этом префикс константы должен быть написан строчной буквой ‘x’.

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

Исключением является тип данных signed long – суффикс L следует писать заглавной буквой (чтобы случайно не перепутать похожие символы 1 и l).

Написание имен Классов

Написание имен Классов

Имена классов и типов можно начинать с заглавной буквы.

Также для именования классов и объектов существуют специальные префиксы и постфиксы:

Примеры:

Написание имен множеств

Использование множественного числа

Если нечто содержит несколько элементов чего-либо, то для именования такого нечто можно использовать множественное число.

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

Примеры:

Модульность и организация проекта

Щёлкните по любому подразделу для его раскрытия-закрытия Раскрыть подразделы

Соглашения по организации проекта и модули

Модульная структура программы

Организация программы

При проектировании программы, её необходимо разбивать на модули.

Модуль — функционально законченный фрагмент программы, оформленный в виде двух отдельных файлов с одинаковым названием, но разным расширением: файл реализации (может иметь расширение: .c на Си, .cc, .cpp на C++) и заголовочный файл (имеет расширение: .h ).

Заголовочный файл предоставляет интерфейс взаимодействия с модулем. Файл реализации содержит реализацию представленного интерфейса модуля.

Организация файлов модулей

Организация файлов модулей

Данные внутри файла реализации следует упорядочивать следующим образом:

  1. Спецификация модуля
  2. Директивы #include
  3. Определения макросов
  4. Определения типов
  5. Определения глобальных переменных
  6. Описания функций
  7. Импортируемые глобальные переменные и функции
  8. Реализации функций

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

  1. Спецификация модуля
  2. Директивы препроцессора для исключения повторного включения h-файла
  3. Директивы #include
  4. Определения макросов
  5. Определения типов
  6. Определения глобальных переменных
  7. Описания функций
  8. Импортируемые глобальные переменные и функции

Заголовки-разделители

Сплиттеры

Для организации спецификации файлов используйте сплиттеры (splitters):

Например:

DRY

Использование принципа DRY

РВН крайне рекомендует разработчикам широко использовать принцип DRY.

DRY – это принцип разработки программного обеспечения, который нацелен на снижение повторения информации различного рода, особенно в системах со множеством слоёв абстрагирования.

Принцип DRY формулируется как: «Каждая часть знания должна иметь единственное, непротиворечивое и авторитетное представление в рамках системы».

Этот принцип настолько важен, что не требует повторения!

Обычно его упоминают акронимом DRY, который впервые появился в небезызвестной книге The Pragmatic Programmer, но сам по себе, концепт был хорошо известен и активно использовался уже довольно давно.

Принцип DRY применяется к схемам баз данных, планам тестирования, сборкам программного обеспечения и документации.

Когда принцип DRY применяется успешно, изменение единственного элемента системы не требует внесения изменений в другие, логически не связанные элементы. Те элементы, которые логически связаны, изменяются предсказуемо и единообразно.

Автодокументирование с помощью Doxygen

Создание документации из исходных кодов


Система Doxygen

Комментарии и спецификации

Щёлкните по любому подразделу для его раскрытия-закрытия Раскрыть подразделы

Соглашения по самодокументированию

Спецификация модулей

Спецификация модулей

Каждый файл модуля должен начинаться с заголовка (шапки файла) и заканчиваться футером (footer):

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

При формировании шапки модуля следует использовать стиль документирования Doxygen. Директивы препроцессора для исключения повторного включения заголовочного файла должны иметь следующий формат:

где MODUL — название данного конкретного модуля.

Все константы, переменные и типы данных необходимо описывать с обязательным комментированием. При комментировании следует использовать стиль документирования Doxygen.

Спецификация функций

Спецификация функций

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

При описании функций следует использовать стиль документирования Doxygen.

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

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

Тело функции должен заканчивать footer:

Если функция включает локальные переменные, то их должен отделить от тела функции splitter:

splitter тела функции поможет вам также выравнивать код функции по ширине экрана.

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

Например:

Код реализации функции нужно отделять от кода другой/других функций двумя пустыми строками.

Комментарии в коде

Комментарии в коде

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

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

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

В теле функции рекомендуется использовать комментарии в стиле С++ – // … и по возможности минимизировать использование массовых комментариев в стиле /* … */.

Обычно комментарии кода должны быть похожи на следующие:

Комментарии внутри функций должны встречаться редко. Их нужно использовать только в специальных ситуациях, таких как документирование дефектов, или для важных замечаний. Важные замечания должны начинаться со строки:

А информация о дефектах — со строки: “@bug”, как в следующем примере:

Для автоматической генерации документации используйте Doxygen.

Документировать код можно путем введения комментариев в специальном формате:

Комментарии лучше писать на русском языке (или на английском). Они должны кратко пояснять смысл и цели выполняемых действий.

Для более подробной информации см. руководство Doxygen и другие разделы стандарта.

Правильно Неправильно

 

При документировании отдельных фрагментов кода рекомендуется использовать однострочные комментарии (отделённые символами “//”).

Правильно Неправильно

 

Комментарии следует располагать непосредственно перед описываемым участком кода. Однотипные короткие конструкции допустимо комментировать, располагая описания справа от инструкций. Такие комментарии следует выравнивать по одному столбцу.

Правильно Неправильно

 

В случае длинных блоков рекомендуется после закрывающей скобки блока в комментарии написать оператор блока.

При документировании кода необходимо отделять текст комментария от символов комментария (“//”) одним пробелом.

Для комментариев следует использовать такой же отступ, как и в соответствующем ему коде.

Форматирование кода

Щёлкните по любому подразделу для его раскрытия-закрытия Раскрыть подразделы

Форматирование исходного кода

Объявления

Объявления

Каждое объявление необходимо размещать на отдельной строке. Счётчики циклов желательно объявлять самыми последними.

Правильно Неправильно

 

При таком размещении проще дописывать комментарии к каждому объявлению, проще искать и редактировать переменные.

При объявлении переменных их следует группировать по логической взаимосвязи.

Правильно Неправильно

Color current_color;
uint8_t column_index;
Color next_color;
uint8_t row_index;
uint8_t i;

 

Отступы и выравнивания

Отступы и выравнивания

Инструкции, находящиеся под управлением блока, должны размещаться со сдвигом. Отступы будут подчеркивать логическую структуру программы. Благодаря этому будут ясно видны инструкции, расположенные внутри блока.

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

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

Размер одного символа табуляции при отображении соответствует 8 позициям.

Это не означает, что для структурирования нельзя использовать 8
или 4 символа пробела либо что-нибудь еще.

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

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

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

Альтернатива: В качестве отступа для сдвига блока можно использовать 4 (четыре) символа пробела.

Отступы и выравнивания должны отражать структурную вложенность языковых конструкций.

Правильно Неправильно

 

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

Можно разбить длинную строку на части, но не располагать параметры функций друг под другом, а просто использовать два символа табуляции для отделения продолжения длинной строки от ее начала, как показано ниже:

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

Описание переменных следует оформлять, выравнивая в вертикальные столбцы: типы, идентификаторы и начальные значения.

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

Фигурные скобки

Фигурные скобки

В РВН принято два соглашения по размещению фигурных скобок. Мы рекомендуем первое соглашение, но вы можете выбрать любое из них или оба сразу.

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

Как видим, по стандарту РВН фигурные скобки размещаются непосредственно под ключевым словом и по горизонтали на одном уровне с ним.

В случае, когда за закрывающей скобкой продолжается то же самое выражение, то продолжение выражения записывается с новой строки, как показано ниже:

Для do можно писать следующим образом:

Второе соглашение - размещать открывающую фигурную скобку в первой строке, сразу за соответствующим оператором. Закрывающая скобка помещается в первой позиции с новой строки, как в следующем примере:

В случае, когда за закрывающей скобкой продолжается то же самое выражение, то продолжение выражения записывается в той же строке, что и закрывающая скобка, как показано ниже:

или следующим образом.

Для функций это правило не действует и функции нужно оформлять только так, как показано ниже:

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

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

Фигурные скобки делают код более целостным и понижают число ошибок при дальнейшем расширении.

Примеры расстановки фигурных скобок

Примеры расстановки фигурных скобок

Пробелы

Пробелы

Операторы +, *, /, = и т.п. нужно отделять от операндов одним пробелом.

Логический оператор отрицания ! следует писать слитно с операндом.

Правильно Неправильно

 

После запятой или точки с запятой, если она не последняя в строке, должен быть пробел.

Правильно Неправильно

 

После открывающей круглой скобки и перед закрывающей круглой скобкой рекомендуется ставить пробел

Правильно Неправильно

 

При работе с массивами после открывающей квадратной скобки и перед закрывающей квадратной скобкой рекомендуется ставить пробел.

Правильно Неправильно

 

Для наглядности можно использовать два и более пробелов подряд.

Правильно Можно и так

 

Для функций рекомендуется не ставить пробел до открывающей круглой скобки, а для управляющих конструкций, таких как if, for, while (и им подобных) до открывающей круглой скобки пробел ставить можно.

Длина строк программного кода

Длина строк программного кода

При написании кода необходимо стараться, насколько это возможно, чтобы длина строки была не больше 80 символов.

Это позволяет строкам при отображении на терминале размером 80x24 символа вмещаться в одну строку терминала (не превышать ширины экрана 80 символов).

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

При необходимости некоторые инструкции можно перенести на другую строку. По возможности нужно стараться избегать переноса на новую строку только одного операнда.

Внимание: не существует стандартного правила, что делать в случае, если длина строки кода обязательно должна быть больше 80 символов.

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

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

Размер кода функций

Размер кода функций

Существует мнемоническое правило: функции не должны иметь больше десяти локальных переменных и по объему кода превышать одного-двух экранов текста. А еще лучше, если вы будете создавать функции не длиннее 40 строк. При большом количестве строк необходимо вынести часть логики в отдельные функции.

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

Исправление ранее написанного кода

Исправление ранее написанного кода

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

indent — отличная утилита GNU, которая предназначена для форматирования исходного кода в соответствии с заданными правилами.

Установки по умолчанию соответствуют стилю форматирования GNU, который выглядит не очень красиво. Для того чтобы утилита выполняла форматирование в соответствии со стилем написания например кода ядра Linux, необходимо использовать следующие параметры.

indent -kr -i8 -ts8 -sob -180 -ss -bs -psl [файл]

Можно также использовать сценарий scripts/Lindent, который вызывает утилиту indent с необходимыми параметрами.

Соглашения по программированию

Щёлкните по любому подразделу для его раскрытия-закрытия Раскрыть подразделы

Методологии и технологии

Портирование

Переносимость

porting.jpg

Переносимость — это свойство ПО, обеспечивающее перенос (портирование) выполнения кода с одной аппаратной платформе, для выполнения на другой.

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

Разработка переносимого кода

Портирование требует строгого учета множества факторов, а именно:
• тип платформы (64, 32, 16, 8 бит)
• размер машинного слова
• использование скрытых и специальных типов данных
• размеры типов данных
• знак char
• выравнивание в памяти (выравнивание нестандартных типов, структур и пр.)
• порядок следования байтов
• получение и использование частоты работы ЦП
• получение и использование частоты срабатывания системного таймера
• размер страницы памяти
• аппаратная зависимость механизмов синхронизации
• порядок выполнения операций ЦП (преемптивность, верхняя память, SMP)
• аппаратная зависимость для некоторых обработчиков прерываний
• знание поведения компилятора и обход реализационно-зависимого поведения
• отказ/принятие во внимание свойств C, зависящих от реализации
• использование длинных имён с внешней связью
• использование ассемблера и ассемблерных вставок
• аппаратная зависимость части кода инициализация памяти и некоторых регистров
• и т.д

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

Выбор языка программирования C — первый шаг в сторону уменьшения затрат на переносимость. Но есть ещё много других вещей, которые придется учитывать.

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

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

При создании переносимого кода изолируйте аппаратно-зависимый и системно-зависимый код в отдельных модулях. Дозировано используйте препроцессор для облегчения переносимости. Минимизируйте аппаратно-зависимый объем кода.

Ссылки

Опыт и нюансы реализации переносимого кода детально освещены в следующих статьях:
Р.Лав Разработка ядра Linux
Переносимость. Основы
Написание переносимых программ
Переносимость ПО GNU

Исключение дублирующего кода

Внедрение принципа DRY или не повторяйся

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

При этом вносить изменения в WET-код («Write Everything Twice») тяжелее, чем в DRY, ибо приходится держать в голове много разных мест (участков кода) и взаимозависимостей между ними. При модификации кода, который вызывает ту или иную функцию, бывает сразу трудно понять, какая же из существующих имплементаций используется (зависит от #define-ов и от #include-ов).

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

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

Переход на модульную платформу

Внедрение модульности

Иногда бывает, что в проекте код различных сущностей перемешан в больших общих файлах. Такой перемешанный код:

• небезопасен и незащищен от случайных изменений
• нечитабелен и, как следствие, плохо поддается модернизации

При поиске ошибки или расширении кода нужно найти соответствующие точки входа. Наличие IDE часто не помогает - бывает еще не ясно, что и где нужно искать. При этом приходится долго перемещаться по экрану среди бесчисленных ifdef (к слову, в ядре Linux использование директив ifdef категорически не рекомендуется). Все вышеперечисленное затрудняет понимание кода и тормозит его обновление.

Что нужно сделать:
Программу необходимо разбивать на модули (см. раздел организация проекта).

Преимущества модульности

Модульность позволит изолировать независимые части проекта друг от друга. Код проекта станет меньше (ничего лишнего) и яснее (унификация), а следовательно, его будет легче наращивать и поддерживать. Все вместе позволит вам ускоренно и безопасно развивать проект, а именно:

• быстро внедрять новые сущности
• исправлять ошибки и развивать отдельные части проекта без негатива для других
• упростить обновления (вплоть до случая, когда для исключения или модификации модуля надо лишь изменить одну-две строчки кода в определенном месте)

Модульность- это прежде всего системность, совокупность взаимодействующих объектов.

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

Настоящую модульность можно легко обеспечить, если использовать ООП или псевдо ООП-подход (там, где это уместно).

Псевдо ООП подход – это механизм создания классов на основе структур языка С, которые объединяют указатели на функции и данные.

ООП подход

Объектно-ориентированный подход

В ANSI-C обычно все проблемы решаются в чисто процедурном стиле. Процедурный стиль - это разрозненные функции, глобальные переменные, #ifdef, обертки и пр.

Почему нужен объектно-ориентированный подход (далее просто ООП):

1. Для получения истинной модульности через инкапсуляцию. Все собрано в одном месте – в объекте. На объект легко ссылаться, копировать и управлять его данными.

2. Для повышения безопасности (защита от случайных изменений, типизация, отсутствие глобальных переменных).

3. Для настоящей расширяемости и поддержки принципа DRY (через наследование, полиморфизм, перегрузку и замещение методов и пр.).

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

В результате ООП сделает код проекта безопасней и проще, причем почти без снижения общей производительности. ООП обеспечит возможность создавать единые сущности (объекты софта и аппаратуры) и избавиться от разрозненных функций и глобальных переменных. Объекты будут включать нужные свойства и методы, необходимые для использования и наращивания нового функционала в истинно модульном стиле. Сode-Reuse и DRY упростят обновления и расширяемость кода (наследование, полиморфизм, замещение) и, следовательно, станет не нужно править все и везде, а лишь изменить часть кода.

Что надо сделать: использовать объектно-ориентированный подход (псевдо-классы С), но только там, где это действительно полезно и упрощает код. Если нужно, выполнить рефакторинг уже существующего кода там, где это уместно.

Поддержка исключений в ANSI-C

Поддержка исключений в ANSI-C

Почему нужно: в сложных системах (написанных на других языках программирования: С++, С#, Delphi, Java, PHP и пр.) для реакции на ошибки применяется механизм обработки исключений. При этом код становится проще для понимания и пригодней для возможных будущих доработок.

Что надо сделать в ANSI-C:

• реализовать удобные для использования макросы подсистемы try...catch...finally (конечно, с учётом ограничений языка С)
• с их помощью переписать участи кода, где нужна и/или производится обработка ошибок

Дополнительный бонус: код будет выполняться быстрее (т.к. throw – это обычный goto), и он не требует нетривиальных пост-проверок в точках, куда выходят break.

Использование существующих возможностей

Используйте то, что уже есть

Не нужно изобретать велосипед. Обычно большой проект или среда, в которой вы работаете, предоставляет множество возможностей. Например функции работы со строками, функции вывода на консоль, различные тесты и asserts, интерфейсы работы со связанными списками и пр. Все это нужно использовать.

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

Использование ресурсов

Управление кучей

Менеджер памяти кучи

Активно используйте менеджер памяти кучи.

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

Ускорение работы кода

Ускорение работы кода

Что надо сделать:

• убрать необоснованные задержки
• обоснованные задержки сократить до определенных стандартами величин
• минимизировать вывод на консоль
• реализовать, где возможно, режим verbose
• если где-то нужна задержка, то её можно запараллелить с той работой, которая от неё не зависит (например, инициализация ethernet с задержкой, а на её фоне активация дисков и чтение файловой системы).

Разделение ресурсов

Разделение ресурсов

Работу кода можно ускорить путем параллельного использования и разделения ресурсов.

При разделении ресурсов следует использовать различные средства синхронизации: спин-блокировки, семафоры, атомарные операции и пр.

Соглашения по кодированию

Использование директивы typedef

Использование директивы typedef

Определение нового типа с помощью оператора typedef имеет следующие недостатки:

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

Конечно, существуют ситуации, в которых полезно использовать оператор typedef:

• сокрытие специфичных для аппаратной платформы деталей реализации или
• обеспечение совместимости при изменении типа

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

Использование ifdef

Никаких директив препроцессора ifdef в исходном коде

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

Вместо этого, если макрос CONFIG_FOO не определен, необходимо определять функцию fоо(), как ту, которая ничего не делает.

После этого можно вызывать функцию fоо() без всяких условий. Пусть компилятор поработает за вас.

Но если все же без директивы ifdef вам не обойтись, то её следует использовать только на очень коротких участках кода.

При этом внутри тела функции ifdef не следует начинать с начала строки. То есть, её выравнивание должно подчинятся правилам окружающего кода.

Инициализация локалов и глобалов

Инициализация локалов и глобалов

Обязательно инициализируйте все переменные и массивы при их объявлении.

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

Инициализация структур

Инициализация структур

Структуры необходимо инициализировать, используя метки полей. Это позволяет предотвратить некорректную инициализацию при изменении структур. Это также позволяет выполнять инициализацию не всех полей. К сожалению, в стандарте С99 принят довольно "страшненький" формат меток полей, а в компиляторе gcc ранее использовавшийся формат меток полей в стиле GNU признан устаревшим. Следовательно, для кода необходимо использовать новый формат согласно стандарту С99, каким бы ужасным он ни был.

Тут а и b — это поля структуры struct foo, а параметры INITIAL_A и INITIAL_B — соответственно их начальные значения.

Если поле не указано при инициализации, то оно устанавливается в свое начальное значение согласно стандарту ANSI С (указателям присваивается значение NULL, целочисленным полям — нулевое значение, а полям с плавающей точкой — значение 0.0 ).

Например, если структура struct foo также имеет поле int с, то это поле в предыдущем примере будет инициализировано в значение 0.

Да, это выглядит ужасно. Но у нас нет другого выбора.

Использование ассемблера

Минимизация ассемблерных вставок

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

Минимизация ассемблерных вставок нужна для улучшения читабельности кода. С учетом того, что C универсален, а ассемблер аппаратно зависим лучше, когда большая часть кода будет написана на C, а ассемблерные вставки будут только там, где это действительно уместно и нужно.

Что надо сделать: переписать всё на C, кроме глубоко аппаратных вещей. Вынести все ассемблерные вставки в ограниченное число файлов.

Преобразование типов

Избегайте ситуаций неявного преобразования типов

При явном приведении типа имя типа указывается в круглых скобках перед переменной или выражением. Например:

Неявное приведение типов происходит в следующих случаях:

• перед выполнением присваивания
• перед передачей аргумента функции
• перед возвратом функцией возвращаемого значения
• после вычисления выражения switch значение приводится к целому
• после вычисления выражений конструкций if, for, while, do-while значение приводится к типу bool
• после вычисления операндов бинарных арифметических, логических, битовых операций, операций сравнения, а также 2-го или 3-го операнда операции ?: значения операндов приводятся к одинаковому типу

Например, при выполнении бинарной арифметической операции значения операндов приводятся к одному типу. При наследовании указатели производного класса приводятся к указателям базового класса.

Пример на C:

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

При неявных преобразованиях возможны побочные эффекты. Например, при приведении числа вещественного типа к целому типу дробная часть отсекается (округление не выполняется). При обратном преобразовании возможно понижение точности из-за различий в представлении вещественных и целочисленных чисел. Например, в переменной типа float (число с плавающей точкой одинарной точности по стандарту IEEE 754) нельзя сохранить число 16 777 217 без потери точности, а в 32-х битной переменной целого типа int — можно. Из-за потери точности операции сравнения одного и того же числа, представленного целым и вещественным типами (например, int и float), могут давать ложные результаты (числа могут быть не равны).

Приведённый код выведет следующее, если размер int — 32 бита и компилятор поддерживает стандарт IEEE 754:

Порядок вычисления аргументов функции

Нельзя полагаться на порядок вычисления аргументов

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

Пример:

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

Оператор return

Использование оператора return

Внутри функций и методов оператор return старайтесь вызывать только один раз. Лучше всего перед выходом из функции или метода (перед финальной закрывающей скобкой }).

Такой подход позволит вам отрабатывать реакцию по завершению функции (или метода) единообразно и в одном месте, например, при отладке.

Если функция возвращает значение, его можно запоминать в локальной переменной и затем вернуть в конце функции или метода.

Для внедрения сказанного выше можно использовать псевдокод try, throw и catch.

Код возврата

При успешном завершении функции или метода рекомендуется возвращать значение SUCCESS - 0 (ноль) в качестве кода возврата.

Для избежания путаницы не следует использовать другие значения кода возврата (значения, отличные от SUCCESS), как признаки успешного выполнения функции или метода.

Прочие требования

Прочие требования

• не используйте магические константы
• используйте структуры и объединения для управления и манипулирования данными
• везде, где это возможно, используйте битовые поля вместо масок
• размещайте глобалы всего проекта в отдельном файле/файлах (например: global.h)
• при доступе к общим данным используйте setters и getters везде, где это возможно
• объявляйте переменные как можно локальнее, инициализируйте их при объявлении
• старайтесь не использовать глобальные переменные

• избегайте длинных функций и глубокой вложенности
• старайтесь не использовать препроцессор для задания определения функций
• активно используйте const
• используйте static для глобальных функций и переменных одного модуля

• проектируйте и пишите безопасный в отношении ошибок код
• проверяйте параметры функций и выходные данные на допустимость значений
• не жалейте сил на диагностику и проверяйте все, что можно проверить
• выдавайте предупреждения об ошибках везде и как можно раньше
• для верификации данных широко применяйте ассерты (asserts)
• для switch обязательно указывайте поведение по умолчанию (default)
• избавьте и не создавайте макросы и функции обертки, стабы, дублеры, заглушки
• повышенная диагностика для: IRQ, IPC, mm, syscalls, callbacks, drivers, libs

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

• не используйте оператор goto
• стремитесь к максимальной простоте (линейный код + минимум ветвлений)
• устраняйте все предупреждения компилятора
• настраивайте проект так, чтобы он компилировался во всех вариантах сборки

• программируйте, заглядывая в будущее
• как в шахматах, постоянно улучшайте позицию и повышайте качество кода

Использование системы контроля версий SVN

Управления версиями кода


Система Subversion

IDE

Kscope IDE для C Linux исходников

kscope.jpg

При разработке исходного кода удобно использовать IDE - интегрированную среду разработки.

Интегрированная среда разработки (Integrated Development Environment или IDE) — система программных средств, применяемая программистами для разработки программного обеспечения.

Integrated Development Environment для C Linux

Основными критериями при выборе IDE для программирования на C Linux являются:
• мульти-проектность
• навигация по коду
• подсветка синтаксиса
• операции с текстом: поиск, замена, перемещение, удаление, вставка и пр.

Этим критериям удовлетворяет множество сред. Наиболее популярные: NetBeans, Eclipse, KDevelop, IDEA, Anjuta. Все эти оболочки включают в себя редактор, компилятор, отладчик, средства сборки проекта и многое другое.

Некоторые разработчики предпочитают им интегрированную среду разработки Kscope, которая, ни в коем случае, не предназначена для замены популярных IDE, таких как NetBeans, Eclipse или KDevelop.

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

Обзор Kscope

Kscope - бесплатная (freeware) IDE, которая включает мощный редактор исходных кодов. Она обеспечивает среду редактирования для большинства проектов на C и позволяет обрабатывать исходники, состоящие из тысяч строк (такие, как ядро Linux).

Kscope - это QT4 front-end для KDE Cscope. Последняя консольная утилита заточена на сканирование исходников и реализует поиск в коде символов, определений, объявлений, функций и файлов по заданному фрагменту текста или шаблону.

Cscope является инструментом Linux для просмотра исходного кода в терминальной среде. Первоначально она была предназначена для работы с C кодом, но также хорошо работает с ПО созданном на C++, Java, а также с проектами, которые написаны на некоторых других языках.

Kscope построена вокруг эффективного Cscope-механизма навигации по исходникам, который позволяет пользователю выполнять запросы к коду.

Типы Kscope запросов к коду могут включают в себя:
• поиск всех определений идентификатора
• поиск всех ссылок на идентификатор
• поиск функций, вызываемых этой функцией
• поиск функций, вызывающих эту функцию:
• поиск по шаблону
• переход к строке
• поиск и замену строки
• копирование, перемещение, удаление фрагмента кода
• поиск файлов по фрагменту имени
• поиск всех #include по фрагменту текста
• и пр.

Запросы к коду обрабатываются с помощью основного Cscope процесса. Kscope просто служит front-end средой к основному Cscope процессу, скармливает ему запросы и анализирует вывод. Результат анализа, в дальнейшем, может использоваться для перехода к соответствующей строке в редакторе кода.

Основные свойства:
• много-оконность (через использование вашего любимого KDE редактора)
• управление проектом
front-end к большинству запросов Cscope
• список тегов для каждого открытого редактора
• вызов дерева окон
• дерево папок
• управление сессиями, включая сохранение и восстановление запросов
• работа с внешне-построенными Cscope.out файлами
• окно последних файлов
• и пр.

Настройка Kscope

Для начала заходим в меню Settings->Configure Kscope. Выбираем вкладку Programmes, настраиваем пути (можно нажать на кнопку Guess, которая находится чуть ниже).

[crayon-5a1660566fd57555118781/]

Жмем OK

На своё усмотрение можно настроить цвета и шрифт в соответствующих вкладках Colours и Fonts.

Далее. Заходим в меню Settings->Configure Kscope. Выбираем вкладку Open/Save.
Устанавливаем Encoding: в Cirillic ( koi8-r )

Заходим в Tools->Encoding.
Выбираем Cirillic ( koi8-r )

Создание Kscope проекта

Заходим в меню Project->New Project. И выполняем такие настройки:

Вкладка Details:
В поле Name вводим название своего проекта. В поле Path указываем путь к папке, в которой будет храниться файл вашего проекта.

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

Например:
Name KSCOPE
Path /home/lomako_g/hw3/allcpu/trunk/KSCOPE/KSCOPE
Source Root /home/lomako_g/hw3/allcpu/trunk/

Жмем OK

Переходим на вкладку File Types:
Здесь мы выбираем тип файлов (расширения), которые нужно добавить в проект.

Выбираем в правой колонке нужный тип файла и нажимаем << Add, нужный нам тип появится в левой колонке. После того, как вы добавите все необходимые типы (например .c, .S, .cc и .h) и нажмите на OK.

Добавление файлов в проект Kscope

После нажатия OK, откроется окно Project Files, которое также можно вызвать из меню Projects->Add/Remove Files. В этом окне можно добавлять файлы для редактирования кода.

В поле Filter можно задать фильтр для добавляемых файлов. Например, если у вас в папке есть файлы .c, .S, .cpp, .cc и .h, то при указания фильтра .h, в проект добавятся только файлы с этим расширением.

Для того, чтобы добавить файлы, нужно кликнуть на любую из трёх кнопок:
Files - просто добавляет в проект файлы из папки, можете сами выбрать нужные файлы
Directory - после клика по папке в проект добавляются все файлы из папки
Tree - в проект добавятся файлы из всего дерева

Добавляем в проект выбранные файлы и жмем OK

Если вы захотите, чтобы можно было добавить файлы с другим расширением, то вам нужно зайти в Project->Properties, выбрать вкладку File Types и произвести уже знакомые вам действия.

Скачать Kscope

Kscope-1.6.2.tar.gz
Kscope-1.9.4.tar.gz

Пример кода

Щёлкните по любому подразделу для его раскрытия-закрытия Раскрыть подразделы

Пример кода в стиле РВН

Пример заголовка модуля

Пример реализации модуля

Приложение А. Префиксы и постфиксы

Щёлкните по любому подразделу для его раскрытия-закрытия Раскрыть подразделы

Список префиксов и постфиксов

Префиксы и постфиксы РВН

Префиксы и постфиксы

el

В РВН запрещено использовать в именах много-буквенные префиксы и постфиксы. Поэтому РВН стиль - это не венгерская нотация и не надо их путать.

В РВН, для информативного и краткого кодирования, рекомендуется (и можно) использовать в именах только одно-буквенные префиксы и постфиксы из следующего списка:

Pre_ , _Pos Тип
   

A, a, a_ , _a Array

B, b, b_ , _b Byte unsigned char, signed char, char, s8, u8

C, _c Class

c, c_ Char, Literal, Letter, Character char, s8, u8

D, d , d_, _d Double double

E Error, Bug, Fail, Failure, Invalid

e, e_, _e Enum enum

F, _f Field, Feature, Attribute, Property, Member

f, f_ Variable of the Floating point, Real, float, double

G, g , g_, _g Global

H, h , h_, _h Header, Descriptor

I Item, Element, Cell, Entry, Entity

i, i_, _i Integer, Index int

J, j , j_, _j Job, Task

K, k , k_, _k Kernel

L, _l List

l , l_ Long long

M, m , m_, _m Method, Function, Procedure, Routine, Subroutine

N, n , n_, _n Numeric, Number unsigned int, unsigned char, unsigned long

O, o , o_, _o Object

P, p , p_, _p Pointer, Address, Link

Q, _q Queue, Table, List

q , q_, Quantity, Aamount, Number

R, r , r_, _r Register

S, _s Struct

s, s_ Signed

T, _t Type

t, t_ String, Text, Message

U, _u Union union

u, u_ Unsigned unsigned

V, v, v_, _v Value, Var, Variant, Void, Volume

W, _w Window, Screen, Display, Message, Screen-Output

w , w_, Word

Y, y , y_, _y Bit, Flag, Yes/No bool, boolean

X, x , x_, _x eXception, Interrupt, Trap, Event, CallBack

Z, z , z_, _z siZe, DiapaZon\Diapason, Zone, Range, Capacity, Dimension, Volume, Quantity, Amount, Weight

 

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

Примеры: [crayon-5a16605672643029228495-i/]

Примеры:

Приложение Б. Принятые сокращения

Щёлкните по любому подразделу для его раскрытия-закрытия Раскрыть подразделы

РВН Сокращения

Англо-русский словарь сокращений

Программные сокращения

el

СОКРАЩЕНИЕ ОПИСАНИЕ КОММЕНТАРИЙ
     

aau Array Access Unit Устройство обращения к массивам

abs Absolute Абсолютный

addr Address Адрес

adr Address Адрес

ahci Advanced Host Controller Interface Интерфейс для подключения по SATA

alc Arithmetic Logic Channel Арифметико-логический канал

alu Arithmetic Logic Unit Арифметико-логическое устройство

ansi American National Standards Inst. Америка?нский институт стандартов

ap App Processor Процессор приложения

apb Array Prefetch Buffer Буфер предварительной подкачки массивов

api App Programming Interface Интерфейс

apic Advanced interrupt controller Программируемый контроллер прерываний

app Application Приложение

arch Architecture Архитектура

arg Argument Аргумент

arr Array Массив

asi Address Space Identifier Идентификатор адресного пространства

asm Assembler Ассемблер, Ассемблерная вставка

atr Attribute Атрибут

     

bar Bar Полоса, панель, строка

bcd Binary-Decimal Двоичное-Десятичное

bg Begin Начало

bin Binary Двоичное

bist Built-in self-test Самотестирование

bit Bit Бит, Да/Нет, Флаг

bmc Baseboard Mng Controller Управляющий контроллер

boot Boot Loader Начальный загрузчик

brd Board Плата

bsp Boot Strap Processor Загрузочный процессор

btn Button Кнопка

buf Buffer Буфер

bus Bus Шина

     

calc Calculation Расчёт, вычисление

cbox CheckBox Флажок интерфейса

ch Channel Канал

cisc Complex Instruction Set Computer Компьютер с полным набором команд

clr Clear Очистить

cls Class Класс

cmd Command Инструкция, Команда, Код операции

cmp Compare Сравнение

cnct Connect Соединение, Подключение

cnt Counter Счётчик

col Column Колонка, Столбец

cond Condition Условие

conf Configuration Конфигурация

cp Copy Копирование, Копировать

cpu Central Processing Unit Центральный процессор

cpy Copy Копирование, Копировать

cs CheckSum Контрольная Сумма

csum CheckSum Контрольная Сумма

cu Control Unit Устройство управления

cur Current Текущий

     

db Data Base База данных

dbg Debug Отладка

dc Device Context Контекст устройства

ddr Double Data Rate Передача данных с двойной скоростью

dec Decimal Десятичное

def Default, Define По умолчанию, Определение

del Delete Удалить

desc Description Дескриптор, Описание

dev Device Устройство

diff Difference Различие, Сравнение

diag Diagnose Проверка, Диагностика

dig Digital Цифра

dim Dimension Размерность, Измерение

dir Directory Папка, Директорий, Каталог

disp Display Дисплей

dlg Dialog Диалог

dma Direct Memory Access Прямой доступ к памяти

dn Down Вниз, Выключить, Деактивировать

doc Documentation Документация

drv Driver Драйвер

dst Destination Место назначения, Цель, Получатель

dt Date-Time Дата-время

dye Color, Colour, Dye

Цвет, Краска, Окраска, Подкрасить, Окрашивать

     

ecc Error-Correcting Code Код коррекции ошибок

ee EEPROM NVRAM

elf Executable Linkable Format Формат исполняемого и линкуемого модуля

en Enable Разрешить

env Environment Среда

epic Explicitly Parallel Instr. Comp. Вычисления с явным параллелизмом

err Error Ошибка

evn Event Событие

exc Except, Exception, Exclusion Исключая, Исключение

exec Execution Выполнить

expo Export Экспорт, Интерфейс

     

fifo First In, First Out Первым пришёл — первым ушёл

fld Field Поле, Свойство, Атрибут

flh Flash Флэш

flop Floating Operations Per Second Вещественных операций в секунду

fram FRAM Энергонезависимое ОЗУ

frm Form Форма

fs File System Файловая Система

func Function Функция

     

gen Generation Герерация, Выработка, Формирование

glob Global Глобал, Глобальный

gnd Ground Земля напряжения питания

gnu GNU`s Not UNIX Лицензия, Стандарт

gpio General-purpose input/output Интерфейс IO общего назначения

gpu Graphics Processing Unit Графический процессор

gui Graphics User Interface Графический пользовательский интерфейс

     

hdd HDD Жесткий диск

hex Hexadecimal Шестнадцатеричное число

hi High Верхний, Старший

html HyperText Markup Language Язык гипертекстовой разметки

http HyperText Transfer Protocol Протокол передачи гипертекста

https Hypertext Transfer Protocol Secure Расширение протокола

hw HardWare Оборудование, Аппаратный

hwnd Window Description Дескриптор окна

     

i2c Inter-Integrated Circuit Последовательная шина

ib Instruction Buffer Буфер команд

id Identifier Идентификатор

ide Integrated Development Environment Интегрированная среда разработки

idx Index Индекс

il Interleaving Интерливинг

img Image Имидж

impl Implementation Реализация

inf Information Информация

info Information Информация

ini Initialisation Инициализация, Формат хранения

init Initialize Инициализация

ins Insert Вставлять, Встраивать, Импорт

int Integer Целое

io Input-Output Ввод-Вывод

ipc Inter-process communication Межпроцессорное взаимодействие

irq Interrupt ReQuest, Trap Прерывание, Обработчик прерывания

     

json JavaScript Object Notation Формат хранения и обмена

     

kbd Keyboard Клавиатура

keyb Keyboard Клавиатура

kpi South Bridge Контроллер Периферии МЦСТ

kpi2 South Bridge Контроллер Периферии V.2

krn Kernel Ядро

     

lbl Label Лейбл, Ярлык, Имя

lcd Liquid Crystal Display Жидкокристаллический дисплей

len Lenght, Size, Volume Длина, Размер, Обьем

lib Library Библиотека

lifo Last In, First Out Последним пришел — первым вышел (стек)

lim Limit Лимит, Граница, Предел

lin Line Линия, Строка

lnk Link Линк, Ссылка,Связь

lo Low Нижний, Младший

lru Least Recently Used Оновление кэш по давнему использованию

ls List Список

lst Text, List Текст, Документ, Лист, Список

lvds Low-Voltage Differential Signaling Низковольтная дифференциальная передача

     

mau Memory Access Unit Устройство доступа к памяти

max Maximum Максимум

mb Mother Board Материнская плата

mbus Module BUS Шина высокоскоростных SPARC компонентов

mc Memory Controller Контроллер памяти

mc Micro Controller Микроконтроллер

mdl Model, Module Модель, Модуль

mem Memory Память

mhi Mem High Верхняя область памяти

min Minimum Минимум

mips Million Instructions Per Second Миллион команд в секунду

mlo Mem Low Нижняя область памяти

mm Memory Manager Менеджер Памяти

mmu Memory Management Unit Устройство управления памятью

mmx Multi Media Extension Расширение системы команд

mng Management Управлять, Управление, Менеджер

moesi modified, owned, exclusive ... Протокол поддержки когерентности кэшей

mpp Massive Parallel Processing Системы с массовым параллелизмом

ms Millisecond Милисекунда

msec Millisecond Милисекунда

msg Message Сообщение

mv Move Переместить

mvc Model-View-Controller Модель-Представление-Контроллер

     

nb North Bridge Системный контроллер - Северный мост

net Network Сеть

nr Number Номер

num Number Номер

numa Non-Uniform Memory Architecture Несимметричное использование памяти

     

obj Object Объект

os Operation System Операционная Система

     

pa Physical Address Физический адрес

pack Package Пакет, Модуль

pf Predicate File Предикатный файл

pg Page Страница

pic Position-Independent Code Позиционно независимый код

pl Physical Layer Физический уровень

pll Phase lock loop Автоматической фазовая подстройка частоты (ФАПЧ)

plu Predicate Logic Unit Устройство логических предикатов

pmc PCI Mezzanine Card Стандарт PCI-мезонинов IEEE 1386.1

pmu Pipeline Management Unit Устройство управления конвейером

post Power on self test Тест при включении

prn Print Печать

proc Procedure Процедура

prop Property Свойство

prot Protocol Протокол

pt Page Table Таблица страниц

pte Page Table Entry Строка таблицы страниц

ptp Page Table Pointer Указатель таблицы страниц

ptr Pointer Указатель

ptrn Pattern Шаблон, Паттерн

pwd Password Пароль

pwm Pulse Width Modulator Широтно-Импульсный Модулятор

pwr Power Напряжение питания

     

ram Random Access Memory ОЗУ

rc Return Code, Recive Код результата вызова, Полученное

rcu Read—Copy—Update Вид синхронизации

rd Read Чтение

rdma Remote Direct Memory Access Прямой доступ к ОЗУ другого компьютера

ref Reference Ссылка

reg Register Регистр

res Resource Ресурс

ret Return Code, Return Код возврата, Выход

rf Register File Регистровый файл

risc Reduced Instruction Set Computer Архитектура с сокращенным набором команд

rm Remove Удалить

rn Rename Переименовать

rom Read-Only Memory ППЗУ, ПЗУ

rout Routine Маршрутизация, Маршрутизатор

rt Real Time Реальное время

rtc Real Time Clock Часы Реальное Времени

rw Read-Write Чтение-Запись

rx Receiver Прием, Принимать

     

sb South Bridge Периферийный контроллер - Южный мост

sbox Select Box Список выбора

sbus SBUS Шина обмена с периферией в SPARC

sc System Commutator Системный коммутатор (входит в состав SIC)

scr Screen, Indicator Экран, Индикатор, Cветодиод

scsi Small Computer System Interface Интерфейс для малых вычислительных машин

sdram Synchronous Dynamic Random Access Синхронная динамическая с произвольным

sec Second Секунда

sel Select Выбор, Выбирать

sem Semaphore Семафор

sen Sensor Сенсор

sh Shell Командная оболочка

sic System Interchange Controller Контроллером системных обменов

siz Size Размер, Объем

smp Symmetric Multi-Processor Симметричная мультипроцессорность

snd Sound Звук

soft Software ПО, Программа, Программный

sparc Scalable Processor Architecture Масштабируемая процессорная архитектура

spi Serial Peripheral Interface Последовательный периферийный

sql SQL SQL язык

src Source Источник

sru SubRoutine Unit Устройство подпрограмм

stdp СТДП Система Тестовых-Диагностических Программ

str String Строка текста

sts Status Статус

sub Subroutine Подпрограмма, Подсистема, Под

sys System Система, Системный

     

talk Talk Диалог

tar Tar Архив

tbl Table Таблица

temp Temperature Температура

tir Trap Info Register Содержит инфу о последних командах

tlb Translation Lookaside Buffer Буфер быстрого преобразования адреса

tlu Table Look-Aside Unit Устройство обращения к таблице страниц

tm Time, Timer Время, Таймер

tmp Temporary Временная переменная

tmr Timer Таймер

ts Temperature Sensor Температурный сенсор

tty Tele Type Writer Компьютерный терминал

try Try, Step, Phase, Stage Попытка, Шаг, Фаза, Этап, Стадия, Попытаться

tu Trap Unit Устройство обработки прерываний

tx Transmit Передача, Ответ, Отвечать

txt Text Текст

     

uart UART Универсальный асинхронный приёмопередатчик

unit Unit Блок, Модуль

url Uniform Resource Locator Единый указатель ресурсов

usr User Пользователь

uucp Unix to Unix CoPy Копирование между UNIX машинами

     

va Virtual Address Виртуальный адрес

val Value Величина, Значение

var Variant Вариант, Переменная

vliw Very Long Instruction Word Широкая команда

vnc Virtual Network Computing Вычисления через виртуальную сеть

vs Virtual System Виртуальная система

     

web Web Интернет

win Window Окно, Вывод на экран

wr Write Запись

     

xml eXtensible Markup Language Расширяемый язык разметки

     

zip Zip Архив

     

БД База данных  

ВК Вычислительный комплекс  

КСПП Сервисное-пользовательское ПО Комплекс

МВК Многопроцессорный ВК  

МЦСТ Центр SPARC-технологий в Москве

ОПО Общее ПО  

ОС Операционная система  

ОСПО Общесистемное ПО  

ПЛИС Интегральная логическая схема Программируемая

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

ППО Прикладное ПО  

ПС Программное средство  

СПО Системное/специальное ПО  

СТДП Тестовоео диагностическое ПО Система

СУБД Система управления БД  

ФПО Функциональное ПО  

ЦП Центральный процессор  

 

© Копировать пост можно лишь при наличии прямой индексируемой ссылки на youinf.ru

  


 
 
 

Яндекс цитирования