将一组结构传递给函数?

时间:2014-12-28 04:28:42

标签: c arrays function struct

我想学习如何通过引用将一个结构数组传递给second function中调用/执行的first function。我的目标是从second function 修改/更改任意结构的内容。下面的代码可行,但遗憾的是,它并没有完全符合我的要求。我想访问second function中的任意结构。换句话说,我想在for内通过调用/执行second function first function一次来处理所有结构(使用main循环)而不是使用for循环。

以下代码中的second function名为passByReference_inner

array_of_struct.h:

struct card
{
    int face;
    int nose;
};

typedef struct card HEAD ;

/* prototype */
extern void passByReference(HEAD **c);      /* first function */
extern void passByReference_inner(HEAD *c); /* second function */

第一个功能:(passByReference)

#include <stdio.h>
#include "array_of_struct.h"

void passByReference(HEAD **c)
{
    passByReference_inner (*c);   /* second function */
}

第二个功能:(passByReference_inner)

#include <stdio.h>
#include "array_of_struct.h"

void passByReference_inner(HEAD *c)
{
    c->face = (c->face) + 1000;
    c->nose = (c->nose) + 2000;
}

主要

#include <stdio.h>
#include "array_of_struct.h"

int main(void)
{
    int             i;
    static HEAD     c[12];
    static HEAD *cptr[12];

    for ( i = 0; i < 12; i++ )
    {
        c[i].face = i + 30;
        c[i].nose = i + 60; 
        cptr[i]   = &c[i];
    }

    for ( i = 0; i < 12; i++ )
    {
        passByReference(&cptr[i]);  /* first function */
    }
    return 0;
}

4 个答案:

答案 0 :(得分:3)

我认为你要做的就是这个

#include <stdio.h>

struct card
{
    int face;
    int nose;
};

typedef struct card HEAD ;

/* prototype */
void passByReference(HEAD *c, int count);      /* first function */
void passByReference_inner(HEAD *c); /* second function */

void passByReference(HEAD *c, int count)
{
    int i;
    for (i = 0 ; i < count ; i++)
        passByReference_inner (&(c[i]));   /* second function */
}

void passByReference_inner(HEAD *c)
{
    c->face = (c->face) + 1000;
    c->nose = (c->nose) + 2000;
}

int main(void)
{
    int  i;
    HEAD c[12]; /* you don't need static here (do you know what static is for?) */

    for ( i = 0; i < 12; i++ )
    {
        c[i].face = i + 30;
        c[i].nose = i + 60;
    }
    /* 
     * the element count of the array is sizeof(c) / sizeof(c[0]) 
     *    (totalSizeOfArray) / (indivudualElementSizeOfArray).
     */
    passByReference(c, sizeof(c) / sizeof(c[0]));  /* first function */

    return 0;
}

你应该知道的是c中的数组在作为参数传递给函数时会衰减到指向其第一个元素的指针。

由于你想处理第二个函数中的所有结构,我不会看到第一个函数的需要,无论如何这就是你如何做到的

#include <stdio.h>

struct card
{
    int face;
    int nose;
};

typedef struct card HEAD ;

/* prototype */
void passByReference(HEAD *const c, int count);      /* first function */
void passByReference_inner(HEAD *const c, int count); /* second function */

void passByReference(HEAD *const c, int count)
{
    passByReference_inner(c, count);   /* second function */
}

/* HEAD *const c prevents the pointer c to be changed
 * this way it will never point anywhere else.
 *
 * And you can be sure to alter the original data.
 */
void passByReference_inner(HEAD *const c, int count)
{
    for (int i = 0 ; i < count ; ++i)
    {
        c[i].face = (c[i].face) + 1000;
        c[i].nose = (c[i].nose) + 2000;
    }
}

int main(void)
{
    int  i;
    HEAD c[12]; /* you don't need static here (do you know what static is for?) */

    for ( i = 0; i < 12; i++ )
    {
        c[i].face = i + 30;
        c[i].nose = i + 60;
    }
    /* 
     * the element count of the array is sizeof(c) / sizeof(c[0]) 
     *    (totalSizeOfArray) / (indivudualElementSizeOfArray).
     */
    passByReference(c, sizeof(c) / sizeof(c[0]));  /* first function */

    return 0;
}

因为你实际上是在传递一个指针,所以你可以直接在第一个和第二个函数中改变它的内容。

还有一件事,你真的不需要static关键字,特别是main()static在函数调用之间保留变量的值,并且main()static通常在程序的生命周期中只调用一次...在那里使用{{1}}没有多大意义。

答案 1 :(得分:1)

你的第二个功能是正确的。

指向数组第一个元素的指针实际上与指向数组本身的指针相同。

你应该做的是

void passByReference_inner(HEAD *c, size_t n)
{
}

因此,您将把指针传递给数组的第一个元素,以及数组中元素的数量,如下所示:

passByReference(c, sizeof(c)/sizeof(c[0]));

这会将指针传递给c数组的第一个元素,以及数组中元素的数量,传递给passByReference_inner()。 sizeof(c)是整个数组的大小(以字节为单位)。 sizeof(c [0])是数组中元素的大小。因此,例如,如果每个结构长度为10个字节(只是一个示例),并且您有一个包含12个结构的数组,则整个数组的大小为120个字节,这将计算值120/10 = 12,数组中的元素数量,自动。

使用数组对象的名称时,在C / C ++中自动成为指向数组第一个元素的指针。

