一回も披露したことのない豆知識

C言語初心者です。以下のようなtypedefの構造体から関数に配列の値を出したいとき、どのようにすれば良いのでしょうか。
#include <stdio.h>
typedef struct aaa{
int *a; int *b;
}test;
void x(test *tp);
int main(void){
test s[2];
s[1].a=1;
s[2].b=2;
x(&s);
}
void x(test *tp){
int y;
for(y=1;y<=2;y++){
printf("%d\n",tp[y].a);
}
}
上のプログラムで、1,2と表示させたいのですが受け渡し方法がよく分かりません。

A 回答 (3件)

やりたいことが解りませんが、配列の扱いもまだ十分理解できていないのでは?


加えてコンパイル時の警告オプションを増やしてやれば、その警告もプログラム改善のヒントになると思います

やりたいことは次のどちらかだと思うのですが…
#include <stdio.h>

typedef struct aaa {
int a;
int b;
} test;

void x( test *tp );

int main( void ) {
test s[2];
s[0].a = 1;
s[1].a = 2;
x( s );
}

void x( test *tp ) {
int y;
for ( y = 0; y < 2; y++ ) {
printf( "%d\n", tp[y].a );
}
}

/* ---------------------------------------------------------------------- */
#include <stdio.h>

typedef struct aaa {
int a[2];
} test;

void x( test *tp );

int main( void ) {
test s;
s.a[0] = 1;
s.a[1] = 2;
x( &s );
}

void x( test *tp ) {
int y;
for ( y = 0; y < 2; y++ ) {
printf( "%d\n", tp->a[y] );
}
}
    • good
    • 0

同じく何をしようとしているのかさっぱりわからんが....



もろもろやったとしても, 「表示させたい」という「1」「2」が
s[1].a と s[2].b の値
のことだとしたら, for でまわすのは単純ではない. offsetof とかを駆使すればできるのだが, そんなことするよりも
メンバーを配列にする
方が簡単だ.

ちなみにそのプログラムの場合 s と &s は型が違う. 値 (アドレス) は同じだけど.
    • good
    • 0

うーん、何がやりたいか良く分からんのですけど。



>test s[2];
>s[1].a=1;
>s[2].b=2;

・配列の長さが「2」でインデックスは「0」と「1」の筈なのに、インデックスに「1」と「2」を指定する初歩的ミスを犯してる。

>typedef struct aaa{
> int *a; int *b;
>}test;

・構造体でint*としてポインタ型変数を宣言してるが、ポインタ型変数に代入されるのは基本的には「アドレス」である。
なのに、

>test s[2];
>s[1].a=1;
>s[2].b=2;

として「アドレスが代入されるべき変数」に、整数「そのもの」を代入しようとしている。両辺の型が不整合だし、1も2もそのままではアドレスを持たない。
従って、例えば、

int i = 1, j = 2

と変数を宣言しておいて、

test s[2]
s[0].a = &i;
s[1].b = &j

とすべきだろう。
なお、s[0].bとs[1].aには何も代入されていない。

> x(&s);

xの定義は

void x(test *tp);

で、どっちみちsは配列なので、先頭アドレスがxに手渡される。
従って、&sで手渡すのは間違い。

x(s);

で充分である。

> printf("%d\n",tp[y].a);

この辺は最終的にはどーしよーもない。
まず、tp[y].aはポインタなので持ってる値は「アドレス」である。が、これは書式指定の%dでは出力出来ない。恐らくコンパイル時にWarningが出るか、あるいは、コンパイル済バイナリを走らせると素っ頓狂な値が表示される。
まず最初は

printf("%d\n", *tp[y].a);

にする。
ポインタのクソ困ったトコは、宣言の時の*は「アドレスだよ〜ん」って言ってるのに、使用の際の*は「ポインタが指すアドレスに入ってる値」を意味してて、*が無い時には「アドレス」だ、と言う事。ぶっちゃけ、意味が真逆である。ポインタ周りの文法が破綻してるのがCが芯から腐ってる辺りだ。
つまり、使用時の、

tp[y].a

はアドレスを意味してて、%dは受け付けない。逆に

*tp[y].a

にすれば、tp[y].aが指すアドレスに書き込まれた値が表示される。

ただ、そこを直しても問題は解決しない。恐らくセグメンテーションフォールトが起こる。略してセグフォだ。
と言うのも、さっき書いた通り、s[1].aは何も代入されてないので、指し示すトコがない。いわゆるヌルポインタである。2ch(現5ch)的に言うと「ぬるぽ」だ。
当然%dと言う書式設定はヌルポインタの出力は受け付けない。元々欠けてる情報はどうしようもない。
単にエラーを出したくない、ってだけなら、

printf("%p\n", tp[y].a);

が一番無難かもしんない。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!