Как напечатать массив строк - PullRequest
1 голос
/ 27 сентября 2019

Я пытаюсь напечатать массив строк.Вот код, который у меня есть до сих пор:

#include <stdio.h>

void print_array (char * strings[]) {
    size_t array_length = sizeof(strings) / sizeof(strings[0]);
    for (int i=0; i < array_length; i++)
        printf("%s, ", strings[i]);
}

int main(void) {

    char * strings[] = {
        "Hello",
        "Zerotom",
        "new"
    };

    // it does work here...
    printf("Array size: %lu\n", sizeof(strings) / sizeof(strings[0]));

    // but not here
    print_array(strings);

    return 0;
}

Отсюда я получаю предупреждение:

strings.c: 4: 30: предупреждение: sizeof в массивеПараметр функции будет возвращать размер 'char **' вместо 'char * []' [-Wsizeof-аргумент-массива] size_t array_length = sizeof (strings) / sizeof (strings [0]);

Однако, если я изменю функцию arg с char * strings[] на char **, она вернет неправильную длину (1 вместо 3).Что я здесь не так делаю?

1 Ответ

2 голосов
/ 27 сентября 2019

Причина, по которой вы можете печатать strings в main(), но не в print_array, является результатом преобразования массива в указатель при доступе.Это означает, что при доступе к массиву (с учетом 4 исключений ниже) массив преобразуется в указатель на первый элемент в массиве.После преобразования, как это происходит при передаче массива в качестве параметра функции, у вас есть только указатель, а не массив.

Стандарт C11 (как и стандарт C17) читается какследует:

Преобразование указателя массива

(p3) За исключением случаев, когда это операнд оператора sizeof, оператора _Alignof или унарный '&' оператор, или строковый литерал , используемый для инициализации массива, выражение с типом "массив типа" преобразуется в выражение с типом "указатель на типMsgstr " указывает на начальный элемент объекта массива и не является lvalue. C11 Standard - 6.3.2.1 Другие операнды - L-значения, массивы и обозначения функций (p3)

Если вы заметите выше, при использовании с оператором sizeof массив не преобразуетсяна указатель, поэтому в main(), sizeof(strings) / sizeof(strings[0]) предоставляет количество элементов в массиве строки.Однако после передачи strings в print_array преобразование в указатель уже произошло, так что в print_array ваша попытка использования sizeof приводит к:

size_t array_length = sizeof(a_pointer) / sizeof(a_char);

(что является 8 на x86_64 или 4 на x86)

У вас есть два варианта (1) передать количество элементов в вашем массиве в качестве второго параметра в print_array, или (2) делает последние указатели в strings NULL (для использования в качестве часового значения).Затем в print_array вы можете просто перебрать strings[i], пока оно не станет NULL.

Несколько быстрых примеров:

Передача количества элементов

#include <stdio.h>

void print_array (char **strings, size_t nptrs)
{
    for (size_t i = 0; i < nptrs; i++)
        printf("%s, ", strings[i]);
    putchar ('\n');
}

int main(void) {

    char *strings[] = { "Hello",
                        "Zerotom",
                        "new" };

    print_array (strings, sizeof strings/sizeof *strings);

    return 0;
}

Пример использования / вывода

$ ./bin/prnarray
Hello, Zerotom, new,

Добавление Sentinel NULL в strings

#include <stdio.h>

void print_array (char **strings)
{
    for (size_t i = 0; strings[i]; i++)
        printf("%s, ", strings[i]);
    putchar ('\n');
}

int main(void) {

    char *strings[] = { "Hello",
                        "Zerotom",
                        "new",
                        NULL };        /* sentinel NULL */

    print_array (strings);

    return 0;
}

(тот же вывод)

Существует, по крайней мере, несколько способов зацикливания, используя либо циклы for или while и либо используя указатель на strings и арифметику указателей, либо используя индексирование массива (Разница заключается в простой семантике, поскольку вы делаете то же самое).Посмотрите вещи и дайте мне знать, если у вас есть дополнительные вопросы.

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