質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

1回答

3648閲覧

[C言語] なぜこの "printf" はまとめて出力されるのでしょうか

Sophian

総合スコア36

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

2グッド

1クリップ

投稿2016/03/13 12:43

編集2016/03/16 08:43

###前提・疑問
お世話になります。
恐ろしく長文になりそうなので外部リンク失礼いたします。

ACM/ICPC国内予選 出題
上記の問に対するコードがあるのですが、入力に対し、なぜ出力がこうなるのでしょうか。
(コード、入力および出力結果は以下に記載してあります)

入力の最後の

"0 0"

にて "break" され、その際に、

"printf("%d\n",shuffle(n,r));"

が2回続けて出力?されているように見えます。
呼び出されている "shuffle(n,r)" は手続き通り実行されて、結果を最後の "Break" でまとめて表示?されているのでしょうか。

この入力ではこのソースコードで無限ループが計2回実行されています。そしてさいごの

"0 0"

にてループを脱出し、その際、その後の"printf" は実行されないはずです。

最初から最後まで入力している間、全く出力がなく、無限ループの1ループ目で "printf" が実行されていないように見えます。

なぜこうなるのでしょうか。

自分で調べてみたところ、「Eclipseにおいて "scanf" 後の "printf" は正常に動作しない」との記述があり、解決策として間に "fflush" を挟む、というのがあったのですが、これと関係あるのでしょうか。

もしEclipse特有の症状であるなら、上記URLのようなコンテストでの出題で、それらを利用することに対して不安があるのですが…。

「一つ一つ順番に処理される」と盲目的に信じ込んでいたので、このように出力される事態が全く理解できません。自分でもどう質問していいのかわからない状態です…。

文章が支離滅裂で申し訳ありませんが、解答よろしくお願いします。

###ソースコード

C

1int shuffle(int n,int r){ 2 3 int i, deck[n+1], temp[n+1]; 4 5 for(i=1;i<=n;i++) 6 deck[i] = n-i+1; 7 8 while(r-->0){ 9 int p,c; 10 scanf("%d %d",&p,&c); 11 for(i=1;i<p;i++) 12 temp[i]=deck[i]; 13 for(i=p;i<p+c;i++) 14 deck[i-p+1]=deck[i]; 15 for(i=1;i<p;i++) 16 deck[i+c]=temp[i]; 17 } 18 19 return deck[1]; 20} 21 22int main(void){ 23 24 for(;;){ 25 int n, r; 26 scanf("%d %d",&n,&r); 27 if(n==0)break; 28 printf("%d\n",shuffle(n,r)); 29 } 30 31 return 0; 32} 33

###入力
5 2
3 1
3 1
10 3
1 10
10 1
8 3
0 0

###出力
4
4

###補足情報(言語/FW/ツール等のバージョンなど)
Eclipse Cpp Mars

star24star, lib👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

こんにちは。

Windowsのコマンド・プロンプトで入力をコピペして与えたら、下記のようになりました。

5 2 3 1 3 1 4 10 3 1 10 10 1 8 3 4 0 0

分かりにくいですが、4が単独で出ている行がプログラムからの出力です。
このように動作するプログラムのようです。

shuffle()の中にscanf()がありますが、これはmain()のscanf()で読まれたrの回数だけ実行されるようです。
最初は2なので、3 13 1まで読まれてその結果の4が出力されてます。
次は3なので、1 1010 18 3まで読まれてその結果の4が出力されてます。

eclipseで出力される場所が異なるのは、バッファリングのやり方がWindowsのコマンド・プロンプトと異なるからだろうと思います。
たぶん、eclipseが表示するのは、コマンド・プロンプトのように"\n"が来た時ではなく、プログラムの終了、もしくは、バッファサイズを越える出力があった時ではないかと思います。

投稿2016/03/13 13:01

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Sophian

2016/03/13 13:24

毎度、お世話になります, m( _ _)m。 なるほど…、命令のたびに出力があるだろうと思い、ループのたびに出力される値(デッキの一番上のカード)を配列にプールしておき後でまとめて吐き出す、という構造にしてこの問題を解いたのですが、どうもうまくいかず…。 解答を受けて、Visual Studioへの乗り換えを考え、まったく同じコードをVisual StudioのVC++Win32 コンソールアプリケーションのプロジェクトに張り付けてコンパイルしてみたところ…。もうエラーが大量に…。そもそもコンパイルできないという…。 もうすこし自分で考えてみたいと思います。 ありがとうございました。 ちなみにこの模範コードは http://www.ipsj.or.jp/07editj/promenade/4512.pdf より持ってきました。
Chironian

2016/03/13 14:25 編集

あ、Visual Studioは下記のような配列定義をサポートしていません。 私はMinGWというWindowsで走るgccを使って確認しました。 > int i, deck[n+1], temp[n+1]; nがコンパイル時にきまっている必要があるのです。gccはサボートしています。 ↓を見ると分かりやすいです。 http://qiita.com/raccy/items/bfcb62086c5f027d57b6 でも、VLAはあまり積極的には使わない方がよいと思います。 スタック上にメモリを取るのでサイズに制限があるし、C++はサポートしてませんし。 【追記】 あう、先頭行をコピペミスしてました。ちゃんと読み取ってくれてありがとうです。
Sophian

2016/03/13 14:10

補足ありがとうございます! おっしゃる通り、以下の > int i, deck[n+1], temp[n+1]; にてエラーが吐き出されました…。 記憶は曖昧ですが、私はMinGWをインストール後、Eclisep→Visual Studioをインストールしました。Eclipseも?MinGW?を使用しているのかと思っていました。 C++では、nがコンパイル時にきまっている必要がある、ということでしょうか、故にC++のコンパイラーを使っているVisual Studioではこの表記ができないということでしょうか。 なるほど…、この表記には気を付けるようにします! 質問攻めにして申し訳ありません。m( _ _)m
Chironian

2016/03/13 14:36

> Eclipseも?MinGW?を使用しているのかと思っていました。 たぶん、MinGWを使っているだろうと思います。 バッファリングの問題はコンパイラだけの問題ではないです。 表示を行う「コンソール」ソフトもバッファリングするのです。 ですので、これはeclipseとWindowsのコマンド・プロンプトの動作の違いですね。 > C++では、nがコンパイル時にきまっている必要がある、ということでしょうか、 C++の規格にてそのように決められているようです。 コンパイラによっては独自拡張している場合もあります。MinGWはC++としてコンパイルしても通りました。 > 故にC++のコンパイラーを使っているVisual Studioではこの表記ができないということでしょうか。 いえ、拡張子がcならばCコンパイラとして動作しますので、単にマイクロソフトの手抜きではないかと思います。 なんかややこしいですね。 標準規格では、C++は可変長配列をサポートしない、Cはサポートする。 gccは可変長配列をC++/Cの両方でサポートし、msvcはどちらもサポートしない。 です。
Sophian

2016/03/13 15:46

Chironianさん、丁寧な解答ありがとうございます! 私はCuda Cを学びたい、ということもあり、今は記述がCであること(C++ではなく)にこだわりたく思います。ですが、後々のことを考えてもやはり、Cだけではなく、C++の知識も必要だと感じました。 なので目前は、C++でもCでも通用するCの書き方、Chironianさんのおっしゃる通りVLAは控える等、欲を言えばEclipseでもmcvcでも通用する書き方も、可能な限り(私なりに;;)意識して記述したいと思います!! m( _ _)m
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問