2014-11-09 3 views
0

У меня есть массив структур размером 10, где назначено только несколько элементов, как узнать, является ли элемент, который я повторяю, NULL или нет?Как перебирать массив структур, который имеет нулевые элементы?

struct child 
{ 
    char *father; 
    char *mother; 
}; 

struct child cont[10]; 
int i = 0; 

memset(cont, 0, sizeof cont); 

for (i = 0; i < 10; i++) 
{ 
    if (cont[i] == NULL) break; // Error 
    else //do something.... 
} 

Приведенный выше код вызывает ошибку: used struct type value where scalar is required!

+3

'прод [я]' не является указателем и, следовательно, не может быть 'NULL' ... – indiv

+0

так я должен использовать' & прод [я] 'вместо этого? – razzak

+0

У массива struct не может быть элементов NULL. Нет структур NULL. –

ответ

2

Инициализация указателей на NULL, как указано в комментариях позволяет тестировать значения, как вы попытались. Ниже приведен пример с использованием while петли для проверки обоих father & mother строковых значений:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

struct child 
{ 
    char *father; 
    char *mother; 
}; 

int main() { 

    struct child cont[10] = {{0}}; 
    int i = 0; 

    memset(cont, 0, sizeof cont); 

    cont[0].father = strdup ("Mark"); 
    cont[0].mother = strdup ("Lisa"); 

    cont[1].father = strdup ("Tom"); 
    cont[1].mother = strdup ("Fran"); 

    while (cont[i].father && cont[i].mother) 
    { 
     printf ("cont[%d]\n father: %s\n mother: %s\n\n", 
       i, cont[i].father, cont[i].mother); 
     i++; 
    } 

    /* free memory allocated by strdup here */ 

    return 0; 
} 

выход:

$ ./bin/structptr 

cont[0] 
    father: Mark 
    mother: Lisa 

cont[1] 
    father: Tom 
    mother: Fran 

массив указателей на STRUCT

Да, вы можете создать массив указателей на struct, а затем выделить m при необходимости. Это позволяет протестировать if (cont[i]). По сути дела вы делаете то же самое, но в первом случае вы объявляете 10 структур. В этом случае вы никогда не сможете проверить только cont[i], потому что это не указатель (не говоря уже о том, что он всегда имеет адрес, заполняются ли строки или нет).

В этом случае вы создаете 10 указателей для всех структур, установленных в NULL (в силу использования calloc вместо malloc для их инициализации). Когда вы на самом деле используете один-на-10, вы выделяете память для структуры, указывая ей адрес, где до NULL. Это позволяет вам перебирать 10 указателей, чтобы узнать, какие они используются. Это очень гибкий метод и может применяться к большому количеству различных структур данных. Я надеюсь, что это помогает. Вот пример (такой же выход):

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

#define MAXS 10 

struct child 
{ 
    char *father; 
    char *mother; 
}; 

int main() { 

    /* create MAXS (10) pointers to child set to NULL */ 
    struct child **cont = calloc (MAXS, sizeof(struct child*)); 
    int i = 0; 

    cont[0] = malloc (sizeof(struct child)); /* allocate as needed */ 
    cont[0]-> father = strdup ("Mark"); 
    cont[0]-> mother = strdup ("Lisa"); 

    cont[1] = malloc (sizeof(struct child)); /* allocate as needed */ 
    cont[1]-> father = strdup ("Tom"); 
    cont[1]-> mother = strdup ("Fran"); 

    while (cont[i])  /* now simply test if pointer is not NULL */ 
    { 
     /* you can check father/mother individually if desired 
      here we simply rely on printf outputting (null) if 
      either father or mother does not point to a string */ 

     printf ("\ncont[%d]\n father: %s\n mother: %s\n", 
       i, cont[i]-> father, cont[i]-> mother); 
     i++; 
    } 

    /* free memory allocated to cont & by strdup here */ 

    return 0; 
} 
+0

спасибо за разработанный ответ, я все еще нооб в c, но я чувствую, что это излишне делать это таким образом. Есть ли другой способ, где я могу использовать указатели и делать что-то вроде 'if (cont [i]! = NULL)' или 'if (ptr! = NULL)'? – razzak

+0

Несомненно, посмотрите на мой второй пример. ** Примечание: ** использование 'calloc' для инициализации указателей на' NULL'. –

+0

one noob question, почему есть фигурные скобки вокруг 'cont [i]', не является ли это указателем на дочернюю структуру? могу ли я не просто сделать 'cont [i] -> father' вместо этого? – razzak

1

В вашем коде cont не указатель, поэтому проверка его на NULL неверна. Как вы могли знать, как только вы создали массив, как это сделано в коде, вы уже выделяете память для своих структурных переменных, даже если вы можете использовать или не использовать его. Итак, ваш вопрос: «Как узнать, является ли элемент, который я повторяю, NULL или нет?» не имеет смысла. Если вы хотите проверить, заполнили ли вы значение для своих членов структуры, не добавляйте еще одно поле в свою структуру, которое уведомляет, заполнены ли элементы структуры, нет.

struct child 
{ 
    boolean is_valid; 
    char *father; 
    char *mother; 
}; 
Смежные вопросы