在您的函数中,您可以按以下方式使用数组:

void passByReference_inner(HEAD *c, size_t n)
{
    for (size_t i=0; i<n; i++)
    {
        HEAD *p=c+i;

        // p is now a pointer to the ith element of the array
    }
}

向指针添加整数n会将指针前进到数组的下一个nth元素。向指针添加整数值不会使指针超过此字节数,而是通过指针指向的对象中的字节数乘以您添加的数字(或减去相同的数字)。这使得指针算法做对了。

答案 2 :(得分:0)

  • 以下代码干净利落地编译。
  • 以下代码移动增量值循环
     在passByReference()函数内部。

/* 
 * Note: guard code is used in a header file
 *       so the header file can only be included once
 *       in each compilation unit 
 */

// note the inclusion of a 'guard' wrapper
// begin: array_of_struct.h file
#ifndef ARRAY_OF_STRUCT_H
#define ARRAY_OF_STRUCT_H

struct card
{
    int face;
    int nose;
};

// dont obsecure the code with useless typedef statements
//typedef struct card HEAD ;

#define MAX_CARDS (12)

/* prototype */
extern void passByReference(struct card *pCards);      /* first function */
extern void passByReference_inner(struct card *pCard); /* second function */
#endif
// end: array_of_struct.h


//first function: (passByReference), in different file

#include <stdio.h>
#include "array_of_struct.h" 

void passByReference(struct card *pCards)
{
    int i=0; // loop index

    for(i=0;i<MAX_CARDS;i++)
    {
        passByReference_inner (&pCards[i]);   /* second function */
    } // end for
} // end function: passByReference

// second function: (passByReference_inner), in different file

#include <stdio.h>
#include "array_of_struct.h"

void passByReference_inner(struct card *pCard)
{
    pCard->face = (pCard->face) + 1000;
    pCard->nose = (pCard->nose) + 2000;
} // end function: passByReference_inner

//main, in a different file

#include <stdio.h>
#include "array_of_struct.h"

int main()
{
    int i = 0; // loop index
    static struct card     cards[MAX_CARDS];

    for ( i = 0; i < MAX_CARDS; i++ )
    {
        cards[i].face = i + 30;
        cards[i].nose = i + 60;
    } // end for

    passByReference(&cards[0]);  /* first function gets ptr to whole array*/
    // could also be written as:
    // passByReference(cards);

    return 0;
} // end function: main

答案 3 :(得分:0)

我已经分析了所有三种解决方案(iharob,user3629249,Sam Varshavchik)并得出结论,Sam Varshavchik和iharob的第二个解决方案是对的。第一个iharob的解决方案和user3629249解决方案实质上是相同的。他们将for循环从main移至first function。 iharob的帖子的第二个解决方案符合初始帖子的要求。 Sam的解决方案给了我足够的提示/说明如何将for循环从主要移动到second function(基本上,我不知道该怎么做它并因此寻求帮助)。

所以,简而言之,这里的源代码几乎可以实现所有贡献者的所有建议。代码编写得很干净,所以像我这样的初学者可以按原样使用它,并学习一些关于指针指针,指针算法和结构数组的详细信息。

array_of_struct.h (标题文件)

#ifndef ARRAY_OF_STRUCT_H
#define ARRAY_OF_STRUCT_H

/* HEAD structure definition */
typedef struct
{
    int face;
    int nose;
} HEAD;       // end structure HEAD

#define MAX_HEADS (12)

/* prototype */
extern void passByReference(HEAD **c, size_t n);
extern void passByReference_inner(HEAD *c, size_t n);

#endif

passByReference.c (第一个功能)

#include <stdio.h>
#include "array_of_struct.h"

void passByReference(HEAD **c, size_t n)
{
    passByReference_inner (*c, n);
}

passByReference_inner.c (第二功能)

#include <stdio.h>
#include "array_of_struct.h"

void passByReference_inner(HEAD *c, size_t n)
{
    int   i;
    HEAD *p;

    printf("\nPOINTER ARITHMETIC: The value of struct's  members after PASS BY REFERENCE \n");
    for ( i = 0; i < n; i++ )
    {
        p = c + i;

        p->face = (p->face) + 1000;
        p->nose = (p->nose) + 2000;
        printf("struct[%i].face = %d  \n",i, p[0].face);
        printf("struct[%i].nose = %d  \n",i, p[0].nose);
    }

    printf("\nARRAY INDEX MATH: The value of struct's  members after PASS BY REFERENCE\n");
    printf("[NOTE: structs were updated in the for loop above]\n");
    for ( i = 0; i < n; i++ )
    {
        printf("struct[%i].face = %d  \n",i, c[i].face);
        printf("struct[%i].nose = %d  \n",i, c[i].nose);
    }
}

<强>的main.c

#include <stdio.h>
#include "array_of_struct.h"

int main(void)
{
    int     i;
    HEAD    c[MAX_HEADS];
    HEAD   *cptr;
    size_t  n;

    n = (sizeof(c) / sizeof(c[0]);

    printf("\nINITIALIZATION of all struct's  members\n");
    for ( i = 0; i < n; i++ )
    {
        c[i].face = i + 30;
        c[i].nose = i + 60; 
        printf("struct[%i].face = %d\n",i, c[i].face);
        printf("struct[%i].nose = %d\n",i, c[i].nose);
    }

    cptr = &c[0];
    passByReference(&cptr, n); 

    return 0;
}