ade*_*rtc 27 c arrays pointers
我正在研究K&R(例如5-9),我试图转换原始程序的2D数组
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}
};
Run Code Online (Sandbox Code Playgroud)
使用指针指向13个整数的数组
static char (*daytab)[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}
};
Run Code Online (Sandbox Code Playgroud)
但编译器会打印警告:标量初始化程序中的多余元素.
谷歌搜索没有帮助,甚至K&R在将数组传递给函数时写道,
myFunction(int daytab[2][13]) {...}
Run Code Online (Sandbox Code Playgroud)
是相同的
myFunction(int (*daytab)[13]) {...}
Run Code Online (Sandbox Code Playgroud)
Dmi*_*tri 30
这两者只是部分相同.不同之处在于:
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}
};
Run Code Online (Sandbox Code Playgroud)
声明一个二维数组,其中包括为数组预留空间并确保daytab引用该内存.然而:
static char (*daytab)[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}
};
Run Code Online (Sandbox Code Playgroud)
...只声明一个指针.因此,您尝试使用数组初始值设定项初始化指针,该指针无法按预期工作.没有阵列; 没有为阵列预留内存.相反的是,初始化程序中的第一个数字被分配给指针daytab,编译器会生成一个警告,通知您已经指定了许多刚丢弃的附加值.由于初始化程序中的第一个数字是0,您只是daytab以NULL相当冗长的方式设置.
因此,如果您想进行这种初始化,请使用第一个版本 - 它会衰减到您在第二个版本中明确声明的相同指针类型,因此您可以使用相同的方式.当您希望动态分配数组或获取对已存在的另一个数组的引用时,需要使用数组指针的第二个版本.
所以你可以这样做:
static char arr[2][3] = { { 1, 2, 3 }, { 4, 5, 6 } };
static char (*ptr)[3] = NULL;
ptr = arr;
Run Code Online (Sandbox Code Playgroud)
......然后使用ptr和arr互换.或这个:
static char (*ptr)[3] = NULL;
ptr = malloc(2 * sizeof(*ptr));
Run Code Online (Sandbox Code Playgroud)
...获取动态分配的二维数组(不是指向一维数组的指针数组,而是一个真正的二维数组).当然,在这种情况下它没有初始化.
两个变体的"等价"仅意味着当2D数组衰减到指向其第一个元素的指针时,它会衰减到第二个变体中声明的指针类型.一旦指针版本实际指向数组,两者是等价的.但是2D数组版本为数组设置了内存,其中指针声明没有......并且可以为指针指定一个新值(指向不同的数组),而2D数组变量则不能.
在C99中你可以做到这一点,但是(如果不是static至少):
char (*daytab)[13] = (char [][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}
};
Run Code Online (Sandbox Code Playgroud)
@Dmitri 解释得很好,但我想补充一点
static char (*daytab)[13] = { ... };
Run Code Online (Sandbox Code Playgroud)
是一个指向 13 个char元素的数组的指针。编译器向您发出警告,因为您传入了两个数组。这就像试图将两个地址分配给一个指针char *p = {a, b}。根据您的声明,元素过多。请参阅Geekforgeek对数组指针真正含义的解释。
至于回答 K&R 练习,请考虑
选项1:
static char *daytab[2] = {
(char []) {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
(char []) {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};}
Run Code Online (Sandbox Code Playgroud)
或选项 2:
static char (*daytab)[13] = (char [][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}
};}
Run Code Online (Sandbox Code Playgroud)
选项 1 是一个包含两个char指针的数组。
选项 2 是一个数组指针。它指向一个包含 13 个char元素的数组。正如您可以增加一个char指针以获取字符串中的下一个字母一样,您可以增加此数组指针以获取下一个 13char秒的数组。