K.Maebashi's BBS

ご自由に書き込んでください。雑談も可。
テスト書き込みの類はテスト用掲示板にどうぞ

[日付順表示] [日付順インデックス] [スレッド順インデックス]

新規投稿 | 開設者ホームページへ戻る | ヘルプ

[825] Re:C言語サブセットについて
投稿者:(ぱ)
2007/02/20 02:13:25

>flexとbissonで言語を作ってみようと思った人ですが。このページを読むと本当に勉強になりました。 どうもです。 >今、crowbarのソースを読んでますが、初心者なので、これよりもっとシンプルのソースあるでしょうか。 単にcrowbarより簡単なソースなら、うちのページにある(マスタングさんも挙げられた) 「電卓を作ってみよう」のcalcなんかがよいかもしれませんけれども。 ただし、作りたいものが「外面がCっぽい言語」なのか、「中の動きがCっぽい言語」で あるかによって、作り方は相当変わってきます。たとえばcrowbarは配列をヒープに 確保しますけど、内部的な動作を含めてCっぽい言語を作りたいのなら、配列もスタックに 確保すべきでしょう。内部的な動作を含めてCっぽい言語を作ったほうが、Cの理解が 深まる、という利点もあります。 >例え、データ型 intしかない、論理演算 if else while for <>= +-* /しかできるC言語サブセットのソース例はあるでしょうか。教えてください。よろしくお願いいたします。^^ 昔、「yacc/lex―プログラムジェネレータonUNIX」という本があって、この本には ・変数はA-Zだけ。配列なし。 ・バイトコードコンパイル方式。 という簡易言語のサンプルが載っていました。 また、「yaccによるCコンパイラプログラミング」 http://www.context.co.jp/~cond/books/yacc-book.html には、8086で動作する簡単なCコンパイラのソースが載っていました(構造体がない くらいで、ほぼCコンパチだったような気がします)。 でも、今はどちらも入手できないと思います。図書館とか会社の書庫とかで 探してみるのがよいのではないでしょうか。
[この投稿を含むスレッドを表示] [この投稿を削除]
[824] Re:elsif と else if
投稿者:(ぱ)
2007/02/20 02:13:25

>if文のぶら下がり文に関してふと思いついたんですが、 >本体にブロックを強制する場合でも >else節にだけ、if文も書けるようにすればelsif(elif, elseif)というようなキーワードを導入しなくても困りませんよね? なるほど。確かに構文規則を以下のようにいじってbisonにかましてみましたが、 特にconflictは起きませんでした。 if_statement: IF LP expression RP block | IF LP expression RP block ELSE block | IF LP expression RP block ELSE if_statement | IF LP expression RP block elsif_list | IF LP expression RP block elsif_list ELSE block | IF LP expression RP block elsif_list ELSE if_statement >文法が微妙に汚くなるからでしょうか >then節とelse節で書けるものが違う、とか、if文だけ特別扱い、とか やっぱりこれを汚いと思う人が多いからではないでしょうか。 汚いかどうかは主観の問題ですけど、私なら、if文だけ特別扱いするくらいなら、 elsifを導入します。 確かに、Cプログラマで、Cにはelse ifという特別な構文があると思っている人は 少なくなかったですから、elseの後のif文だけ特別扱いしてもさほど混乱はないのかも しれませんけど、「Cにはelse ifという特別な構文があると思っている人」が 周囲にたくさんいた私としては、そういう人への啓蒙もこめてelsifを導入した、 という意図もあったようななかったような。
[この投稿を含むスレッドを表示] [この投稿を削除]
[823] Re:C言語サブセットについて
投稿者:マスタング
2007/02/20 02:13:25

