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

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

 詳しくはこちら



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

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


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

No.19018

関数について(part2)
投稿者---チャイ(2005/01/04 19:30:54)


先日、質問の仕方がよくないとダメだしを喰らい、このままだとヒントももらえないと思い、以前のを削除して新しくたてました。
学校の課題で、C言語のソースファイルから関数の使用頻度を求めそれを使用頻度順にソートせよ。
ってな感じの問題が出ました。
で、C言語における関数がよく分からないので質問です。
例えば、mainとかは関数で、ifとかは演算子ですよね??
ならばifは今回の問題では使用頻度とかはいらないわけです。
単語に()がついたのを見分けようとするのはこの時点で不可能になりました。
そこで、自分が考えたのは、演算子ならば「!、=、<」とかが()の中に入るはずだからそれを除外すればいい。
ってことなんですけど、switch文の場合必ずしもそういうのが入るわけではないですよね?
次に考えたのは関数の宣言の部分で、mainとか自分で作ったやつはintやらvoidやら型宣言しますよね??
それで判断しようかともしたんですけど、printfとかは宣言しない。ってことに書いてる途中で気づいて断念。。
第一、printfなら=も入るじゃん!!
っていうことで四面楚歌の状態におちいりました。
関数を見分ける方法。。
これを教えてください。


この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:関数について(part2) 19019 あかま 2005/01/04 20:05:49
<子記事> Re:関数について(part2) 19038 nop 2005/01/05 12:04:28


No.19019

Re:関数について(part2)
投稿者---あかま(2005/01/04 20:05:49)


>先日、質問の仕方がよくないとダメだしを喰らい、このままだとヒントももらえないと思い、以前のを削除して新しくたてました。
おしい。たとえ注意されても削除するのはよくないです。
注意されたことをそのままスレッドの続きに書いたほうがいいと思います。

>ならばifは今回の問題では使用頻度とかはいらないわけです。
>単語に()がついたのを見分けようとするのはこの時点で不可能になりました。
単語+()で組み込みなのはfor,while,if,switchぐらいしかないのでこれをはじくようにしては?

>そこで、自分が考えたのは、演算子ならば「!、=、<」とかが()の中に入るはずだからそれを除外すればいい。
>ってことなんですけど、switch文の場合必ずしもそういうのが入るわけではないですよね?
switchだけでなくif(i)のように演算子を使わないことはかなり多いです。
やはりこれは無理ですね。

>次に考えたのは関数の宣言の部分で、mainとか自分で作ったやつはintやらvoidやら型宣言しますよね??
>それで判断しようかともしたんですけど、printfとかは宣言しない。ってことに書いてる途中で気づいて断念。。
これも無理っぽいですね。

>関数を見分ける方法。。
>これを教えてください。
まえのスレッドでも書きましたが、この問題は結構難しい(はず)です。
卒論ならきっちり仕様を調べて仕上げなければなりませんが、
明日までに作って来い!って問題なら手を抜かないときついでしょう。

きっちり作ると私なら一ヶ月あってもできるかな…
結局は単語+()が実用的?な気がします。


ちゃんとやるなら構文解析を勉強するところからですね。
http://www.amazon.co.jp/exec/obidos/ASIN/4844317210/250-9807643-3133846
↑の本がCで書かれたRubyの処理系を解説した本で、パーサの作り方とか(処理系全般ですが)載ってました。
参考になるかもしれません。いい本です。

この問題を解いたら、ぜひソースコードを載せてください。


この投稿にコメントする

削除パスワード

No.19020

Re:関数について(part2)
投稿者---チャイ(2005/01/04 20:19:43)


あかまさん。先日のヒントありがとうございます。
今回もアドバイスありがとうがざいます。
本、、高いですね。。
時間もあまりないんで(期限が来週まで)明日、本屋に行って買ってきます。
>単語+()で組み込みなのはfor,while,if,switchぐらいしかないのでこれをはじくようにしては?
学校への提出には多分これでやるかもしれません。
ただ、勉強にはなると思うんで、何とか解決したいですね。
>おしい。たとえ注意されても削除するのはよくないです。
>注意されたことをそのままスレッドの続きに書いたほうがいいと思います。
指摘ありがとうございます。


