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

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

 void foo(char arr_arg[]) 

如果我在char之前放置constvoid foo(const char arr_arg[]) )或在charvoid foo(char const arr_arg[]) ),那将意味着它的char是常量,而不是arr_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保持常量的语法。

在C中你必须把const放在[] 之间 ,不管看起来多么奇怪,可能看起来没有准备的人

 void foo(char arr_arg[const]); 

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

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

 void foo( char * arg ); 

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

 void foo( const char * arg ); void foo( char const * arg ); 

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

 void foo( char * const arg ); 

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

 void foo( char * const arg ); void foo( char * arg ); 

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

[*]我更倾向于使用char const *格式,因为它提供了一种读取类型的一致方式:从右到左,它读取: 一个指向const char的非const指针 。 另外,更简单地推断typedef-ed类型(通过在表达式中执行直接替换)。 给定typedef char* char_p;const char_pchar_p const都等效于char * const ,与const char *不同。 通过在右侧持续使用const ,您可以盲目地替换typedef并在不必推理的情况下读取类型。

是的,在C中这是可能的,因为C99:

 void foo(char ptr_arg[const]); 

是有效的语法和等价于

 void foo(char *const ptr_arg); 

更一般地, []可以包含任何类型限定符, static和整数表达式。 但

可选的类型限定符和关键字static应仅出现在具有数组类型的函数参数的声明中,然后仅出现在最外层的数组类型派生中。

对于与指针声明等效的维度。

在C ++中有几种方法,但没有一种方法可以满足您的需求。

 //typedef has a very clear intent typedef char* array; void f0(const array a) {} //switch to pointers to sidestep the problem void f1(char* const a) {} //references are inherently const //can't take pointers, but guarantees the size, sometimes nice //this version obviously doesn't work in C template void f2(char (&a)[n]) {} 

http://ideone.com/4LvYT

对于C ++,Mooing Duck使用模板的答案是最直接的。

如果您有调用C ++实现的C接口的C代码,那么您将继续将参数转换为指针参数,并使其成为const

如果您使用Boost的数组而不是直接使用C数组,那么您将能够制作该const ,尽管它也是一个模板函数:

 template  void foo (Boost::array const & arg) {} 

Boost::array的优点在于它使您能够从堆栈中轻量级地分配数组,但能够完全使用依赖于容器中的特征的STL算法。