>flexとbissonで言語を作ってみようと思った人ですが。このページを読むと本当に勉強になりました。 >今、crowbarのソースを読んでますが、初心者なので、これよりもっとシンプルのソースあるでしょうか。 >例え、データ型 intしかない、論理演算 if else while for <>= +-* /しかできるC言語サブセットのソース例はあるでしょうか。教えてください。よろしくお願いいたします。^^ crowbar 0.1のソースや「プログラミング言語を作る」の"電卓を作ってみよう"は 参考にならないでしょうか? また、初心者さんが求めている内容とは少し違いますが、 以下のものはどうでしょうか? 1) yacc入門講座(簡単な説明) http://www.tokumaru.org/yacc/index.htm 2) Bison入門(リファレンス) http://guppy.eng.kagawa-u.ac.jp/~kagawa/2000/SysProg/bison-1.2.8/bison-ja_toc.html 3) Flex(リファレンス) http://www.asahi-net.or.jp/~wg5k-ickw/html/online/flex-2.5.4/flex_toc.html 4) lex&yaccプログラミング(残念ながら日本語版は売り切れなようです) http://www.amazon.co.jp/exec/obidos/ASIN/4756102972/qid=1141565795/br=3-2/br_lfncs_b_2/249-0186723-6715515 5) いまどきのプログラム言語の作り方(Javaで再帰下降型パーサの実装です) http://www.amazon.co.jp/exec/obidos/ASIN/4839919232/qid=1141567196/br=3-1/br_lfncs_b_1/249-0186723-6715515 私も興味ありますので、何か良いサイトや参考書などあれば 逆に教えてください。 あくまでもflexやbison(yaccやlex)にこだわるなら 私は、ドラゴンブックやタイガーブックなどより先に、 yaccやlexをある程度理解しておくことが重要だと思っています。
[この投稿を含むスレッドを表示] [この投稿を削除]
[822] C言語サブセットについて
投稿者:初心者
2007/02/20 02:13:25

flexとbissonで言語を作ってみようと思った人ですが。このページを読むと本当に勉強になりました。 今、crowbarのソースを読んでますが、初心者なので、これよりもっとシンプルのソースあるでしょうか。 例え、データ型 intしかない、論理演算 if else while for <>= +-* /しかできるC言語サブセットのソース例はあるでしょうか。教えてください。よろしくお願いいたします。^^
[この投稿を含むスレッドを表示] [この投稿を削除]
[821] Re:elsif と else if
投稿者:NykR
2007/02/20 02:13:25

># elseというキーワードはあるのにthen節であることを示すキーワードはない訳で 何を言ってるんだろ? ええと、ブロックを中括弧で表現する言語でelsifのようなものを使う言語の中には、elseはあるのにthen節を示すキーワードは存在しない、というようなものもある訳で、 と言いたかったんですね。多分(ぉ
[この投稿を含むスレッドを表示] [この投稿を削除]
[820] elsif と else if
投稿者:NykR
2007/02/20 02:13:25

if文のぶら下がり文に関してふと思いついたんですが、 本体にブロックを強制する場合でも else節にだけ、if文も書けるようにすればelsif(elif, elseif)というようなキーワードを導入しなくても困りませんよね? 何で世の中の多くの言語はそうなってないんでしょう? 文法が微妙に汚くなるからでしょうか then節とelse節で書けるものが違う、とか、if文だけ特別扱い、とか でも、then節とelse節を全く同じにする必要はないと思いますし、 # elseというキーワードはあるのにthen節であることを示すキーワードはない訳で # というのはちょっと苦しいか if文の中でif文を特別扱いするのもそんなに変なこととは思いません # うーん、気付いてないだけで何か他に問題があるんだろうか? # そこまでして else if と書けるようにするより、elsifを導入した方が簡単・・・でもないよなぁ。 どう思います?
[この投稿を含むスレッドを表示] [この投稿を削除]
[819] Re:長文すみません
投稿者:マスタング
2007/02/20 02:13:25

