我的团队开始使用 doxygen 记录我们的 C 代码,特别关注我们的公共 API 标头。doxygen 中似乎有很多灵活性和不同的特殊命令,这很棒,但如果没有反复试验,就不清楚什么是好事,什么是坏事。
您最喜欢的标记代码的方式是什么?您必须做什么和不应该做什么?
请提供您的重要提示,每个答案一个,以方便投票。
我希望定义 API 文档的整个方法,包括提供一个模板来让团队的其他成员开始。到目前为止我有这样的事情:
/**
* @file example_action.h
* @Author Me (me@example.com)
* @date September, 2008
* @brief Brief description of file.
*
* Detailed description of file.
*/
/**
* @name Example API Actions
* @brief Example actions available.
* @ingroup example
*
* This API provides certain actions as an example.
*
* @param [in] repeat Number of times to do nothing.
*
* @retval TRUE Successfully did nothing. …Run Code Online (Sandbox Code Playgroud) 我一直看到这个常量弹出各种图形头文件
0.0039215689
Run Code Online (Sandbox Code Playgroud)
它似乎与颜色有关吗?
void RDP_G_SETFOGCOLOR(void)
{
Gfx.FogColor.R = _SHIFTR(w1, 24, 8) * 0.0039215689f;
Gfx.FogColor.G = _SHIFTR(w1, 16, 8) * 0.0039215689f;
Gfx.FogColor.B = _SHIFTR(w1, 8, 8) * 0.0039215689f;
Gfx.FogColor.A = _SHIFTR(w1, 0, 8) * 0.0039215689f;
}
void RDP_G_SETBLENDCOLOR(void)
{
Gfx.BlendColor.R = _SHIFTR(w1, 24, 8) * 0.0039215689f;
Gfx.BlendColor.G = _SHIFTR(w1, 16, 8) * 0.0039215689f;
Gfx.BlendColor.B = _SHIFTR(w1, 8, 8) * 0.0039215689f;
Gfx.BlendColor.A = _SHIFTR(w1, 0, 8) * 0.0039215689f;
if(OpenGL.Ext_FragmentProgram && (System.Options & BRDP_COMBINER)) {
glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 2, Gfx.BlendColor.R, …Run Code Online (Sandbox Code Playgroud) 我观察到rand()库函数在循环中只调用一次,它几乎总是产生正数.
for (i = 0; i < 100; i++) {
printf("%d\n", rand());
}
Run Code Online (Sandbox Code Playgroud)
但是当我添加两个rand()电话时,现在生成的数字会有更多的负数.
for (i = 0; i < 100; i++) {
printf("%d = %d\n", rand(), (rand() + rand()));
}
Run Code Online (Sandbox Code Playgroud)
有人可以解释为什么我在第二种情况下看到负数吗?
PS:我在循环之前初始化种子为srand(time(NULL)).
众所周知,NaNs在算术中传播,但我找不到任何演示,所以我写了一个小测试:
#include <limits>
#include <cstdio>
int main(int argc, char* argv[]) {
float qNaN = std::numeric_limits<float>::quiet_NaN();
float neg = -qNaN;
float sub1 = 6.0f - qNaN;
float sub2 = qNaN - 6.0f;
float sub3 = qNaN - qNaN;
float add1 = 6.0f + qNaN;
float add2 = qNaN + qNaN;
float div1 = 6.0f / qNaN;
float div2 = qNaN / 6.0f;
float div3 = qNaN / qNaN;
float mul1 = 6.0f * qNaN;
float mul2 = qNaN * qNaN;
printf( …Run Code Online (Sandbox Code Playgroud) 我看到在使用了一个有趣的技术,答案到另一个问题,并想好一点理解.
我们给出了一个无符号的64位整数,我们对以下几位感兴趣:
1.......2.......3.......4.......5.......6.......7.......8.......
Run Code Online (Sandbox Code Playgroud)
具体来说,我们希望将它们移到前八位,如下所示:
12345678........................................................
Run Code Online (Sandbox Code Playgroud)
我们不关心指示的位的值.,并且不必保留它们.
该溶液是屏蔽掉不需要的位,并且乘以结果0x2040810204081.事实证明,这就是诀窍.
这种方法有多普遍?这种技术可以用来提取任何比特子集吗?如果不是,如何判断该方法是否适用于特定的位组?
最后,如何找到(a?)正确的乘数来提取给定的位?
我在编码书中看到了以下宏定义.
#define TRUE '/'/'/'
#define FALSE '-'-'-'
Run Code Online (Sandbox Code Playgroud)
那里没有解释.
请向我解释如何将这些作为工作TRUE和FALSE.
我正在开发一个包含大量遗留C代码的项目.我们已经开始用C++编写,目的是最终转换遗留代码.我对C和C++的交互方式有点困惑.我知道通过使用C++编译器包装C代码extern "C"不会破坏C代码的名称,但我不完全确定如何实现它.
因此,在每个C头文件的顶部(在包含警卫之后),我们有
#ifdef __cplusplus
extern "C" {
#endif
Run Code Online (Sandbox Code Playgroud)
在底部,我们写
#ifdef __cplusplus
}
#endif
Run Code Online (Sandbox Code Playgroud)
在两者之间,我们拥有所有的includes,typedef和函数原型.我有几个问题,看看我是否理解正确:
如果我有一个C++文件A.hh,其中包含一个C头文件Bh,包含另一个C头文件Ch,这是如何工作的?我认为当编译器进入Bh时,
__cplusplus将被定义,因此它将包装代码extern "C"
(并且__cplusplus不会在此块内定义).因此,当它进入Ch时,
__cplusplus将不会定义并且代码将不会被包装
extern "C".它是否正确?
包装一段代码有什么问题
extern "C" { extern "C" { .. } }吗?第二个会extern "C"
做什么?
我们不把这个包装器放在.c文件周围,只放在.h文件中.那么,如果函数没有原型会发生什么?编译器是否认为它是C++函数?
我们还使用了一些用C语言编写的第三方代码,并没有这种包装.每当我从该库中包含一个标题时,我就一直extern "C"在使用#include.这是处理这个问题的正确方法吗?
最后,这是一个好主意吗?还有什么我们应该做的吗?我们将在可预见的未来混合C和C++,我想确保我们覆盖所有基础.
我经常听到,在编译C和C ++程序时,我应该“始终启用编译器警告”。为什么这是必要的?我怎么做?
有时我也听说我应该“将警告视为错误”。我是不是该?我怎么做?