标量初始值设定项c中的多余元素



正如在"int数组指针的标量初始值设定项的多余元素"的问题中一样,我也在研究K&R、 尝试转换

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"
};

而不是CCD_ 3阵列?

我假设您的代码看起来像(因为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("%dn", 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("%dn", ptr[0][0]);
    return 0;
}

对于这两个例子,static关键字的含义也存在根本差异。前者影响链接,后者影响特定对象的存储持续时间(由标识符表示)。

对于第二个问题,您可以将其简化为更基本的形式:

为什么以下内容是合法的:

char *name = "January";

而这不是:

int *name = "January";

在这里(以及您问题中的上一个形式),"January"不是被解释为数组初始值设定项,而是被解释为字符串文本

这些文字是char[n]类型的只读对象(任何修改它们的尝试都会导致未定义的行为),其中n等于"分隔符之间的字符数(具有转义序列的特殊处理),加上空字符(通常表示为'')。对于字符串文字,n的值在编译时总是已知的。它们具有静态存储持续时间,因此您可以将它们视为执行is程序时已经存在的现有对象。

指向int的指针与char[n]数组不兼容,因此无法将字符串文字分配给int *

老实说,是的,你可以通过明确的演员阵容来"强迫"它,比如这里:

int *name = (int *) "January";

但任何从这样的指针读取的尝试都会违反严格的混叠规则,从而导致UB。

最新更新