C言語関係掲示板

過去ログ

No.556.switch内での変数の初期化

[戻る] [ホームページ]
No.5017

switchについて
投稿者---mana(2003/02/05 20:49:46)


前にも投稿させてもらったんですがswitchの所でエラーがでるんです。
なぜかわかりません。
Borland c++使用
キーボードの早撃ちプログラムを作っているところなんですが・・・

#include<conio.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>


  void nyuryoku(char bb[]);

    char a[256];

main()
{
   int i,j=0;
   char b[256];
   char start[10];
   char end[]="END";
   time_t time1;
   time_t time2;
   double timer;

//   srand((unsigned)time(NULL));
   printf("エンターキーを押してください(END入力で終了します)\n") ;
   gets(start);
  if( strcmp(start,end)==0){
          return 0;
          }
     time(&time1);
     while(1){

     if(j>=2)
        break;
     i=(rand()%3+1);
     j++;
   switch(i){
         case 1:
                printf("東京特許許可局:toukyoutokkyokyokakyoku\n");
                char *p="toukyoutokkyokyokakyoku";
                nyuryoku(p);
                break;
         case 2:
                printf("生麦生米生卵:namamuginamagomenamatamago\n");
                char *ppp="namamuginamagomenamatamago";
                nyuryoku(ppp);
                break;
         case 3:
                printf"隣の客はよく柿食う客だ:tonarinokyakuhayokukakikuukyakuda\n");
                char *pppp="tonarinokyakuhayokukakikuukyakuda";
                nyuryoku(pppp);
                break;
//         case 4:
//         case 5:
//         case 6:
//         case 7:
//         case 8:
//         case 9:
//         case 10:
           default: printf("もう一回\n");

         }
  }

  timer=difftime(time(NULL),time1);
  printf("%.0f秒かかりました。\n",timer);
  getch();
}


  void  nyuryoku(char *pp)
{
       int mozi,a=0;

       while(*pp!=NULL){
       if(*pp==(char) getch()){
             printf("%c",*pp++);
          }
          else{
          printf("\a");
          }
       }
       printf("\n");

}


No.5018

Re:switchについて
投稿者---雪猫(2003/02/05 21:03:38)


