Инициализация переменных в C
Я знаю, что иногда, если вы не инициализируете int
, вы получите случайное число, если вы напечатаете целое число.
Но инициализация всего до нуля кажется глупым.
Я спрашиваю, потому что я комментирую свой проект на C, и я довольно прямо на отступы, и он полностью компилируется (90/90 спасибо Stackoverflow), но я хочу получить 10/10 в точках стиля.
Итак, вопрос: когда это целесообразно инициализировать, и когда вы должны просто объявить переменную:
int a = 0;
против.
int a;
Ответы
Ответ 1
Правило, которое еще не упоминалось, следующее: когда переменная объявлена внутри функции, она не инициализируется, и когда она объявлена в статическом или глобальном масштабе, она устанавливает значение 0:
int a; // is set to 0
void foo() {
int b; // set to whatever happens to be in memory there
}
Однако - для удобства чтения я бы обычно инициализировал все во время объявления.
Если вам интересно узнать об этом в деталях, я бы рекомендовал эту презентацию и эта книга
Ответ 2
Существует несколько обстоятельств, когда вы не должны инициализировать переменную:
- Когда он имеет статическую продолжительность хранения (
static
ключевое слово или глобальный var), и вы хотите, чтобы начальное значение было равно нулю. Большинство компиляторов фактически сохраняют нули в двоичном формате, если вы явно инициализируете, что обычно является пустой тратой пространства (возможно, огромной тратой для больших массивов).
- Когда вы немедленно передаете адрес переменной другой функции, которая заполняет ее значение. Здесь инициализация - просто пустая трата времени и может смущать читателей кода, которые задаются вопросом, почему вы храните что-то в переменной, которая должна быть перезаписана.
- Если значение переменной не может быть определено до тех пор, пока последующий код не завершит выполнение. В этом случае он активно вреден для инициализации переменной с помощью фиктивного значения, такого как zero/NULL, поскольку этот запрещает компилятору предупреждать вас, если у вас есть некоторые пути кода, где значимое значение никогда не назначается. Компиляторы хорошо предупреждают вас о доступе к неинициализированным переменным, но не могут предупредить вас о переменных "все еще содержит фиктивные значения".
Помимо этих проблем, я бы сказал, что в целом хорошая практика - инициализировать ваши нестатические переменные, когда это возможно.
Ответ 3
Если переменная находится в области действия функции, а не является членом класса я всегда, инициализируйте ее, потому что в противном случае вы получите предупреждения. Даже если эта переменная будет использоваться позже, я предпочитаю назначать ее при объявлении.
Что касается переменных-членов, вы должны инициализировать их в конструкторе вашего класса.
Для указателей всегда инициализируйте их по умолчанию, особенно NULL, даже если они будут использоваться позже, они опасны при неинициализации.
Также рекомендуется создать код с максимальным уровнем предупреждений, который поддерживает ваш компилятор, помогает выявить плохие методы и потенциальные ошибки.
Ответ 4
Статические и глобальные переменные будут инициализированы нулем для вас, чтобы вы могли пропустить инициализацию. Автоматические переменные (например, нестатические переменные, определенные в теле функции) могут содержать мусор и, вероятно, всегда должны быть инициализированы.
Если для инициализации требуется ненулевое конкретное значение, вы должны всегда инициализировать явно.
Ответ 5
Я могу вспомнить пару причин с головы:
-
Когда вы собираетесь инициализировать его позже в своем коде.
int x;
if(condition)
{
func();
x = 2;
}
else
{
x = 3;
}
anotherFunc(x); // x will have been set a value no matter what
-
Если вам нужна память для хранения значения, заданного функцией или другим фрагментом кода:
int x; // Would be pointless to give x a value here
scanf("%d", &x);
Ответ 6
Всегда правильная практика инициализации ваших переменных, но иногда она не является строго необходимой. Рассмотрим следующее:
int a;
for (a = 0; a < 10; a++) { } // a is initialized later
или
void myfunc(int& num) {
num = 10;
}
int a;
myfunc(&a); // myfunc sets, but does not read, the value in a
или
char a;
cin >> a; // perhaps the most common example in code of where
// initialization isn't strictly necessary
Это всего лишь несколько примеров, где нет необходимости инициализировать переменную, поскольку она устанавливается позже (но не доступна между объявлением и инициализацией).
В общем, не всегда полезно инициализировать ваши переменные при объявлении (и действительно, это, вероятно, лучшая практика).
Ответ 7
В общем случае нет необходимости инициализировать переменную с двумя заметными исключениями:
- Вы объявляете указатель (и не назначаете его сразу) - вы
должен всегда устанавливать их в NULL как хороший стиль и защитный
программирование.
- Если, когда вы объявляете переменную, вы уже знаете какое значение будет присвоено ему. Дальнейшие присвоения используются больше циклов процессора.
Кроме того, это о том, чтобы заставить переменные в правильном состоянии вы хотите, чтобы они выполняли операцию, которую вы собираетесь выполнять. Если вы не собираетесь их читать до того, как операция изменит их значение (а операции не важно, в каком состоянии оно находится), нет необходимости инициализировать их.
Лично мне всегда нравится их инициализировать; если вы забыли присвоить ему значение, и оно было передано в функцию по ошибке (например, оставшаяся длина буфера) 0 обычно обрабатывается чисто - 32532556 не будет.
Ответ 8
Нет абсолютно никакой причины, по которой переменные не должны инициализироваться, компилятор достаточно умен, чтобы игнорировать первое присваивание, если переменная назначается дважды. Легко для кода расти в размерах, где вещи, которые вы считали само собой разумеющимися (например, назначение переменной перед использованием) больше не верны. Рассмотрим:
int MyVariable;
void Simplistic(int aArg){
MyVariable=aArg;
}
//Months later:
int MyVariable;
void Simplistic(int aArg){
MyVariable+=aArg; // Unsafe, since MyVariable was never initialized.
}
Один хорошо, другой забрасывает вас в кучу неприятностей. Иногда вы будете иметь проблемы, когда ваше приложение будет работать в режиме отладки, но режим выпуска вызовет исключение, одна из причин этого - использование неинициализированной переменной.
Ответ 9
До тех пор, пока я не прочитал переменную перед ее записью, мне не пришлось беспокоиться о ее инициализации.
Чтение до написания может привести к серьезным и трудным ошибкам. Я думаю, что этот класс ошибок достаточно известен, чтобы получить упоминание в популярных лекционных лекциях SICP.
Ответ 10
Инициализация переменной, даже если она не является строго обязательной, ВСЕГДА является хорошей практикой. Несколько дополнительных символов (например, "= 0
" ), введенных во время разработки, могут сэкономить время отладки позже, особенно когда забывают, что некоторые переменные остались неинициализированными.
Попутно, я считаю, что полезно объявить переменную, близкую к ее использованию.
Плохо выглядит следующее:
int a; // line 30
...
a = 0; // line 40
Хорошо следующее:
int a = 0; // line 40
Кроме того, если переменная должна быть перезаписана сразу после инициализации, например
int a = 0;
a = foo();
лучше записать его как
int a = foo();