Подтвердить что ты не робот

Где я могу найти ресурсы о "современном" программировании на C?

Несмотря на то, что он читал K & R и даже преподавал классы C, я смущающе не могу полностью понять, что можно назвать "современным".

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

Возьмем, к примеру, исходный код SQLite. В нем я нахожу, например:

 SQLITE_API int sqlite3_close(sqlite3 *);

Что означает SQLITE_API? Как это даже синтаксически правильно?

Или это:

#ifndef _SQLITE3_H_
#define _SQLITE3_H_

Есть ли принятое соглашение где-нибудь, когда префикс макросов с символами подчеркивания? Иногда я вижу макросы с двумя символами подчеркивания.

Или как использовать типы фиксированного размера, такие как uint32 и т.д. Когда следует использовать эту практику, а когда нет? Как насчет типа new-ish bool, когда он должен быть предпочтительнее простых ints?

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

4b9b3361

Ответ 1

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

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

Ответ 2

Стандарты кодирования Afaik GNU постоянно обновляются/обновляются, поэтому может быть хорошим снимком "современного" стиля.

http://www.gnu.org/prep/standards/

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

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

Ответ 3

Это

#ifndef _SQLITE3_H_
#define _SQLITE3_H_

- это просто защита от множественного включения.

Он предотвращает ошибки в случае, когда xxx.h включает этот файл, а также yyy.h, а yyy.h также включает этот файл.

Ответ 4

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

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

Вы должны найти его определение в файле заголовка.

Ответ 5

Я не думаю, что есть одна замечательная ссылка на этот материал. То, что вы наблюдаете, - это серия конвенций, некоторые из которых очень широко используются в отрасли, а некоторые, возможно, более специфичны для вашей собственной базы кода, которые возникли для обработки стандартных задач или ситуаций в крупномасштабных проектах программного обеспечения в C (и производных). Как вы заметили, K & R - отличный инструмент обучения, но не затрагивает ни одно из этих широкомасштабных соглашений о проектах, которые в основном появились органично и в промышленности.

Вы даете два замечательных примера. Во-первых, это #define d где-то, чтобы украсить функцию, чтобы она либо экспортировалась правильно, либо просто задокументирована, что она будет экспортироваться. Второй шаблон называется " включить охрану" (см. Ссылку), а обычные подчеркивания являются необязательными, но являются хорошим способом избежать конфликта с нормальной магией -number.

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

Ответ 6

Expert C Programming Отличное продолжение работы с K & R. Не откладывайте название. Это очень доступная книга, если вы знаете основы C. Она охватывает множество ситуаций реального мира, которые K & R довольно коротки.

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

Ответ 7

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

Что касается SQLLITE_API, он, вероятно, по-разному определяется на разных платформах. Например, если вы строили его как DLL на Windows, вероятно, было бы определено что-то вроде:

#define SQLLITE_API __declspec(dllexport) __stdcall

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

#define SQLLITE_API __declspec(dllimport) __stdcall

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

Ответ 8

Я бы рекомендовал Дэвид Р. Хансон "C-интерфейсы и реализации: методы создания многоразового программного обеспечения". Я думаю, что это одна из лучших книг об использовании языка С.