Як зазначалося, з цього приводу існує дві школи думки.
1) оголосити все на початку функцій, оскільки рік - 1987 рік.
2) оголосити найближчим до першого використання та в найменшому обсязі.
Моя відповідь на це - ДО БУТИ! Дозволь пояснити:
Для довгих функцій 1) робить рефакторинг дуже важким. Якщо ви працюєте в кодовій базі, де розробники проти ідеї підпрограм, на початку функції у вас буде 50 змінних оголошень, а деякі з них можуть бути просто "i" для циклу for-циклу, який знаходиться в самому внизу функції.
Тому я розробив з цього декларацію на початку ПТСР і спробував зробити варіант 2) релігійно.
Я повернувся до варіанту один через одне: короткі функції. Якщо ваші функції недостатньо короткі, то у вас буде кілька локальних змінних, і оскільки функція коротка, якщо поставити їх у верхній частині функції, вони все ще будуть близькими до першого використання.
Крім того, антидіаграма "заявити та встановити NULL", коли ви хочете оголосити вгорі, але ви не зробили деякі розрахунки, необхідні для ініціалізації, вирішено, тому що речі, які потрібно ініціалізувати, ймовірно, будуть отримані як аргументи.
Тож тепер я думаю, що вам слід оголосити вгорі функцій і якомога ближче до першого використання. Тож БУТИ! І спосіб зробити це з добре розділеними підпрограмами.
Але якщо ви працюєте над тривалою функцією, то поставте речі, найближчі до першого використання, тому що таким способом буде простіше витягти методи.
Мій рецепт такий. Для всіх локальних змінних візьміть змінну і перемістіть її декларацію донизу, компілюйте, а потім перемістіть декларацію безпосередньо перед помилкою компіляції. Це перше використання. Зробіть це для всіх локальних змінних.
int foo = 0;
<code that uses foo>
int bar = 1;
<code that uses bar>
<code that uses foo>
Тепер визначте блок області, який починається перед оголошенням, і перемістіть його до завершення, поки програма не скомпонує
{
int foo = 0;
<code that uses foo>
}
int bar = 1;
<code that uses bar>
>>> First compilation error here
<code that uses foo>
Це не компілюється, оскільки є ще якийсь код, який використовує foo. Ми можемо помітити, що компілятор зміг пройти код, який використовує бар, оскільки він не використовує foo. На даний момент є два варіанти. Механічним є просто перемістити "}" вниз, поки він не складеться, а другий вибір - перевірити код і визначити, чи можна змінити порядок на:
{
int foo = 0;
<code that uses foo>
}
<code that uses foo>
int bar = 1;
<code that uses bar>
Якщо замовлення можна переключити, це, мабуть, те, що ви хочете, оскільки це скорочує термін служби тимчасових значень.
Ще слід зазначити, чи потрібно зберігати значення foo між блоками коду, які його використовують, чи це може бути просто інший foo в обох. Наприклад
int i;
for(i = 0; i < 8; ++i){
...
}
<some stuff>
for(i = 3; i < 32; ++i){
...
}
Ці ситуації потребують більше, ніж моя процедура. Розробнику доведеться проаналізувати код, щоб визначити, що робити.
Але перший крок - пошук першого використання. Ви можете це зробити візуально, але іноді просто простіше видалити декларацію, спробувати скласти і просто поставити її назад вище першого використання. Якщо це перше використання знаходиться в операторі if, поставте його там і перевірте, чи він компілюється. Потім компілятор визначить інші види використання. Спробуйте створити блок області, який охоплює обидва напрями використання.
Після того, як ця механічна частина виконана, тоді стає легше аналізувати, де знаходяться дані. Якщо змінна використовується у великому блоці діапазону, проаналізуйте ситуацію і перевірте, чи ви просто використовуєте одну і ту ж змінну для двох різних речей (наприклад, "i", яка використовується для двох для циклів). Якщо використання не пов'язане між собою, створіть нові змінні для кожного з цих неспоріднених застосувань.