Подтвердить что ты не робот

C - Проверить, назначен ли Integer

Как определить, нецело ли целое число?

int i; /* no assignment */

if (/* conditional statement here to check if int i is unassigned or not */) {
   printf("Integer is unassigned!\n");
} else {
   printf("Integer is assigned!\n");
}
4b9b3361

Ответ 1

Вы не можете. Он будет иметь контент "undefined", то есть он будет содержать то, что когда-либо было в этом месте памяти в то время.

., если я не объявлен в глобальной области, то он будет инициализирован нулем.

Ответ 2

C не поддерживает внутреннюю поддержку этого - так же, как он не поддерживает внутреннюю проверку границ на массивах. Это компромисс между скоростью/эффективностью и безопасностью.

В общем... инициализируйте переменные.

Ответ 3

Это очень просто. Вы знаете, что он не назначен, потому что вы его не инициализировали.

Ответ 4

Если i является глобальным или статическим, его значение будет 0, в противном случае его значение может быть любым, и нет способа узнать, является ли это мусором или нет.

Ответ 5

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

Для GCC:

-Wuninitialized -O1

Если вы хотите записать условный код:

int a = 3;
int b;
int *p = (rand() > RAND_MAX/2) ? &a : &b;
if (is_uninitialized(*p)) // blah

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

Ответ 6

Как отмечали другие, вы не можете написать программу на C, которая обнаруживает, что одна из ее собственных переменных не инициализирована, и вы должны стремиться к тому, чтобы переменные всегда инициализировались.

  • Если ваша цель - убедиться, что все переменные инициализированы, такой инструмент, как valgrind, может обнаруживать использование неинициализированных переменных динамически, через дорогостоящий анализ времени выполнения.

  • Если ваша цель - убедиться, что личные данные инициализированы ровно один раз, обычный способ - защитить его с помощью

    int i;
    static bool initialized = 0;
    
    ... 
    if (!initialized) {
      initialized = 1;
      i = ... i initial value ...;
    }
    

Ответ 7

Обычно переменные устанавливаются в 0 библиотекой C, но необязательно.

Но в принципе, вы не можете. Присвойте им значение по умолчанию в определении, например:

int i = 0; /* Or what ever value you know won't be used elsewhere */

Затем, если вы запустите некоторый код и хотите проверить, было ли там установлено значение, вы можете сравнить его с начальным значением.

Ответ 8

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

Ответ 9

Использование переменной перед инициализацией (или назначением) является серьезной причиной ошибок. Вы не можете надежно проверить его во время выполнения, но вы можете обнаружить его во время или до компиляции.

Я предлагаю не проверить его внутри кода. Поскольку это может вызвать предупреждения компилятора (переменная "i" используется до того, как ей было присвоено значение), ввести новые ошибки и имеет очень мало шансов на успех в средних и больших программах.

Лучший способ - использовать статические инструменты анализа кода (например, QA/C или PCLint). Использование компилятора с высоким уровнем чувствительности предупреждений является бесплатным вариантом, с гораздо меньшим охватом, чем специализированные инструменты.

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

Если вам нужна проверка времени выполнения, вы можете начать с intializing переменных до значения вне диапазона. Например, -1 для другого значения post. Затем вы можете проверить

#define UNASSIGNED_VALUE -1
    static int number_of_apples = UNASSIGNED_VALUE;
    if (UNASSIGNED_VALUE == number_of_apples)
    {
       // error handling
    }

это не истинная "неинтеллизированная" переменная, но, по крайней мере, вы можете определить, были ли выполнены задания времени выполнения в правовом диапазоне.

Ответ 10

В C целое число принимает значение undefined при его создании. Это означает, что если ваше первое использование этого целого происходит из регистра/места/устройства памяти с 5893872 в нем, это значение этого целого. (Пробег варьируется для компиляции отладки/выпуска.)

Обычным методом борьбы с этим является использование бессмысленного значения по умолчанию:

int number_of_widgets = -1;

... или флаг для указания его состояния:

int number_of_widgets;
int number_of_widgets_assigned = 0;

if (number_of_widgets_assigned)
  do something
else
  do something else
number_of_widgets_assigned = 1;

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

Ответ 11

Проверка того, была ли инициализирована (назначена) переменная, которую вы используете, во время выполнения, как правило, сложна для C. Нет поддержки языка для нее, а информация, доступная во время выполнения, просто недостаточна для идеального обнаружения неинициализированных значений. Инструменты динамического анализа, такие как Valgrind/Memcheck, проходят большую длину (например, отслеживание каждого байта памяти в адресном пространстве процесса, а затем изучение каждого хранилища для отметки байта как интериализованного), чтобы определить, инициализируется ли использование значения и все еще подвержены ложным срабатываниям.

Если вы пытаетесь свести к минимуму такие ошибки в своих программах, инструменты статического анализа, такие как lint, могут сделать достаточно хорошую работу, чтобы информировать вас о том, используете ли вы неинициализированные переменные. На самом деле, я считаю, что большинство компиляторов сделают все возможное, чтобы рассказать вам, когда вы это делаете (хотя они, конечно, не идеальны.)

Ответ 12

В С# я бы использовал:

Nullable<int> i = null; /* null assignment */

if (i == null) {
   printf("Integer is unassigned!\n");
} else {
   printf("Integer is assigned!\n");
}

Не уверен, что это переводится на C.