【问题标题】:Declaring function arguments as const in C在 C 中将函数参数声明为 const
【发布时间】:2019-01-15 13:52:13
【问题描述】:

在 C 中将函数的参数声明为 const 有什么用?它对性能有影响吗?

例如为什么你更喜欢 f1 而不是 f2?还是 f2 到 f1?

void f1(const char* arg) {
/* some code */
}

void f2(char* arg) {
/* some code */
}

【问题讨论】:

  • 嗯...作为参数传递的指针可以在函数中修改。所以如果它们被定义为const,那么它们将永远指向同一个地址……另一个参考:stackoverflow.com/questions/12291607/…
  • 表示不会修改,看这里:stackoverflow.com/questions/9419051/…
  • @PhoenixBlue 当然是错的。
  • 如果f1() 保证不会更改输入arg 或其内容,我更喜欢void f1(const char const * arg)
  • @PhoenixBlue 请看const的位置。它不影响指针。

标签: c constants


【解决方案1】:

const char* arg 表示arg 是一个指向常量char 的指针。如果您尝试更改 arg 指向的数据,您将收到类似以下内容的错误消息:error: assignment of read-only location ‘*arg’。但是,您可以更改arg 中包含的地址。

然而,通过删除const 关键字,您声明arg 指向的数据可以更改。

您的偏好应基于您的需求。请查看this 了解更多信息。

回复您的评论:char * const arg 表示arg 是指向char 的常量(停顿一秒)指针。因此,您无法更改 arg 中包含的地址,并且您可以更改驻留在该地址的数据。

【讨论】:

  • thx,那么,char * const arg 是否意味着我可以更改数据而不是指针的地址?
  • @FakherMokadem 已更新我的答案以包括 char * const arg
【解决方案2】:

你喜欢

void f1(const char* arg) 

如果不想通过 arg 修改 arg 指向的对象。 但是你可以修改 arg 本身。

你喜欢

void f2(char* arg) 

如果要通过arg修改arg指向的对象。

【讨论】:

  • 如果f1() 保证不会更改输入arg 或其内容,我更喜欢void f1(const char const * arg)
  • @Mawg:不,你的原型是多余的,你的意思是void f1(const char * const arg) 指定f1 不会改变参数本身的值。这样的const 限定是没用的,而且会混淆代码。
【解决方案3】:
void foo(const char *arg)

声明指向 const char 的指针。你不能改变引用的对象,但你可以改变指针

void foo(char * const arg)

声明指向 char 的 const 指针。你不能改变指针,但你可以改变引用的对象

void foo(const char * const arg)

声明指向 const char 的 const 指针。你不能改变指针和引用的对象

声明参数允许许多编译时优化,并且可能对生成代码的性能产生重大影响。

const 用于不应更改的参数和变量被认为是一种非常好的做法。被称为“const 正确性”

延伸阅读:restrict关键字。

【讨论】:

  • 我不会夸大可能的性能改进,这是有限的。 const 正确性更多的是关于提高代码质量和减少程序员错误。
  • @user694733 我在回答中写了什么?您认为正确使用 const 有什么缺点吗?
  • 没有缺点。我只是觉得“对生成代码的性能影响很大。”有点过分了。
  • @user694733 如果您认为这些琐碎的例子是肯定的。不是微不足道的——是的,它可能有。
【解决方案4】:

void f1(const char *arg) 中,参数arg 本身不是const 限定的,它被定义为指向函数不应修改的char 数组的指针。这对于读者一眼就能理解f1函数并没有修改它接收到的字符串非常有用。

例如strcpy<string.h> 中声明为:

char *strcpy(char *dest, const char *src);

第一个参数指向的数组被修改,它是目标数组,第二个参数指向源数组,没有被修改。

这种const 限定是病毒式的:一旦将参数定义为指向const 对象,您就只能将其传递给具有类似const 限定参数的函数。

关于对性能的影响,没有缺点。一些编译器甚至可能会从这种限定条件中受益并生成更好的代码。

所以在你的例子中,如果f1不修改arg指向的数组,除非你需要将f1存储在void (*)(char*)类型的函数指针中并且不能改变这个类型,我强烈建议使用:

void f1(const char *arg);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-08
    相关资源
    最近更新 更多