Проблема: Предположим, вы пытаетесь написать функцию в C, которая заполнит 2D-массив значениями из файла. Файл содержит значения, расположенные в строках (записях), где каждая строка содержит несколько полей. Функция должна принимать указатель на 2D-массив и адрес файла и заполнять массив. Важно отметить, что функция должна работать независимо от количества полей на каждой записи. Например, в одной программе можно вызвать функцию, чтобы считывать значения из файла, в котором Есть четыре поля на запись:Можете ли вы передать многомерные массивы в функцию C в качестве указателей, а затем отбросить их обратно в массивы внутри функции?
int array_of_values[MAX_NUMBER_OF_RECORDS][4];
fill_in_array(array_of_values, "spacetime.csv");
В другой программе, вы можете заполнить значения, когда есть одиннадцать полей в записи :
int array_of_values[MAX_NUMBER_OF_RECORDS][11];
fill_in_array(array_of_values, "M-theory.csv");
к сожалению, если вы попытаетесь сделать это, вы ссориться пути C обрабатывает многомерные массивы. Многомерные массивы не реализованы в C как массивы указателей на массивы, а вместо этого как один длинный одномерный массив. Это означает, что функция должна знать ширину массива, чтобы читать данные из него.
Таким образом, следующее определение функции будет выдавать ошибку:
void fill_in_array(int array_of_values[MAX_NUMBER_OF_RECORDS][], char *path)
[Обратите внимание, что следующий будет в порядке:
void fill_in_array(int array_of_values[][MAX_NUMBER_OF_RECORDS], char *path)
, так как компилятор не нужно знать индекс для но предположим, что это недопустимо (например, если функция должна обходиться с отдельными записями, такими как array_of_values[1]
).]
Это t он указывает, что я достиг в своей программе. Существуют два решения:
- Заставить функцию работать с фиксированным количеством полей. Я бы предпочел не делать этого, но я мог бы, например, объявить константу
MAX_NUMBER_OF_FIELDS
и оставить неиспользуемые поля пустыми. - Выполнение функции
fill_in_array
выполняется в указателе, а не в массиве, и динамически выделяет вектор Iliffe, содержащий эти поля. Это привлекательная идея (так как это помешает нам объявить максимальное количество записей/полей, но это также означало бы, что нам нужно было бы создать (и не забудьте использовать!) Функцию для освобождения массива полей.
у меня есть одна другая идея, что это изменить объявление функции на следующее:.
void fill_in_array(int **array_of_values, int number_of_fields, char *path)
(Здесь number_of_fields
относится к числу полей в записи, так что мы могли бы назвать его как fill_in_array(array_of_values, 4, "spacetime.csv");
.
Обратите внимание, что параметр array_of_values
больше не является явным массивом, а является указателем. Обычно, если вы назначаете двунаправленный указатель на 2D-массив, результат не имеет смысла. Моя идея состоит в том, что можно было бы использовать параметр number_of_fields
, чтобы функция умела справляться с выражениями типа array_of_values[i][j]
.
В принципе, это должно быть довольно легко: в самом деле, если a
является 2D массив, то a[i][j]
определяется как
*(a + (i * n) + j)
где n
длина массива, так что мы могли бы заменить все вхождения array_of_values[i][j]
с *(array_of_values + (i * number_of_fields) + j)
, и каждый случай array_of_values[i]
с array_of_values + (i * number_of_fields)
. Однако этот код очень трудно прочитать. Есть ли способ сообщить компилятору, что ширина массива равна number_of_fields
, чтобы я мог использовать нотацию индекса для доступа к элементам массива?
'Многомерные массивы не реализованы в C как массивы массивов, а как один длинный одномерный массив »(a) Нет, они не являются, и (б) я не понимаю различия. –
Извините, что не ясны. Я имел в виду: «Массивы массивов» = вектор Iliffe (т. Е. Одномерный массив, элементами которого являются адреса одномерных массивов, доступ к элементам осуществляется по формуле «a [i] [j] = * (* (a + i) + j) ') - это НЕ, как они реализованы в C; 'Один длинный одномерный массив' = одномерный массив из m * n элементов, где m, n - размеры массива; Элементы доступны как 'a [i] [j] = * (a + (i * n) + j)' - это то, как они реализованы в C, что означает, что компилятор должен знать значение 'n' , –
Итак, вы хотели сказать, что это «массивы указателей на массивы», что является самой другой (и более низкой) вещью. –