ショッピングモール  


【掲示板ご利用上の注意】

 ※題名は具体的に!
 ※学校の課題の丸投げ禁止!
 ※ソースの添付は「HTML変換ツール」で字下げ!
 ※返信の引用は最小限に!
 ※環境(OSとコンパイラ)や症状は具体的に詳しく!
 ※マルチポスト(多重投稿)は謹んで!

 詳しくはこちら



 本当はこんなに大きく書きたくはないのですが、なかなか守っていただけなくて…。
 守ってくださいね。お願いします。(by管理人)

C言語ソース⇒HTML形式ツール   掲示板1こちら


管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    記事検索    ログ    タグ一覧

No.3169

うまく注釈 "/* 〜 */" をつけたい
投稿者---初心者(2004/12/06 18:34:17)


 過去ログから30桁まで同士の四則演算(負の数も含む)をするプログラムを見つけたのですが、
とても長いのに プログラムの注釈"/* 〜 */"がありません。 さすがに全ての
行とはいきませんが、重要なところに注釈をつけて 第三者にも分かり易い見た目に
したいのです。 上手い言葉が見つかりません、ぜひ、要所要所につける的確な
注釈を教えてください。 プログラムは次のようになっています。

#include <stdio.h>
#include <ctype.h>
#include <string.h>

#define N   31

static char zero[N];

/* 足し算の計算処理 */
static int add0(char *c, const char *a, const char *b)
{
  int i, carry = 0;
  
  for (i = 0; i < N-1; i++) {
    c[i] = a[i] + b[i] + carry;
    carry = (c[i] > 9);
    if (carry) c[i] -= 10;
  }
  return carry;
}

/* 引き算の計算処理 */
static int sub0(char *c, const char *a, const char *b)
{
  int i, borrow = 0;
  
  for (i = 0; i < N-1; i++) {
    c[i] = a[i] - b[i] - borrow;
    borrow = ((unsigned)c[i] > 9);
    if (borrow) c[i] += 10;
  }
  return borrow;
}

/* 掛け算の計算処理 */
static int mul0(char *c, const char *a, const char *b)
{
  int i, j;  char x[2*(N-1)] = { 0 };
  
  for (i = 0; i < N-1; i++) {
    for (j = 0; j < N-1; j++)
      x[i+j] += a[i] * b[j];
    for (j = 0; j < N-1; j++)
      if (x[j]) x[j+1] += x[j] / 10, x[j] %= 10;
  }
  memcpy(c, x, N-1);
  return memcmp(x + N - 1, zero, N-1) != 0;
}

/* 割り算の計算処理 */
static int div0(char *q, char *r, const char *a, const char *b)
{
  int i;  char x[2*(N-1)];
  
  if (memcmp(b, zero, N-1) == 0) return 1;
  memcpy(x, a, N-1);  memset(x + N - 1, 0, N-1);
  for (i = N-2; i >= 0; i--) {
    for (q[i] = 0; q[i] < 10; q[i]++)
      if (sub0(x + i, x + i, b)) break;
    add0(x + i, x + i, b);
  }
  memcpy(r, x, N-1);
  return 0;
}

int add(char *c, const char *a, const char *b)
{
  if (a[N-1] == b[N-1]) {
    c[N-1] = a[N-1];
    return add0(c, a, b);
  }
  c[N-1] = a[N-1] ? sub0(c, b, a) : sub0(c, a, b);
  if (c[N-1]) sub0(c, zero, c);
  return 0;
}

int subtract(char *c, const char*a, const char *b)
{
  char x[N];
  
  x[N-1] = 1 - b[N-1];
  memcpy(x, b, N-1);
  return add(c, a, x);
}

int multiply(char *c, const char *a, const char *b)
{
  c[N-1] = a[N-1] ^ b[N-1];
  return mul0(c, a, b);
}

int divide(char *c, const char *a, const char *b)
{
  char x[N-1];
  
  c[N-1] = a[N-1] ^ b[N-1];
  return div0(c, x, a, b);
}

int get_int(const char *msg, char *a)
{
  int i, c;
  
  if (msg) fputs(msg, stdout);
  while ((c = getchar()) == ' ' || c == '\t' || c == '\n')
    ;
  a[N-1] = 0;
  switch (c) {
  case '-': a[N-1] = 1;
  case '+': c = getchar();
  }
  if (!isdigit(c)) { ungetc(c, stdin); return 1; }
  for (i = 0; i < N-1; i++) {
    if (!isdigit(c)) { ungetc(c, stdin); break; }
    a[N-1 - 1 - i] = c - '0';
    c = getchar();
  }
  if (i != N-1) {
    memcpy(a, a + N - 1 - i, i);
    memset(a + i, 0, N - 1 - i);
  }
  return 0;
}