この投稿にコメントする

削除パスワード

No.19022

Re:関数について(part2)
投稿者---あかま(2005/01/04 21:00:38)


と、色々書いておいて関数名っぽいものを出すだけならそれほど難しくないかも?
変に解析しようとするからいけなかったかw
たぶん単語+'('だけでいけますね(とじ括弧がいらない)
↓結構綺麗に出ます。

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

char *get_func_name(char *str,char *c){
    for(;str < c && isspace(*c);c--)//空白飛ばし
        ;
    *(c+1) = '\0';
    
    for(;isalpha(*c) || *c == '_';c--){//名前探し
        if(str == c) return c;
    }
    return c+1;
}
void get_func(char *str){
    char *c=str,*d;
    for(;c = strchr(c,'(') ;c++){
        d = get_func_name(str,c-1);
        if(*d != '\0' && strcmp(d,"if") && strcmp(d,"for") && strcmp(d,"while") && strcmp(d,"switch")){
            printf("%s\n",d);
        }
    }
    
    return;
}
int main(){
    char str[256];
    while(fgets(str,256,stdin)){
        get_func(str);
    }
    return 0;
}




この投稿にコメントする

削除パスワード

No.19023

Re:関数について(part2)
投稿者---Ban(2005/01/04 21:53:44)


> たぶん単語+'('だけでいけますね(とじ括弧がいらない)

C に限れば、他に '(' 使うようなものは、演算の優先度変更か
キャストかマクロくらいだと思うので、
「引数付マクロまたは関数名」まではそれで絞れると思います。

お題は「関数の使用頻度」とのことですので、ちゃんと頑張るなら
後は #define を検索して引数付きマクロ名をキーワードと同様の
除外対称に登録できるようにし、
「関数宣言」と「関数定義」を除外すればいいのではないでしょうか。

これを判断する(比較的お手軽な)条件は多分このあたり。
・#define で始まる行のマクロ名 + ( の値を除外対象に記録。
・#で始まる行は検索対象外 (defined や pragma、マクロ宣言等を除外)
・ifなどは除外なので、対応する ')' を特定して '{' が続けば関数定義
・'{' が続かず、関数の前が型名(組み込み型/識別子)なら関数宣言

少なくとも ')' の特定に引数解析はやっぱり必要?(^_^;

但し、これでも暗黙の戻り値 int までは対応できてません。
ただ、他の方法で引数の仮引数宣言を見るにしても foo(); とか
されると判断できず、記述場所がグローバルか否かが
判断できれば話が早いですが、インデントを仮定しないでそれを
判断するには、ちゃんと構文解析するしかない気がします。
# 行頭の '{', '}' を関数の始点・終点と仮定すれば判断できそう。

あと、マクロ定義の有無を調べるには #include なども解析しないと....
こり始めるときりがないですね。
どこまでやるかは、現実と相談して決めてみてください。

# C++ だと、更に operator() やら foo<bar>() やらが...。


この投稿にコメントする

削除パスワード

No.19038

Re:関数について(part2)
投稿者---nop(2005/01/05 12:04:28)


>C言語における関数がよく分からないので

でしたら、まず C の規格を調べればよいのではないでしょうか?


>例えば、mainとかは関数で、ifとかは演算子ですよね??

if() などは演算子ではなく制御文です。


>関数を見分ける方法。。
>これを教えてください。

本格的にやるのでしたら、

1.コンパイラと同じプリプロセスを行う
2.構文解析

と言う複雑な処理が必要となります。
どちらにしろ、C の規格を熟知する必要があるので、
まずは、C の規格を勉強することをお勧めします。



この投稿にコメントする

削除パスワード

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