Передача массива 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, но безуспешно.

Что я делаю не так?

, 👍0

Обсуждение

вы должны передать размер в качестве дополнительного параметра. размер массива, входящего в функцию, неизвестен во время выполнения, @Juraj

@Juraj - Это означает, что ссылка в порядке, но ее размер нельзя рассчитать?, @Guy . D

указатель или ссылка - это только начальный адрес, @Juraj

@Юрай, которого я знаю...., @Guy . D

а как размер считать? нет информации о конечном адресе или длине. то, как вы вычисляете размер, работает для определенного массива, когда компилятор знает определение массива. но в эту функцию можно передать массив любой длины, @Juraj

@Juraj Ну, я думал, что есть какой-то нулевой знак завершения. Работает - спасибо!, @Guy . D

для массива символов это соглашение. для массива указателей вы можете использовать нулевой указатель в качестве метки. здесь вы можете выбрать некоторое значение time_t в качестве конечной метки, но, как правило, все они имеют значение., @Juraj


1 ответ


Лучший ответ:

2

Когда вы передаете массив функции, он "схлопывается" массив в просто указатель. Все, что знает принимающая функция, — это тип содержимого массива (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