2

ある関数から別の関数に構造体を渡すにはどうすればよいですか?

typedef char word_t[MAX_WORD_LEN+1];

typedef struct {
    int nwrds;
    word_t words[MAX_PARA_LEN];
} para_t;

int
main() {
    para_t onepara;
    while (get_paragraph(onepara, MAX_PARA_LEN) != EOF) {
        put_paragraph(onepara, MAX_SNIPPET_LEN);
    }
    end_output();
    return 0;
}

int
get_paragraph(para_t p, int limit) {
    int d, i;
    word_t w;
    for (i=0;i<limit;i++) {
        if ((d=get_word(w, MAX_WORD_LEN))==EOF) {
            return EOF;
        } else if(d==WORD_FND) {
            strcpy(p.words[i], w);
        } else if (d==PARA_END) {
            new_paragraph();
            break;
        }
    }
    return PARA_FND;
}

void
put_paragraph(para_t p, int limit)  {
    int i;
    for (i=0;i<limit; i++)  {
    printf("%s\n", p.words[i]);
    }
}

strcpyを使用して、単語「w」を構造体「p」(get_paragraph内)の配列にコピーしましたが、その構造体を出力しようとすると、出力を取得できません。現在、put_paragraphは文字列を出力しませんが、理由がわかりません。

get_paragraphのget_word関数は単語を識別するために正しく機能しますが、スペースを節約するためにそれを含めていません。

4

3 に答える 3

2

para_t関数が呼び出し元に表示される方法でそれを変更する場合は、へのポインターを渡す必要があります。

Cのすべてがによって渡されるため、構造体のコピーがget_paragraph関数に渡され、コピーのみが変更されます。関数によって引数を変更する場合は、ポインターを渡す必要があります。

typedef struct {
    char p[10];
} foo;

void bar(foo *f) {
    strcpy(f->p, "hello");
}

int main() {
    foo f = {0};
    bar(&f);
    printf("%s", f.p);  // prints "hello"
}

すべてが値渡しwordsであるため、配列ではなくポインターであれば、これは機能します(ただし、ポインターを渡すことはできますが、ここでコピーを作成する必要はありません)。

ポインタはコピーされますが、ポインタのはメモリアドレスであるため、コピーに保持され、元のwords変数が参照していたのと同じメモリチャンクが変更されます。

typedef struct {
    char *p;
} foo;

void bar(foo f) {
    strcpy(f.p, "hello");
}

int main() {
    foo f = {0};
    f.p = malloc(10);
    bar(f);
    printf("%s", f.p);  // prints "hello"
}

ちなみに...

したがって、関数が引数自体に完全に新しい値を割り当てる必要がある場合は、さらに別のレベルの間接参照、つまりポインターからポインターを使用する必要があります。

于 2012-09-22T08:17:14.063 に答える
1
while (get_paragraph(onepara, MAX_PARA_LEN) != EOF) {
        put_paragraph(onepara, MAX_SNIPPET_LEN);
    }

コードでは、構造体変数onepara値で渡しました。変数をで渡すと、実際の値ではなく、変数のコピーのみが関数によってアクセスされます。したがって、変数に加えた変更はすべてコピーされ、呼び出し関数の変数には反映されません。

あなたの場合、値で渡しましたが、コードが意図したとおりに機能するためには、 とを呼び出すoneparaときに のアドレスを渡す必要があります。oneparaget_paragraphput_paragraph

関数宣言は次のようになります。

int get_paragraph(para_t *p, int limit)

void put_paragraph(para_t *p, int limit)

そして、上記の関数を呼び出すときに、のアドレスを渡す必要がありますone_para

while (get_paragraph(&onepara, MAX_PARA_LEN) != EOF) {
        put_paragraph(&onepara, MAX_SNIPPET_LEN);

関数get_paragraphおよび内では、次のように、演算子ではなく、演算子put_paragraphによって構造体のメンバーにアクセスする必要があります。->.

p->words[i](代わりにp.words[i])

たとえば、次のようにしますstrcpy

strcpy(p->words[i], w)
于 2012-09-22T12:22:42.967 に答える
0

あなたはそれを渡すことができます(そして同様に戻ることができます):

#include <stdio.h>

typedef struct
{
  int x;
  const char* str;
} T;

T fxn(T t)
{
  t.x++;
  t.str++;
  return t;
}

int main(void)
{
  T t1 = { 1, "XYZ" };
  T t2;
  printf("t1: %d, %s\n", t1.x, t1.str);
  t2 = fxn(t1);
  printf("t1: %d, %s\n", t1.x, t1.str);
  printf("t2: %d, %s\n", t2.x, t2.str);
  return 0;
}

出力(ideone):

t1: 1, XYZ
t1: 1, XYZ
t2: 2, YZ

上記の例は、構造体を値で渡す(および返す)方法を示しています。fxn()ご覧のとおり、渡されたもののコピーを取得します。したがって、渡される構造を変更する場合は、上記の例のように新しい構造を返すか、参照によって構造を渡す必要があります。

#include <stdio.h>

typedef struct
{
  int x;
  const char* str;
} T;

void fxn2(T* t)
{
  t->x++;
  t->str++;
}

int main(void)
{
  T t1 = { 1, "XYZ" };
  printf("t1: %d, %s\n", t1.x, t1.str);
  fxn2(&t1);
  printf("t1: %d, %s\n", t1.x, t1.str);
  return 0;
}

出力(ideone):

t1: 1, XYZ
t1: 2, YZ
于 2012-09-22T08:12:52.763 に答える