Не совсем ясно, что вы ожидаете увидеть в результате вывода кода, который вы разместили.Если вы ожидаете увидеть «25», то вы правы.Доступ к членам вашей структуры так, как вы пытаетесь это сделать, хотя и «действителен» в данном конкретном случае, может быть очень опасным, если вы точно не знаете, что делаете.Рассмотрите следующие незначительные изменения в вашей структуре:
struct
{
int x;
char y;
} s[] = {10,20,15,25,8,75,6,2};
Как вы думаете, что ваш код получит сейчас?Простой ответ «это зависит».На что, спросите вы?Размер char
в выбранной вами архитектуре системы.Это обычно 8 бит, но это не гарантировано.ANSI C и C99 определяют char
следующим образом:
"Объект, объявленный как тип char
, достаточно велик для хранения любого члена базового набора символов выполнения."
Это также зависит от того, как ваш конкретный компилятор «выравнивает» элементы структуры.Компилятор обычно выравнивает элементы по границам слова, но, опять же, что это означает, зависит от размера слова.Структура также может быть выровнена по границам байтов.Дело в том, что есть лучшие способы доступа к данным в структурах.Рассмотрим:
#include <stdio.h>
int main()
{
struct
{
int x, y;
} *ps, s[] = { {10, 20}, {5, 25}, {8, 75}, {6, 2} };
ps = s;
printf( "%d\n", *(ps + 3) );
printf( "%d\n", s[3].x );
printf( "%d\n", (ps + 3)->x );
return 0;
}
В этом примере ps
объявлен как указатель на безымянную структуру.После выполнения присваивания ps = s
, ps
указывает на первый элемент структуры.Если вы добавите 1 к ps
, как в ps += 1;
, это будет указывать на второй элемент структуры и так далее.Итак, в примере все три оператора printf
печатают число 6. Вы понимаете, почему?В первом случае, *(ps + 3)
, как показано при добавлении к ps
, мы продвигаем указатель через массив структур, чтобы он указывал на третий элемент.Во втором случае, s[3].x
, мы ссылаемся на третий элемент в массиве структур s
и принимаем значение x
в этом элементе.Наконец, (ps + 3)->x
, мы добавляем три к ps
, как и раньше, разыменовывая его как указатель на наш тип структуры, мы берем значение x
.
Также обратите внимание на способ, который я инициализировалs
.Хотя внутренние скобки не требуются, они в хорошей форме.Если бы у вас была более сложная структура, было бы очень трудно выполнить правильную инициализацию без фигурных скобок, которые могли бы помочь в качестве руководства, а для кого-то, кто последует за ней, было бы невозможно прочитать.