C言語関係掲示板

過去ログ

No858 ループ、条件分岐を使用しないで文字数を数える

[戻る] [ホームページ]
No.11030

ループ、条件分岐を使用しない方法
投稿者---taro(2003/12/11 09:54:23)


文字数を数えるプログラムは、普通ループを使えば
いいのですがループ、条件分岐を使用しないでも
可能らしいということでループを使わない方法は
何とかできました。

条件分岐を使わない方法は、考えつかないため、
どなたかご教授していただけないでしょうか?
宜しくお願いします。
/*
  SampleSource*/
#include <stdio.h>

int count_char(char *check);

int main(){
  char string[] = "hello";
  printf("結果 %d\n",count_char(string));
  return 0;
}

int count_char(char *check){
  if(*check){   
    return count_char(check+1)+1;
  }
  return 0;
}




この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:ループ、条件分岐を使用しない方法 11031 ひっこしさかい 2003/12/11 10:14:42


No.11031

Re:ループ、条件分岐を使用しない方法
投稿者---ひっこしさかい(2003/12/11 10:14:42)


>条件分岐を使わない方法は、考えつかないため、
>どなたかご教授していただけないでしょうか?

テーブルジャンプだ。

switch文では
コンパイラが吐き出すアセンブラを見れば判るが
対象のcaseの値が連続して密接していると
ジャンプテーブルを作る。
離れ離れだと条件分岐のコードとなる。

関数をさすポインタの配列(要素数 char分:256個)
を用意
*checkの値で飛ばす。
0の要素は、0を返す関数を作って、そのポインタ。
それ以外の要素は、自分自身(再帰関数)。
で いけるんではないかい?




この投稿にコメントする

削除パスワード

No.11050

Re:ループ、条件分岐を使用しない方法
投稿者---taro(2003/12/11 16:11:08)


レスありがとうございます。

>テーブルジャンプだ。

すいません。googleでも調べたのですが
理解できませんでした。

>関数をさすポインタの配列(要素数 char分:256個)
>を用意
>*checkの値で飛ばす。
>0の要素は、0を返す関数を作って、そのポインタ。
>それ以外の要素は、自分自身(再帰関数)。
>で いけるんではないかい?

できればこんな感じですというような
サンプルコードをつけていただけると
ありがたいのですが・・・
宜しくお願いします。




この投稿にコメントする

削除パスワード

No.11068

Re:ループ、条件分岐を使用しない方法
投稿者---かずま(2003/12/11 16:53:15)


> できればこんな感じですというようなサンプルコードをつけていただけると
> ありがたいのですが・・・
#include <stdio.h>

#define F4    count_char, count_char, count_char, count_char
#define F32   F4,  F4,  F4,  F4,  F4,  F4,  F4,  F4
#define F256  F32, F32, F32, F32, F32, F32, F32, F32

int minus_one(const char *s) { return -1; }

int count_char(const char *s)
{
    static int (*f[])(const char *) = { minus_one, F256 };
    return f[*s & 0xFF](s+1) + 1;
}

int main(void)
{
    char string[] = "hello";

    printf("結果 %d\n", count_char(string));
    return 0;
}



この投稿にコメントする

削除パスワード

No.11084

Re:ループ、条件分岐を使用しない方法
投稿者---かずま(2003/12/11 18:22:05)


テーブルを小さくしてみました。
#include <stdio.h>

int minus_one(const char *s) { return -1; }

int count_char(const char *s)
{
    static int (*f[])(const char *) = { count_char, minus_one };
    return f[!*s](s+1) + 1;
}

int main(void)
{
    printf("結果 %d\n", count_char("hello"));
    return 0;
}



この投稿にコメントする

削除パスワード

No.11087

Re:ループ、条件分岐を使用しない方法
投稿者---taro(2003/12/11 20:02:39)


かずまさん、ありがとうございます。

> static int (*f[])(const char *) = { count_char, minus_one };
> return f[!*s](s+1) + 1;

勉強不足でどのような動きをしているのか
理解できませんでした。
もしよろしければ解説をお願いできないでしょうか?
そうでなければ、やさしく解説されてるHPなどありましたら
教えていただけないでしょうか?
宜しくお願いします。



この投稿にコメントする

削除パスワード

No.11088

Re:ループ、条件分岐を使用しない方法
投稿者---かずま(2003/12/11 22:18:18)


> 勉強不足でどのような動きをしているのか
> 理解できませんでした。
> もしよろしければ解説をお願いできないでしょうか?
static int (*f[])(const char *) = { count_char, minus_one };

これは動きません。static ですから、プログラム実行開始時に、
f[0] は count_char、f[1] は minus_one と既に初期化されています。

動くのは、return f[!*s](s+1) + 1; のところだけです。

*s が '\0' でないとき、!*s は 0 ですから、
f[0] すなわち、count_char を呼び出して、その結果 + 1 を返します。

*s が '\0' のとき、!*s は 1 ですから、
f[1] すなわち、minus_one を呼び出して、0 を返します。

どこまで詳しく説明すればよいか分からないので、この程度にしておきます。
まだ分からなければ、どこが分からないのかを具体的に質問してください。



この投稿にコメントする

削除パスワード

No.11130

Re:ループ、条件分岐を使用しない方法
投稿者---たか(2003/12/12 17:54:00)


>> 勉強不足でどのような動きをしているのか
>> 理解できませんでした。
>> もしよろしければ解説をお願いできないでしょうか?

多分関数へのポインタとその呼び出し方の理解がまだ足りないと思われま
す。

ここのサイトの解説にはないようですので、
この当たりを見て勉強してみてください。似たようなサイ
トも無数にあります。


この投稿にコメントする

削除パスワード

No.11133

Re:ループ、条件分岐を使用しない方法
投稿者---taro(2003/12/12 18:56:06)


たかさん、ありがとうございます。

>多分関数へのポインタとその呼び出し方の理解がまだ足りないと思われま
>す。

まさにその通りです。今回は大変勉強になりました。

>この当たりを見て勉強してみてください。似たようなサイ
>トも無数にあります。

非常にわかりやすいサイトでした。ありがとうございます。



この投稿にコメントする

削除パスワード

No.11132

Re:ループ、条件分岐を使用しない方法
投稿者---taro(2003/12/12 18:51:52)


かずまさん、説明ありがとうございました。

> *s が '\0' でないとき、!*s は 0 ですから、
> f[0] すなわち、count_char を呼び出して、その結果 + 1 を返します。

> *s が '\0' のとき、!*s は 1 ですから、
> f[1] すなわち、minus_one を呼び出して、0 を返します。

このような使い方ができることを初めて知りました。
また宜しくお願いします。


この投稿にコメントする

削除パスワード