ページ 1 / 1
異なる型に変数を変換する
Posted: 2017年3月23日(木) 22:11
by Hiragi(GKUTH)
いつもお世話になっております。
今回はC/C++の初歩的な質問になります。
文に起こし辛いのでソースで示しますと、
コード:
void hoge(int *i,int *ii,int *iii)
{
*i = 0;
*ii = 0;
*iii = 0;
}
void hogehoge()
{
float f,g,h;
hoge(&f,&g,&h); //ココ
}
このようにすると呼び出し側から*float -> *int の変換は出来ない、と怒られてしまいます。
関数hogehogeの変数f,g,hを*intに変換する方法は無いのでしょうか?
コード:
void hoge(int *i,int *ii,int *iii)
{
*i = 0;
*ii = 0;
*iii = 0;
}
void hogehoge()
{
float f,g,h;
int seisu1,seisu2,seisu3;
hoge(&seisu1,&seisu2,&seisu3);
f = (int)seisu1,g = (int)seisu2,h = (int)seisu3;
}
このようにすれば動作するでしょうが、もう少し良い書き方は無いでしょうか。
学習の過程でこのような場面に出くわしたので気になって投稿させて頂きました。よろしくお願いします。
Re: 異なる型に変数を変換する
Posted: 2017年3月23日(木) 22:31
by inemaru
スマートかと言われると微妙ですが
キャストを呼ばないで済む方法として、共用体を使用するのはどうでしょうか?
コード:
void hoge(int *i, int *ii, int *iii)
{
*i = 0;
*ii = 0;
*iii = 0;
}
void hogehoge()
{
// float f, g, h;
// hoge(&f, &g, &h); //ココ
union{
struct{ float f, g, h; };
struct{ int seisu1, seisu2, seisu3; };
}data;
hoge(&data.seisu1, &data.seisu2, &data.seisu3);
}
Re: 異なる型に変数を変換する
Posted: 2017年3月23日(木) 23:18
by zeek
inemaru さんが書きました:
// float f, g, h;
// hoge(&f, &g, &h); //ココ
union{
struct{ float f, g, h; };
struct{ int seisu1, seisu2, seisu3; };
}data;
[/code]
float と int の共用体に何の意味があるというのでしょう?
sizeof(float) と sizeof(int) が同じ保証はない上に、同じ size であったとしても int で代入した値を float で読み出したらデタラメな値になるでしょう。
共用体は自動的にキャストしてくれるわけではないよ。
Re: 異なる型に変数を変換する
Posted: 2017年3月23日(木) 23:44
by inemaru
キャストを呼ばない という文言が誤解を招きますね。
意味的には、アドレスのキャストを指していますが、zeek さんの指摘は理にかなっています。
Hiragi(GKUTH) さんが書きました:
このようにすると呼び出し側から*float -> *int の変換は出来ない、と怒られてしまいます。
関数hogehogeの変数f,g,hを*intに変換する方法は無いのでしょうか?
先ほどの回答は、
float*をint*に変換できないということを観点に回答しました。
論点がずれていたのなら申し訳ない。
intで取得された値をfloatに変換したいとなると、キャストは必要です。
zeek さんが書きました:
sizeof(float) と sizeof(int) が同じ保証はない上に、同じ size であったとしても int で代入した値を float で読み出したらデタラメな値になるでしょう。
共用体は自動的にキャストしてくれるわけではないよ。
型の事を気にしていないのは、前述したとおりの理由です。
サイズに関して、気にするのであれば下記のコードを追加すればよいでしょう。
コード:
static_assert(sizeof(int) == sizeof(float), "int型とfloat型のサイズは同じです");
[hr]
(追記)
型の違いを考慮した回答です。
コード:
template <class Type>
void hoge(Type* i, Type* ii, Type* iii)
{
*i = 0;
*ii = 0;
*iii = 0;
}
void hogehoge()
{
float f, g, h;
hoge(&f, &g, &h);
}
Re: 異なる型に変数を変換する
Posted: 2017年3月24日(金) 00:26
by zeek
inemaru さんが書きました:
intで取得された値をfloatに変換したいとなると、キャストは必要です。
でも共用体を使ったらどうやってキャストするの?
// hoge(&f, &g, &h); //ココ
hoge((int*)&f, (int*)&g, (int*)&h);
とせずに共用体を提示するメリットを考えると
hoge((int*)&f, (int*)&g, (int*)&h); とした場合は、(float 変数の領域に int の形式で書き込まれるから float 値に意味はないでしょう)、sizeof(int) > sizeof(float) であればどこかを壊してしまうかもしれない危険なコードだが、共用体を使えば共用体以外の領域は壊さないというメリットがあることはあるね。
float 変数から読み出す float 値に意味がない時点でコードの価値を見出せないが...
Re: 異なる型に変数を変換する
Posted: 2017年3月24日(金) 00:40
by inemaru
zeek さんが書きました:inemaru さんが書きました:
intで取得された値をfloatに変換したいとなると、キャストは必要です。
でも共用体を使ったらどうやってキャストするの?
共用体を使ってキャストするとは、書いていませんよ。
言葉通りの意味です。
zeek さんが書きました:
float 変数から読み出す float 値に意味がない時点でコードの価値を見出せないが...
価値や意味なんて、質問者さんにしかわかりませんが、
floatをintとして扱った場合の値がわかりますね。
オフトピック
とはいえ、質問内容的に、それはないだろ って話なのは理解しています。
質問の受け取り方は、人それぞれということで。
駄文回答をしてしまい、質問者さん申し訳ない。
以降の回答は控えます。
Re: 異なる型に変数を変換する
Posted: 2017年3月24日(金) 09:44
by Hiragi(GKUTH)
返信ありがとうございます。私の質問意図が不明で的確な回答ができずにいるようで、申し訳ありません。
具体的にしたいことはDxLibに
GetMousePointや
GetTouchInputなる関数があり、渡す値の型として*int型が指定されています。
現在スマホ向けのゲームのような物を学習の一環として作成しており、プレイヤーの座標にfloat型を使用しています。タップされた座標をプレイヤーの座標に反映したく
コード:
void Player::Move()
{
GetTouchInput(0,&x,&y,NULL,NULL);//x,yはfloat型のためエラー発生
}
のように書きましたが、見てのとおり*float -> *intは勝手には(変数の値の整合性を保ちつつ)変換してくれないため、このような質問をいたしました。
プレイヤーの座標の変数の型をintにすれば一発解決ですが... 最初の質問にある通り、気になったので質問したという意味合いが強いです。色々誤解させてしまい申し訳ないです。
Re: 異なる型に変数を変換する
Posted: 2017年3月24日(金) 10:01
by usao
オフトピック
int*を引数とする関数hoge()が既に存在していてそれを利用したい( hoge()は変更できない)のだけども,
その出力を "float 型の変数f,g,h" に格納したい(変数の型も変更できない)
という状況での話であれば,結局,それを行う関数を書くのが素直かな,と思う.
やってることは何もかわらないから,回答にならないけれど……
コード:
void hogef( float *pf, float *pg, float *ph )
{
int i_f, i_g, i_h;
hoge( &i_f, &i_g, &i_h );
*pf = i_f;
*pg = i_g;
*ph = i_h;
}
Re: 異なる型に変数を変換する
Posted: 2017年3月25日(土) 10:48
by Hiragi(GKUTH)
>>usaoさん
回答ありがとうございます。おとなしくそう言う関数を定義したほうが良さそうですね、キャスト変換のようにさっと変換できる方法が存在しない事が
分かっただけでも十分です。 ありがとうございました。