2012-09-22 183 views
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函数能够正确识别一个单词,并且我没有包含它以节省空间。

回答

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 
+0

-1你改变了这个问题。如果结构的成员确实是一个指针,那么是的,你*可以*传递一个结构本身的副本,因为指针的副本将被传递,并且被复制的指针将指向与原始地址相同的地址。但是,由于“单词”是一个数组,所以你不能;如果函数需要修改所述数组,则必须传递指向该结构的指针。 –

+0

@EdS。不对。您也可以通过任何类型的结构与数组成员进行通信:http://ideone.com/exSPn。顺便说一句,我已经包括了一个在我的答案中通过引用传递结构的例子。 –

+1

您只需返回原始参数的修改副本。你自己的例子表明我其实是正确的;该参数没有修改,只有一个副本。 OP正在对'get_paragraph'的参数执行一个'strcpy',并期待它被修改。我不是说你最初的例子是*错误*,我只是说它没有解决OP有问题 –

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" 
} 

在一个侧面说明...

由此推论,如果函数需要指定一个完全新的价值的争论本身,你必须使用又另一水平间接,即指向指针的指针。

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

在代码中,你已经通过通过结构变量onepara,而当你通过传递变量,只有一个变量的副本将被函数访问,而不是实际值 - 因此您对该变量所做的任何修改都将作为副本,并且不会反映在调用函数中的变量中。

在你的情况,你已经通过了价值onepara,但对你的代码像预期的那样,你需要传递的onepara地址同时呼吁get_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_paragraphput_paragraph地址,您需要通过->运营商而不是.运营商访问结构的成员如下:

p->words[i](的p.words[i]代替)

例如,你会做strcpy如,

strcpy(p->words[i], w)