タイガー改めマスタングです。 私なりに思ったことを書いてみます。 まず思ったのは、自分が少しでも複雑だなと感じる処理を考える場合は、 図を書いてみると理解しやすいです。 掲示板では少々書きづらいので自分なりに紙にでも書いてみてください。 >線形リストif(sagyou->num < fo->next->num)が、他の参考書を見ながら打ってた時 >next->next->...->numという感じで全部比較して見てるのか?となぜか思い >それで、逐一アドレス表示させるようにしたりして、自分なりに疑問を解消しつつ >本当に、fo->next->numは、nextだけを見てるのかとまだ疑問だったんですが >実は言いますと、この投稿フォームに、その疑問を考えながら書いてる間に >「あれ、これって、for文で回して、単に比較してチェーン変えてるだけだ」 >と、なぜか、その場で気づいたのですが、やはり確認しておこうと思い書きました。 listが数珠つなぎになっていて、forループの中でのfo変数は、 イメージとして、カーソルを表しています。 カーソルが先頭から末尾まで1つずつ各listを指しながら動く感じです。 これは、例えば、for (i = 0; i < num; i++)の、「i」と似ています。 iは、0から(num - 1)まで値を変えながら進んで行きます。 これは、「処理」としては、同じなので抽象化(同じ扱い)ができ、 一般的に、こういったカーソルをiteratorと言います (若干厳密性はないかもしれないですが、イメージはそんな感じだと思います)。 >free()に関しては、リストでmalloc()を使うのは解るが、それらをfree()にする >タイミングがよくわからなかったんですが、リストにして結果をはき出したら >またチェーンでたどってfree()にするのかなとか、まぁ、その、まだまだ >例題をみながら打ち込みながら理解しつつ、昨日覚えた事を今日忘れるような >日々つれづれとおくっておりまして、、、 負け組一号さんのサンプルで、startという変数が重要になります。 どこかで(例えば関数で)free処理をするのでしょうが、 start変数は、listの先頭を表していますので、これさえあれば listにつながっているデータは全てfreeできます。 関数でfreeするなら、引数でstartを渡してあげればOKです。 つまり、どこでfreeするかはユーザの自由ですが、freeするタイミングまで start変数を管理できていればOKな訳です。 start変数を管理(保持)する方法としては、ある関数内(ローカル)に持ち歩くか、 static変数(あるいは、グローバル変数)などで持っておくかの どちらかになると思います。 もちろん、別のデータ(構造)内に保持していても同じです。 freeするタイミングは重要ではないと思うのですが、 言えることがあるとすれば、いらなくなった時です。 >ただ、nextポインタがNULLになってるポインタを順次free()していけば出来るのかな >と思い、試してみます。 これは、違います。 nextポインタがNULLであろうが、NULLでなかろうが、 現在、カーソルが指しているlistをfree()します。 しかし、現在指しているlistをfree()してしまうと、 listに入っているnextの(ポインタの)情報がとれなくなってしまうので、 現在のlistのnextの情報を先にとっておきます。 そして、現在のlistをfree()します。 その処理を現在のカーソルがNULLになるまで繰り返します。 つまり、nextがNULLになるまで繰り返すのです。 まだ不明な点があればいくらでも聞いてください。
[この投稿を含むスレッドを表示] [この投稿を削除]
[818] Re:長文すみません
投稿者:負け組一号
2007/02/20 02:13:25

確かに、おっしゃるとおりっす。 自分の文章は、論理的に書けてないですね。 とにかく、もっとソースを体当たりで打ち込んで理解を深めます。 その上で、ポインタ関連で疑問が生じたら書き込みささしてもらいます。
[この投稿を含むスレッドを表示] [この投稿を削除]
[817] Re:長文すみません
投稿者:本多
2007/02/20 02:13:25

あまり本質的な議論には参加してないくせに言うのもおかしいかもしれませんが少しだけ。 負け組一号さんは、一つの文章を短く切った方が文章の意味がわかりやすくなると思います。 「それが私の文章の味」とか言われちゃうと、それまでなのですが、 技術的な文章は、わかりやすさ重視でしょう。 なんとなく古文の授業を思い出してしまいます。 さて(ぱ)さんへのコメント中に 「どうfree()して行けば良いのかが解らない」とおっしゃってますが、 「どこでfree()というやつで解放してやれば良いのでしょうか」という質問では 求める答えが得られないのはお解かりでしょうか。 「方法」がわからないときに「記述する位置」を質問しても求める答えは得られないのは自明でしょう。 わからないことが「考え方や根拠」「概念」「方法」「動作原理」の どれなのかを分類するといいと思います。 少々きつい言葉で批判めいたことを書きましたが 自分自身の経験から「わからないことが何か」を理解した段階で 自然に「理解できる」場合が多いように思えます。 その一助として 「自分がわからない事柄は『方法』なのか?『考え方』なのか?『動作原理』なのか?」 と自問することは重要だと思っています。
[この投稿を含むスレッドを表示] [この投稿を削除]
[815] 長文すみません
投稿者:負け組一号
2007/02/20 02:13:25

