- 1 名前:デフォルトの名無しさん mailto:sage [2008/01/24(木) 14:52:45 ]
- このスレは標準C規格や規格に合致した移植性の高い記法・技法に関するスレです。
C言語初心者の初歩的な質問、GUIなどの標準Cではできない事の質問、 ソース丸投げ、宿題、書籍 などは専門の別スレッド↓があるのでそちらへ。 C言語なら俺に聞け(入門篇) Part 24 pc11.2ch.net/test/read.cgi/tech/1201083176/ 【初心者歓迎】C/C++室 Ver.47【環境依存OK】 pc11.2ch.net/test/read.cgi/tech/1200464091/ C/C++の宿題を片付けます 103代目 pc11.2ch.net/test/read.cgi/tech/1200318925/ 【書き込む前に】 ・まず問題を冷静に吟味してCの話か否かをはっきりさせてから質問しましょう。 ・質問する前には最低限検索を。 ・エラー(警告含む)が起きたのならばエラーメッセージを書きましょう。 【参考文献】 C FAQ 日本語訳 www.kouno.jp/home/c_faq/ Cプログラマ必読 ・プログラミング言語C(通称 K&R) www.amazon.co.jp/exec/obidos/ASIN/4320026926/250-7563469-9920244 【このスレのログ】 前スレ:pc11.2ch.net/test/read.cgi/tech/1190261457/ 他の過去ログ:nssearch.hp.infoseek.co.jp/clang/ 【このスレ住人としての心得】 わざとスレ違いあるいはごく低レベルな質問を繰り返して 流れを妨害する荒らしがいます。適当に誘導して放置してください。
- 350 名前:デフォルトの名無しさん mailto:sage [2008/08/06(水) 14:47:43 ]
- >>349
規格的には不定だよ. {} の中では新たなスコープが有効になるので {} 内の a が 宣言された瞬間に {} 外の a は shadow される # 言い方が厳密じゃないんだけど、言いたいこと分かってね Lisp 系言語の (let ((a 3)) (let ((a a)) (???? a))) ==> (let ((a 3)) (lambda (a) (??? a)) a) みたいな物を, 求めてはいけない
- 351 名前:349 (>>348 じゃないよ) mailto:sage [2008/08/06(水) 14:56:08 ]
- >>350
こういうのはOKですか? int a = 3; { int b = a; int a = b; printf( "a=%d b=%d", a, b ); }
- 352 名前:デフォルトの名無しさん mailto:sage [2008/08/06(水) 15:01:52 ]
- >>351 いや、だから…
言い方が悪かったのかorz {} 外の名前が {} 内で宣言されたら shadow される 処理系によっては「{} 外の a」が意味をなす場合もあるかも知れないが 可搬なプログラムを書こうと思ったら、その事実に依存してはならない
- 353 名前:349 mailto:sage [2008/08/06(水) 15:07:08 ]
- >>352
規格では変数の宣言順序に関係なく 同一スコープ内で同名の変数が現れた場合には 外側の変数は見えなくなる だから >>351 は次のようにしないと動作の保証ができないということですね int a = 3; { int b = a; { int a = b; printf( "a=%d b=%d", a, b ); } }
- 354 名前:デフォルトの名無しさん mailto:sage [2008/08/06(水) 16:13:40 ]
- JIS X 3010-1993 には以下のように書いてあるけどこれからは判断できなかった。
6.1.2.1 識別子の有効範囲 識別子は、有効範囲(scope)と呼ぶプログラムテキストの範囲にあるときだけ、可視(visible) (すなわち、使用可能)とする。有効範囲は、関数、ファイル、ブロック、及び関数原型の4種類とする。 識別子を宣言する宣言子又は型指定子がブロック内又は関数定義の仮引数宣言子の並びに現れる場合、 その識別子はブロック有効範囲(block scope)をもち、その範囲は対応するブロックを閉じる}によって 終了する。 字句的に同一な識別子のより外側の宣言が同一の名前空間にある場合、外側の宣言は現在の 有効範囲が終了するまで不可視となり、その後再び可視となる。 二つの識別子は、有効範囲が同じ場所で終わる場合、そしてその場合に限り同じ有効範囲を持つ。
- 355 名前:デフォルトの名無しさん mailto:sage [2008/08/06(水) 16:48:27 ]
- そうか?
はっきり書いてあると思うんだが。
- 356 名前:349 mailto:sage [2008/08/06(水) 23:17:37 ]
- >>354 を読んで解釈のひとつとして
int a, *p=&a; // これは OK int *q=&b, b; // これは NG ということは有効範囲とは変数の宣言順序によって変化するのではないか? >>351 の int b=a; の時点ではブロック内で変数 a が未定義であるため 外側の a が可視だから動作が保障されるのでは?
- 357 名前:デフォルトの名無しさん mailto:sage [2008/08/06(水) 23:58:57 ]
- いや、shadowされているが未定義である状態。
- 358 名前:349 mailto:sage [2008/08/07(木) 00:23:41 ]
- >>357
>>354 のこの部分 >識別子を宣言する宣言子又は型指定子がブロック内又は関数定義の仮引数宣言子の並びに現れる場合、 >その識別子はブロック有効範囲(block scope)をもち、その範囲は対応するブロックを閉じる}によって >終了する。 これは有効範囲の終わりについてのみ言及しており、 変数自体は変数宣言以降から有効になるのではないの?
- 359 名前:デフォルトの名無しさん mailto:sage [2008/08/07(木) 00:29:19 ]
- だからそういっているんだが。
- 360 名前:349 mailto:sage [2008/08/07(木) 00:52:52 ]
- shadow されるのは
1.同一変数名の定義されているブロックの開始部分からなのか 2.それとも同一変数名が宣言された後なのか というところで 2 で解釈可能では? ちなみに下記のコードで gcc および Borland C++ Compiler では、警告も無し // 出力結果は a=2.000000 *p=3 が保障される? #include<stdio.h> int main(){ int a=3; { int *p=&a; double a=2.0; printf("a=%f *p=%d\n", a, *p); } return 0; }
- 361 名前:349 mailto:sage [2008/08/07(木) 01:15:04 ]
- >>360 の
int *p=&a; の行が規格としては 1.エラーになるべきか 2.未定義(実装依存、鼻から悪魔)か が知りたいのですが >>357 さんは 2 ということでしょうか?
- 362 名前:349 mailto:sage [2008/08/07(木) 01:16:35 ]
- >>361 に追記
3.定義済み (>>360 のコードは規格に沿っている)
- 363 名前:デフォルトの名無しさん mailto:sage [2008/08/07(木) 01:17:28 ]
- ISO の、ダウンロードできるドラフトでは >354 が引用した部分の直後にスコープの開始位置に
ついての説明があった。それによると、変数名のスコープが始まるのは変数宣言内の変数名の 直後。 ってことで >351 は OK 。
- 364 名前:349 mailto:sage [2008/08/07(木) 01:20:49 ]
- >>363
ありがとうございます スッキリしました これでゆっくり眠れます
|

|