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

Что делает только ";" внутри блока "if" означает?

Зачем кому-то это использовать?

if(a==1){;} 

Нет инструкции, только одна точка с запятой, и она не выдает ошибку. Какую цель выполняет эта точка с запятой?

4b9b3361

Ответ 1

Это пустое утверждение. Одна точка с запятой сама по себе не выполняет никаких операций.

В этом контексте это означает, что если условие if истинно, ничего не делать.

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

В этом случае это простой условный, поэтому по стилю он, вероятно, лучше инвертировать его, однако, если условие более сложное, может быть яснее написать этот путь. Например, это:

if ((a==1) && (b==2) && (c==3) && (d==4)) {
    ;
} else {
    // do something useful
}

Может быть яснее, чем это:

if (!((a==1) && (b==2) && (c==3) && (d==4))) {
    // do something useful
}

Или это:

if ((a!=1) || (b!=2) || (c!=3) || (d!=4)) {
    // do something useful
}

Лучший пример из комментариев (спасибо Бен):

if (not_found) {
    ;
} else {
    // do something
}

Versus:

if (!not_found) {
    // do something
}

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

Другим примером того, когда вы можете использовать это, является то, что у вас есть набор операторов if..else для проверки диапазона значений и вы хотите документировать в коде, что ничего не должно происходить для определенного диапазона:

if (a < 0) {
    process_negative(a);
} else if (a >=0 && a < 10) {
    process_under_10(a);
} else if (a >=10 && a < 20) {
    ;   // do nothing
} else if (a >=20 && a < 30) {
    process_20s(a);
} else if (a >= 30) {
    process_30s_and_up(a);
}

Если пустой if был опущен, читатель мог бы задаться вопросом, должно ли что-то произошло там, и разработчик забыл об этом. Включая пустой if, он говорит читателю: "Да, я объяснил это, и в этом случае ничего не должно произойти".

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

Ответ 2

Он вызвал нулевой оператор.

Из 6.8.3 Выражения и нулевые утверждения:

Оператор null (состоящий только из точки с запятой) не выполняет никаких операции.

В этом конкретном примере if(a==1){;} он не делает ничего полезного (кроме, возможно, более очевидного), так же как if(a==1){} или if(a==1);.

Ответ 3

Никакой цели вообще. Это пустое утверждение. Возможно, разработчик хотел что-то сделать, если a не был 1, и в этом случае код был бы чем-то вроде (даже если ; можно опустить):

if(a==1)
{
  ;
}
else
{
  //useful code...
}

Но в этом случае его можно было бы легко записать как if(a != 1).


Обратите внимание, что если это С++ (теги еще не ясны), тогда существует вероятность перегрузки operator== типа a, и некоторые побочные эффекты могут быть обнаружены. Это означало бы, что код безумный, хотя.

Ответ 4

Это так называемый оператор null. Это своего рода выражение, в котором выражение отсутствует.

Иногда он используется в операторах if-else, как вы показали, когда легко записать условие if, чем его отрицание (или условие if более понятно), но код должен выполняться, когда условие if оценивается как false.

Например

if ( some_condition )
{
   ; // do nothing
}
else
{
   // here there is some code
} 

Обычно оператор null используется для изложения только для того, чтобы показать, что, например, тело функции или конструктор класса или цикл for пуст. Например

struct A
{
    A( int x ) : x( x )
    {
        ;
    }

    //...
};

или

char * copy_string( char *dsn, const char *src )
{
    char *p = dsn;

    while ( ( *dsn++ = *src++ ) ) ;
                                 ^^^
    return p;
}

Здесь нулевой оператор требуется для цикла while. Вы также можете переписать его как

    while ( ( *dsn++ = *src++ ) ) {}

Иногда нулевой оператор требуется особенно в редких случаях, когда используется инструкция goto. Например, в объявлениях C нет утверждений. Если вы хотите передать управление программой в точку перед некоторым объявлением, вы можете поместить ярлык перед объявлением. Однако в C метка может быть помещена только перед оператором. В этом случае вы можете поместить нулевой оператор с меткой перед объявлением. Например

Repeat:;
      ^^^
    int a[n];

    //....

    n++;
    goto Repeat;

Обратите внимание на нулевую инструкцию после метки. Если его удалить, то компилятор C выдаст ошибку.

Этот трюк также используется для передачи управления программой в конец составного оператора. Например

{
   // some code
    goto Done;
   //...

   Done:;
}

Хотя вы не должны использовать инструкцию goto, но вы должны знать об этих случаях.:)

Ответ 5

Как говорили многие, он ничего не делает.

Почему он там? Вот возможность...