774RRさん、(ぱ)さん、返信ありがとうございます。 線形リストif(sagyou->num < fo->next->num)が、他の参考書を見ながら打ってた時 next->next->...->numという感じで全部比較して見てるのか?となぜか思い それで、逐一アドレス表示させるようにしたりして、自分なりに疑問を解消しつつ 本当に、fo->next->numは、nextだけを見てるのかとまだ疑問だったんですが 実は言いますと、この投稿フォームに、その疑問を考えながら書いてる間に 「あれ、これって、for文で回して、単に比較してチェーン変えてるだけだ」 と、なぜか、その場で気づいたのですが、やはり確認しておこうと思い書きました。 free()に関しては、リストでmalloc()を使うのは解るが、それらをfree()にする タイミングがよくわからなかったんですが、リストにして結果をはき出したら またチェーンでたどってfree()にするのかなとか、まぁ、その、まだまだ 例題をみながら打ち込みながら理解しつつ、昨日覚えた事を今日忘れるような 日々つれづれとおくっておりまして、、、 とりあえず、まだまだ、打ち込んで、理解を深め、この劣化した脳に新たなメモリを 加えたく(脳の細胞は再生しないが、新生はするらしいので)思いつつ、今度は ちゃんと何が解らないのかが解らない状態で質問せず、何が解らないか解るよう 質問(甘え)さしてもらいたいです。 上記の文を書いて、ポインタ完全制覇を読み直した結果、駄目じゃん俺と再認識 >>774Rさん >提示コードは先頭に追加される必要がある場合にうまくない。 >それとも最初に作ってる sta は番兵? 番兵の意味を聞かれて、持ってる書籍を見て初めて意味を知りました。番兵って奴です。 >一番最初の1個目を作る場合と、末尾に追加する場合とが特殊なわけだ。 >でも、実際には特殊ではなくて、ロジック上真ん中に挿入の場合と同じに扱える >ということが理解できるかどうかが肝 まだまだ、理解は出来るが、「さぁ作れ」と言われたら悩んでしまうレベルです。 >>(ぱ)さん >「どうわからないのか」をもう少し具体的に書いていただけませんか。 わからない部分は線形リストでmalloc()で割り当てて行った領域をどうfree()して行け ば良いのかが解らないといった感じです。 ただ、nextポインタがNULLになってるポインタを順次free()していけば出来るのかな と思い、試してみます。
[この投稿を含むスレッドを表示] [この投稿を削除]
[814] Re:(ぱ)さんに甘えさして頂きます
投稿者:(ぱ)
2007/02/20 02:13:25

どうも、(いつものことですが)「何がわからないのか」がわからないので 答えようにも困ってしまうわけですが。 >    if(sagyou->num < fo->next->num ) >の、fo->next->numは、その時点でのfoのnext側のnumを見てる >と捉えて良いのでしょうか。 この質問にYesかNoかで答えれば、(774RRさんが書いておられるように)「Yes」と 答えるしかないわけですが、疑問に思ったからには、何か引っかかるところが あるわけでしょう。 ->は所詮演算子なので、 p = fo->next->num; として「foのnext側のnumを見」る代わりに、 temp = fo->next; p = temp->num; と書いてもよいし、 fo->next->numの代わりに(fo->next)->numと書いても構わないわけですが、 こうやって書き換えると感覚的にわかりやすくなったりしますかね。 >ついで、malloc()で得たメモリは >どこでfree()というやつで解放してやれば良いのでしょうか。 これも、「要らなくなったとき」としか答えようがないのですが、 そんなことは入門書にも書いてあるはずで、それでわからなかったから 質問しているわけでしょう。 「どうわからないのか」をもう少し具体的に書いていただけませんか。
[この投稿を含むスレッドを表示] [この投稿を削除]
[813] Re:線形リスト
投稿者:774RR
2007/02/20 02:13:25

