2013-04-24 3 views
11

Я знаю, что этот вопрос задан очень часто, но я до сих пор неясно, как получить доступ к структурам.c указатель на массив структур

Я хочу, чтобы глобальный указатель на массив структур:

typdef struct test 
{ 
    int obj1; 
    int obj2; 
} test_t; 

extern test_t array_t1[1024]; 
extern test_t array_t2[1024]; 
extern test_t array_t3[1025]; 

extern test_t *test_array_ptr; 

int main(void) 
{ 
    test_array_ptr = array_t1; 

    test_t new_struct = {0, 0}; 
    (*test_array_ptr)[0] = new_struct; 
} 

Но это дает мне предупреждения. Как мне получить доступ к конкретным структурам с помощью []?

Как я могу создать массив указателей типа struct? test_t *_array_ptr[2];?

+1

не должен дать вам предупреждение, должен дать ошибку. '(* test_array_ptr) [0]' разыгрывает дважды, но есть только один уровень звезд. –

+0

@ DanielFischer: gcc, например, часто печатает предупреждения для конструкций, которые являются «нарушениями ограничений» (примерно так же, как C приходит к утверждению, что что-то незаконно *). Опция '-pedantic-errors' позволяет вести себя более строго. –

+0

@KeithThompson Да, но для этой конкретной проблемы gcc говорит 'deref.c: 18: 18: error: индексированное значение не является ни массивом, ни указателем, ни вектором' без каких-либо флагов. (Хм, что такое 'vector', это C?) Для таких вещей, как разыменование структуры или доступ к члену' int', где компилятор просто не знает, как это сделать, он отказывается и бросает ошибка. –

ответ

14

Синтаксис вы ищете несколько громоздко, но это выглядит следующим образом:

// Declare test_array_ptr as pointer to array of test_t 
test_t (*test_array_ptr)[]; 

Вы можете использовать его следующим образом:

test_array_ptr = &array_t1; 
(*test_array_ptr)[0] = new_struct; 

Чтобы сделать синтаксис легче понять, вы можете использовать typedef:

// Declare test_array as typedef of "array of test_t" 
typedef test_t test_array[]; 
... 
// Declare test_array_ptr as pointer to test_array 
test_array *test_array_ptr = &array_t1; 
(*test_array_ptr)[0] = new_struct; 

Утилита cdecl полезна для дешифровки сложных деклараций C, особенно когда массивы и указатели на функции вовлеченные.

+0

за полезный ответ! но в чем отличие от первого ответа. где функция foo() { test_array_ptr = array_t1; test_t new_struct = {0,0}; test_array_ptr [0] = new_struct; } – user1539348

0

Проблема заключается в том, что вы принимаете (*test_array_pointer), который является первым элементом массива. Если вы хотите назначить конкретный элемент массива, вы могли бы сделать следующее ...

function foo() 
{ 
    test_array_ptr = array_t1; 

    test_t new_struct = {0,0}; 
    memcpy(&test_array_ptr[0], &new_struct, sizeof(struct test_t)); 
} 

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

function foo() 
{ 
    test_array_ptr = array_t1; 

    test_t new_struct = {0,0}; 
    memcpy(test_array_ptr, &new_struct, sizeof(struct test_t)); 
} 

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

function foo() 
{ 
    test_array_ptr = array_t1; 

    test_t new_struct = {0,0}; 
    test_array_ptr[0] = new_struct; 
} 
+1

Я уверен, что вы можете скопировать структуры (не указатели на структуры), просто используя '='. – 2013-04-24 20:37:42

+1

Да, вы можете. Это, например, один из способов копирования массивов с простым назначением, заверните их в 'struct'. –

+0

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

4

test_t * test_array_ptr является указателем на test_t. Это может быть указатель на один экземпляр test_t, но это может быть указателем на первый элемент массива экземпляров test_t:

test_t array1[1024]; 

test_t *myArray; 
myArray= &array1[0]; 

это делает myArray точку к первому элементу array1 и арифметика указателей позволяет вы должны рассматривать этот указатель как массив. Теперь вы можете получить доступ к 2-му элементу array1 следующим образом: myArray[1], что равно *(myArray + 1).

Но от того, что я понимаю, что вы на самом деле хотите сделать здесь, чтобы объявить указатель на указатель на test_t, который будет представлять собой массив указателей на массивы:

test_t array1[1024]; 
test_t array2[1024]; 
test_t array3[1025]; 

test_t **arrayPtr; 
arrayPtr = malloc(3 * sizeof(test_t*)); // array of 3 pointers 
arrayPtr[0] = &array1[0]; 
arrayPtr[1] = &array2[0]; 
arrayPtr[2] = &array3[0]; 
+0

как бы просто создать указатель на единую структуру массива за раз? и как мне получить доступ к структуре внутри массива? – user1539348

+0

@ user1539348: Посмотрите мой ответ сейчас :) – LihO

0

Я хотел бы использовать указатель на указатель, как:

test_t array_t1[1024]; 
test_t **ptr; 
ptr = array_t1; 
ptr[0] = ...; 
ptr[1] = ...; 
etc. 
Смежные вопросы