【问题标题】:C++ - char array and the null characterC++ - 字符数组和空字符
【发布时间】:2012-04-21 08:17:21
【问题描述】:

我有两个关于 char 数组的问题。

  1. 从下面的代码来看,既然arrconst,为什么我正在重写它,编译器不给我一个错误?

    char arr[5]; // arr is a const pointer to (*)[5] array
    cin>>arr; //   
    
  2. 当我像这样初始化一个 char 数组时:

    char arr[5]={'h','i'};
    

    如果我这样做了:

    cout << arr << "something here \n"; 
    

    它将打印hisomething here。我认为它应该打印出来

    hi   something here
    

    有 3 个空位。

    但如果我这样做:

    for(int i = 0; i < 5; i++){
      cout << arr[i];
    }
    

    打印出 3 个空格。

第二种情况似乎证明编译器没有添加任何空字符。那么编译器如何忽略这 3 个空格呢?

【问题讨论】:

    标签: c++ arrays chat null-character


    【解决方案1】:
    1. 此数组不是const,因为没有const 限定符。
    2. 如果你没有在初始化列表中指定剩余的值,它们将被初始化为00 用于终止 C 字符串,而不是作为空格。

    至于您的声明,for(int i=0;i&lt;5;i++){ cout &lt;&lt; arr[i]; } 打印了空格 - 您是如何检查的?

    对我来说:

    #include <iostream>
    
    int main(){
        char arr[5]={'h','i'};
        for(int i=0;i<5;i++){ std::cout << arr[i]; }
        std::cout << "X" << std::endl;
    }
    

    打印:

    hiX
    

    和十六进制转储:

    $ ./t | hexdump -Cv
    00000000  68 69 00 00 00 58 0a                              |hi...X.|
    00000007
    

    打印了'\0' 字符。它们的显示似乎取决于操作系统。但它们不是空格。

    【讨论】:

    • 如果它们将被初始化为0,那么为什么在第二个代码中,它们被视为空格?
    • 为什么你认为它们被视为空格?尝试将输出重定向到文本文件,然后使用十六进制编辑器进行检查。
    • @AlexDan:然后您的系统将空字符显示为空格。但是,它仍然是一个空字符。
    • @MooingDuck : 你能告诉我 '\0' 和 "\0" 之间的区别吗,因为第一个显示为空格,第二个没有。
    • @AlexDan 这不是由它们的存储方式引起的,而是由您打印它们的方式引起的。 cout 区分字符和字符串。打印一个字符会输出一个字符,不管它是不是\0。打印字符串会输出字符串中的所有字符,直到(但不包括)第一个 \0
    【解决方案2】:
    1. arr 本身是“char[5]”而不是“const char (*)[5]”。当您编写 cin >> arr 时,它会隐式转换为“char *”右值。它不是 const,因为它甚至不是左值。

    而“const char *”或“char const *”表示指向的左值不能改变,而“char * const”表示指针的左值本身不能改变。但这与你的问题无关。

    1. 首先,没有空格。并且是 cin 附加了空字符。

    数组只是一个数组:

    char a[5]; //a's type is char[5];
    

    但是数组几乎不能是操作数。只有运算符我记得接受数组类型是 sizeof 和 &(address-of) (另一方面,这意味着有时 a 必须是一个数组。否则如果你写 sizeof(a),它会给你大小的指针。)。对于其他操作 a 被转换为 char * rvalue。是的,即使你写了 a[0]、a[1] 等。a[0] 等价于 *(a + 0),它对指针而不是数组进行操作。

    当你不能给某个东西赋值时,它并不总是意味着那个东西是“const”:

    1. 您当然不能分配给 const 变量。
    2. 您只能分配给一个变量(或称左值),因此您不能为右值(或称值)分配一些东西。所以你不能写 1 = 2,因为 1 是右值而不是变量,而不是因为 1 是“const”。
    3. 您必须为与其类型匹配的变量赋值。所以如果你有一个 const char *p 和一个 char *q,你不能写 q = p。他们的类型不匹配。再说一次,这并不意味着 q 是 const,因为它显然不是。但是你可以写 p = q,因为 char * 可以隐式转换为 const char *。但是 const char * 必须明确地转换为 char *。

    【讨论】:

    • arr 是一个常量指针,所以你不能这样做 arr="something"。但你是说你可以做到这一点 cin>>arr;例如我有 cin>>arr;我输入“cpp”;这会被 arr[0]='c',arr[1]='p',arr[2]='p' 代替吗;
    • 你不能写 arr = "" 因为 arr 是一个数组而不是一个指针。即使隐式转换为指针,arr 也是指针右值,不能赋值。 "cpp" 部分:不,你错过了 arr[3] = '\0';
    • 关于 const 指针的事情:如果 arr 是 const char *,你就不能写 char *x = arr,但实际上你可以。
    • 正在做 char*x=arr;与 arr 是否为 const 没有任何关系。试试 char &x=arr;你会得到一个错误。因为 arr 是常量。
    • 常量指针不能直接赋值给非常量指针。 char &x = arr,好吧,军队永远不能被称为一个人。我建议你先读一读,你相信很多事情是错误的。
    【解决方案3】:

    arr 充当 const 指针,这意味着您不能将指针设置为另一个地址。它不是指向 const 的指针,因此您可以更改指针指向的地址处的数据。

    例子:

    arr=&another_variable; //Illegal
    *arr='A';              //Legal
    

    【讨论】:

    • 是的,我知道,但是例如cin>>arr;我输入了“cpp”。编译器会像这样对待它 1) arr="cpp" 还是像这样 2) arr[0]='c',arr[1]='p',arr[2]='p'.
    • 它会这样对待它:arr[0]='c',arr[1]='p',arr[2]='p'
    【解决方案4】:
    1. 首先它不是 const。第二,这段代码不安全。
    2. 你应该在最后设置终止符号'\0'。

    你不应该使用char类型,尝试使用string而不是char数组。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-04
      • 2015-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-25
      • 2012-12-24
      相关资源
      最近更新 更多