リスト構造自体はそんなに難しいものではなくて、単に数珠つなぎになってるだけ。 例えば http://www9.plala.or.jp/sgwr-t/c/sec15-5.html 演習のほうも見てみませう。 提示コードは先頭に追加される必要がある場合にうまくない。 それとも最初に作ってる sta は番兵? 番兵にせよなんにせよ今のままでは sta が auto なのでまずいけど。 >fo->next->numは、その時点でのfoのnext側のnumを見てる もちろん >どこでfree()というやつで解放してやれば良いのでしょうか。 要らなくなったとき。 malloc() するってことは、当座しばらくは必要だから保持しとけ、ということ。 例えばワード等で文章を開いたときなんかにこうやって文書データを保持してるわけだ。 free() するのは文章を閉じたときとかワードを終了するときとか。 提示コードであればリストを破棄するのは main 終了直前でしょうな。 こういうのはポインタに関する「文法理解」ではなくてむしろ「アルゴリズム理解」の話。 線形リストの場合「真ん中に挿入」する場合がいちばん簡単で、紹介先の図のとおり。 一番最初の1個目を作る場合と、末尾に追加する場合とが特殊なわけだ。 でも、実際には特殊ではなくて、ロジック上真ん中に挿入の場合と同じに扱える ということが理解できるかどうかが肝。
[この投稿を含むスレッドを表示] [この投稿を削除]
[812] (ぱ)さんに甘えさして頂きます
投稿者:負け組一号
2007/02/20 02:13:25

