Передача массива time_t в качестве параметра функции
Я пытаюсь регистрировать повторные подключения и отключения сети. Для этого я создал 2 массива time_t
для хранения таких вхождений:
const int logSize = 10;
time_t conLog[logSize];
time_t disconLog[logSize];
Теперь, в будущем, мне нужно выполнить некоторые манипуляции и расчет времени, и для этого я хочу передать этот журнал как переменную.
Например, обнуление его значений:
void initLog(time_t log[], time_t init_val = 0)
{
int sizeLog = sizeof(log) / sizeof(log[0]);
Serial.print("size: ");
Serial.println(sizeLog);
for (int i = 0; i < sizeLog; i++)
{
log[i] = init_val;
}
}
чтобы использовать его простым способом: initLog(conLog);
Но, к сожалению, это неправильно.
Я пытался заменить time_t log[]
на time_t &log
, но безуспешно.
Что я делаю не так?
@Guy . D, 👍0
Обсуждение1 ответ
Лучший ответ:
Когда вы передаете массив функции, он "схлопывается" массив в просто указатель. Все, что знает принимающая функция, — это тип содержимого массива (time_t
) и место его начала в памяти — ей ничего не известно о размере массива.
Вызов sizeof()
просто дает вам размер этого указателя, а не размер памяти, на которую он указывает.
sizeof()
на самом деле не функция, это конструкция времени компиляции. Он ничего не может знать о значениях времени выполнения, только то, что есть во время компиляции.
Вместо этого вы должны передать длину массива с массивом в качестве отдельного параметра, который может быть рассчитан только в той же области, в которой определен массив, и только с использованием исходного имени массива. Обычно для этого создается макрос во время создания массива:
time_t conLog[logSize];
#define CONLOG_SIZE (sizeof(conLog) / sizeof(conLog[0]))
Затем передайте это своей функции:
initLog(conLog, CONLOG_SIZE);
В качестве альтернативы, поскольку в этом случае у вас уже есть размер в константе, вы можете просто использовать это:
initLog(conLog, logSize);
Хороший ответ, за исключением... Если у вас есть константа logSize
, которую вы используете для создания conLog, зачем писать код для ее вычисления? Просто используйте logSize
напрямую., @Duncan C
@DuncanC В данном случае это правда, но бывает редко., @Majenko
Почему? Для массивов, размер которых определяется во время компиляции, использование константы времени компиляции для выражения этого размера является хорошим и чистым способом сделать это., @Duncan C
@DuncanC Да. Ты знаешь что. Я знаю это. Очень немногие пользователи Arduino знают об этом. Вы должны помнить: это пользователи Arduino, **не программисты**., @Majenko
Некоторые из нас оба..., @Duncan C
Но большинство - нет. Вот почему вы отвечаете на вопросы и не задаете вопросов. Просто не забудьте адаптировать свои ответы к уровню аудитории. Если вы сомневаетесь, почитайте о лестнице Витгенштейна и о «лжи детям»., @Majenko
Мне нравится ваша редакция, предлагающая лучший вариант. Почему люди минусуют этот ответ? Это **правильный** ответ., @Duncan C
...Ревность...?, @Majenko
- Невозможно преобразовать 'int (*)[size]' в 'int**': Cannot convert 'int (*)[size]' to 'int**'
- Как удалить элемент из массива arduino?
- Как вернуть значение массива символов в функции Arduino IDE?
- Передача массивов, глобальных массивов внутри функций, указателей и объявление размеров массивов.
- Вычислить размер массива, который был передан в качестве параметра функции
- Можно ли создать массив для функций?
- Ошибка получения адреса временного массива при передаче массива составных литералов
- Как создать функцию, которая будет вводить определенное значение для подзначения массива в зависимости от положения джойстика?
вы должны передать размер в качестве дополнительного параметра. размер массива, входящего в функцию, неизвестен во время выполнения, @Juraj
@Juraj - Это означает, что ссылка в порядке, но ее размер нельзя рассчитать?, @Guy . D
указатель или ссылка - это только начальный адрес, @Juraj
@Юрай, которого я знаю...., @Guy . D
а как размер считать? нет информации о конечном адресе или длине. то, как вы вычисляете размер, работает для определенного массива, когда компилятор знает определение массива. но в эту функцию можно передать массив любой длины, @Juraj
@Juraj Ну, я думал, что есть какой-то нулевой знак завершения. Работает - спасибо!, @Guy . D
для массива символов это соглашение. для массива указателей вы можете использовать нулевой указатель в качестве метки. здесь вы можете выбрать некоторое значение time_t в качестве конечной метки, но, как правило, все они имеют значение., @Juraj