Я устал от плохих кодеров в моей команде, не проверяя возвращаемые значения функций.

Итак, поскольку мы разрабатываем в Linux с компилятором GCC, я добавляю __attribute__((warn_unused_result)) к объявлению всех моих типизированных функций. См. Также этот вопрос для эквивалента MS VC.

Если пользователь не проверяет возвращаемое значение, компилятор генерирует предупреждение.

Ковбои, конечно же, играли в систему и код if (foo() != SUCCESS) ;, который удовлетворяет компилятору (хотя он не удовлетворяет мне: -).

Ответ 6

Единственный ; - это нулевой оператор, который ничего не делает. Он часто используется в длинных цепочках if/else, например:

if (a == 1) {
    // Do nothing.
    ;
}
else if (...) {
    ...
}
else if (...) {
    ...
}

Это также можно записать как:

if (a != 1) {
    if (...) {
        ...
    }
    else if (...) {
        ...
    }
}

Последний добавляет еще один уровень отступов, но IMO, это яснее. Но null-инструкции иногда могут быть полезны, чтобы избежать чрезмерного отступа, если существует несколько ветвей без кода.

Обратите внимание, что пустой составной оператор (также называемый блоком) имеет тот же эффект:

if (a == 1) {}

Технически вам нужна точка с запятой, если вы хотите напрямую использовать оператор выражения:

if (a == 1) ;
else if (...) { ... }
else if (...) { ... }

Таким образом, запись {;} является избыточной и служит лишь для сомнительной иллюстративной цели.

Другой пример из стандарта C, где оператор null используется для подачи пустого тела цикла:

char *s;
/* ... */
while (*s++ != '\0')
    ;

Но здесь я также предпочел бы пустое составное утверждение.

Ответ 7

Это в основном оператор null/empty, который делает ничего и, как и ожидалось, доброкачественный (без ошибок) характер.

C Проект черновика N1570 поясняет, что:

  • выражения необязательны: выражение [opt];
  • Оператор null (состоящий только из точки с запятой) не выполняет никаких операций.

С другой стороны, Bjarne цитирует в своей книге на С++ #9.2 Statement Summary:

Точка с запятой - это оператор, пустой оператор.

Обратите внимание, что эти два кода if(1) {;} и if(1) {} имеют нет разницы в сгенерированных инструкциях gcc.

Ответ 8

; сам по себе является пустой инструкцией. Если a является инициализированным не указательным типом, то

if(a==1){;}

всегда является no-op в C. Использование фигурных скобок добавляет дополнительный вес к утверждению о том, что нет опечатки. Возможно, под ним находится else, который будет выполняться, если a не был 1.

Ответ 9

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

Обычно, хотя я делаю это очевидным, отметка отладки

if( (a==1) && (b==2) && (c==3) && (d==4) ){

  int debug=1;

}

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

Но это не гарантирует, что это было.

Ответ 10

; это пустой оператор noop

В чем его цель?

Иногда мы просто хотим сравнить вещи, как в этом случае, равенство a и 1. С примитивными типами, такими как integer, это установит регистр условий, если вы после этого, если что-то вроде if (a > 1) или if ( a < 1) и a не изменяется в то же время, это может не быть оценено снова в зависимости от решения компилятора.

Этот код

 int f(int a){
        if(a == 1){;}
        if(a > 1){return 3;}
        if(a < 1){return 5;}

        return 0;
 }

даст

.file   "c_rcrYxj"
.text
.p2align 2,,3
.globl  f
.type   f, @function
f:
.LFB0:
    .cfi_startproc
    cmpl    $1, 4(%esp)
    jle .L6
    movl    $3, %eax
    ret
    .p2align 2,,3
.L6:
    setne   %al
    movzbl  %al, %eax
    leal    (%eax,%eax,4), %eax
    ret
    .cfi_endproc
 .LFE0:
.size   f, .-f
.ident  "GCC: (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4"
.section    .note.GNU-stack,"",@progbits

Сравнение выполняется только один раз cmpl $1, 4 (% esp), где именно (a == 1) записано.

Ответ 11

Вероятно, вы уже знаете, что точка с запятой - это пустой оператор. Что касается фактического вопроса: "Какая цель служит этой точкой с запятой", то ответ будет (если автор этого кода не захотел оживить код каким-то странным смайликом), что он служит абсолютно цели вообще. То есть {;} полностью эквивалентен {} в любом контексте (где ожидается утверждение, которое, я думаю, является единственным местом, где {;} можно использовать). Присутствие точки с запятой изменяет составной оператор с 0 составными операторами в составной оператор с одним составным выражением, который является пустым оператором, но оба случая эквивалентны по отношению к семантике.

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