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

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

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

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

Q&A

解決済

3回答

915閲覧

C言語の変数仕様と出力結果について

Tsutsujun_1231

総合スコア19

C

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

0グッド

0クリップ

投稿2020/02/04 08:22

編集2020/02/04 15:14

恐らく、はじめて質問させていただきます。
大学で習ったC言語を復習しはじめたのですが、以下のソースコードを記述して色々とトライして考えてみたところ、よく分からなくなってしまいました。
なぜ、このような結果になるのでしょうか?

もちろん、printf文の書式内の変数と変数仕様は1対1に対応していなければならないのは分かっているのですが、試しに後ろの「, 変数」のところを省略してみたら、以下のような結果になりました。

###ソースコード(言語は ANSI C です。)

C

1#include <stdio.h> 2 3int main(void) 4{ 5 char a; int b; 6 float c; double d; 7 8 a='K'; b=123456; 9 c=123.456; d=0.123456789; 10 11 printf("a=%c\n"); 12 printf("b=%d\n"); 13 printf("c=%f\t"); printf("c=%15.10f\n"); 14 printf("d=%f\t"); printf("d=%15.10f\n"); 15 16 return 0; 17}

<メッセージ(これは当たり前ですが・・)>
警告 W8004 program02_2'.c 17: 'd' に代入した値は使われていない(関数 main )
警告 W8004 program02_2'.c 17: 'c' に代入した値は使われていない(関数 main )
警告 W8004 program02_2'.c 17: 'b' に代入した値は使われていない(関数 main )
警告 W8004 program02_2'.c 17: 'a' に代入した値は使われていない(関数 main )

<出力結果>
a=
b=2147348480
c=0.000000 c= 0.0000000000
d=0.000000 d= 0.0000000000

試したこと

①printf文内に各変数を1種類ずつ割り当てたところ、'b'に代入した値を使ったときのみ全体が異なる出力結果となりました。

②①より、printf("b=%d\n",b);のところをコメントアウトすると、'a'のみ異なる出力結果となりました。

<①出力結果>
a=ク
b=123456
c=+NAN c= +NAN
d=+NAN d= +NAN

<②出力結果>
a= ←ASCIIコード01の値
c=0.000000 c= 0.0000000000
d=0.000000 d= 0.0000000000

他にも、最初の結果b=2147348480の実態を調べるために、%xで16進数表示をして出力を何回か繰り返したら、7ffdb000~7ffdf000の範囲でランダム(結果的には7ffdf000となることが多かった)に値が出力されたり、
a= と表示されていることからASCIIコード00のNULLが出力されているのではないかと考えたりしたんですが、①の結果からどうも違うようだし、
本来でしたらゴミのデータとしてスルーすべきなのでしょうが、どうも気になって仕方ありません。
なぜ変数仕様%dはこのような特殊な挙動(?)を示し、それにより他の変数仕様の部分の結果までおかしくなるのでしょうか?

補足情報(FW/ツールのバージョンなど)

  • OS:Windows8.1
  • コンパイラ:Borland C++ 5.5.1 for Win32
  • 開発環境:CPad for Borland C++Compiler Ver 2.31

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

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

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

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

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

guest

回答3

0

本来でしたらゴミのデータとしてスルーすべきなのでしょうが、どうも気になって仕方ありません。

気にしても仕方ありません。

未定義の動作タイムトラベルを起こしても構わないと言われるようなものです。今日そのような結果が出て、明日実行すればまた違うかもしれないし、もしかしたらOSごとクラッシュするかもしれない、その程度のものです。

投稿2020/02/04 08:34

maisumakun

総合スコア145184

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

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

Tsutsujun_1231

2020/02/04 08:40

回答ありがとうございます。 OSクラッシュは避けたいものです。笑
maisumakun

2020/02/04 08:40

(あくまで推測の範囲内ですが)可変長引数はスタックに積まれますので、個数を違えるとスタックポインタがおかしくなります。
episteme

2020/02/04 19:15

↑可変長引数が許されるC/C++の場合、スタックは呼び側が元に戻すので心配には及ばんのちゃうかな。 # 言語仕様に未定義とある以上、どうなっても文句言えんのは変わらんけど
guest

0

どうも気になって仕方ありません。なぜ変数仕様%dはこのような特殊な挙動(?)を示し…

いったい、どこの、どういうゴミなのか・・・既に回答がついている通り、それはC言語の未定義動作なのでC言語の挙動として説明することがそぐわない問題だと言えます。でも全く説明不能な問題でもありません。私にはある程度その挙動が見えています。しかし今の貴方に説明する気力はありません。

 C言語 一皮むけば アセンブラ (るばーと心の俳句w)

ということで、Cのコードをアセンブリコードに変換し、アセンブリコードを読んでみれば・読めるようになれば、何が起こっているのか、その動きが見えるようになります。逆に、それなしに説明を受けても、ある程度状況が見えてきたとしても、どこかに釈然としないものが残ると思います。貴方の霧を晴らすのはアセンブリコードを読む力です。
要するに、気になって仕方ないのであればアセンブリ言語を勉強することです。少々道のりは長いでしょうが、それが完全な解決への道です。C言語では他にも不可解な事象や理解に苦しむ事柄に遭遇することがありますが、アセンブリ言語の知識があると理解できるものがあります。たとえば、アセンブリ言語の経験があったからポインタで悩まなかった、という人の声を私はたくさん聞いています。
また、この界隈には私以上に「アセンブリコードを読め!」とおっしゃる方がいらっしゃいましたから、「さっさとアセンブリコードを読まんかい!そのあと出なおして来い!」と心の中で叫んでいるのではないかと思っています。

投稿2020/02/04 16:17

rubato6809

総合スコア1380

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

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

Tsutsujun_1231

2020/02/04 16:46

回答ありがとうございます。 どうも、細かいことっていうか、ちゃんと理解しようと思ってしまう性格なので、Cの学習を進めつつ似たような問題に直面したら、アセンブリ言語も勉強してから質問するようにします!
guest

0

ベストアンサー

引数を省略したら、たまたまそこのメモリエリアにあった値が出力されます。
早い話がでたらめな値が出力されるってことで、なにが出力されるかはわかりませんし、なにが出てきても文句は言えないということです

投稿2020/02/04 08:28

y_waiwai

総合スコア87774

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

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

Tsutsujun_1231

2020/02/04 08:34

回答ありがとうございます。 メモリのどこからかテキトウに持ってきた値なんですね。
y_waiwai

2020/02/04 08:40

そゆことです。 関数の実行順序でも変わりますし、コンパイラの設定次第でも変わるでしょう。 また、不正アクセスとしてエラーが出たり暴走したりしても不思議ではない状態だと思っておいてください。
Tsutsujun_1231

2020/02/04 08:48

ありがとうございます。プログラムの暴走は避けるべきなのでちゃんと修正しておきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問