Какая разница (в терминах памяти), если я заранее объявляю аргументы в качестве переменных вместо записи их в строке вызова функции?

Например, для фиктивной функции write(int length, const char* text){...}Есть ли разница в показателях памяти между этими двумя подходами?

write(18,"The cake is a lie.");

или же

int len = 18;
char txt[19] = "The cake is a lie.";
write(len,txt)

Бонус: что если есть какое-то повторение? то есть цикл вызывает функцию несколько раз, используя массив, элементы которого являются предполагаемыми аргументами.

Я задаю этот вопрос, особенно бонус, в надежде лучше понять, как каждый из них использует память, чтобы оптимизировать мою эффективность при записи на чувствительных к памяти платформах, таких как Arduino. Тем не менее, если вы знаете еще более эффективный способ, пожалуйста, поделитесь! Спасибо!

0

Решение

Это зависит от того, char txt[19] объявлен в объем функции или в глобальной области (или пространстве имен).

Если в рамках функции, то txt будет размещен в стеке и инициализирован во время выполнения из копии строковый литерал Находясь в (только для чтения) сегмент данных.

Если в глобальном масштабе, то он будет размещен во время сборки в сегменте данных.

Бонус: если он размещен в какой-то дополнительной области, например в теле цикла, то вы должны предполагать, что он будет инициализироваться во время каждой итерации цикла (оптимизатор может делать некоторые трюки, но не рассчитывать на это).

Пример 1:

int len = 18;
char txt[19] = "The cake is a lie.";
int main() {
write(len,txt);
}

Вот len ( int) а также txt (19 байт + выравнивание выравнивания) будет выделено в сегменте данных программы во время сборки.

Пример 2:

int main() {
int len = 18;
char txt[19] = "The cake is a lie.";
write(len,txt);
}

Здесь строковый литерал "The cake is a lie." будет размещен в сегменте данных программы во время сборки. К тому же, len а также txt (19 байт + заполнение) может быть выделено в стеке во время выполнения. Оптимизатор может опустить len распределение и, возможно, даже txt, но не рассчитывайте на это, так как это будет зависеть от многих факторов, таких как write Тело доступно, что именно он делает, качество оптимизатора и т. д. В случае сомнений, смотреть в сгенерированном коде (godbolt теперь поддерживает цели AVR).

Пример 3:

int main() {
write(18,"The cake is a lie.");
}

Здесь строковый литерал "The cake is a lie." будет размещен в сегменте данных программы во время сборки. 18 будет встроен в код программы.


Поскольку вы разрабатываете на AVR, стоит упомянуть некоторые дополнительные особенности, а именно, исполняемый файл приложения изначально хранится в вспышка, и как только вы «запускаете» его, он копируется в оперативную память. Можно избежать копирования в ОЗУ и сохранить данные во Flash, используя PROGMEM ключевое слово (хотя, чтобы сделать что-либо значимое с данными, вам нужно будет скопировать их в оперативную память).

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]