В C является ли более эффективным использование пространства для объявления двумерного массива символов или рваного массива строк? (уточните c вопрос ниже) - PullRequest
3 голосов
/ 29 апреля 2020

У меня есть конкретный c вопрос относительно эффективности использования пространства ниже:

Предположим, вы хотите объявить массив из 7 строковых литералов, которые представляют 7 цветов радуги (т.е. красный, оранжевый, желтый, зеленый, синий, инди go и фиолетовый). Предполагая, что размер указателя равен 8 байтам, более эффективно с точки зрения пространства объявлять двумерный массив символов или рваный массив строк?

Строки в C меня смущают и я не уверен, что сразу же займусь этим вопросом. Любая помощь будет принята с благодарностью, особенно если для демонстрации используется даже небольшой объем кода. Спасибо всем заранее!

РЕДАКТИРОВАТЬ: Я написал следующий код:

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

int main(void) {
    char *string_array[] = {"red", "orange", "yellow", "green", "blue", "indigo", "violet"};
    char char_array[][7] = {"red", "orange", "yellow", "green", "blue", "indigo", "violet"};

    printf("\nThe size of a string is: %lu", sizeof(char *));
    printf("\nThe size of a string array with the given data is: %lu", sizeof(string_array));
    printf("\nThe size of a char is: %lu", sizeof(char));
    printf("\nThe size of a char array with the given data is: %lu", sizeof(char_array));

    return 0;
}

, который выводит следующее:

The size of a string is: 4
The size of a string array with the given data is: 28
The size of a char is: 1
The size of a char array with the given data is: 49

Я не уверен, правильно ли я это сделал, так как ожидал, что первый массив (рваный массив строк) будет больше?

Ответы [ 2 ]

5 голосов
/ 29 апреля 2020

Вариант 1:

const char *colors = ["red", "orange", "yellow", "green", "blue", "indigo", "violet"];

Здесь все строки занимают столько памяти только для чтения, сколько им нужно (43 байт), но дополнительно 56 (7 указателей по 8 байт) байты используются для хранения всех 7 указателей в памяти, в результате чего получается 99 байт.

Опция 2:

const char colors[][7] = ["red", "orange", "yellow", "green", "blue", "indigo", "violet"];

Здесь вы объявляете двумерный массив, но так как чтобы объявить 2-е измерение во время компиляции, оно должно быть достаточно большим, чтобы вместить самую длинную строку в массиве (+1 байт в каждой строке для нулевого завершающего байта). Таким образом, вы теряете место на всех более коротких строках.

Здесь 49 (7 строк по 7 байтов), байты распределены в общей сложности, но для хранения всех строк вам нужно всего 43 байтов, таким образом, 6 байтов «потрачены впустую».


Заключение

В целом для второго варианта требуется меньше памяти.

1 голос
/ 30 апреля 2020

вариант 1 и вариант 2: см. Ответ bool3max.

вариант 3

char *data = "red\0orange\0yellow\0"
      "green\0blue\0indigo\0violet";
skiprint(data, 3);

с

void skiprint(const char *zs, int n) {
    while (n--) { while (*zs) zs++; zs++; }
    puts(zs);
}

https://ideone.com/vI6wqs

...