переменная определена в переключателе в C - PullRequest
0 голосов
/ 04 апреля 2019

Когда я пытался назначить указатель в операторе switch,
Компиляция выдала мне предупреждение об ошибке, но когда я отладил код, объявив
указатель вне оператора switch. Код
синтаксически передан. Зачем? Кто-нибудь может мне это объяснить? Спасибо!

До того, как я отладил:

void Left_Balance(treeNode **T)
{
    treeNode *p=(*T)->left;  
    switch(p->bf)
    {
        case LH:
            p->bf=(*T)->bf=EQ;
            L_Rotate(T);
            break;
        case RH:
             treeNode *q = p->right;  
            switch(q->bf)
           {
               case LH:
                   (*T)->bf=RH;
                   p->bf=EQ;
                   break;
               case EQ:
                   (*T)->bf=q->bf=EQ;
                   break;
               case RH:
                   p->bf=LH;
                   (*T)=EQ;
                   break;
           }
            q->bf=EQ;
            R_Rotate(&p);
            L_Rotate(T);
            break;
    }
}

После того, как я отладил:

void Left_Balance(treeNode **T)
{
    treeNode *p=(*T)->left;
    treeNode *q;     //Here is the difference 
    switch(p->bf)
    {
        case LH:
            p->bf=(*T)->bf=EQ;
            L_Rotate(T);
            break;
        case RH:
            q = p->right;    //Here is the difference 
            switch(q->bf)
           {
               case LH:
                   (*T)->bf=RH;
                   p->bf=EQ;
                   break;
               case EQ:
                   (*T)->bf=q->bf=EQ;
                   break;
               case RH:
                   p->bf=LH;
                   (*T)=EQ;
                   break;
           }
            q->bf=EQ;
            R_Rotate(&p);
            L_Rotate(T);
            break;
    }
}

Ответы [ 2 ]

1 голос
/ 04 апреля 2019

в вашей первой версии treeNode *q = p->right; не в блоке ({})

другой возможностью было добавить этот блок

    case RH:
  {
    treeNode *q = p->right;  
        switch(q->bf)
       {
           case LH:
               (*T)->bf=RH;
               p->bf=EQ;
               break;
           case EQ:
               (*T)->bf=q->bf=EQ;
               break;
           case RH:
               p->bf=LH;
               (*T)=EQ;
               break;
       }
        q->bf=EQ;
        R_Rotate(&p);
        L_Rotate(T);
        break;
  }

Предупреждение

 (*T)=EQ;

очень подозрительно, потому что *T - это treeNode *, а EQ - не один из-за case EQ

Возможно, вы хотите

 (*T)->bf = EQ;

(edit)

Поскольку @dbush указывает, что достаточно добавить оператор между меткой и объявлением, но не помещать объявление в блок очень опасно, посмотрите на этот код:

#include <stdio.h>

int main(int argc, char ** argv)
{
  switch (argc) {
  case 1:
    puts("case 1");

    int i = 123;

    puts("i initialized and continue in case 2");

  case 2:
    printf("in case2, i values : %d\n", i);
  }

  return 0;
}

Как насчет i , используемого в printf , если программа вызывается с аргументом, инициализирующим argc , равным 2?

Примечание gcc принимает этот код, но не g ++ без опции -fpermissive, и с этой опцией код компилируется без case 2:

Вот почему япредложил добавить блок.

0 голосов
/ 04 апреля 2019
    case RH:
         treeNode *q = p->right;  

Здесь у вас есть ярлык прямо перед объявлением . Метка может появляться только перед оператором . Это можно исправить, добавив пустой оператор непосредственно перед объявлением, с которым может быть связан ярлык:

    case RH:
         ;
         treeNode *q = p->right;  
...