В новинку для программирования, не получайте 2D/3D массивы

Эй все, я в основном плохо знаком с программированием. Я решил попытаться начать с C (не C++ или C#), и до сих пор я делал вполне прилично. Мне удалось стать далеким как двухмерные антенные решетки, прежде чем я начал колебаться. В то время как я думаю, что широко понимаю 2D целочисленные массивы, я, конечно, не понимаю 3D массивов строк.

Я учусь путем взятия методов и применения их в фактической программе, которую я создал, обменный курс "калькулятор", который в основном берет, просит, чтобы пользователь для выбора базовой валюты затем распечатал ее значение в долларе США. Нет никакой включенной математики, я просто погуглил материал как евро/ДОЛЛАР США и установил значения вручную в массиве, который я обсуждаю ниже.

Но вот то, где я застреваю. Я изображаю лучший способ узнать, что многомерные массивы состоят в том, чтобы практически применить теорию, таким образом, вот то, что я ввел до сих пор (я опустил другие функции своей программы (включая код, который вызывает эту функцию) для краткости):

 char currencies[5][3][4] = {
    {'1','2','3','4','5'},
    {'GBP','EUR','JPY','CAD','AUD'},
    {'1.5','1.23','0.11','0.96','0.87'}
};

int point, symbol, value;

displayarraycontents()
{
    for(point=1;point<5;point++){
        for(symbol=1;symbol<5;symbol++){
            for(value=1;symbol<5;symbol++)
                printf("%s ", currencies[point][symbol][value]);
            printf("\n");
        }}

}

Поскольку C не показывает тип данных String, создавание массивов строк полностью смешивает с моей головой.

Почему валюты [5] [3] [4]? Поскольку я храню в общей сложности 5 валют, каждый отмеченный 3 буквенными обозначениями (например, евро, CAD), которые имеют значение до 4 цифр, включая десятичную точку.

Я пытаюсь отобразить этот список:

1 ФУНТ СТЕРЛИНГОВ 1.5
2 ЕВРО 1.23
3 JPY 0.11
4 CAD 0.96
5 AUD 0.87

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

предупреждение: переполнение в неявном постоянном преобразовании

... и строка, где я печатаю содержание массива, выделяется с этим предупреждением:

предупреждение: формат '%s' ожидает тип 'символ *', но аргумент 2 имеет тип 'интервал'

После выполнения кода остальная часть программы хорошо работает кроме этой функции, которая производит "ошибку сегментации" или somesuch.

Кто-то мог дать мне руку здесь? Любая справка значительно ценилась бы, а также любые ссылки на простые 2D/3D учебные руководства по инициализации массива строк C! (мои две книги, K&R и Учат Себя, что C только обеспечивают неопределенные примеры, которые не релевантны),

Заранее спасибо!
- Ryan

Править: обновленный код с помощью структуры:

struct currency {
    char symbol[4];
    float value[5];
};


void displayarraycontents(){

        int index;

        struct currency currencies[] {
            {"GBP", 1.50},
            {"EUR", 1.23},
            {"JPY", 0.11},
            {"CAD", 0.96},
            {"AUD", 0.87},};

}

Я получаю следующие ошибки: основной c:99: ошибка: вложенные функции отключены, используют - fnested-функции, чтобы повторно включить
основной c:99: ошибка: ожидаемый '=', '', ';', 'asm' или 'атрибут' прежде '{' маркер
основной c:100: ошибка: ожидаемый''; прежде '}' маркер
основной c:100: ошибка: ожидаемое выражение прежде'', маркер

В самом фактическом окне кода каждый символ отмечается как "неожиданный маркер".

9
задан Ryan 27 June 2010 в 23:26
поделиться

8 ответов

В этом случае вам действительно не нужен 3D-массив. Фактически, поскольку у вас есть таблица значений, все, что вам нужно, - это одномерный массив.

Сложность заключается в том, что каждый элемент массива должен хранить две вещи: символ валюты и соответствующий обменный курс. В C есть способ создания типа, который хранит две вещи - это механизм struct . Мы можем определить структуру для хранения одной валюты:

struct currency {
    char symbol[4];
    char value[5];
};

(Обратите внимание, что это не создает переменную ; она создает тип . struct currency аналогична char , за исключением того, что мы сами определили значение первого).

... и теперь мы можем создать массив из 5 из них:

struct currency currencies[5] = { 
    {"GBP", "1.5" },
    {"EUR", "1.23" },
    {"JPY", "0.11" },
    {"CAD", "0.96" },
    {"AUD", "0.87" } };

Чтобы перебрать их и распечатать, код будет выглядеть так:

void displayarraycontents(void)
{
    int point;

    for(point = 0; point < 5; point++)
    {
        printf("%d %s %s\n", point + 1, currencies[point].symbol, currencies[point].value);
    }
}
9
ответ дан 4 December 2019 в 12:16
поделиться

Вам нужен, чтобы исправить размеры вашего массива, и вам также нужно объявить ваши строки как строки, а не как константы многобайтовых символов:

char currencies[3][5][5] = {
    {"1","2","3","4","5"},
    {"GBP","EUR","JPY","CAD","AUD"},
    {"1.5","1.23","0.11","0.96","0.87"}
};

Ваша логика для размеров массива неверна - вам нужно 3 столбца, каждый с 5 записей, каждая из которых представляет собой строку длиной 5 байтов.

Ваш цикл for должен индексироваться с 0, а не с 1.

3
ответ дан 4 December 2019 в 12:16
поделиться

Также имеется ошибка в операторах for:

for(point=1;point<5;point++)

Первый элемент в массиве находится в позиции 0, поэтому операторы for должны быть такими:

for(point=0;point<5;point++)
2
ответ дан 4 December 2019 в 12:16
поделиться

Он должен быть

char currencies[3][5][5] = {

, потому что он содержит 3 списка по 5 строк в каждом.

Каждая строка может содержать не более 4 символов, но вам понадобится дополнительный символ NUL, поэтому в конце будет 5.

- РЕДАКТИРОВАТЬ

Вы запутали доступ к массиву. Используя определение вашего массива (фиксированное, как указано выше), для получения строки будет использоваться currencies [data_type] [index].

  • data_type = 0 -> индекс
  • data_type = 1 -> символ
  • data_type = 2 -> значение

первая строка

{'1','2','3','4','5'},

является избыточным.

Фиксированный код:

 char currencies[2][5][5] = {
     {"GBP","EUR","JPY","CAD","AUD"},
     {"1.5","1.23","0.11","0.96","0.87"}
 };

 void displayarraycontents()
 {
    int index;
    for(index = 0;index < 5;index++) {
        printf("%i %s %s\n", index, currencies[0][index], currencies[1][index]);
    }
}
1
ответ дан 4 December 2019 в 12:16
поделиться

Вам не нужно хранить индексы (1-5), поскольку вы можете получить доступ к массиву (0-4) и, таким образом, знать индексы. Вы можете инкапсулировать другие значения в struct или два отдельных массива, что уменьшит ваш массив(ы) до одной размерности, как и должно быть... Таким образом, элементы имеют правильные типы, и вы не злоупотребляете двумерными массивами.

Двумерная или трехмерная область не должна заполняться элементами, которые должны быть другого типа, она нужна, когда у вас есть элементы одного типа, имеющие логическую двумерную или трехмерную структуру. Пиксели на вашем экране - хороший пример того, что нуждается в двумерной структуре, координаты в трехмерном графе - хороший пример того, что нуждается в трехмерной структуре.

0
ответ дан 4 December 2019 в 12:16
поделиться

В C / C ++ вы обычно читаете размеры вашего массива справа налево, чтобы получить хорошее представление о том, как его увидит компилятор. В этом случае вам нужно сохранить строки из 4 символов каждая, что требует хранения для 5 символов (включая завершающий \ 0), поэтому [5] будет размером массива. Затем вы сохраняете группы из 5 элементов, поэтому среднее значение будет [5] и, наконец, вы сохраняете в общей сложности 3 группы этих элементов, следовательно, [3]. Конечный результат всего этого - char валюты [3] [5] [5] =. . .;

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

0
ответ дан 4 December 2019 в 12:16
поделиться

Это имеет смысл использовать здесь struct , а не многомерный массив.

#include <stdio.h>

typedef struct Currency {
   const char* symbol;
   double value;
} Currency;

Currency CURRENCIES[] = {
   {"GBP", 1.5},
   {"EUR", 1.23},
   {"JPY", 0.11},
   {"CAD", 0.96},
   {"AUD", 0.87},
};
size_t NUM_CURRENCIES = sizeof(CURRENCIES) / sizeof(Currency);

int main()
{
   size_t index;

   for (index = 0; index < NUM_CURRENCIES; index++)
   {
      printf("%zu %s %.2f\n",
         index + 1, CURRENCIES[index].symbol, CURRENCIES[index].value);
   }

   return 0;
}
2
ответ дан 4 December 2019 в 12:16
поделиться

Если вы хотите решить эту проблему с помощью многомерных массивов, как говорит @Forrest, вам понадобится [3][5][5]. Взгляните на это так: в инициализаторе найдите крайние фигурные скобки: сколько там элементов на верхнем уровне? 3. Сколько элементов в каждом из этих элементов (на одном уровне)? 5. Переходя дальше вниз, внутри каждого из них у вас есть строка из 4 элементов, плюс один для терминатора, снова 5.

Вторая ошибка: вы можете иметь только один символ в одинарных кавычках, например ' a '; это тип char , эквивалентный коду ASCII (97 в данном случае). Для строк необходимо использовать двойные кавычки ( «abc» , что эквивалентно {97, 98, 99, 0} ).

Ошибка третья: петли. Фактически вы не выполняете итерацию по всем трем циклам при печати строки за раз (поскольку printf фактически выполнит один из циклов за вас) - поэтому у вас должно быть только 2 цикла (или, что менее эффективно, вы может сохранить все три цикла, но затем печатать только символ за раз). Кроме того, вам нужно знать об ограничениях цикла; вы увеличиваете до 5 в каждом случае, но это приведет к мусору во время выполнения (в лучшем случае) или краху во время выполнения (в худшем случае), когда вы выйдете за пределы измерения [3] . Таким образом, что-то вроде этого:

Опять же, ваш самый внутренний цикл несовместим с использованием вашей переменной (ошибка копирования-вставки).

Однако писать подобный код почти никогда не придется. В основном вы используете 2D-массивы для матричных операций. Что-то вроде этого должно иметь только одномерный массив, хранящий элементы записи.

struct currency {
    int     id;
    char[4] symbol;
    float   value;
} currencies[5];
0
ответ дан 4 December 2019 в 12:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: