Новичок в программировании, не получайте 2D / 3D массивы - PullRequest
9 голосов
/ 28 июня 2010

Привет всем, я в основном новичок в программировании.Я решил попробовать начать с C (, а не C ++ или C #), и до сих пор у меня все получалось.Мне удалось добраться до двумерных массивов, прежде чем я начал колебаться.Хотя я думаю, что я в целом понимаю двумерные целочисленные массивы, я, конечно, не понимаю трехмерные строковые массивы.

Я учусь, применяя методы и применяя их в реальной программе, которую я создал, в курсе валют "калькулятор ", который в основном требует, чтобы пользователь выбрал базовую валюту, а затем печатает ее значение в долларах США.Там нет математики, я просто погуглил такие вещи, как EUR / USD и вручную установил значения в массиве, который я обсуждаю ниже.

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

 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 не имеет строкового типа данных, построение строковых массивов полностью мешает моей голове.

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

I'mпытаясь отобразить этот список:

1 GBP 1,5
2 EUR 1,23
3 JPY 0,11
4 CAD 0,96
5 AUD 0,87

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

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

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

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

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

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

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

РЕДАКТИРОВАТЬ: обновленный код с использованиемstruct:

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},};

}

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

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

Ответы [ 8 ]

9 голосов
/ 28 июня 2010

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

Хитрость в том, что каждый элемент массива должен хранить two вещи: символ валюты и связанный с ним обменный курс.В C есть способ создания типа, который хранит две вещи - это механизм struct.Мы можем определить 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);
    }
}
3 голосов
/ 28 июня 2010

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

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.

2 голосов
/ 28 июня 2010

Было бы более разумно использовать 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 голосов
/ 28 июня 2010

Существует также опцион для операторов:

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

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

for(point=0;point<5;point++)
1 голос
/ 28 июня 2010

должно быть

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

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

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

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

Вы запутали доступ к массиву. Используя ваше определение массива (фиксированное, как указано выше), для получения строки будут валюты [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]);
    }
}
0 голосов
/ 28 июня 2010

Если вы хотите решить эту проблему с помощью многомерных массивов, как говорит @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 голосов
/ 28 июня 2010

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

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

0 голосов
/ 28 июня 2010

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

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

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