我想弄清楚一件事。
我知道我不能改变常量指针的值,但我可以改变它的地址,如果我用下面的方式初始化一个指针:
int foo = 3;
const int *ptr = &foo;
*ptr = 6; // throws an error
int bar = 0;
ptr = &bar; // foo == 0
现在,假设我声明(/define,我不记得是哪一个)一个函数:
void change(const int arr[], int size);
int main() {
int foo[2] = {};
change(foo, 2);
std::cout << foo[0];
}
void change(const int arr[], int size) {
// arr[0] = 5 - throws an error
int bar = 5;
arr = &bar;
}
上面代码的最后一行没有抛出任何错误。然而,当函数结束并且我显示第一个元素时,它显示 0 - 所以什么都没有改变。
为什么会这样?
在这两种情况下,我都有常量指针,并且我尝试更改它的地址。在第一个例子中它起作用了。在第二个中它没有。
我还有一个问题。有人告诉我,如果我想将两指针类型传递给函数,const 关键字将无法按预期工作。真的吗?如果是这样,那么原因是什么?
最佳答案
你搞砸了很多术语,所以我将从这里开始,因为我认为这是造成你混淆的主要原因。考虑:
int x;
int* p = &x;
x
是一个 int
而 p
是一个“指向 int
的指针”。 修改 p
的值意味着更改 p
本身以指向其他地方。指针值是它保存的地址。此指针 p
包含一个 int
对象的地址。改变指针的值并不意味着改变 int
对象。例如,p = 0;
将修改 p
的值。
除此之外,p
的地址不是它持有的地址。 p
的地址将是您执行 &p
时获得的地址,并且类型为“指向 int
的指针”。也就是说,p
的地址是您在内存中找到指针 p
的位置。由于对象不会在内存中四处移动,因此不存在“更改其地址”这样的事情。
既然已经讲完了,让我们来了解一下什么是常量指针。 const int*
不是常量指针。它是指向常量对象的指针。它指向的对象是常量,而不是指针本身。常量指针类型看起来更像 int* const
。这里的const
适用于指针,所以它是“const
pointer to int
”的类型。
好的,现在我将快速给你一个简单的方法来记住声明和定义之间的区别。如果你买了一本字典,里面只有一个单词列表,你真的会称它为字典吗?不,字典应该充满单词的定义。它应该告诉你这些词的意思。没有定义的字典只是声明在给定的语言中存在这样的词。所以声明说某物存在,而定义给出它的意义。在你的情况下:
// Declaration
void change(const int arr[], int size);
// Definition
void change(const int arr[], int size) {
// arr[0] = 5 - throws an error
int bar = 5;
arr = &bar;
}
现在解释一下这里的问题。没有数组参数类型这样的东西。任何数组类型的参数都会转换为指针。所以 change
的声明实际上等同于:
void change(const int arr*, int size);
当您执行 arr = &bar;
时,您只是将 bar
的地址分配给指针 arr
。这对 arr
指向的数组元素没有影响。为什么要这样?您只是在更改 arr
指向的位置,而不是它指向的对象。事实上,您无法更改它指向的对象,因为它们是 const
int
。
关于c++ - 改变常量指针的地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16091793/