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如果您希望函数以调用者可见的方式修改它,则需要传递一个指向 a 的指针。

C 中的所有内容都是通过value传递的,所以你的结构的副本被传递给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按值传递,但是为了使您的代码按预期工作,您需要传递oneparawhile 调用get_paragraphand的地址put_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_paragraphand中,您需要通过运算符而不是运算符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 回答