開発環境
- OS X Lion - Apple(OS)
- Emacs、BBEdit - Bare Bones Software, Inc. (Text Editor)
- プログラミング言語: C
- Clang (コンパイラ)
プログラミング言語C 第2版 ANSI規格準拠 (B.W. カーニハン D.M. リッチー (著)、 石田 晴久 (翻訳)、共立出版)の第3章(制御の流れ)、3.6(do-while)の演習 3-4、3-5、3-6を解いてみる。
その他参考書籍
- プログラミング言語Cアンサー・ブック 第2版 (クロビス・L.トンド、スコット・E.ギンペル(著)、矢吹 道郎(翻訳))
演習 3-4.
int型の最大値は2^(wordsize - 1) - 1だけど、負の数-(2^wordsize-1)はコードの
n = -n
の部分で正の数に変換するとき2^(wordsize - 1)となり最大値を超えてしまうから処理できない。
修正。
コード
sample.c
#include <stdio.h> #include <string.h> void itoa(int n, char s[]); int main() { char s1[1000], s2[1000], s3[1000], s4[1000], s5[1000]; int a = -123456789, b = -987654321, c = 2147483647, d = -2147483648, e = -0; itoa(a, s1); itoa(b, s2); itoa(c, s3); itoa(d, s4); itoa(e, s5); printf("%d 文字列: %s\n", a, s1); printf("%d 文字列: %s\n", b, s2); printf("%d 文字列: %s\n", c, s3); printf("%d 文字列: %s\n", d, s4); printf("%d 文字列: %s\n", e, s5); return 0; } void itoa(int n, char s[]) { int i, sign, m; void reverse(char s[]); sign = n; i = 0; do { m = n % 10; if ( m < 0 ) m *= -1; s[i++] = m + '0'; } while ((n /= 10) != 0); if (sign < 0) s[i++] = '-'; s[i] = '\0'; reverse(s); } void reverse(char s[]) { int c, i, j; for (i = 0, j = strlen(s) - 1; i < j; i++, j--) { c = s[i]; s[i] = s[j]; s[j] = c; } }
入出力結果(Terminal)
$ ./a.out -123456789 文字列: -123456789 -987654321 文字列: -987654321 2147483647 文字列: 2147483647 -2147483648 文字列: -2147483648 0 文字列: 0 $
intの範囲はこちらの方法で取得。
演習3-5.
コード
sample.c
#include <stdio.h> #include <string.h> void itob(unsigned int n, char s[], int b); int main() { char s1[1000], s2[1000], s3[1000], s4[1000], s5[1000], s6[1000], s7[1000], s8[1000]; int a = 100, b = 2147483647, c = -2147483648, d = -0; itob(a, s1, 10); itob(a, s2, 2); itob(a, s3, 8); itob(a, s4, 16); itob(a, s5, 6); itob(b, s6, 10); itob(c, s7, 10); itob(d, s8, 4); printf("%d 文字列(%d進数): %s\n", a, 10, s1); printf("%d 文字列(%d進数): %s\n", a, 2, s2); printf("%d 文字列(%d進数): %s\n", a, 8, s3); printf("%d 文字列(%d進数): %s\n", a, 16, s4); printf("%d 文字列(%d進数): %s\n", a, 6, s5); printf("%d 文字列(%d進数): %s\n", b, 6, s6); printf("%d 文字列(%d進数): %s\n", c, 6, s7); printf("%d 文字列(%d進数): %s\n", d, 6, s8); return 0; } void itob(unsigned int n, char s[], int b) { int i, sign, m; void reverse(char s[]); sign = n; i = 0; do { m = n % b; if (m < 0) m *= -1; if ( m < 10 ) s[i++] = m + '0'; else s[i++] = m - 10 + 'a'; } while (( n /= b) != 0); if (sign < 0) s[i++] = '-'; s[i] = '\0'; reverse(s); } void reverse(char s[]) { int c, i, j; for (i = 0, j = strlen(s) - 1; i < j; i++, j--) { c = s[i]; s[i] = s[j]; s[j] = c; } }
入出力結果(Terminal)
$ ./a.out 100 文字列(10進数): 100 100 文字列(2進数): 1100100 100 文字列(8進数): 144 100 文字列(16進数): 64 100 文字列(6進数): 244 2147483647 文字列(6進数): 2147483647 -2147483648 文字列(6進数): -2147483648 0 文字列(6進数): 0 $
演習3-6.
コード
sample.c
#include <stdio.h> #include <string.h> void itoa(int n, char s[], int cols); int main() { char s1[1000], s2[1000], s3[1000], s4[1000], s5[1000]; int a = 1, b = 12, c = 123, d = 1234, e = 12345; itoa(a, s1, 10); itoa(b, s2, 10); itoa(c, s3, 10); itoa(d, s4, 10); itoa(e, s5, 10); printf("12345678901234567890\n"); printf("%s\n", s1); printf("%s\n", s2); printf("%s\n", s3); printf("%s\n", s4); printf("%s\n\n", s5); itoa(-a, s1, 20); itoa(-b, s2, 20); itoa(-c, s3, 20); itoa(-d, s4, 20); itoa(-e, s5, 20); printf("12345678901234567890\n"); printf("%s\n", s1); printf("%s\n", s2); printf("%s\n", s3); printf("%s\n", s4); printf("%s\n", s5); return 0; } void itoa(int n, char s[], int cols) { int i, sign, m; void reverse(char s[]); sign = n; i = 0; do { m = n % 10; if ( m < 0 ) m *= -1; s[i++] = m + '0'; } while ((n /= 10) != 0); if (sign < 0) s[i++] = '-'; while (i < cols) s[i++] = ' '; s[i] = '\0'; reverse(s); } void reverse(char s[]) { int c, i, j; for (i = 0, j = strlen(s) - 1; i < j; i++, j--) { c = s[i]; s[i] = s[j]; s[j] = c; } }
入出力結果(Terminal)
$ ./a.out 12345678901234567890 1 12 123 1234 12345 12345678901234567890 -1 -12 -123 -1234 -12345 $
0 コメント:
コメントを投稿