fc2ブログ

C99に対応した標準Cライブラリの実装レポートを行っていきます。

プロフィール 

高木信尚

Author:高木信尚

ホームページ
ブログ

最近の記事 

最近のコメント 

最近のトラックバック 

月別アーカイブ 

カテゴリー 

ブロとも申請フォーム 

この人とブロともになる

ホーム 全記事一覧 << 前の記事 次の記事 >>

 

atoi関数は、エラー処理ができないこともあり、なるべくstrtol関数に置き換えるべき非推奨の関数です。しかし、エラーがないことが分かっている場合には、エラー判定の処理がないことと、10進数固定であることにより、strtol関数より効率がよいのも確かです。特に、long型とint型が異なるサイズの場合、その違いが顕著に現れます。

atol関数との対象性もあるので、やや悩むところではありますが、今回の実装では、atoi関数に関してはstrtol関数を使用せずに独自の実装を行うことにしました。atol関数については、別の機会に取り上げますが、strtol関数を内部で使用することにします。

atoi関数の実装に入る前に、atoi関数のほかに、strtol関数やstrtod関数などで共通に使用する下請け関数を定義します。この関数は、空白類文字を読み飛ばし、符号文字を判定して、負であれば-1を、それ以外は0を返す仕様です。また、空白類文字と符号文字の直後にポインタを位置付けます。

#include <ctype.h>

int _space_sign(const char *s, const char **endptr)
{
  while (isspace((unsigned char)*s))
    ++s;
  int sign = 0;
  switch (*s)
  {
  case '-':
    sign = -1;
    // fall through
  case '+':
    ++s;
    break;
  }
  *endptr = s;
  return sign;
}

なお、リンク後のプログラムサイズを最小にするため、この_space_sign関数は、それだけで単独のソースファイルに記述するようにします。そうしないと、strtod関数を使いたいだけの場合でも、atoi関数がリンクされてしまい、非常に空間効率が悪くなります。

それでは、atoi関数本体の実装です。

#include <ctype.h>

int atoi(const char *s)
{
  int sign = _space_sign(s, &s);
  int result;
  for (result = 0; isdigit((unsigned char)*s); s++)
    result = result * 10 + *s - '0';
  if (sign != 0)
    result = -result;
  return result;
}

本来であれば、for文の中でオーバーフローの判定を行うべきですが、仮にエラーを検出しても適切にレポートする方法がないため、何もせずに放置しています。その引き換えとして、文字列から数値への変換を高速に行うことができるようになっています。

2006/06/29 22:32|一般ユーティリティTB:0CM:0

コメント
コメントの投稿

管理者にだけ表示を許可する


トラックバック
トラックバックURLはこちら
http://libc.blog47.fc2.com/tb.php/74-abfba30c

ホーム 全記事一覧 << 前の記事 次の記事 >>

ブログ内検索 

お勧め書籍 

RSSフィード 

リンク 

このブログをリンクに追加する

Copyright(C) 2006 TAKAGI Nobuhisa All rights reserved.
Powered by FC2ブログ. template designed by 遥かなるわらしべ長者への挑戦.