【问题标题】:Is it a good practice to group related constants using structs in C?使用 C 中的结构对相关常量进行分组是一种好习惯吗?
【发布时间】:2020-04-07 11:12:04
【问题描述】:

我想知道将结构用作伪命名空间(类似于 C++)对在功能上或概念上相互关联的常量进行分组是否是个好主意。

static const struct {

    const unsigned int START;
    const unsigned int END;

} COUNTER = {.START = 1, .END = 100};

这有什么缺点吗?如果不是,将结构实例及其成员都声明为const 是否是多余的(甚至可能不方便)?这些值的恒定性应该在哪里声明?

【问题讨论】:

  • const 是多余的,const struct 表示所有成员都是const
  • 为什么不枚举?
  • @bolov 因为枚举不能满足模拟命名空间的目的。
  • 没有缺点。好主意。 (除了多余的const 和大写)
  • gian 微优化。现在可执行文件是 1M + 4,而不是优化后的 1M。

标签: c struct constants


【解决方案1】:

我想知道将结构用作伪命名空间是否是个好主意

嗯,这可能是个好主意。它本质上并不坏。反对的一个论点是,如果你觉得你需要命名空间,那么 C 很可能一开始就是错误的语言。但是可以这样用,有时也这样用。

这些值的恒定性应该在哪里说明?

一般来说,将整个结构声明为 const 就足够了。但要小心指针。此代码有效,将打印“42”:

int x = 5;

const struct {
        int *p;
} S = {.p = &x };

int main()
{
        *(S.p) = 42;
        printf("%d\n", x);
}

在上面的代码中,你不能改变 S.p 使它指向别的东西,但是 const 指针和指向 const 的指针是有区别的。所以对于指针,添加一个额外的常量可能是个好主意。

为了澄清,指针p 将被声明为int * const p,这意味着您不能更改指针本身,但为了保护它指向的数据,您需要const int *p。要同时获得两者,请使用 const int * const p,但如果结构声明为 const,您将“免费”获得其中一个,因此 const int *p 足以获得两者。

如果您考虑指向指针的指针,那么请考虑很长时间并对其进行测试以确保它以您想要的方式工作。

来自 cmets:

为什么不用枚举?

因为这是无效的:

enum S {a = 5};
enum Y {a = 6};

编译器会告诉你a 已经定义好了。所以枚举不适合模拟命名空间。此外,您不能将枚举用于非整数。

【讨论】:

  • 所以,这样做基本上没有任何问题,但是它可能真正有用的情况很少见,并且对于大多数目的来说,使用枚举不仅仅是过分的吗?
  • @Gian 嗯,真的不知道如何回答。如果枚举合适,则结构不合适,反之亦然。它们是具有不同目的的不同事物。
  • 我的意思是,正如已经指出的那样,NAMESPACE.constant 和 NAMESPACE_CONSTANT 之间没有太大区别。所以从这个意义上说,枚举和结构可以互换使用,而且枚举更方便。
  • 发现了一个关于C++的类似问题。不知道这也适用于 C,但用户建议这样做可能会阻止编译器优化未使用的命名值,因为它们是名称的一部分,整体上已被程序使用并且然后全部分配stackoverflow.com/questions/51162789/… 那么也许这是反对以这种方式使用结构的另一个论点?
【解决方案2】:

在 C 中使用结构对相关常量进行分组是一种好习惯吗?

这是基于意见的。如果它适合你,那就去做吧。

我不会那样做 i C。相反,我使用 #define

喜欢:

#define GROUPNAME_NAME

所以在你的情况下我会这样做

#define COUNTER_START 1
#define COUNTER_END 100

在 C++ 中我会这样做:

const unsigned int COUNTER_START = 1;
const unsigned int COUNTER_END = 100;

C 和 C++ 的区别在于语言规范的不同。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-02
    • 2016-03-21
    • 2013-03-30
    • 1970-01-01
    • 2015-02-18
    • 2016-03-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多