我在哪里可以找到有关“现代”C编程的资源?

时间:2011-06-10 14:04:58

标签: c

尽管已经读过K& R,甚至教过C课程,但我发现自己很难完全理解人们可能称之为“现代”的C语言。

在现代编程中似乎有许多不成文的约定,据我所知,在任何地方都没有记录。

以SQLite源代码为例。我在其中找到了例如:

 SQLITE_API int sqlite3_close(sqlite3 *);

SQLITE_API代表什么?这在句法上是如何正确的?

或者这个:

#ifndef _SQLITE3_H_
#define _SQLITE3_H_

在使用下划线为宏添加前缀的某个地方是否存在接受的约定?有时候我会看到带有两个下划线的宏。

或者使用固定大小的类型,例如uint32等等。什么时候应该使用这种做法,何时不使用?新的bool类型怎么样,什么时候应该优先于简单的整数呢?

当我阅读其他人的源代码时,这些是我自己提出的一些问题。是否有某个参考可以帮助我回答这些问题?

8 个答案:

答案 0 :(得分:4)

像这样的代码中的

SQLITE_API很可能是一个预处理器定义,它担心将调用暴露在例如DLL库构建。这很常见。

如果它在C中都是大写字母,那么它很可能是一个预处理器符号,一个好主意通常是通过预处理器运行游戏并阅读出来的内容。

答案 1 :(得分:3)

Afaik GNU编码标准正在不断修订/更新中,因此可能是“现代”风格的一个很好的快照。

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

Re:根据我的经验和我经常阅读的内容,特别是单下或双下划线;它是非常接受的更安全以避免使用双下划线前缀,因为它们通常是“保留”用于框架/系统/编译器特定和编译器相关的元素,因此宏 soley 可供使用在模块/包/单元/项目中,它们被定义应该避免被非语言加前缀。

大多数生命都有自己的语言编码标准和指导方针,这些标准和指南可能会有很大差异一如既往,一致性是关键。

答案 2 :(得分:2)

这个

#ifndef _SQLITE3_H_
#define _SQLITE3_H_

只是防范多重包容。

它可以防止xxx.h包含此文件以及yyy.h时的错误,yyy.h也包含此文件。

答案 3 :(得分:2)

SQLITE_API是我称之为'呼叫类型成语'的一个例子。它是一个预处理器指令,用于提高头文件的可移植性,其中头文件需要定义一些特定的调用模式,通常在主代码和DLL或类似之间。

根据所使用的平台和编译器,SQLITE_API通常会扩展为可用调用约定的某种组合,例如cdecl,__stdcall or similar.

您应该在头文件中找到它的定义。

答案 4 :(得分:1)

我认为这个东西没有一个很好的参考。您正在目睹的是一系列惯例,一些在业界广泛使用,一些可能更适用于您自己的代码库,这些惯例已经出现在C(以及衍生工具)中处理大型软件项目中的标准挑战或情况)。正如您所指出的,K& R是一个很好的教学工具,但没有涉及任何这些大规模的项目惯例,这些大会主要是在行业中有机地出现。

你举两个很好的例子。第一个是#define d,用于装饰一个函数,以便正确导出或只记录它将被导出。第二种模式称为“include guard”(参见链接),传统的下划线是可选的,但它是避免与普通魔数定义冲突的好方法。

有许多约定,其中许多涉及带有定义和宏的预处理器。您最好的选择可能是查找每个模式并单独询问。你可能会在这里得到关于理由和良好讨论的深思熟虑的答案。

答案 5 :(得分:0)

Expert C Programming是K& R的一个很好的跟进。不要被标题推迟。如果你了解C的基础知识,它是一本非常容易理解的书。它涵盖了很多现实世界的代码情况,K& R很短。

据说,实际上没有任何东西可以代替读写代码。大多数现代惯例并不是真正的标准,并且在不同的代码库中通常会有不同的遵守。它们只是解决每个人在语言中所面临的问题和限制的常见解决方案。在我看来,最重要的是要了解这些问题和限制是什么。

答案 6 :(得分:0)

首先,您应该意识到实际上禁止定义“_SQLITE3_H_” - 所有以下划线开头,后跟另一个下划线或大写字母的名称都会被保留。当你这样做时,简单的答案是,最好避免在你定义的任何上使用前导下划线。留下他们来实施。

就SQLLITE_API而言,它的可能在不同平台上的定义不同。例如,如果您在Windows上将其构建为DLL,则可能会定义如下:

#define SQLLITE_API __declspec(dllexport) __stdcall

另一方面,当您在代码中使用标题时,它可能会扩展为:

#define SQLLITE_API __declspec(dllimport) __stdcall

这些基本上告诉编译器在构建DLL时,您希望导出函数(因此它对世界其他地方可见)。当你在自己的代码中使用它时,它告诉编译器有问题的函数将来自DLL。

答案 7 :(得分:0)

我推荐David R. Hanson撰写的“C接口和实现:创建可重用软件的技术”。我认为这是关于使用C语言的最好的书之一。