Доступ к массиву как структура * - PullRequest
3 голосов
/ 22 декабря 2010

Это один из тех Я думаю, что это должно сработать, но лучше проверить вопросов. Он компилируется и отлично работает на моей машине.

Гарантируется ли это тем, что я ожидаю (т. Е. Разрешить мне доступ к первым нескольким элементам массива с гарантией того, что расположение, выравнивание, отступы и т. Д. Структуры совпадают с массивом)?

struct thingStruct
{
    int a;
    int b;
    int c;
};


void f()
{
    int thingsArray[5];
    struct thingStruct *thingsStruct = (struct thingStruct *)&thingsArray[0];

    thingsArray[0] = 100;
    thingsArray[1] = 200;
    thingsArray[2] = 300;

    printf("%d", thingsStruct->a);
    printf("%d", thingsStruct->b);
    printf("%d", thingsStruct->c);
}

РЕДАКТИРОВАТЬ: С какой стати я хотел бы сделать что-то вроде этого? У меня есть массив, который я отображаю в файл. Я рассматриваю первую часть массива как «заголовок», в котором хранится различная информация о массиве, а остальную часть я рассматриваю как обычный массив. Если я укажу структуру на начало массива, я получу доступ к частям данных заголовка как к элементам структуры, что более удобно для чтения. Все члены в структуре будут того же типа, что и массив.

Ответы [ 4 ]

3 голосов
/ 22 декабря 2010

Несмотря на то, что я видел, как это часто делается, вы не можете (то есть, это недопустимо, стандарт C) делать предположения о двоичной структуре структуры, так как она может иметь отступы между полями.в файле comp.lang.c часто задаваемые вопросы: http://c -faq.com / struct / padding.htmls

3 голосов
/ 23 декабря 2010

Хотя , вероятно, будет работать в большинстве мест, это все же немного ненадежно. Если вы хотите дать символические имена частям заголовка, почему бы просто не сделать:

enum { HEADER_A, HEADER_B, HEADER_C };

/* ... */.

printf("%d", thingsArray[HEADER_A]);
printf("%d", thingsArray[HEADER_B]);
printf("%d", thingsArray[HEADER_C]);
2 голосов
/ 22 декабря 2010

Как прокомментировал вопрос Эван, это, вероятно, будет работать в большинстве случаев (опять же, вероятно, лучше всего, если вы используете #pragma pack, чтобы гарантировать, что они не заполнены), предполагая, что все типы в вашей структуре совпадают с типом вашего массива.Учитывая правила С, это законно.

Мой вопрос к вам "почему?"Это не особо безопасно.Если поплавок попадает в середину структуры, все это разваливается.Почему бы просто не использовать структуру напрямую?Это действительно не метод, который я бы рекомендовал в большинстве случаев.

0 голосов
/ 22 апреля 2015

Другое решение для представления заголовка и остальных файловых данных заключается в использовании структуры, подобной этой:

struct header {
    long  headerData1;
    int   headerData2;
    int   headerData3;
    int   fileData[ 1 ];  // <- data begin here
};

Затем вы выделяете блок памяти с содержимым файла и приводите его как struct header *myFileHeader (илисопоставить блок памяти с файлом) и получить доступ ко всем данным файла с помощью

myFileHeader->fileData[ position ]

для произвольного большого position.Язык не накладывает никаких ограничений на значение индекса, поэтому вы несете ответственность за то, чтобы ваш произвольно большой posistion не превышал фактический размер выделенного блока памяти (или размер отображаемого файла).

Еще одно важное примечание: помимо отключения заполнения элементов структуры, которое уже было описано другими, следует тщательно выбирать типы данных для элементов заголовка, чтобы они соответствовали фактическим данным файламакет, несмотря на используемый вами компилятор (скажем, int не изменится с 32 на 64 бита ...)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...