代码编译不干净:
$ gcc -O3 -g -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition wd.c -o wd
wd.c:9:5: warning: return type defaults to ‘int’ [enabled by default]
wd.c:9:5: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
wd.c: In function ‘main’:
wd.c:9:5: warning: old-style function definition [-Wold-style-definition]
wd.c:12:13: warning: initialization makes pointer from integer without a cast [enabled by default]
wd.c:12:13: warning: (near initialization for ‘s[0].a’) [enabled by default]
wd.c:12:13: warning: excess elements in struct initializer [enabled by default]
wd.c:12:13: warning: (near initialization for ‘s[0]’) [enabled by default]
wd.c:13:13: warning: initialization makes pointer from integer without a cast [enabled by default]
wd.c:13:13: warning: (near initialization for ‘s[1].a’) [enabled by default]
wd.c:13:13: warning: excess elements in struct initializer [enabled by default]
wd.c:13:13: warning: (near initialization for ‘s[1]’) [enabled by default]
wd.c:13:13: warning: excess elements in struct initializer [enabled by default]
wd.c:13:13: warning: (near initialization for ‘s[1]’) [enabled by default]
wd.c:16:9: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Wformat]
wd.c:17:9: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Wformat]
wd.c:19:9: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Wformat]
wd.c:20:9: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Wformat]
$
基本上,这就是说“你不能那样做”,至少不是那样。
警告并不意味着你不能做某事。
你必须对 C 语言足够好,才能不问这类问题,然后才能忽略编译器发出的警告。一般来说,编译器(或至少编译器的作者)对 C 的了解比您多得多。直到您足够了解能够引用标准中关于为什么不应该给出警告的章节和经文,将编译器的话视为福音。如果我正在审查你的代码,千万不要试图偷偷溜过我的代码——我不会接受的。
可以使用 C99 复合文字来拯救代码:
#include <stdio.h>
typedef struct str
{
int *a;
} str;
int main(void)
{
str s[] =
{
{ (int[]){1000,2000} },
{ (int[]){3000,4000,5000} },
};
printf("%d\n", *(s[0].a + 0));
printf("%d\n", *(s[0].a + 1));
printf("%d\n", s[1].a[0]);
printf("%d\n", s[1].a[1]);
}
此外,以下划线开头的名称基本上是为实现保留的。规则比这更细微,但为了最大程度的安全,您不会创建以下划线开头的名称。所以,我重命名_str
为str
,虽然str
在 C 中更常用于表示“字符串”而不是“结构”(但我想不出更好的名字)。请注意语句中所需的额外间接级别,printf()
前两个以一种方式编写,后两个以另一种方式编写。