массив указателей на массив символов - PullRequest
1 голос
/ 24 августа 2010

gcc 4.4.4 c89

Однако у меня проблема с отображением всех животных.

У меня есть следующий код.

Я пытаюсь отобразить всех животных в массиве. Таким образом, у меня есть 3 массива указателей на символ *. Затем массив указателей на эти наборы данных.

Я попытался контролировать внутренний цикл для проверки -1 и NULL для внешнего.

void initialize_char_array()
{
    char *data_set1[] = {"dog", "cat", "bee", NULL};
    char *data_set2[] = {"rabbit", "ant", "snake", "rat", NULL};
    char *data_set3[] = {"cow", "lizard", "beaver", "bat", "hedgehog", NULL};

    char *ptr_char[] = {*data_set1, *data_set2, *data_set3, NULL};

    display_char_array(ptr_char);
}

void display_char_array(char **ptr_char)
{
    size_t inner = 0, outer = 0;

    for(outer = 0; ptr_char[outer] != NULL; outer++) {
        for(inner = 0; *ptr_char[inner] != -1; inner++) {
            printf("data [ %s ]\n", ptr_char[outer][inner]);
        }
    }
}

Большое спасибо за любые предложения,

Ответы [ 5 ]

5 голосов
/ 24 августа 2010

*data_set1 совпадает с data_set1[0].Вот исправленная версия того, что вы пытаетесь сделать.ИМХО, это вопрос вкуса, который вы используете: переменные индекса или итераторы указателя в цикле, очевидно, компилятор сгенерирует тот же машинный код.

// type of ptr_char changed
void display_char_array(char **ptr_char[])
{
    size_t inner = 0, outer = 0;

    for(outer = 0; ptr_char[outer] != NULL; outer++) {
        // check for NULL in inner loop!
        for(inner = 0; ptr_char[outer][inner] != NULL; inner++) {
            printf("data [ %s ]\n", ptr_char[outer][inner]);
        }
    }
}
void initialize_char_array()
{
    char *data_set1[] = {"dog", "cat", "bee", NULL};
    char *data_set2[] = {"rabbit", "ant", "snake", "rat", NULL};
    char *data_set3[] = {"cow", "lizard", "beaver", "bat", "hedgehog", NULL};

    // fixed
    char **ptr_char[] = {data_set1, data_set2, data_set3, NULL};

    display_char_array(ptr_char);
}
3 голосов
/ 24 августа 2010

Учитывая то, как ваша функция initialize_char_array инициализирует массив ptr_char, вы никогда не сможете отобразить всех животных.Вы сможете отобразить только первый из каждого из ваших трех списков.Если вы хотите иметь доступ ко всем вашим животным, вы должны сначала определить ptr_char как массив указателей на указатели на символы: char **ptr_char[].

Тогда функция отображения должна принимать параметр этого типаchar *** в качестве аргумента.Да, это 3 уровня косвенности.Тогда не используйте переменные size_t для циклического преобразования в ваших массивах, используйте char ** и char *.

2 голосов
/ 24 августа 2010

Это может помочь просмотреть типы каждого массива. Помните, что в большинстве случаев тип выражения массива неявно преобразуется (разлагается) из N-element array of T в pointer to T или T * 1 . В случаях data_set1, data_set2 и data_set3, T равен char *, поэтому выражение data_set1 неявно преобразуется из 4-element array of char * в pointer to char * или char **. То же самое верно и для двух других массивов, как показано в таблице ниже:

Array        Type            Decays to
-----        ----            ---------
data_set1    char *[4]       char **
data_set2    char *[5]       char **
data_set3    char *[6]       char **

Если вы создаете массив этих выражений (что вы, похоже, пытаетесь сделать), тогда объявление массива должно быть

char **ptr_char[] = {data_set1, data_set2, data_set3, NULL};

что дает нам

Array        Type            Decays to
-----        ----            ---------
ptr_char     char **[4]      char ***

Таким образом, ptr_char - это массив указателей на указатели на char или char **ptr_char[4]. Когда вы передаете ptr_char аргумент в функцию отображения, он снова неявно преобразуется из типа 4-element array of char ** в pointer to char ** или char ***.


1. Исключениями из этого правила являются случаи, когда выражение массива является операндом операторов sizeof или & (address-of), или если выражение является строковым литералом, используемым для инициализации другого массива в объявлении.
1 голос
/ 24 августа 2010

ошибка была в инициализации ptr_char только с первым элементом из data_set ?, см. Ниже:

void initialize_char_array()
{
    char *data_set1[] = {"dog", "cat", "bee", NULL};
    char *data_set2[] = {"rabbit", "ant", "snake", "rat", NULL};
    char *data_set3[] = {"cow", "lizard", "beaver", "bat", "hedgehog", NULL};

    char **ptr_char[] = {data_set1, data_set2, data_set3, NULL};

    display_char_array(ptr_char);
}

void display_char_array(char ***p)
{
  while( *p )
  {
    while( **p )
    {
      puts(**p);
      ++*p;
    }
    ++p;
  }
}
1 голос
/ 24 августа 2010

Я переписал вашу программу после попытки (безуспешно) отладки версии, которую вы написали:

#include <stdio.h>

void display_char_array(char ***ptr_char)
{
    for ( ; *ptr_char != NULL; ptr_char++ ) {
        char **data_set;
        for ( data_set = *ptr_char; *data_set != NULL; data_set++ ) {
            printf("data [ %s ]\n", *data_set);
        }
    }
}

void initialize_char_array()
{
    char *data_set1[] = {"dog", "cat", "bee", NULL};
    char *data_set2[] = {"rabbit", "ant", "snake", "rat", NULL};
    char *data_set3[] = {"cow", "lizard", "beaver", "bat", "hedgehog", NULL};

    char **ptr_char[] = { data_set1, data_set2, data_set3, NULL };

    display_char_array(ptr_char);
}

int main( void )
{
    initialize_char_array();

    return 0;
}

Ваша версия будет работать с ошибками, а использование указателей было очень запутанным!

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