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

initializing char pointer as string vs other type pointers as arrays

本文关键字:初始化 指针 类型 数组 其他 字符串 char      更新时间:2023-10-16

我有一个关于初始化char指针与其他数据类型指针的问题。具体来说,允许按如下方式初始化char指针:

char *char_ptr = "Hello World";

据我所知,字符串的唯一特殊之处在于它是一个以'0'结尾的字符数组。但是,我们不允许做以下事情:

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

但是我们必须这样做:

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

让int_ptr指向int_array的第一个元素。

在char的情况下,在让char_ptr指向字符串之前,我们没有显式地将字符串"Hello World"定义为char数组,而是直接使用字符串"Hello World"初始化了char_ptr。

我的问题是,为什么会这样,字符串有什么特殊之处,允许我们这样做,但不能对其他类型这样做?

提前感谢,

您可以在C99或更高版本中使用复合字面值对其他类型执行相同的操作:

#include <stdio.h>
int main(void) {
    int *ptr = (int[]){ 1, 2, 3, 4 };
    for(int i = 0; i < 4; ++i) {
        printf("%d: %dn",i, ptr[i]);
    }
    return 0;
}

复合文字(int[]){ 1, 2, 3, 4 }创建了一个未命名的int[4],就像"Hello"创建了一个未命名的char[6]一样。

所以从C99开始,char的特别之处在于提供了更方便的语法。

答案是:

字符串(字面量)被视为特殊的

相信!

这是因为字符串使用得太多,所以有一种更简单的方法来定义它们。这比每次显式地创建字符数组要容易得多。

"Hello World"是字符串字面值。它的类型为"array of 12 const char"和静态存储时间。也就是说,它在内存中为您提供一个在程序运行期间持续的数组。它有12 char,因为你正确地指出了空字符。现在让我们考虑这两种情况。

使用const char *char_ptr = "Hello World";,您依赖于可以将数组转换为指向其第一个元素的指针的事实。因此,您的char_ptr指向该字面值表示的静态数据的第一个元素。

对于const char char_arr[] = "Hello World";,所发生的是用于初始化字符数组的特殊规则。你得到的是char_arr,它的类型还是"数组12 const char",但是来自静态字符串数据的字符用于初始化数组中的每个元素(§8.5.2)。这意味着,您的数组char_arr是静态字符串数据的副本。

当我们执行int *int_ptr = {1,2,3,4};时,我们得到一个错误。为什么?因为{1, 2, 3, 4}不像上面的字符串字面值。{1, 2, 3, 4}是一个初始化式,根本不是字面量。事实上,它是一个初始化列表,只能用于初始化事物。这不是字面意思。它不会创建一些静态数组,其中包含值1, 2, 34,然后给您一个指针。它只是用于直接初始化数组。那么你的int_ptr会指向什么?

该数组不存在,无法指向。

然而,int int_arr[] = {1,2,3,4};是对这个初始化列表的正确使用。您将得到一个数组int_arr,其中每个元素都被初始化为初始化列表中的元素。

当您设置char *char_ptr =" Hello World"时,您正在设置字符串文字的地址为char_ptr。但是,在其他数据类型的情况下,没有类似于字符串字面值的东西。所以,这是不允许的