简体   繁体   English

将结构数组传递给函数?

[英]Passing an array of structs to a function?

I would like learn how to pass, by reference, an array of structs to the second function called/executed from within the first function . 我想学习如何通过引用将结构数组传递给从second function调用/执行的first function My goal is to modify/change the contents of arbitrary struct from the second function only . 我的目标是修改/从武断改变结构的内容, second function 而已 The code below works, but, unfortunately, does not do exactly what I want to achieve. 下面的代码可以正常工作,但是不幸的是,它并不能完全实现我想要的目标。 I would to have access to arbitrary struct within second function . 我将可以在second function访问任意结构。 In other words, I would like to process all structs (using for loop) within second function by calling/executing first function in main only once and not using for loop. 换句话说,我想处理所有的结构(使用for内环路) second function调用/执行first functionmain只有一次 ,不使用for循环。

The second function , in the code below, is named passByReference_inner . 在下面的代码中, second function名为passByReference_inner

array_of_struct.h : 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 */

first function: (passByReference) 第一个功能: (passByReference)

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

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

second function: (passByReference_inner) 第二个功能: (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;
}

main: 主要:

#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;
}

I think what you are trying to do is this 我想你想做的是

#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;
}

what you should know is that arrays in c decay to a pointer that points to their first element when passed as parameters to functions. 您应该知道的是, c中的数组在作为参数传递给函数时会衰减为指向其第一个元素的指针。

Since you want to process all the structs in the second function, I don't see the need for the first function, anyway this is how you would do it then 因为您要处理第二个函数中的所有结构,所以我看不到第一个函数的需要,反正这就是您的处理方式

#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;
}

since you are effectively passing a pointer, you alter it's contents directly in both functions the first and the second. 由于您实际上是在传递指针,因此您可以直接在第一个和第二个函数中直接更改其内容。

One more thing, you don't really need the static keyword, specially in main() , static keeps the value of the variable between function calls, and since main() will normally be called only once in the lifetime of the program... it doesn't make much sense to use static there. 还有一件事,您实际上并不需要static关键字,特别是在main()static保留函数调用之间的变量值,并且由于main()通常在程序生命周期中仅被调用一次。 。在那儿使用static没有多大意义。

Your second function is correct. 您的第二个功能是正确的。

A pointer to the first element of an array is effectively the same thing as the pointer to an array itself. 指向数组第一个元素的指针实际上与指向数组本身的指针相同。

What you should do is 你应该做的是

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

So, you'll pass the pointer to the first element of the array, and the number of elements in the array, something like this: 因此,您将把指针传递给数组的第一个元素以及数组中的元素数,如下所示:

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

This will pass the pointer to the first element of the c array, and the number of elements in the array, to passByReference_inner(). 这会将指针传递到c数组的第一个元素,并将数组中的元素数传递给passByReference_inner()。 sizeof(c) is the size of the entire array in bytes. sizeof(c)是整个数组的大小(以字节为单位)。 sizeof(c[0]) is the size of an element in the array. sizeof(c [0])是数组中元素的大小。 So, if, for example, each struct is 10 bytes long (just an example), and you have an array of 12 structs, the size of the entire array is 120 bytes, and this calculates the value 120/10=12, the number of elements in the array, automatically. 因此,例如,如果每个结构的长度为10个字节(仅作为示例),而您有12个结构的数组,则整个数组的大小为120个字节,这将计算出值120/10 = 12,则数组中元素的数量,自动。

When you use the name of an array object, in C/C++ that automatically becomes a pointer to the first element of the array. 当您使用数组对象的名称时,在C / C ++中,它会自动成为指向数组第一个元素的指针。

In your function, you can work with the array in the following manner: 在函数中,可以按以下方式使用数组:

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

Adding an integer n to a pointer advances the pointer to the next nth element of an array. 向指针添加整数n会使指针前进到数组的下一个nth元素。 Adding an integer value to a pointer doesn't advance the pointer by this number of bytes, but by the number of bytes in the object the pointer points to, multiplied by the number you're adding (or subtracting, same thing). 向指针添加整数值不会使指针超前此字节数,而是指针所指向的对象中的字节数乘以您要添加(或减去,等于)的数字。 That makes pointer arithmetic do the right thing. 这使指针算法可以正确地执行操作。

  • The following code compiles cleanly. 以下代码可以干净地编译。
  • The following code moves the increment values loop 以下代码移动了增量值循环
    to inside the passByReference() function. 到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

I've analyzed all three solutions (iharob, user3629249, Sam Varshavchik) and came to the conclusion that Sam Varshavchik and the second solution from iharob were right on the money. 我分析了所有三个解决方案(iharob,user3629249,Sam Varshavchik),得出的结论是,Sam Varshavchik和iharob的第二个解决方案确实物有所值。 The first iharob's solution and user3629249 solution are, in essence, equal. 本质上,第一个iharob的解决方案和user3629249解决方案是相等的。 They moved for loop from main to the first function . 他们从main转到第first function for循环。 The second solution of the iharob's post matches the requirements from the initial post. iharob帖子的第二个解决方案符合初始帖子的要求。 Sam's solution gave me enough hints/instructions for 'how to move for loop from the main to the second function (which was, basically, what I did not know how to do it and therefore asked for help). 山姆的解决方案给了我足够的提示/指令“如何移动for循环从主到second function (这是,基本上,我不知道如何做到这一点,因此要求帮助)。

So, to make long story short, here is the source code which implements almost all suggestions from all contributors. 因此,总而言之,这是实现几乎所有贡献者的所有建议的源代码。 The code compiles cleanly, so, beginners like me, can take it as-is and learn few details about pointer to pointer, pointer arithmetic and about array of structs. 该代码可以干净地编译,因此像我这样的初学者可以直接使用它,并学到一些有关指针的指针,指针算术以及结构数组的详细信息。

array_of_struct.h (header file) 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 (first function) passByReference.c (第一个函数)

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

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

passByReference_inner.c (second function) 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 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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM