简体   繁体   English

为什么字符串可以工作,但字符和 int 数组在指针数组中不起作用?

[英]Why do strings work, but character and int arrays do not work in a pointer array?

I understand if I add the arrays, st and st2, to give it space in the memory, and then add it to the pointer array, it shouldn't be a problem:我明白如果我添加数组 st 和 st2 以在内存中给它空间,然后将它添加到指针数组,它应该不是问题:

/* works */
int st[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
int st2[]= {0,31,29,31,30,31,30,31,31,30,31,30,31};
int *day_tab[]= {
        st,
        st2
};

But without first giving it space in memory, why do strings specifically work?但是如果没有先给它在内存中的空间,为什么字符串特别有效? The code below gives an error:下面的代码给出了一个错误:

int *day_tab[]= {
        {0,31,28,31,30,31,30,31,31,30,31,30,31},
        {0,31,29,31,30,31,30,31,31,30,31,30,31}
};

so does the code below:下面的代码也是如此:

char *day_tab[]= {
        {'0','1','\0'},
        {'0','1','\0'}
};

but the code below works但下面的代码有效

char *day_tab[]= {
        "01",
        "01"
};

This这个

int st[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
int st2[]= {0,31,29,31,30,31,30,31,31,30,31,30,31};
int *day_tab[]= {
        st,
        st2
};

Is three arrays: two of integers (with their own storage), and one array of two elements which are pointers to the first two arrays.是三个数组:两个整数(具有自己的存储空间)和一个包含两个元素的数组,它们是指向前两个数组的指针。

However, this is not valid:但是,这是无效的:

int *day_tab[]= {
        {0,31,28,31,30,31,30,31,31,30,31,30,31},
        {0,31,29,31,30,31,30,31,31,30,31,30,31}
};

As before you have declared an array of pointers to integers, but pointers to what?和之前一样,您已经声明了一个指向整数的指针数组,但是指向什么的指针呢? Those braced lists are not storage locations, they cannot be pointed to.那些花括号列表不是存储位置,它们不能被指向。

Your final example is basically valid but dangerous:你的最后一个例子基本上是有效但危险的:

char *day_tab[]= {
        "01",
        "01"
};

It is an array of two pointers to characters, and those pointers are initialized with string literals.它是一个由两个指向字符的指针组成的数组,这些指针是用字符串文字初始化的。 String literals are very special in that they are actually stored somewhere, usually in read-only memory, and they can be shared (so the "01" string used twice can be stored just once).字符串文字非常特殊,因为它们实际上存储在某个地方,通常在只读内存中,并且可以共享(因此使用两次的“01”字符串只能存储一次)。 Braced lists don't have this feature in C, it's only for string literals.花括号列表在 C 中没有这个功能,它仅用于字符串文字。

The reason the final code is dangerous is that it is char* not const char* .最终代码危险的原因是它是char*而不是const char* The non-const type is accepted for reasons of backward compatibility but is not a good idea because modifying the data in a literal string is not allowed.出于向后兼容性的原因,接受非常量类型,但这不是一个好主意,因为不允许修改文字字符串中的数据。 So you're setting yourself up for a potential disaster if you actually use those pointers to write to the "01" string storage.因此,如果您实际使用这些指针写入“01”字符串存储,那么您就为潜在的灾难做好了准备。

The following works以下作品

int *day_tab[]= {
        st,
        st2
};

because when you access an array, it is converted to a pointer to first element (there are few exceptions to this rule).因为当您访问一个数组时,它会被转换为指向第一个元素的指针(这条规则很少有例外)。 So, when you used st and st2 array in initialisation, they will convert to pointer to first element of respective array and , after initialisation, pointer day_tab[0] will point to first element of array st and pointer day_tab[1] will point to first element of array st1 .因此,当您在初始化时使用stst2数组时,它们将转换为指向相应数组第一个元素的指针,初始化后,指针day_tab[0]将指向数组st第一个元素,而指针day_tab[1]将指向数组st1第一个元素。

In the code snippet在代码片段中

int *day_tab[]= {
        {0,31,28,31,30,31,30,31,31,30,31,30,31},
        {0,31,29,31,30,31,30,31,31,30,31,30,31}
};

and

char *day_tab[]= {
        {'0','1','\0'},
        {'0','1','\0'}
};

you are trying to initialise the pointers of array day_tab with more than one initialiser.您正在尝试使用多个初始化程序初始化数组day_tab的指针。 Note that pointers are scalar types and from C11 Standard#6.7.9p11请注意,指针是标量类型并且来自 C11 Standard#6.7.9p11

11 The initializer for a scalar shall be a single expression, optionally enclosed in braces.... 11 标量的初始值设定项应为单个表达式,可选择括在大括号中....

However, you can use the compound literal to initialise the pointers of day_tab int pointer array, like this:但是,您可以使用复合文字来初始化day_tab int指针数组的指针,如下所示:

    int *day_tab[]= {
        (int []){0,31,28,31,30,31,30,31,31,30,31,30,31},
        (int []){0,31,29,31,30,31,30,31,31,30,31,30,31}
    };

This will initialise the pointers day_tab[0] and day_tab[1] to point to the first element of respective array.这将初始化指针day_tab[0]day_tab[1]以指向相应数组的第一个元素。 Similarly, for char pointers array, you can do同样,对于char指针数组,你可以这样做

    char *day_tab[]= {
        (char []){'0','1','\0'},
        (char []){'0','1','\0'}
    };

When you do当你做

char *day_tab[]= {
        "01",
        "01"
};

It works because string literals are array of characters and when it is used in the expression it will convert to pointer to type char that point to first element of array.它起作用是因为字符串文字是字符数组,当它在表达式中使用时,它将转换为指向数组第一个元素的char类型的指针。 So, this initialises the pointers day_tab[0] and day_tab[1] to point to the first element of read only string literal "01" .因此,这会初始化指针day_tab[0]day_tab[1]以指向只读字符串文字"01"的第一个元素。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM