Как объявить и инициализировать массив указателей на массив указателей на char? - PullRequest
1 голос
/ 03 мая 2019

Я хочу объявить массив указателей на массив указателей на символ и инициализировать его.Но я не мог объявить и инициализировать его следующим образом:

char *(*array[])[] = {
  { "car", "toy", "game" },
  { "go", "play", "read" }
};

Пожалуйста, напишите правильную форму моего объявления и инициализации?Я получаю предупреждающие сообщения, такие как «warning: скобка вокруг скалярного инициализатора», а также «note: (рядом с инициализацией для 'array [0]')" "

Ответы [ 2 ]

1 голос
/ 03 мая 2019

До C99 вы должны были определять внутренние массивы отдельно:

#include <stdio.h>

int main() {
    const char *array_0[] = { "car", "toy", "game" };
    const char *array_1[] = { "go", "play", "read" };
    const char **array[] = { array_0, array_1 };
    int i, j;

    for (i = 0; i < 2; i++) {
        for (j = 0; j < 3; j++) {
            printf("%s ", array[i][j]);
        }
        printf("\n");
    }
    return 0;
}

С C99 вы теперь можете определять и инициализировать один и тот же объект напрямую:

#include <stdio.h>

int main() {
    const char **array[] = {
        (const char *[]){ "car", "toy", "game" },
        (const char *[]){ "go", "play", "read" },
    };

    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < 3; j++) {
            printf("%s ", array[i][j]);
        }
        printf("\n");
    }
    return 0;
}

Конечно, этоявляется более гибким, чем 2D-матрица: каждый внутренний массив может иметь различный размер, например:

#include <stdio.h>

int main() {
    const char **array[] = {
        (const char *[]){ "car", "toy", "game", NULL },
        (const char *[]){ "go", "play", NULL },
        (const char *[]){ "read", NULL },
        NULL,
    };

    for (int i = 0; array[i]; i++) {
        for (int j = 0; array[i][j]; j++) {
            printf("%s ", array[i][j]);
        }
        printf("\n");
    }
    return 0;
}

Вывод:

car toy game 
go play 
read 

Обратите внимание, что я добавил ключевое слово const, посколькуСтроковые литералы не должны быть изменены, поэтому указатели на них должны быть определены как const char *.

0 голосов
/ 03 мая 2019
char *(*array[])[] = {
    &(char*[]){"car","toy","game" },
    &(char*[]){"go","play","read" }
};

компилируется без предупреждения.

Это не вложенные массивы, это массив указателей (&) на массивы char* (char * [] `), поэтому я не думаю, что вы можете обойтись без составных литералов или отдельных объектов массива, чтобы сделать указатели на массив из.

(Не забывайте, что присвоение char* из строковых литералов является плохой практикой, поскольку строковые литералы практически, но не формально char const [] , so using char const *instead of char * `будет предпочтительнее.)

...