c++ - 改变常量指针的地址

标签 c++

我想弄清楚一件事。

我知道我不能改变常量指针的值,但我可以改变它的地址,如果我用下面的方式初始化一个指针:

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 是一个 intp 是一个“指向 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/

相关文章:

c++ - 引用变量存储在哪里

c++ - fstream、ofstream、传递文档名称、C++

c++ - asio::strand<asio::io_context::executor_type> 与 io_context::strand

c++ - 使用 boost::thread::interrupt() 时,您*需要*捕获 thread_interrupted 异常吗?

c++ - 如何通过 C API 传递带捕获的 std::function?

调用指令时 C++ 程序崩溃(C0000005 访问冲突)

c++ - 尝试将结构成员函数传递给 atexit

c++ - malloc 不应该是异步的吗?

c++ - 录制屏幕时不会出现奇怪的 MFC/GDI 行为(空白图像)

C++:按值传递变量