10進数を16進数に変換するプログラム
AtCoderで「0~255の整数を2桁の16進数表記に変換してください」という問題を解いていました。
問題:
0 以上 255 以下の整数 N を、必要に応じて先頭に 0 を加えることでちょうど 2 桁の 16 進表記に変換してください。(AtCoder Biginner Contest271より引用)
問題は無事に解答できました。
さらに練習として、問題にある整数の範囲0~255よりも広い 10桁以内の10進数から16進数に変換するプログラム を書いてみたので、自分用メモとして残しておきます。
文字列終端の確認
#include <stdio.h>
int main(void)
{
char str[5] = {'a', 'b', '\0', 'd', '\0'};
printf("%s\n", str);//ab(dは表示されない)
printf("%c\n", str[2]);//(何も表示されない)
str[2] = '0';
printf("%s\n", str);//ab0d
printf("%c\n", str[2]);//0(文字0が表示される)
str[2] = NULL;
printf("%s\n", str);//ab(dは表示されない)
printf("%c\n", str[2]);//('\0'は何も表示されない)
}
調べてみると、'\0'
は文字という値ですが、NULL
はポインタという別物のようです。
多くのコンピュータでは '\0' も NULL も同じ値(ビットフィールドがすべて 0 である)として扱われているため正しく動作しますが、 正確に文法をチェックすると間違ったプログラムとなります。(コンパイラによってはWarningを出します。)
(コンピュータによっては、NULLをビットフィールドをすべて 0 としていないものもあるようです)
まだポインタについて勉強できていませんが、現時点では文字列の終端には\0を使うのがいいということが分かりました。
16進数に変換するプログラム
方針:
・変換用に一時的に使うテンポラリ変数(temp)を用意する
・変換したい10進数をテンポラリ変数に代入する
・テンポラリ変数が0になるまで以下の処理を繰り返す:
16のx乗の位 = テンポラリ変数 % 16
テンポラリ変数 = 現在のテンポラリ変数 / 16
最初は、ループ条件(whileの部分)をループ処理の内容よりも先に書いていたため、10進数の値が0のとき一度も処理がされずに答えが「無」になってしまいました。そこでdo {処理} while (temp != 0);
という順番にすることで対応しました。
文字列(char配列)の終わりのしるしとして\0
を入れる
(このため配列の長さは文字数より1多くなる)
特定の文字コードを文字型に代入したいときは、char変数名 = '文字';
という風にシングルクオーテーション'
で文字を囲んで表現する
#include <stdio.h>
int main(void)
{
int n, i, j, temp;
int num[10];
char answer[10];
//入力を受け取る
scanf("%d", &n);
//各桁の値を求める(num[0]が1の位)
i = 0;
temp = n;
do {
num[i] = temp % 16;
temp = temp /16;
i++;
} while (temp != 0);
//値が10以上になる桁をA~Fに変換する(answer[i-1]が1の位)
for (j = 0; i > j; j++) {
if (num[i - j - 1] > 9) {
answer[j] = num[i - j - 1] + 'A' - 10;
}
else {
answer[j] = '0' + num[i - j - 1];
}
answer[j + 1] = '\0';
}
//出力する
printf("16進数に変換すると %s です\n", answer);
}
2022/10/5実施
参照先:AtCoder
今後の課題
・文字コード(A~F)を代入するときのスムーズな方法
・16進数に直したint型配列(num)がchar型配列(answer)と桁の並び順が逆になっていて分かりづらい