简体   繁体   English

将char指针初始化为字符串,将其他类型指针初始化为数组

[英]initializing char pointer as string vs other type pointers as arrays

I've got a question about initializing char pointers vs other data type pointers. 我有一个关于初始化char指针和其他数据类型指针的问题。 Specifically, we are allowed to initialize char pointers as follows: 具体来说,我们可以按如下方式初始化char指针:

char *char_ptr = "Hello World";

As far as I know, the only thing special about a string is that it is a '0' terminated character array. 据我所知,字符串唯一特别之处在于它是一个'0'终止的字符数组。 However, we are not allowed to do the following: 但是,我们不允许执行以下操作:

int *int_ptr = {1,2,3,4};

but we must do this: 但我们必须这样做:

int int_arr[] = {1,2,3,4};
int_ptr = int_arr;

in order to let int_ptr point to the first element of int_array. 为了让int_ptr指向int_array的第一个元素。

In the char case, we have not explicitly defined the string "Hello World" as a char array before letting char_ptr point to the string, but have initialized the char_ptr directly using the string "Hello World". 在char情况下,我们没有在让char_ptr指向字符串之前将字符串“Hello World”显式定义为char数组,而是使用字符串“Hello World”直接初始化char_ptr。

My question is, why is this the case, what is special about strings that allows us to do this but can't do so with other types? 我的问题是,为什么会这样,有什么特别的字符串允许我们这样做,但不能与其他类型这样做?

Thanks in advance, 提前致谢,

Sriram 斯利拉姆

You can do the same in C99 or later for other types using compund literals: 对于使用复合文字的其他类型,您可以在C99或更高版本中执行相同的操作:

#include <stdio.h>

int main(void) {
    int *ptr = (int[]){ 1, 2, 3, 4 };
    for(int i = 0; i < 4; ++i) {
        printf("%d: %d\n",i, ptr[i]);
    }
    return 0;
}

The compound literal (int[]){ 1, 2, 3, 4 } creates an unnamed int[4] , just like "Hello" creates an unnamed char[6] . 复合文字(int[]){ 1, 2, 3, 4 }创建一个未命名的int[4] ,就像"Hello"创建一个未命名的char[6]

So as of C99, char is only special in providing a more convenient syntax. 从C99开始, char只提供更方便的语法。

The answer is: 答案是:

Strings(literals) are treated as special. 字符串(文字)被视为特殊字符串。

Believe it! 相信它! Accept it, and Live with it. 接受它,并与它一起生活。

It is because string are used so much that there's an easier way to define them made available. 这是因为字符串的使用非常多,以至于可以更容易地定义它们。 It's way easier than making explicitly an array of character every time. 这比每次明确地创建一个字符数组更容易。

"Hello World" is a string literal. "Hello World"是一个字符串文字。 It has type "array of 12 const char " and static storage duration. 它具有类型“12 const char数组”和静态存储持续时间。 That is, it gives you an array in memory that lasts for the duration of your program. 也就是说,它会在内存中为您提供一个持续一段时间的数组。 It has 12 char because of the null character, which you correctly point out. 它有12个char ,因为空字符,你正确地指出的。 Now lets consider the two cases. 现在让我们考虑两种情况。

With const char *char_ptr = "Hello World"; 使用const char *char_ptr = "Hello World"; you are relying on the fact that an array can be converted to a pointer to its first element. 您依赖的事实是数组可以转换为指向其第一个元素的指针。 So your char_ptr points to the first element of the static data that the literal represents. 所以你的char_ptr指向文字所代表的静态数据的第一个元素。

With const char char_arr[] = "Hello World"; 使用const char char_arr[] = "Hello World"; , what happens is a special rule for initializing arrays of characters. ,会发生什么是初始化字符数组的特殊规则。 What you get is char_arr which is of type "array of 12 const char " again, but the characters from the static string data are used to initialize each element in the array (§8.5.2). 你得到的是char_arr ,它的类型是“12个const char数组”,但静态字符串数据中的字符用于初始化数组中的每个元素(§8.5.2)。 That means, your array char_arr is a copy of the static string data. 这意味着,您的数组char_arr是静态字符串数据的副本。

When we do int *int_ptr = {1,2,3,4}; 当我们做int *int_ptr = {1,2,3,4}; we get an error. 我们收到一个错误。 Why? 为什么? Because {1, 2, 3, 4} isn't like the string literal above. 因为{1, 2, 3, 4}不像上面的字符串文字。 {1, 2, 3, 4} is an initializer, not a literal at all. {1, 2, 3, 4}是初始化器,而不是文字。 In fact, it's an initializer list and can only be used to initialize things. 实际上,它是一个初始化列表 ,只能用于初始化事物。 It is not a literal. 这不是文字。 It does not create some static array with the values 1 , 2 , 3 , and 4 in it and then give you a pointer. 它不创建一些静态数组与值123 ,和4中,然后给你的指针。 It is simply used to directly initialize an array. 它只是用于直接初始化数组。 So what would your int_ptr point to? 那么你的int_ptr指向什么? The array does not exist anywhere for it to point to. 该数组不存在于任何指向它的位置。

However, int int_arr[] = {1,2,3,4}; 但是, int int_arr[] = {1,2,3,4}; is the correct use of this initializer list. 是正确使用此初始化列表。 You get an array, int_arr , where each of the elements are initialized to the elements in the initializer list. 你得到一个数组int_arr ,其中每个元素都初始化为初始化列表中的元素。

When you set char *char_ptr = "Hello World", you are setting the address of the string literal to char_ptr. 设置char * char_ptr =“Hello World”时,将字符串文字的地址设置为char_ptr。 But, in case of other data types, there is nothing analogous to string literals. 但是,在其他数据类型的情况下,没有什么类似于字符串文字。 So, it is not allowed. 所以,这是不允许的。

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

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