レス頂き、ありがとうございました。 そんで、(ぱ)さんに、甘えた質問さしていただきます。 ソースなんで長いですが自分でリストを理解しようと改造した線形リストです。 typedef struct list {     int num;     struct list *next; }list; int main() {     list sta ={0,NULL};     list *start = &sta; /*先頭*/     list *sagyou; /*作業領域*/     list *fo; /*for用*/     char str[16]; /*入力用*/     while(1) {         printf("整数を入力(Eで終了)-->");         gets(str);         if(strcmp(str,"E") != 0){//strcmpは文字列の比較             sagyou = (list *)malloc(sizeof(list));             if(sagyou == NULL ){                 printf("メモリ確保できず\n");                 exit(1);             }         }         else break;         sagyou->num = atoi(str);//atoiは文字列をint型に変換する         for(fo = start; fo->next != NULL; fo = fo->next){             if(sagyou->num < fo->next->num ){                 sagyou->next = fo->next;                 fo->next = sagyou;                 break;             }         }         if(fo->next == NULL){             fo->next = sagyou;             sagyou->next = NULL;         }     } で、上のリストで、数字を大きい順にしようとするとき for(fo = start; fo->next != NULL; fo = fo->next){     if(sagyou->num < fo->next->num ) の、fo->next->numは、その時点でのfoのnext側のnumを見てる と捉えて良いのでしょうか。ついで、malloc()で得たメモリは どこでfree()というやつで解放してやれば良いのでしょうか。 線形リスト、双方向リスト等、及び二分木探索などの例ばかりが 載ってる書籍を探しても、あるのは入門書ばかりで、初心者 から脱皮できない自分に負い目を感じる今日このごろです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[811] Re:カナダで「ほげ通り(HOGE ST.)」を見つけました
投稿者:マモル
2007/02/20 02:13:25

>情報ありがとうございます。後ほど「ほげを考えるページ」に追加情報として >挙げさせていただきます。 ありがとうございます。リンクにスペースが入ってリンク切れのようになっていました。もう一度リンクを書き込ませて頂きます。スイマセン…。 http://ameblo.jp/mamoru/entry-10009422221.html >リンクはどのページにもご自由にどうぞ。 勝手な書き込みでしたが、丁寧に対応して頂いてありがとうございました。 ではっ。
[この投稿を含むスレッドを表示] [この投稿を削除]
[810] Re:左辺値としての配列名
投稿者:774RR
2007/02/20 02:13:25

なんとなくネタ的に面白いので追加検証。gcc ならソースコードがあるので読んでみた。 gcc-3.4.5 を追っかけ。 gcc-4 では大幅な変更が入っているので変わっているかもしれない。 int array[1]; array=0; なるソースコードに対する挙動 C の場合 gcc/c-typeck.c Line 3677 でエラーメッセージを出力 これは convert_for_assignment() 関数の末尾である。この関数の先頭部分で if (TREE_CODE (TREE_TYPE (rhs)) == ARRAY_TYPE || TREE_CODE (TREE_TYPE (rhs)) == FUNCTION_TYPE) rhs = default_conversion (rhs); なるコードが実行されている(すなわち右辺はデフォルト変換が実施されている) のに対して左辺のデフォルト変換を行うコードは見当たらない。 =代入式の左辺においては「配列名を先頭へのポインタに読み替える」変換は実施していない C++ の場合 gcc/cp/typeck.c Line 5295 でエラーメッセージを出力 これは build_modify_expr() 関数の一部であり if (TREE_CODE (lhstype) == ARRAY_TYPE) の内側にある。この例では右辺左辺の型が異なるのでこのエラー。 もし array=array; であるなら、型一致なのでこの行ではなく先に進んで ISO C++ forbids assignment of arrays エラーが発生。 いずれにせよ左辺のデフォルト変換を行う関数は呼ばれていない。
[この投稿を含むスレッドを表示] [この投稿を削除]
[809] Re:カナダで「ほげ通り(HOGE ST.)」を見つけました
投稿者:(ぱ)
2007/02/20 02:13:25

>はじめまして。マモルと申します。 はじめまして。 >カナダのホワイトホースという町で「ほげ通り(HOGE ST.)」を見つけました↓。 > >http://ameblo.jp/mamoru/entry-10009422221.html 情報ありがとうございます。後ほど「ほげを考えるページ」に追加情報として 挙げさせていただきます。 >hoge研究の参考になれば嬉しく思います。また、誠に勝手ながら「ほげを考えるページ 」に無断でリンクを張らして頂きました。もし不都合があればリンクを削除いたします。 リンクはどのページにもご自由にどうぞ。
[この投稿を含むスレッドを表示] [この投稿を削除]
[808] Re:左辺値としての配列名
投稿者:(ぱ)
2007/02/20 02:13:25

774RRさん: >ところで JIS X 3010 は 2003 版が発行済で 2003 版には 6.2.2.1 が無かったです。 >引用元は 1990 版でしょうか? そうです。 NykRさん: >私自身は「変換する」と書いてあるんだから変換するんだろうと思ってますが、 >例えばこんなコードをgccでコンパイルすると コンパイラがそう実装するのは当然なので、特定の3つのケースを除き「変換する」と 書いてありそれに含まれないのだから(文法上は)変換すると解釈するのが自然だろうと 私は思いますが、変換するかどうかはさておき、代入できない理由としては、 「変更可能な左辺値ではないから」という理由も挙げておくべきであるように 思います。今は無理ですが、近々Web上で対応します。 >ついでに、K&Rの附録Aでは制約が書き加えられて変換しないことになっています。 日本語版p.245ですね。規格と違う説明をするのはいかがなものかと思いますが… ポインタ完全制覇を書いているとき、これに気付いてなかったのかなあ… 今となってはすっかり忘れています。
[この投稿を含むスレッドを表示] [この投稿を削除]
[807] カナダで「ほげ通り(HOGE ST.)」を見つけました
投稿者:マモル
2007/02/20 02:13:25

はじめまして。マモルと申します。 カナダのホワイトホースという町で「ほげ通り(HOGE ST.)」を見つけました↓。 http://ameblo.jp/mamoru/entry-10009422221.html hoge研究の参考になれば嬉しく思います。また、誠に勝手ながら「ほげを考えるページ 」に無断でリンクを張らして頂きました。もし不都合があればリンクを削除いたします。 ではっ。
[この投稿を含むスレッドを表示] [この投稿を削除]
[806] 管理者により削除されました
2007/02/20 02:22:36

意味不明の投稿なので削除しました。
[この投稿を含むスレッドを表示]
[805] Re:左辺値としての配列名
投稿者:NykR
2007/02/20 02:13:25

私自身は「変換する」と書いてあるんだから変換するんだろうと思ってますが、例えばこんなコードをgccでコンパイルすると int main(void) { int a[1]; a++; return 0; } array_inc_test.c: In function `main': array_inc_test.c:4: wrong type argument to increment と、型に問題がある、というメッセージが表示されます。 a++を(&a)++と、ポインタ値のインクリメントに置き換えると array_inc_test.c:4: invalid lvalue in increment と表示されますからgccではaはポインタではないみたいです。 ついでに、K&Rの附録Aでは制約が書き加えられて変換しないことになっています。
[この投稿を含むスレッドを表示] [この投稿を削除]
[804] 管理者により削除されました
2007/02/20 02:22:56

意味不明の投稿なので削除しました。
[この投稿を含むスレッドを表示]
[803] 管理者により削除されました
2007/02/20 02:23:12

意味不明の投稿なので削除しました。
[この投稿を含むスレッドを表示]
[802] 管理者により削除されました
2007/02/20 02:23:48

意味不明の投稿なので削除しました。
[この投稿を含むスレッドを表示]
[801] Re:左辺値としての配列名
投稿者:774RR
2007/02/20 02:13:25

あう sizeof は右辺値でもいいのか。 だったら「sizeof の係る式が左辺値の場合には右辺値変換するな」って旨を コンパイラ作者に通知する条文でもあるわけだな。 結論は変わらん。
[この投稿を含むスレッドを表示] [この投稿を削除]
[800] Re:左辺値としての配列名
投稿者:774RR
2007/02/20 02:13:25

規格書の一部はコンパイラ作者向けに、一部はユーザ向けに書かれている。 で、当該項はユーザ向けだと、俺は思う。 俺がコンパイラ作るなら、左辺値が必要とされる文脈で右辺値変換するなんて無駄なことはしない。 単項 & や sizeof はまさに左辺値が必要とされるところであるから、そこで 無駄な右辺値変換を行わなければ規格書どおりの動作となるわけだ。 同じことが代入式の左辺でもいえる。 だから、俺的には配列名が代入式の左辺に現れたときに右辺値変換されるとは思わない。 「変更不可能」だから左辺におくとエラーと考えるほうが自然。 まあどう解釈しても結果は同じだからどうでもいいけど。
[この投稿を含むスレッドを表示] [この投稿を削除]
[799] Re:左辺値としての配列名
投稿者:yuya
2007/02/20 02:13:25

前橋さん、774RRさん、ありがとうございます。 > 配列に代入できないのは変更可能な左辺値ではないから なるほど、 「配列に代入できないのは、配列は左辺値だが変更不可能だから」 と考える必要はないんですね。 「『変更可能な左辺値』ではないもの」には、 「変更不可能な左辺値」だけでなく「右辺値」も含まれますから。 (a)変更可能な左辺値 (b)変更不可能な左辺値 (c)右辺値 (d)その他 に分けたとして、 ・「ポインタ完全制覇」での説明:    「配列に代入できないのは、(c)だから」 ・私が[796]で書いた説明:    「配列に代入できないのは、(b)だから」 ・おそらく最も正確な説明:    「配列に代入できないのは、(a)でないから」 「(a)でない」を満たしさえすれば 配列に代入ができないことには変わりなく、 その実態が(b)なのか(c)なのか、あるいは(d)なのかは 別問題である、ということですね。
[この投稿を含むスレッドを表示] [この投稿を削除]
[798] Re:左辺値としての配列名
投稿者:774RR
2007/02/20 02:13:25

char a[10]; char (*p)[10]=&a; // である場合に *p=0; あるいは *p={0}; であれなんであれ *p は代入式の左辺に置けません。 JIS X 3010:2003 6.5.16 代入演算子 [制約] 変更可能な左辺値でなければならない。 JIS X 3010:2003 6.3.2.1 変更可能な左辺値とは...[配列を含まない] なので >配列に代入できないのは変更可能な左辺値ではないから であり、それ以上でも以下でもないです。 ただしこの話はスレ題の「左辺値が要求される場所においても読み替えが起こるか」とは無関係。 無関係ではありますが、やはり同じく JIS X 3010:2003 6.3.2.1 型"~の配列"を持つ式は、型"~へのポインタ"の式に型変換する。 それは配列オブジェクトの先頭の要素を指し、左辺値ではない。 とありますから、スレ題に関して言えば「どちらでもいい」となります。 起こると解釈しても起こらないと解釈しても、いずれにせよ代入式の左辺に置けないことに違いは無い。 ところで JIS X 3010 は 2003 版が発行済で 2003 版には 6.2.2.1 が無かったです。 引用元は 1990 版でしょうか?
[この投稿を含むスレッドを表示] [この投稿を削除]
[797] Re:左辺値としての配列名
投稿者:(ぱ)
2007/02/20 02:13:25

>配列名は式の中では先頭要素へのポインタ(右辺値)に読み替えられる、 >という規則は、代入演算子の左側のような、 >「左辺値が要求される場所」においてもそうなのでしょうか? JIS X3010の6.2.2.1によれば、 | 左辺値がsizeof演算子のオペランド、単項&演算子のオペランド、文字配列を初期化 | するのに使われる単純文字列リテラルまたはwchar_tに適合する要素型をもつ配列を | 初期化するのに使われる文字列リテラルである場合を除いて、型"~型の配列"をもつ | 左辺値は、型"~型へのポインタ"を持つ式に型変換する。 とあります。 もし、代入演算子の左側のような「左辺値が要求される場所」においては配列から ポインタへの読み替えが行われないのだ、とするのなら、上記の3つの条件の中に 単項&演算子のオペランドを含める必要はないはずです。&演算子のオペランドは もともと左辺値が要求される場所だからです。 ということで、上記3つの箇所を除いて、(左辺値が要求されようがされまいが) 式の中では配列はポインタに読みかえられる、と解釈するのが自然ではないでしょうか。 # とはいうものの、「変更可能な左辺値」の定義からわざわざ配列が除かれている # ところからすると、配列に代入できないのは変更可能な左辺値ではないからだ、 # という解釈もできるような気が…
[この投稿を含むスレッドを表示] [この投稿を削除]
[796] 左辺値としての配列名
投稿者:yuya
2007/02/20 02:13:25

こんにちは。Cの「配列名」について、質問があります。 「ポインタ完全制覇」には、 char hoge[5]; hoge = "abcd"; がダメな理由は、hogeが右辺値だから、とあります。 配列名は式の中では先頭要素へのポインタ(右辺値)に読み替えられる、 という規則は、代入演算子の左側のような、 「左辺値が要求される場所」においてもそうなのでしょうか? 配列名は、右辺値(先頭要素へのポインタ)に読み替えられる前は、 配列オブジェクトそのものを表す変更不可能な左辺値なので、 「hoge = "abcd";がダメなのは、hogeは左辺値だけど変更不可能だから」 という説明であれば納得できるのですが、 どちらの説明が正しいのでしょうか?
[この投稿を含むスレッドを表示] [この投稿を削除]
[795] Re:ポインタってそんなに難しいか?
投稿者:774RR
2007/02/20 02:13:25

>ところで、ポインタの概念は難しくないですが、使いこなすのは大変だ 禿げ上がるほど御意。 むかーーーーしの自分のソースを見ると良くわかったりします。 >実行時に型情報を持っていると誤解する人が出そうです。 今までに扱ったCPU/コンパイラ全てで「実行時型情報をもつポインタ」って無いですね。 無駄っぽなので。ただ、規格書は何も言及してないので「あっても違反ぢゃない」です。 # CPU 何種類使っただろう? 両手ぢゃ足らんくらいだな。 メモリアドレスをどう扱うか、ソースレベルで指定してる。と言うべきだったかな。 C++ の dynamic_cast/typeid 系が扱う型情報は、ポインタ自体にではなく、 その指す先のオブジェクトにあるワケで、やはりポインタには型情報は無いな。
[この投稿を含むスレッドを表示] [この投稿を削除]