誰だよ! char に数値が入れられるとか言ったの!
信じてた……信じてたのに……!!
整数型 char の値域は -128~127 で、
小さな値であれば char型 や unsigned char型(0~255) を使えるから、
本によっては、メモリ節約のために使うことを考えよう、と推奨していることもあります。
環境にもよりますが、たいてい、
char : 1 Byte
short int : 2 Byte
int : 4 Byte
float : 4 Byte
double : 8 Byte
ですからね。
単純に考えればint型の4分の1です。
しかししかし、だめでした!
正常に動かないことがあるようです。
以下が書いたコードの全文です。
#include <iostream> using namespace std ; // (x, y) にいる人が 中心 (xc, yc) にある、半径 r_2 の台風の暴風域にいるか判定 // 内側の半径 r_1 は台風の目とする。 bool isThere(char xc, char yc, char r_1, char r_2, char x, char y){ int term = (x - xc) * (x - xc) + (y -yc) * (y-yc) ; if( (r_1) * (r_1) <= term && term <= (r_2) * (r_2) ){ return true ; } return false ; } int main(){ char r_1, r_2 ; // 内側の半径、外側の半径 char n ; // 人数 // 上記の値は 1~100 で与えられる char xc, yc ; // 台風の中心座標 char x[100], y[100] ; // 人物のいる座標 // 上記の値は -100~100 で与えられる cin >> xc >> yc >> r_1 >> r_2 ; cin >> n ; for(char i=0; i<n; ++i){ cout << "test-i_" << i << "\t test-n_" << n << endl ; cin >> x[i] >> y[i] ; } for(char i=0; i<n; ++i){ if( isThere(xc, yc, r_1, r_2, x[i], y[i]) ){ cout << "yes" << endl ; }else{ cout << "no" << endl ; } } }
しかしこれを実行すると、以下のようになります。
実行結果1
0 0 1 2 3 test-i_ test-n_3 0 0 test-i_ test-n_3 1 2 test-i_ test-n_3 3 4 test-i_ test-n_3 1 1 test-i_ test-n_3 2 2 test-i_ test-n_3
ループが終わりません。
終わらない、素敵なループです。
i が表示されないことを不審に思い、for文のところを
for(int i=0; i<n; ++i){
と直してみても……
実行結果2(for文中の i を int に)
0 0 1 2 3 test-i_0 test-n_3 0 0 test-i_1 test-n_3 1 2 test-i_2 test-n_3 3 4 test-i_3 test-n_3 1 1 test-i_4 test-n_3 2 2 test-i_5 test-n_3
やはりダメ。
実のところ、はじめの n の宣言を
short int n ;
とするだけで、このfor文は正しく動くようになります。
実行結果3( n の宣言を short int に)
0 0 1 2 3 test-i_ test-n_3 0 0 test-i_ test-n_3 1 1 test-i_ test-n_3 2 2 no no no
まあ、i の値が表示されないので、やはりfor文の i も short int で宣言するべきですが……。
それに、出力も間違っています。
では、もうあきらめてプログラム中の char はすべて short int に直してしまいましょう。
実行結果4( char ではなく全て short int に)
0 0 1 2 3 test-i_0 test-n_3 0 0 test-i_1 test-n_3 1 1 test-i_2 test-n_3 2 2 no yes no
正しく実行されました。
このように、char で宣言しても、コンソールアウトされなかったり
for文が正しく回らなかったり、正しい計算がされずあせることになります。
これはC++だけで起こることなのかなんなのかわかりませんが、
小さな値でも、せいぜい short int を使うくらいに留めた方がいいようですね。
誰だ char型に数値を代入できると言ったやつは!!
追記:コメントいただきました!
char型にcinで入力する場合、数値ではなく文字として扱われるのが問題ではないでしょうか。
たとえば 3 と入力すると整数値3ではなく文字'3'となるので整数値としては51です。
char型は8bit整数型として使えますよ。
なるほど!
たしかに char型 は通常文字が代入されるものですから、そのような処理になっていると思われます。
というわけで、以下のようにプログラムを書き換えました。
#include <iostream> #include <stdio.h> // scanf を実行させるために必要 using namespace std ; // (x, y) にいる人が 中心 (xc, yc) にある、半径 r_2 の台風の暴風域にいるか判定 // 内側の半径 r_1 は台風の目とする。 bool isThere(char xc, char yc, char r_1, char r_2, char x, char y){ int term = (int)(x - xc) * (x - xc) + (int)(y -yc) * (y-yc) ; cout << term << ", " << (int)(r_1) * (r_1) << endl ; // debug if( (int)(r_1) * (r_1) <= term && term <= (int)(r_2) * (r_2) ){ return true ; } return false ; } int main(){ char r_1, r_2 ; // 内側の半径、外側の半径 char n ; // 人数 // 上記の値は 1~100 で与えられる char xc, yc ; // 台風の中心座標 char x[100], y[100] ; // 人物のいる座標 // 上記の値は -100~100 で与えられる // cin >> xc >> yc >> r_1 >> r_2 ; // cin >> n ; scanf("%d %d %d %d", &xc, &yc, &r_1, &r_2) ; scanf("%d", &n) ; printf("r_1 = %d \n", r_1) ; // debug for(char i=0; i<n; ++i){ cout << "test-i_" << i << "\t test-n_" << n << endl ; // cin >> x[i] >> y[i] ; scanf("%d %d", &x[i], &y[i]) ; } for(char i=0; i<n; ++i){ if( isThere(xc, yc, r_1, r_2, x[i], y[i]) ){ cout << "yes" << endl ; }else{ cout << "no" << endl ; } } }
ところが残念なことに、
実行結果 a1
0 0 1 2 3 r_1 = 0 test-i_ test-n_ 0 0 test-i_ test-n_ 1 1 test-i_ test-n_ 2 2 0, 0 yes 2, 0 no 8, 0 no
と、 r_1 の値が読み込まれず正しい実行結果となりません。
scanf("%d%d", &xc, &yc) ;
scanf("%d%d", &r_1, &r_2) ;
と、入力部分を直してみても同じ結果です。
うーん、なぜなんだ・・・。
今のところの結論としては、C++の手法で書けなくなり複雑になりますし、
インプットを求める場合は char を使わないのが無難ですね。