阅读复杂的 const 声明的简单规则?

2022-01-23 00:00:00 c constants c++ declaration

对于阅读复杂的指针声明,有 左右规则.

For reading complex pointer declarations there is the right-left rule.

但是这条规则并没有提到如何阅读const修饰符.

But this rule does not mention how to read const modifiers.

例如在一个简单的指针声明中,const 可以通过多种方式应用:

For example in a simple pointer declaration, const can be applied in several ways:

char *buffer; // non-const pointer to non-const memory
const char *buffer; // non-const pointer to const memory
char const *buffer; // equivalent to previous declartion
char * const buffer = {0}; // const pointer to non-const memory
char * buffer const = {0}; // error
const char * const buffer = {0}; // const pointer to const memory

现在 const 与指针声明的指针一起使用怎么样?

Now what about the use of const with a pointer of pointer declaration?

char **x; // no const;
const char **x;
char * const *x;
char * * const x;
const char * const * x;
const char * * const x;
const char * const * const x;

阅读这些声明的简单规则是什么?哪些声明有意义?

And what is an easy rule to read those declarations? Which declarations make sense?

顺时针/螺旋规则是否适用?

ASTUnit::LoadFromCommandLine 方法使用const char ** 提供命令行参数(在 llvm clang 源中).

The method ASTUnit::LoadFromCommandLine uses const char ** to supply command line arguments (in the llvm clang source).

getopt()的自变量向量参数为声明如下:

The argument vector parameter of getopt() is declared like this:

int getopt(int argc, char * const argv[], const char *optstring);

在该上下文中,char * const argv[] 等价于 char * const * argv.

Where char * const argv[] is equivalent to char * const * argv in that context.

由于这两个函数使用相同的概念(一个指向字符串的向量来提供参数)并且声明不同 - 显而易见的问题是:它们为什么不同?一个比另一个更有意义?

Since both functions use the same concept (a vector of pointers to strings to supply the arguments) and the declarations differ - the obvious questions are: Why do they differ? Makes one more sense than the other?

意图应该是:const 修饰符应该指定函数不操作此向量的字符串,也不改变向量的结构.

The intend should be: The const modifier should specify that the function does not manipulate strings of this vector and does not change the structure of the vector.

推荐答案

const 修饰符是微不足道的:它修改它之前的内容,除非在它之前没有任何东西.所以:

The const modifier is trivial: it modifies what precedes it, unless nothing precedes it. So:

char const* buffer;  // const modifies char
char* const buffer;  // const modifies *

等.一般情况下,最好避免前面没有任何内容的形式const,但实际上,你会看到它们,所以你必须请记住,当 const 之前没有类型时,您必须在逻辑上将其移到第一种类型的后面.所以:

, etc. Generally, It's best to avoid the forms where nothing precedes the const, but in practice, you're going to see them, so you have to remember that when no type precedes the const, you have to logically move it behind the first type. So:

const char** buffer;

其实是:

char const** buffer;

,即指向 const char 的指针.

, i.e. pointer to pointer to const char.

最后,在函数声明中,[] after 读作 * before.(同样,最好避免这种误导性的符号,但是你会看到它,所以你必须处理它.)所以:

Finally, in a function declaration, a [] after reads as a * before. (Again, it's probably better to avoid this misleading notation, but you're going to see it, so you have to deal with it.) So:

char * const argv[],  //  As function argument

是:

char *const * argv,

指向 const 的指针,指向 char.

a pointer to a const pointer to a char.

相关文章