为什么字符串可以工作,而字符和 int 数组在指针数组中不起作用?
Why do strings work, but character and int arrays do not work in a pointer array?
我理解如果我把数组st和st2加到内存里给它space,然后加到指针数组,应该没问题:
/* 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
};
但是没有先在内存中给它space,为什么字符串特别有效?
下面的代码给出了一个错误:
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}
};
下面的代码也是如此:
char *day_tab[]= {
{'0','1','[=12=]'},
{'0','1','[=12=]'}
};
但下面的代码有效
char *day_tab[]= {
"01",
"01"
};
这个
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
};
是三个数组:两个整数(有自己的存储空间)和一个包含两个元素的数组,这两个元素是指向前两个数组的指针。
但是,这是无效的:
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}
};
和之前一样,您已经声明了一个指向整数的指针数组,但是指针指向什么?那些花括号列表不是存储位置,无法指向它们。
你最后的例子基本有效但很危险:
char *day_tab[]= {
"01",
"01"
};
它是一个包含两个指向字符的指针的数组,这些指针是用字符串文字初始化的。字符串文字非常特殊,因为它们实际上存储在某个地方,通常在只读内存中,并且可以共享(因此使用两次的“01”字符串可以只存储一次)。大括号列表在 C 中没有此功能,它仅适用于字符串文字。
最终代码之所以危险,是因为它是 char*
而不是 const char*
。出于向后兼容性的原因,可以接受非常量类型,但这不是一个好主意,因为不允许修改文字字符串中的数据。因此,如果您实际使用这些指针写入“01”字符串存储,那么您就是在为潜在的灾难做好准备。
以下作品
int *day_tab[]= {
st,
st2
};
因为当你访问一个数组时,它被转换为指向第一个元素的指针(很少有exceptions符合这个规则。因此,当您在初始化中使用 st
和 st2
数组时,它们将转换为指向相应数组第一个元素的指针,并且在初始化后,指针 day_tab[0]
将指向数组 st
和指针 day_tab[1]
将指向数组 st1
.
的第一个元素
在代码片段中
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}
};
和
char *day_tab[]= {
{'0','1','[=12=]'},
{'0','1','[=12=]'}
};
您正在尝试使用多个初始化程序初始化数组 day_tab
的指针。请注意,指针是 标量类型 并且来自 C11 标准#6.7.9p11
11 The initializer for a scalar shall be a single expression, optionally enclosed in braces....
但是,你可以使用compound literal来初始化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}
};
这将初始化指针 day_tab[0]
和 day_tab[1]
以指向相应数组的第一个元素。
同样,对于 char
指针数组,你可以做
char *day_tab[]= {
(char []){'0','1','[=14=]'},
(char []){'0','1','[=14=]'}
};
当你这样做时
char *day_tab[]= {
"01",
"01"
};
之所以有效,是因为字符串文字是字符数组,当它在表达式中使用时,它将转换为指向数组第一个元素的 char
类型的指针。因此,这将指针 day_tab[0]
和 day_tab[1]
初始化为指向 只读 字符串文字 "01"
.
的第一个元素
我理解如果我把数组st和st2加到内存里给它space,然后加到指针数组,应该没问题:
/* 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
};
但是没有先在内存中给它space,为什么字符串特别有效? 下面的代码给出了一个错误:
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}
};
下面的代码也是如此:
char *day_tab[]= {
{'0','1','[=12=]'},
{'0','1','[=12=]'}
};
但下面的代码有效
char *day_tab[]= {
"01",
"01"
};
这个
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
};
是三个数组:两个整数(有自己的存储空间)和一个包含两个元素的数组,这两个元素是指向前两个数组的指针。
但是,这是无效的:
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}
};
和之前一样,您已经声明了一个指向整数的指针数组,但是指针指向什么?那些花括号列表不是存储位置,无法指向它们。
你最后的例子基本有效但很危险:
char *day_tab[]= {
"01",
"01"
};
它是一个包含两个指向字符的指针的数组,这些指针是用字符串文字初始化的。字符串文字非常特殊,因为它们实际上存储在某个地方,通常在只读内存中,并且可以共享(因此使用两次的“01”字符串可以只存储一次)。大括号列表在 C 中没有此功能,它仅适用于字符串文字。
最终代码之所以危险,是因为它是 char*
而不是 const char*
。出于向后兼容性的原因,可以接受非常量类型,但这不是一个好主意,因为不允许修改文字字符串中的数据。因此,如果您实际使用这些指针写入“01”字符串存储,那么您就是在为潜在的灾难做好准备。
以下作品
int *day_tab[]= {
st,
st2
};
因为当你访问一个数组时,它被转换为指向第一个元素的指针(很少有exceptions符合这个规则。因此,当您在初始化中使用 st
和 st2
数组时,它们将转换为指向相应数组第一个元素的指针,并且在初始化后,指针 day_tab[0]
将指向数组 st
和指针 day_tab[1]
将指向数组 st1
.
在代码片段中
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}
};
和
char *day_tab[]= {
{'0','1','[=12=]'},
{'0','1','[=12=]'}
};
您正在尝试使用多个初始化程序初始化数组 day_tab
的指针。请注意,指针是 标量类型 并且来自 C11 标准#6.7.9p11
11 The initializer for a scalar shall be a single expression, optionally enclosed in braces....
但是,你可以使用compound literal来初始化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}
};
这将初始化指针 day_tab[0]
和 day_tab[1]
以指向相应数组的第一个元素。
同样,对于 char
指针数组,你可以做
char *day_tab[]= {
(char []){'0','1','[=14=]'},
(char []){'0','1','[=14=]'}
};
当你这样做时
char *day_tab[]= {
"01",
"01"
};
之所以有效,是因为字符串文字是字符数组,当它在表达式中使用时,它将转换为指向数组第一个元素的 char
类型的指针。因此,这将指针 day_tab[0]
和 day_tab[1]
初始化为指向 只读 字符串文字 "01"
.