C中的常量指针数组是什么?

时间:2014-03-31 13:50:46

标签: c arrays function pointers const

不是数组的地址,也不是所有元素的地址也不变吗?

如果是这样,请在如下的声明中说明:

char *const argv[] 

不是const限定词的冗余吗?

3 个答案:

答案 0 :(得分:7)

没有

首先,const和"常数"实际上是C中的两个不同的东西,即使const关键字显然来自单词"常数"。 常量表达式是可以在编译时计算的表达式。 const真的意味着"只读"。例如:

const int r = rand();

完全合法。

是的,数组的地址 - 就像任何对象的地址一样 - 是只读的。但这并不意味着数组的(由其元素的值组成)是只读的,任何其他对象都必须是只读的。

考虑这三个声明:

char *arr1[10];
char *const arr2[10];
const char *arr3[10];

arr1是指向char的10个元素的指针数组。您可以修改char*元素,您可以修改这些元素指向的对象。

arr2是一个const(只读)指向char的数组。这意味着您无法修改数组的char*元素(一旦它们被初始化) - 但您仍然可以修改这些元素指向的char个对象或数组

arr3是指向const char的指针数组;您可以修改数组元素,但不能修改它们指向的内容。

现在您使用名称argv的事实表明您正在谈论main的第二个参数,这对此有一些巨大的影响。该语言指定main的第二个参数是

char *argv[]

或等同地

char **argv

没有const。您可能可以添加一个,但最好遵循标准指定的格式。 (更新:我从您的评论中看到您已经询问argv getopt() char * const argv[]参数,该参数定义为{{1}}。)

由于它是一个定义为数组的参数,另一个规则起作用:定义为某种类型数组的参数是"调整"指向该类型的指针。 (此规则仅将 应用于参数。)这不是运行时转换。函数不能有数组类型的参数。

C中数组和指针之间的关系可能令人困惑 - 而且那里有很多错误的信息。要记住的最重要的事情是数组不是指针

comp.lang.c FAQ的第6节是对细节的极好解释。

答案 1 :(得分:3)

  

不是数组的地址,也是其所有元素的地址   不管怎么说?

是的,C中的任何对象都是如此。回想一下,通过这里的对象,我们指的是存储器中具有值并由标识符引用的位置。标识符在其整个范围内绑定到固定的内存位置,您无法更改它。您可以更改对象的值。

int a = 4;
a = 6;  // legal. you can change the value of the object
&a = 23456; // illegal. you cannot change the address of the object

类似地,数组也是一个对象,其每个元素都有一个固定的内存地址。但是,数组元素保存的值与元素的地址无关。

请注意,如果声明出现在函数参数列表中,则以下内容是等效的

char *const argv[]
char *const *argv

这意味着argv是指向类型为char *const的对象的指针,即指向字符的常量指针。很明显char *const *argvchar **argv是不同的。所以让我们再举一个例子。

char *const argv[10];

上述语句将argv定义为一个10常量指向字符的数组。这意味着您必须初始化数组,以后不能将指针更改为指向不同的字符。但是,这与数组元素的地址无关。

char c = 'A';
char d = 'B';
char *const argv[2] = {&c, &d}; 

argv = &c; // illegal. you cannot the change the address of an object
argv[0] = &d; // illegal. you cannot change the value of the array element
*argv[0] = 'C'; // legal. you change the value pointed to by the element

如果没有const限定符,char *argv[2]表示一个2指向字符的数组。 这与我们如上所述具有const限定符的情况明显不同。因此,回答第二个问题,不,const限定符不是多余的。这是因为const限定符限定了数组元素的类型。

答案 2 :(得分:2)

不,不是。 char *const argv[]是一个指向char的常量指针数组。所以const使数组中的指针保持不变(你不能将它们改为指向内存中的其他字符串)。