void put_int(const char *msg, const char *a, const char *msg2)
{
  int i = N-1;
  
  if (msg) fputs(msg, stdout);
  if (a[N-1]) putchar('-');
  while (--i > 0 && a[i] == 0)
    ;
  do putchar(a[i] + '0'); while (i--);
  if (msg2) fputs(msg2, stdout);
}

int main(void)
{
  char a[N], b[N], c[N];
  
  while (!get_int("a: ", a) && !get_int("b: ", b)) {
    if (add(c, a, b)) puts("[+] overflow");
    else put_int("  a + b = ", c, "\n");
    
    if (subtract(c, a, b)) puts("[-] overflow");
    else put_int("  a - b = ", c, "\n");
    
    if (multiply(c, a, b)) puts("[*] overflow");
    else put_int("  a * b = ", c, "\n");
    
    if (divide(c, a, b)) puts("zero divide");
    else put_int("  a / b = ", c, "\n");
  }
  return 0;
}

 途中にある注釈は自分で考えたものですが、適切なのか自信がありません。
もし検討違いでしたら、ここの訂正の含めて、教えてください。



この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:うまく注釈 "/* 〜 */" をつけたい 3170 通りすがり 2004/12/06 20:41:36
<子記事> Re:うまく注釈 "/* 〜 */" をつけたい 3171 RAPT 2004/12/06 20:43:28
<子記事> Re:うまく注釈 "/* 〜 */" をつけたい 3183 かずま 2004/12/08 02:50:32


No.3170

Re:うまく注釈 "/* 〜 */" をつけたい
投稿者---通りすがり(2004/12/06 20:41:36)


分かりづらいなら自分で納得行く形に書き直せばいいと思いますよ。
それにプログラムが読めるなら、あなたの付けたコメントが正しいかどうか分かると思いますけど。
ちなみにその第3者のレベルはどの程度なのでしょうか。

しかし変数名が分かりづらいですね、コメント付ける前に変数名を意味あるものにしましょう。それだけでずいぶん違います。


この投稿にコメントする

削除パスワード

No.3171

Re:うまく注釈 "/* 〜 */" をつけたい
投稿者---RAPT(2004/12/06 20:43:28)


で、どの辺が分からない/分かりにくいのですか?

やっている処理が分かっているのなら、コメントはいくらでも書けるでしょう。
多分、あなたが理解されていない部分があるから、悩むのではないでしょうか。

自分が第三者的であるといった遠まわしな表現を止めて、自ら取り組む姿勢で
行なうとよろしいかと思われます。

例えば、
carry = (c[i] > 9);
これは、どういった処理で、結果、どうなるか説明できますか?



この投稿にコメントする

削除パスワード

No.3183

Re:うまく注釈 "/* 〜 */" をつけたい
投稿者---かずま(2004/12/08 02:50:32)


> 過去ログから30桁まで同士の四則演算(負の数も含む)をするプログラムを
> 見つけたのですが、

見つけたのなら、他の人の便宜も考えて、どこにあったかを書きましょう。
過去ログの No. 615 ですね。


> とても長いのに プログラムの注釈"/* 〜 */"がありません。

get_int 以外はどれも 10行程度の関数です。これのどこが「とても長い」の
でしょうか?


> さすがに全ての行とはいきませんが、重要なところに注釈をつけて

注釈はプログラムに書かれていることをそのまま書いても意味がありません。
プログラムに書かれていないことを書くべきです。

コードより、データ構造のほうが重要です。
注釈なら、冒頭に次のようにでも書いておけばよいのでは?
/*
 * 多倍長演算
 *
 * データ形式
 *  char a[N]:
 *     a[i] (i = 0〜N-2) は、10の i乗の位の値 0〜9。
 *     a[N-1]は符号。正は 0、負は 1。
 *
 * 入出力
 *   get_int:  メッセージを出力し、整数値を入力。
 *   put_int:  メッセージ、整数値、メッセージを出力。
 *     
 * 符号付き演算
 *   add:      c = a + b;
 *   subtract: c = a - b;
 *   multiply: c = a * b;
 *   divide:   c = a / b; 注意: b と c は同じ配列であってはならない。
 *
 * 符号無し演算
 *   add0:     c = a + b;
 *   sub0:     c = a - b;
 *   mul0:     c = a * b;
 *   div0:     q = a / b;
 *             r = a % b; 注意: b と q は同じ配列であってはならない。
 *
 * 各演算の返却値
 *   +, -, * の場合、オーバーフローがあれば 1、なければ 0。
 *   割り算の場合、ゼロで割ろうとすれば 1、そうでなければ 0。
 */



この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    記事検索    ログ    タグ一覧




掲示板提供:Real Integrity