объявление переменной C++

Я задаюсь вопросом если этот код:

int main(){
    int p;
    for(int i = 0; i < 10; i++){
      p = ...;
    }
    return 0
}

точно то же как то

int main(){
    for(int i = 0; i < 10; i++){
      int p = ...;
    }
    return 0
}

с точки зрения эффективности? Я имею в виду, p переменная будет воссоздана 10 раз во втором примере?

5
задан swan 8 May 2010 в 12:17
поделиться

4 ответа

  • То же самое с точки зрения эффективности.
  • Это не то же самое с точки зрения удобочитаемости. Второй вариант лучше в этом аспекте, не так ли?

Это семантическая разница, которую код скрывает, потому что она не имеет значения для int , но имеет значение разница для человеческого читателя. Вы хотите вынести значение любого вычисления, которое вы выполняете в ... , за пределы цикла? Вы этого не сделаете, поэтому вам следует написать код, отражающий ваше намерение.

Человек-читатель должен будет искать функцию и искать другие варианты использования p , чтобы убедиться, что то, что вы сделали, было просто преждевременной «оптимизацией» и не преследовало более глубокой цели.

Предполагая, что это имеет значение для используемого вами типа, вы можете помочь читателю, прокомментировав свой код

/* p is only used inside the for-loop, to keep it from reallocating */
std::vector<int> p;
p.reserve(10);

for(int i = 0; i < 10; i++){
  p.clear();
  /* ... */
}
9
ответ дан 18 December 2019 в 13:11
поделиться

В этом случае все то же самое. Используйте наименьшую область видимости для наиболее читабельного кода.

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

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

Итог - напишите это четко, и если профилирование покажет, что это имеет значение, уберите это :)

.
4
ответ дан 18 December 2019 в 13:11
поделиться

Они равны по эффективности - вы должны доверить компилятору избавиться от неизмеримо маленькой разницы. Второй - лучший дизайн.

Изменить: это не обязательно верно для пользовательских типов, особенно тех, которые имеют дело с памятью. Если бы вы писали цикл для любого T, я бы на всякий случай использовал первую форму. Но если вы знаете, что это встроенный тип, например int, pointer, char, float, bool и т. Д., Я бы выбрал второй.

1
ответ дан 18 December 2019 в 13:11
поделиться

Во втором примере p виден только внутри цикла for. дальше в коде его использовать нельзя. С точки зрения эффективности они равны.

0
ответ дан 18 December 2019 в 13:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: