【问题标题】:Are there any exceptions to const char*?const char* 有什么例外吗?
【发布时间】:2019-09-27 07:55:33
【问题描述】:

如果cstring是一个指针,那为什么它可以直接取值呢?其次,为什么 ‍‍‍*cstring 的结果不等于整个字符串?第三,cstring是一个指向常量字符的非常量指针,那为什么改变它的值而不改变它的地址呢?

#include <cstdio>
#include <conio.h>
#include <iostream>

using namespace std;

int main() 
{
    const char* cstring = "string";
    cout << cstring << endl << *cstring << endl << &cstring << endl;

    cstring = "foo";
    cout << cstring << endl << *cstring << endl << &cstring << endl;

    _getch();
    return 0;
}

【问题讨论】:

  • cstriing 是一个const char *,所以它的值是单个char 的地址。根据语言规则(即 C 和 C++),当使用字符串文字初始化或分配给字符串文字时,该地址是该字符串文字中第一个字符的地址(即初始化时 "string"'s' 和分配后的'f'"foo")。由于cstring是一个变量,它的地址不能改变,但它的值(假设const限定符一致)可以赋值。

标签: c++ string pointers ostream


【解决方案1】:

如果cstring是指针,那为什么可以直接取值呢?

coutconst char*operator &lt;&lt; 专门用于这种行为。它将指针视为 NULL 终止的字符串,并将打印它而不是指针值。对于不同的类型,您会得到不同的行为。对于char*,您打印了整个字符串。

为什么 ‍‍‍*cstring 的结果不等于整个字符串?

那是因为 *cstring 的类型是 char,而且 operator &lt;&lt; 的行为正确,只需打印一个字符即可。 const char* 本质上是一个 char 数组。数组本质上是指向数组第一个元素的指针。如果您在指针上使用* 运算符,您将访问指针指向的任何内容。如果它指向第一个元素,那么你就得到了第一个元素。

第三,cstring是一个指向常量字符的非常量指针,那为什么改变它的值而不改变它的地址呢?

正如你所说,cstring 是一个指向常量数据的非常量指针。您无法更改它指向的位置(它是一个常量指针),但您可以用其他内容替换指向数据的内容。您指向相同的位置,但该单元格的内容发生了变化。

【讨论】:

    【解决方案2】:

    如果cstring是指针,那为什么可以直接取值呢?

    任何人都可以通过取消引用指针来获取指针所指向的值。这就是您执行std::cout &lt;&lt; cstring 时发生的情况。选择正确的重载来打印由cstring 表示的字符串,假设该字符串格式正确,以空字符结尾的 C 样式字符串。

    其次,为什么 ‍‍‍*cstring 的结果不等于整个 字符串?

    cstringconst char*,所以 *cstringconst char。将它传递给std::cout,它将调用一个重载,打印一个char。内部调用的函数甚至都不知道这只是一个字符串中的一个char

    第三,cstring 是指向常量字符的非常量指针,所以 为什么改变它的值而不改变它的地址?

    您不能更改变量的地址。 cstring 在堆栈上的固定位置。您更改cstring 的值,这是它所指向的字符串的地址(它现在指向不同的字符串,具有不同的地址,"string" 当然仍然具有相同的地址)。

    你可能想尝试的是:

    const char* cstring = "string";
    std::cout << (void*)cstring << std::endl;
    cstring = "foo";
    std::cout << (void*)cstring << std::endl;
    

    现在您可以看到不同的地址。一个是"string"的地址,一个是"foo"的地址。

    【讨论】:

      猜你喜欢
      • 2010-10-27
      • 2014-02-15
      • 2012-12-26
      • 2013-04-23
      • 2012-07-21
      • 1970-01-01
      • 2011-10-24
      • 1970-01-01
      相关资源
      最近更新 更多