エラー画面から脱出できない雪猫です(><;

え〜と、case3:の個所のprintf();ありますよね?
そこの「( 」が足りないと思うのですが?

printf"隣の客はよく柿食う客だ:tonarinokyakuhayokukakikuukyakuda\n");

この文の「隣」の左ですね。

間違っていたらごめんなさいm(__)mペコリ

No.5019

Re:switchについて
投稿者---mana(2003/02/05 21:20:28)


すいません。そこは無視してください。括弧をつけたんですがまだエラーがでます。どうもcase 2,case 3,defaultの所でエラーが出るんです。なんでだろ〜。

No.5020

Re:switchについて
投稿者---みゃあ(2003/02/05 22:13:37)


switch(i){
         case 1:
           {
                printf("東京特許許可局:toukyoutokkyokyokakyoku\n");
                char *p="toukyoutokkyokyokakyoku";
                nyuryoku(p);
           }
                break;
         case 2:
           {
                printf("生麦生米生卵:namamuginamagomenamatamago\n");
                char *ppp="namamuginamagomenamatamago";
                nyuryoku(ppp);
           }
                break;
         case 3:
           {
                printf("隣の客はよく柿食う客だ:tonarinokyakuhayokukakikuukyakuda\n");
                char *pppp="tonarinokyakuhayokukakikuukyakuda";
                nyuryoku(pppp);
           }
                break;
//         case 4:
//         case 5:
//         case 6:
//         case 7:
//         case 8:
//         case 9:
//         case 10:
           default: printf("もう一回\n");

         }

のように中括弧でくくるとできると思います。

No.5022

Re:switchについて
投稿者---とま(2003/02/05 22:34:30)


エラーは、どう出るんですか。
それも書けば答える方も楽だと思います。

ちなみに、私がソースを見て思ったのは、
switch内で変数を宣言するのはまずくないですか。
Cだと変数は、先頭で宣言するはずだった気がするのですが・・・

No.5026

Re:switchについて
投稿者---mana(2003/02/06 09:47:25)


どうもありがとうございました。うまくいきました。


No.5045

Re:switchについて
投稿者---ともじ(2003/02/06 22:30:35)


こんばんは。少々整理してみようと思います。

manaさんの環境はBorland c++とのことですから、
C言語でも、C++でもコンパイルが可能です。

まず、ソースの拡張子を.cにした場合、
	switch(i){
         case 1:	char *p="abc"; 
		func(p);
		break;
         case 2:	char *pp="def"; 
		func(pp);
		break;
         case 3:	char *ppp="hij"; 
		func(ppp);
		break;
	}
では、変数の宣言場所が正しくないのでエラーになります。
C言語では、関数のブロックも含め、ブロック内では変数の宣言は
実行文よりも先でなければいけないからです。
ですから、{}で囲んで新たなブロックを作れば、新たな変数を宣言
することができます。この場合、変数の有効範囲はブロック内と
なります。つまり、
	switch(i){
         case 1:{
		char *p="abc"; 
		func(p);
	       }
	       break;
         case 2:{
		char *pp="def"; 
		func(pp);
	       }
	       break;
         case 3:{
		char *ppp="hij"; 
		func(ppp);
	       }
	       break;
	}

は正しくコンパイルされます。

一方、拡張子を.cppとした場合は、
	switch(i){
         case 1:	char *p;
		p="abc"; 
		func(p);
		break;
         case 2:	char *pp;
		pp="def"; 
		func(pp);
		break;
         case 3:	char *ppp;
		ppp="hij"; 
		func(ppp);
		break;
	}
はコンパイルすることができます。これは、C++では任意の箇所で
宣言を書くことができるからです。しかし、C++でも、
	switch(i){
         case 1:	char *p="abc"; 
		func(p);
		break;
         case 2:	char *pp="def"; 
		func(pp);
		break;
         case 3:	char *ppp="hij"; 
		func(ppp);
		break;
	}

caseの中で変数の宣言と初期化を行うことはできません。
(caseの中以外では宣言と初期化は任意の場所で行うことができます。)
これは、自動変数の初期化はプログラムの処理が走って始めて行われる
ものなので、case中で行うと、初期化が条件によって行われたり、行われ
なかったりするので、支障があると言うことなのだと思います。

ただし、この場合でも新たなブロックを作れば、初期化は可能になります。
	switch(i){
         case 1:{
		char *p="abc"; 
		func(p);
	       }
	       break;
         case 2:{
		char *pp="def"; 
		func(pp);
	       }
	       break;
         case 3:{
		char *ppp="hij"; 
		func(ppp);
	       }
	       break;
	}

ブロック内で宣言された変数は、ブロック内でのみ有効なので、
ブロックを越えて使用されることがないからです。

さて、manaさんの例ですが、変数を*p、*ppp、*pppppと分けずに、
*pのみにし、最初に宣言、case中では代入のみでいいと思いますが、
いかがでしょう。

   char *p;
	:
   switch(i){
         case 1:
                printf("東京特許許可局:toukyoutokkyokyokakyoku\n");
                p="toukyoutokkyokyokakyoku";
                nyuryoku(p);
                break;
         case 2:
                printf("生麦生米生卵:namamuginamagomenamatamago\n");
                p="namamuginamagomenamatamago";
                nyuryoku(p);
                break;
         case 3:
                printf"隣の客はよく柿食う客だ:tonarinokyakuhayokukakikuukyakuda\n");
                p="tonarinokyakuhayokukakikuukyakuda";
                nyuryoku(p);
                break;
	:



No.5054

Re:switchについて
投稿者---mana(2003/02/07 16:41:08)


どうもありがとうございました。よくわかりました。