код не компилируется чисто:
$ 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
чаще всего используется для обозначения «string», чем «struct» в C (но у меня закончились идеи для лучшего имени). Обратите внимание на дополнительный уровень косвенности, необходимый в операциях printf()
, написанных одним способом в первых двух, а другой во втором.
Это потому, что вы объявили поле struct как 'int *'. – squiguy
У меня нет окончательного ответа, потому что я не уверен, что вы пытаетесь сделать. Но причина, по которой вы видите результаты, вы видите, потому что вы определили struct ('_str'), который содержит указатель (адрес). Затем вы определили массив из них со значениями '{1000, 2000}' и '{3000, 4000, 5000}'. Помните, что это указатели (адрес). В компьютере адрес указывает на 32-битное значение (в данном случае). Поэтому, когда вы печатаете 's [0] .a + 1', вы печатаете первый адрес (' s [0] .a' - который установлен в 1000), увеличивающийся на 1 значение указателя (что составляет 4 байта), поэтому вы получаете 1004. Аналогичная проблема для 's [1] .a'. – lurker