将const关键字添加到作为参数传递给函数的数组中

ovg*_*vin 15 c pointers

有没有什么办法可以将const关键字添加到作为参数传递的数组中来运行:

void foo(char arr_arg[])
Run Code Online (Sandbox Code Playgroud)

如果我放在()const之前或之后(),那将意味着它不是常数,而不是.charvoid foo(const char arr_arg[])charvoid foo(char const arr_arg[])chararr_arg

我刚刚读到,在引擎盖下,作为参数发送的数组被表示为指针,因此void foo(char arr_arg[])也是如此void foo(char* ptr_arg).考虑到这一点,我可能会重写函数,void foo(char * const ptr_arg)因为它正是我想要实现的.

但是我想知道是否有一种方法可以const在此声明中添加关键字,void foo(char arr_arg[])使其与void foo(char * const ptr_arg)(而不是 void foo(char const * ptr_arg)void foo(const char * ptr_arg))相同?

我只是想了解是否存在arr_arg使用数组表示法使常量变为常量的语法[].

AnT*_*AnT 18

在C语言中,你必须把const 之间[],但奇怪的是,看起来到毫无准备的人

void foo(char arr_arg[const]);
Run Code Online (Sandbox Code Playgroud)

这是"新的" C99特定语法.在C89/90或C++中,没有办法使用"数组"语法,所以你必须切换到等效的"指针"语法,如David的回答所示.

  • @ovgolovin:请注意,参数仍然不是数组,而是*指针*,并且该指针被复制,这意味着原始指针(和数组)无法在函数内部更改。如果您谈论的是真正的数组(而不是动态分配的内存),那么数组是不可变的(内容可以更改,但数组作为容器不能),因此将其标记为“const”没有什么意义 (2认同)
  • @ovgolovin:正如David指出的,在这种情况下,它不是数组,而是被声明为const的指针。首先,当支持要求所有功能参数保持不变的编码标准(并可能显式声明为“ const”)时,这可能很有用。其次,此功能可能是为了在此上下文中支持其他“更有用”的说明符而引入的,例如“ restrict”和“ static”,而“ const”只是为了顺便标记了。 (2认同)

Dav*_*eas 8

第一件事是在你的特定签名中,参数被编译器转换为指针,所以你拥有的是:

void foo( char * arg );
Run Code Online (Sandbox Code Playgroud)

现在,有两个实体可以在该签名中成为const:指针和指向的类型.为了使尖头类型可以用两种不同但等效的方式制成const [*]:

void foo( const char * arg );
void foo( char const * arg );
Run Code Online (Sandbox Code Playgroud)

可以使用以下语法将指针设为const:

void foo( char * const arg );
Run Code Online (Sandbox Code Playgroud)

但请注意,在函数签名中,与char arg[]转换为指针的方式相同char *arg,顶级限定符将被丢弃.因此,从宣言的角度来看,这两者是等价的:

void foo( char * const arg );
void foo( char *       arg );
Run Code Online (Sandbox Code Playgroud)

在定义中,顶级const可用于指示编译器不应在函数内更改参数指针(按值),并且它将检测您是否尝试将指针重置为其他位置.但是,如果只有指针是const,那么编译器很乐意让你修改指向的内存.如果您不希望该函数更改数组的内容,则应选择前两个签名之一.

[*]我更喜欢这种char const *格式,因为它提供了一种读取类型的一致方式:从右到左,它读取:一个指向const char的非const指针.另外,对typedef-ed类型进行推理更简单(通过在表达式中执行直接替换).给定typedef char* char_p;,const char_p并且char_p const既相同char * const又不同const char *.通过const在右侧持续使用,您可以盲目地替换typedef并阅读类型而无需推理.