常量指针数组

6

好的,我知道这是无效的

 char char_A = 'A';
    const char * myPtr = &char_A;
    *myPtr = 'J'; // error - can't change value of *myP

[因为我们声明了一个指向常量字符的指针]
这为什么是合法的呢?
 const char  *linuxDistro[6]={ "Debian", "Ubuntu", "OpenSuse", "Fedora", "Linux Mint", "Mandriva"};

for ( int i=0; i < 6; i++) 
cout << *(linuxDistro+i)<< endl;

*linuxDistro="WhyCanIchangeThis";// should result in an error but doesnt ? 
for ( int i=0; i < 6; i++) 
cout << *(linuxDistro+i)<< endl;

感谢您的关注!

现在是C还是C++? - user529758
C++ 我的错,我移除了 C 标签。 - Illusionist
感谢大家的回复,你们太棒了! - Illusionist
4个回答

12

你写

*linuxDistro =  "WhyCanIchangeThis";

这是完全有效的,因为linuxDistro的声明是

const char *linuxDistro[6];

也就是说,它是一个包含6个指向const char的指针的数组。也就是说,您可以更改指针本身,但不能更改这些指针所指向的字符。也就是说,您无法编译

*linuxDistro[0] = 'B';
为了获得字符串"Bebian",因为这些字符串包含常量字符,你可能想要的是一个常量指针数组:

What you probably want is an array of constant pointers to constant characters:

const char *const linuxDistro[6];

“*linusDistro 和 *linuxDistro[0] 不是一样的吗?” - Ashwin
@Ashwin 不是的。为什么会呢? - user529758
数组的名称保存了数组第一个元素的内存地址。 - Ashwin
记录一下,即使我从linuxdistro中移除了const,linuxDistro [0] ='B' 在运行时仍会崩溃。 - Illusionist
@Illusionist:那是因为你使用字符串字面量进行了初始化。字符串字面量是不可更改的,编译器会自动去除 const 限定符。(如果开启了警告,它会告诉你这个问题。) - icktoofay
显示剩余2条评论

3

*linuxDistro仍然是一个指针,它是linuxDistro[0],*linuxDistro="WhyCanIchangeThis"它只是将指针更改为指向新地址,而不是修改旧地址中的内容,所以这没问题。

如果你写**linuxDistro='a',那么应该会出现错误。


1

因为 char 不等于 char[],所以当您访问 char[]* 时,您将访问它的第一个元素(Debian)。

当您移动指针(例如 +1)时,您将访问数组的下一个元素

这里有一个好例子可以更好地理解

#include <iostream>
using namespace std;

int main ()
{
  int numbers[5];
  int * p;
  p = numbers;  *p = 10;
  p++;  *p = 20;
  p = &numbers[2];  *p = 30;
  p = numbers + 3;  *p = 40;
  p = numbers;  *(p+4) = 50;
  for (int n=0; n<5; n++)
    cout << numbers[n] << ", ";
  return 0;
}

这将输出:

10、20、30、40、50、


1
因为指针是存储内存地址的变量,如果一个指针是const,那么指针将继续存储相同的内存地址,因此指针本身的值不能改变,但你并没有说指针所指向的值,根据你所说的,改变指向的值是允许的操作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接