私はこの簡単なプログラムを持っています:
#include <stdio.h>
struct time
{
int hours ;
int minutes ;
int seconds ;
} t[2] = {1,2,3,4,5,6};
int main() {
struct time *tt = t;
printf("%d\n", (*tt));
printf("%d", *(tt+1));
}
これで、期待される出力は次のようになります。
1
4
しかし、私が得ている出力は、2つのまったく同じメモリアドレスです。私はこのプログラムを他の人に送りました、そして、いくつかは期待された出力を持っていますが、いくつかはそうではありません。これはCまたはGCCのバージョンの問題だと思います。それは解決可能ですか?私のバージョンのCでこれが発生している理由について何か説明はありますか?
最も奇妙なことは、ポインターを逆参照した後でも、アドレスを出力していることです。これはどのように可能ですか?
一方、プログラムをこれに変更すると、次のようになります。
$include <stdio.h>
struct time
{
int hours ;
int minutes ;
int seconds ;
} t[2] = {1,2,3,4,5,6};
int main() {
struct time *tt = t;
printf("%d\n", (*tt).hours);
printf("%d", (*(tt+1)).hours);
}
期待される出力を出力します。
この振る舞いの説明は何ですか?ありがとう。
問題はコンパイラではなく、Cの理解にあります。GCCバージョン7.3.0(Ubuntu 7.3.0-27ubuntu1〜18.04)でコンパイルしましょう。
% gcc struct_time.c
struct_time.c: In function ‘main’:
struct_time.c:12:14: warning: format ‘%d’ expects argument of type ‘int’,
but argument 2 has type ‘struct time’ [-Wformat=]
printf("%d\n", (*tt));
~^ ~~~~~
struct_time.c:13:14: warning: format ‘%d’ expects argument of type ‘int’,
but argument 2 has type ‘struct time’ [-Wformat=]
printf("%d", *(tt+1));
~^ ~~~~~~~
あなたのフォーマットは、対応する引数として%d
を期待int
するものであり、あなたはを渡していstruct time
ます。変換指定子が実際の引数のタイプと一致しないため、プログラムの動作は未定義です。
値がメモリ内のどこにあるかは関係ありません。値のタイプも重要です。のアドレスはtt[0]
と同じですが、tt[0].hours
タイプが異なります。1つは構造体全体が必要で、もう1つは最初のメンバーに含まれる値が必要です。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加