标量初始值设定项 c 中的多余元素
excess elements in scalar initializer c
正如“Excess elements of scalar initializer for pointer to array of ints”的问题一样,我也在研究 Ex。 K&R 中的 5–9,试图转换
static char daytab[2][13] = {
{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}
};
进入
static char *daytab[] = {
{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}
};
我收到了那里描述的错误。但是,
接受的答案
static char arr[2][3] = { { 1, 2, 3 }, { 4, 5, 6 } };
static char (*ptr)[3] = NULL;
ptr = arr;
只是在
的 ptr = arr
处给我另一个错误
error: data definition has no type or storage class
有人能帮忙吗?
此外,为什么使用指向 char
数组的指针数组是合法的,例如
static char *name[] = {
"Illegal month",
"January", "February", "March",
"April", "May", "June",
"July", "August", "September",
"October", "Novemer", "December"
};
但不是 int
数组?
我假设您的代码看起来像(gcc
的错误消息完全相同):
#include <stdio.h>
static char arr[2][3] = { { 1, 2, 3 }, { 4, 5, 6 } };
static char (*ptr)[3] = NULL;
ptr = arr;
int main(void)
{
printf("%d\n", ptr[0][0]);
return 0;
}
这确实是无效的,因为 ptr = arr;
赋值是放在任何函数之外的。 C语言的语法规则只允许放在里面,像这里:
#include <stdio.h>
int main(void)
{
static char arr[2][3] = { { 1, 2, 3 }, { 4, 5, 6 } };
static char (*ptr)[3] = NULL;
ptr = arr;
printf("%d\n", ptr[0][0]);
return 0;
}
对于这两个示例,static
关键字的含义也存在根本差异。前者影响链接,后者特定对象的存储期限,由标识符表示。
对于你的第二个问题,你可以将其简化为更基本的形式:
Why the following is legal:
char *name = "January";
while this is not:
int *name = "January";
?
此处(以及您问题中的先前形式),"January"
不被解释为数组初始值设定项,而是被解释为 字符串文字 .
这些文字是只读的(任何修改它们的尝试都会导致 undefined behavior)类型为 char[n]
的对象,其中 n 等于 "
分隔符之间的字符数 (对 转义序列 进行特殊处理),再加上一个 空字符 (通常表示为 '[=21=]'
)。 n
的值在字符串文字的编译时始终是已知的。它们具有 静态存储持续时间 ,因此您可以将它们视为现有对象,在执行程序时已经存在。
指向 int
的指针与 char[n]
数组不兼容,因此您不能将字符串文字分配给 int *
。
老实说,是的,你可以 "force" 它,通过显式转换,如下所示:
int *name = (int *) "January";
但是任何从此类指针读取的尝试都会违反 strict aliasing rule,这会导致 UB。
正如“Excess elements of scalar initializer for pointer to array of ints”的问题一样,我也在研究 Ex。 K&R 中的 5–9,试图转换
static char daytab[2][13] = {
{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}
};
进入
static char *daytab[] = {
{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}
};
我收到了那里描述的错误。但是,
接受的答案static char arr[2][3] = { { 1, 2, 3 }, { 4, 5, 6 } };
static char (*ptr)[3] = NULL;
ptr = arr;
只是在
的ptr = arr
处给我另一个错误
error: data definition has no type or storage class
有人能帮忙吗?
此外,为什么使用指向 char
数组的指针数组是合法的,例如
static char *name[] = {
"Illegal month",
"January", "February", "March",
"April", "May", "June",
"July", "August", "September",
"October", "Novemer", "December"
};
但不是 int
数组?
我假设您的代码看起来像(gcc
的错误消息完全相同):
#include <stdio.h>
static char arr[2][3] = { { 1, 2, 3 }, { 4, 5, 6 } };
static char (*ptr)[3] = NULL;
ptr = arr;
int main(void)
{
printf("%d\n", ptr[0][0]);
return 0;
}
这确实是无效的,因为 ptr = arr;
赋值是放在任何函数之外的。 C语言的语法规则只允许放在里面,像这里:
#include <stdio.h>
int main(void)
{
static char arr[2][3] = { { 1, 2, 3 }, { 4, 5, 6 } };
static char (*ptr)[3] = NULL;
ptr = arr;
printf("%d\n", ptr[0][0]);
return 0;
}
对于这两个示例,static
关键字的含义也存在根本差异。前者影响链接,后者特定对象的存储期限,由标识符表示。
对于你的第二个问题,你可以将其简化为更基本的形式:
Why the following is legal:
char *name = "January";
while this is not:
int *name = "January";
?
此处(以及您问题中的先前形式),"January"
不被解释为数组初始值设定项,而是被解释为 字符串文字 .
这些文字是只读的(任何修改它们的尝试都会导致 undefined behavior)类型为 char[n]
的对象,其中 n 等于 "
分隔符之间的字符数 (对 转义序列 进行特殊处理),再加上一个 空字符 (通常表示为 '[=21=]'
)。 n
的值在字符串文字的编译时始终是已知的。它们具有 静态存储持续时间 ,因此您可以将它们视为现有对象,在执行程序时已经存在。
指向 int
的指针与 char[n]
数组不兼容,因此您不能将字符串文字分配给 int *
。
老实说,是的,你可以 "force" 它,通过显式转换,如下所示:
int *name = (int *) "January";
但是任何从此类指针读取的尝试都会违反 strict aliasing rule,这会导致 UB。