2013-05-25 3 views
1

Я пытаюсь получить элементы из массива указателей в структуре. Не уверен, что я делаю это правильно.Получение значений динамического массива int в структуре с помощью указателя

#include<stdio.h> 

    typedef struct _str 
    { 
     int *a; 
    } _str; 


    main() 
    { 
     _str s[]={ 
      {1000,2000}, 
      {3000,4000,5000} 
      }; 

     printf("%d\n", s[0].a); 
     printf("%d\n", s[0].a + 1); /* Gives me 1004 instead of 2000 */ 

     printf("%d\n", s[1].a); 
     printf("%d\n", s[1].a + 1); /* Gives me 3004 instead of 4000 */ 
    } 
+0

Это потому, что вы объявили поле struct как 'int *'. – squiguy

+2

У меня нет окончательного ответа, потому что я не уверен, что вы пытаетесь сделать. Но причина, по которой вы видите результаты, вы видите, потому что вы определили struct ('_str'), который содержит указатель (адрес). Затем вы определили массив из них со значениями '{1000, 2000}' и '{3000, 4000, 5000}'. Помните, что это указатели (адрес). В компьютере адрес указывает на 32-битное значение (в данном случае). Поэтому, когда вы печатаете 's [0] .a + 1', вы печатаете первый адрес (' s [0] .a' - который установлен в 1000), увеличивающийся на 1 значение указателя (что составляет 4 байта), поэтому вы получаете 1004. Аналогичная проблема для 's [1] .a'. – lurker

ответ

2

код не компилируется чисто:

$ 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(), написанных одним способом в первых двух, а другой во втором.

+0

Предупреждение не означает, что вы ничего не можете сделать. Но это, конечно, означает, что вы должны вернуться и проверить, что вы действительно имеете в виду, что вы делаете. – lurker

+0

Удивительно. Это именно то решение, которое я искал. Спасибо !! Спасибо !!. –

Смежные вопросы