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

时间:2012-06-06 20:14:37

标签: c pointers

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

void foo(char arr_arg[])

如果我在constchar)之前或void foo(const char arr_arg[])之后char放置void foo(char const arr_arg[]),那就意味着char是常数,而不是arr_arg

我刚才read在幕后,作为参数发送的数组被表示为指针,因此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与数组表示法[]保持一致的语法。

5 个答案:

答案 0 :(得分:18)

在C语言中,您必须将const 放在<{em> []之间,无论多么奇怪,都可能看起来毫无准备的人

void foo(char arr_arg[const]);

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

答案 1 :(得分:8)

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

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并阅读类型而无需推理。

答案 2 :(得分:2)

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

void foo(char ptr_arg[const]);

是有效的语法,等同于

void foo(char *const ptr_arg);

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

  

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

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

答案 3 :(得分:2)

在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<int n>
void f2(char (&a)[n]) {}

http://ideone.com/4LvYT

答案 4 :(得分:0)

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

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

如果您使用Boost's array而不是直接使用C数组,那么您可以制作const,尽管它也是模板函数:

template <unsigned N>
void foo (Boost::array<char, N> const & arg) {}

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