Эй все, я в основном плохо знаком с программированием. Я решил попытаться начать с 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: ошибка: ожидаемое выражение прежде'', маркер
В самом фактическом окне кода каждый символ отмечается как "неожиданный маркер".
В этом случае вам действительно не нужен 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);
}
}
Вам нужен, чтобы исправить размеры вашего массива, и вам также нужно объявить ваши строки как строки, а не как константы многобайтовых символов:
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.
Также имеется ошибка в операторах for:
for(point=1;point<5;point++)
Первый элемент в массиве находится в позиции 0, поэтому операторы for должны быть такими:
for(point=0;point<5;point++)
Он должен быть
char currencies[3][5][5] = {
, потому что он содержит 3 списка по 5 строк в каждом.
Каждая строка может содержать не более 4 символов, но вам понадобится дополнительный символ NUL, поэтому в конце будет 5.
- РЕДАКТИРОВАТЬ
Вы запутали доступ к массиву. Используя определение вашего массива (фиксированное, как указано выше), для получения строки будет использоваться currencies [data_type] [index].
первая строка
{'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-5), поскольку вы можете получить доступ к массиву (0-4) и, таким образом, знать индексы. Вы можете инкапсулировать другие значения в struct или два отдельных массива, что уменьшит ваш массив(ы) до одной размерности, как и должно быть... Таким образом, элементы имеют правильные типы, и вы не злоупотребляете двумерными массивами.
Двумерная или трехмерная область не должна заполняться элементами, которые должны быть другого типа, она нужна, когда у вас есть элементы одного типа, имеющие логическую двумерную или трехмерную структуру. Пиксели на вашем экране - хороший пример того, что нуждается в двумерной структуре, координаты в трехмерном графе - хороший пример того, что нуждается в трехмерной структуре.
В C / C ++ вы обычно читаете размеры вашего массива справа налево, чтобы получить хорошее представление о том, как его увидит компилятор. В этом случае вам нужно сохранить строки из 4 символов каждая, что требует хранения для 5 символов (включая завершающий \ 0), поэтому [5] будет размером массива. Затем вы сохраняете группы из 5 элементов, поэтому среднее значение будет [5] и, наконец, вы сохраняете в общей сложности 3 группы этих элементов, следовательно, [3]. Конечный результат всего этого - char валюты [3] [5] [5] =. . .;
Конечно, как уже было сказано в другом месте, вам нужно использовать двойные кавычки для строковых значений.
Это имеет смысл использовать здесь 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;
}
Если вы хотите решить эту проблему с помощью многомерных массивов, как говорит @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];