ベストアンサー
>??の部分のソースコードが分かりません。 「C言語独学中の初心者」ということですが、この質問の問題は、テキストなどに書かれていたものですか? まったくの自作ですか? テキストに書かれていたのなら、後述する回答のように、正しくはmainよりも先にPrintHexを定義する必要があるのに、順番が逆です。 このことも、「コンパイルエラーが出るので、自分で原因を調べ、関数の方をmainよりも先に書くべきことを見つけなさい。」という、問題の一部なのかもしれません。 >教えて頂きたいです 中身を考える為、10進数892が入力された場合を考えます。 ●入力された10進数値と、16進数と、表示する文字の関係 892÷16=商55、余り12 「余り12」は、「10→A、11→B、12→C」なので16進数C。 55÷16=商3、余り7 3÷16=商0、余り3 上記により、892の16進数は37C。 「商」は、整数どうしの割り算で計算。163/16は10。 「余り」は、剰余算の演算子%で計算。163%16は3。 計算で求めた余り「12、7、3」を、表記するASCII文字”C"、”7”、”3”にする処理は、次で行う。 余りが0~9→下記のASCII表の「10進」と「ASCIIの0から9」の関係を見極める→数+48 余りが10~15→下記のASCII表の「10進」と「ASCIIのAからF」の関係を見極める→数+55 ●入力された10進数値を、16進数の文字に変換する処理 余りが0~9の時は「+48」、10~15なら「+55」にように切り替える方法は、次の3つだけでなく、他にもある。 1)if文で余りを判別し、48を足すか55を足すか、処理を分ける。 2)3項演算子「(条件式)?TRUE時の処理:FALSE時の処理」を使う。具体的には、配列要素str[i]なら ( (AMARI=num%16)<10) ? (str[i]=AMARI+48) : (str[i]=AMARI+55) ); 3)余りを10で割った結果は、余りが0~9なら0、余りが10~15なら1になるので、その値変数Moji_offsetセット。余りに定数48を足し、さらにMoji_offset*7も足すことで、48を足すか55を足すか区別する。 ●表示する文字を作り、配列strに格納する処理 ここでは、16進数4文字をstrに格納する処理に、上記の2番目を使う。 配列要素str[0]、str[1]、str[2]、str[3]、str[4]への文字格納は、str[3]からstr[0]に向かって行い、str[4]にはヌルを格納。ループは、i=3からi=0まで、iを1ずつ減らしながら反復する。 ((AMARI=num%16)<10) ? (str[i]=AMARI+48) : (str[i]=AMARI+55); 1サイクル後のnumの更新は、「num=num/16;」。 ●ロジックの確認(エラー処理) str配列は、「4文字+終端1配列要素」なので、16進数5文字以上ならstrで表せないから、リターン値に-1を返さねばならない。 16進数4桁の最大値FFFF→10000-1→10進数値は16⁴-1=65535 よって、PrintHexに追加するエラー判定は if (65535 < num) { return -1; } 本来は、負値エラーと、値のオーバーエラーとを区別するため、-2を返したいが、メインは-1との比較チェツクしかしていないため、-1にする。 添付図 (クリックで拡大表示される)
おまけ。 ●コーディングについて 変数AMARIを使わず、次のようにも書ける。 ((num%16)<10) ? (str[i]=(num%16)+48) : (str[i]=(num%16)+55); そうしなかったのは、「演算回数は少なくしたい」というクセにしたがっただけで、この程度の処理なら、その都度演算しても実際上の問題はない。 また、演算子そのものに優先順位があるので、上記のようにカッコだらけにしなくても良いのだろうが、多く使うのもクセ。 ●実行例 添付図の、緑は正しい入力値と出力 赤は不正な入力とエラーメッセージ 添付図
質問者からのお礼コメント
またお願いします!ありがとうございます!
お礼日時:1/25 17:26