指针和基元类型返回不同的数组成员

Pointer and primitive type return different array members

本文关键字:数组 组成员 返回 类型 指针      更新时间:2023-10-16

一些事情。

  1. 当我用3大小的成员数组声明我的结构时,这不是意味着该数组有4个元素吗?0、1、2、3?为什么是它们,当我尝试插入字符ABC时,它会告诉我initializer-string for array of chars is too long [-fpermissive]

    #include <iostream>
    using namespace std;
    struct Student {
        double no;
        char grade[3];
    };
    int main() {
        struct Student harry = {975, "ABC"};
    }
    
  2. 当我打印字符数组的特定索引的地址时,我从以下代码中得到以下结果:

    struct Student {
        double no;
        char grade[4];
    };
    int main() {
        struct Student harry = {975, "ABC"};
        for (int i = 0; i < 4; i++)
            cout << "h.g[" << i << "]" << harry.grade[i] << endl;
        for (int i = 0; i < 4; i++)
            cout << "h.g[" << i << "]" << &harry.grade[i] << endl;
    }
    

结果:

h.g[0]A
h.g[1]B
h.g[2]C
h.g[3]
&h.g[0]ABC
&h.g[1]BC
&h.g[2]C
&h.g[3]

为什么第一个索引打印ABC,然后打印BC等等,而不是像第一个循环那样分别打印每个字符?

否,声明像T arr[3]这样的数组会得到一个包含3个元素而不是4个元素的数组。声明中的3是数组的大小。索引从0开始,因此元素的索引为0、1和2。

字符串文字"ABC"为您提供了一个"4个const char的数组",其中最后一个元素是null字符。如果您试图用包含太多字符的字符串文字初始化数组,则程序格式错误:

初始化器的数量不应超过数组元素的数量。

在第一个循环中,您将获取数组的每个字符并将其打印出来。当您打印一个char时,您只能得到该char作为输出。

当您获取数组中某个元素的地址时,使用&harry.grade[i],您将得到一个char*。输出char*时,I/O库将其视为C样式的以null结尾的字符串。它将从该字符输出到它找到的第一个空字符。这就是为什么您在i位置获得字符及其后面的字符。

当我用大小为3的成员数组声明我的结构时,这不是意味着该数组有4个元素吗?0、1、2、3?

不,这意味着它有三个元素,您可以使用索引0,1,2访问它们。

为什么第一个索引打印ABC,然后打印BC等等,而不是像第一个循环那样分别打印每个字符?

您的访问超出了数组的范围,这将导致未定义的行为。这意味着任何事情都有可能发生。您还将大小为4的字符数组"ABC"分配给大小为3的数组。所以你有债券外的读写权限字符数组"ABC"中的第四个元素是空终止。当您用std::cout打印char[N]的任何元素的地址时,它将看到一个char*,它将其解释为以null结尾的字符串。因此,它将打印字符直到空终止。因此,如果从一开始打印,则会得到A, b, C。如果从第二个元素打印,则会得到B,C,依此类推。