将结构数组传递给函数

时间:2018-07-10 10:51:28

标签: c function pointers struct

我已经学习C大约2个月了,但仍然是新手:(

我知道此网站上还有其他类似的问题。我读过它们,但仍然听不懂,所以我在这里。下面是我的代码:

List<String> names= new ArrayList<String>();
        names.add("John");
        names.add("Mark");

        if (names.stream().distinct().limit(2).count() > 1) {
            a= 1,
            Assert.fail("Received different name in between");      

        } else {
        System.out.println("Received Same name");
}

和下面是我的函数接收数组:

//naming my structure as ball
typedef struct ball_room {
int enter;
int exit;
} ball;

//I've omitted some irrelevant details for brevity
    int i, n, max;
    scanf("%d", &n);
    ball person[n];
    .../*assign values to ball.enter and ball.exit with user input*/
    max = 1;
    for (i = 0; i < n; i++)
        if (ball_room(person, person[i].enter, n) > max)
            max = ball_room(person, person[i].enter, n);
    printf("%d\n", max);
    return 0;
}

我的问题是,为什么编译器不接受//This function returns the number of people in the ballroom //when b[j](person[j] in "main") enters int ball_room(ball *b, int i, int n) { int people = 0, j; for (j = 0; j < n; j++) if (b[j].enter <= i && b[j].exit > i) people++; return people; } 而不是b[j].enter? 以我有限的经验,在操纵结构本身(对象)时,我使用b[j]->enter进入结构内部,而当它是指针(地址)时,我使用.(希望这是正确的。 )

在这种情况下,我使用->(代表ball *b的地址)将数组传递给函数,因此可以访问整个数组。但是person[0]是否不应该采用指针形式,因此我应该使用ball *b来访问其内容?这只是我传递给函数的地址。

这是我第一次使用一系列结构进行操作,请帮助我弄清楚这一点,谢谢!

5 个答案:

答案 0 :(得分:5)

由于使用了以下参数声明,因此您使用.而不是->

int ball_room(ball *b, int i, int n)

b应该指向类型为ball的数据的指针,因此您可以通过多种方式访问​​它:

  1. 数组方式:例如b[5].somefield = 15-在这里使用点,因为如果bball *类型,则意味着b是指针,或者它是类型为b的对象数组,如果它是类型为b的对象数组(您的情况),则可以使用.访问对象的字段
  2. 指针方式:例如(b+5)->somefield = 15-与上述代码完全相同,但是您将以pointer的方式访问数据

答案 1 :(得分:5)

给出ball *bb[j]b指向的元素中的一个元素。因此b[j]不是指针;这是一个结构。由于它是一个结构,因此您可以使用.来引用其中的成员。

C标准中b[j]的定义是*((b)+(j))。因此它需要使用指针b,将j元素移到其后,然后再应用*

由于*中已经应用了b[j],因此您不需要->,只需要.

答案 2 :(得分:2)

在C / C ++中,数组归入其第一个成员的地址。因此,当您将数组传递给ball_room时,实际上传递的是&ball[0]

现在在ball_room内部,情况相反。 b是指向球的指针。但是在这里,您将其用作数组b[j]。因此,它分解为一系列结构。因此b[j]给您的是结构,而不是结构的指针。因此,您使用.而不是->来访问它。

您也可以使用(b + j)->somefield。或者,更有趣的是如何编写j[b].somefield。后来是以前的编译器时代留下的一个令人困惑的遗留物,当时a[b]在内部真正变成了*(a + b)

答案 3 :(得分:1)

有关当前问题的说明,请参见Ericanswer;在到目前为止给出的一些答案中,使用了危险的措词,因此请明确:我们何时有数组,何时有指针??

请考虑以下内容:

int a[7];

只要我们可以直接引用a,我们仍然有一个数组,并且可以使用在e上有效的任何操作。 G。变大:

size_t n = sizeof(a); // size in bytes, not ints, i. e. 7*sizeof(int)

您可以将数组传递给函数,甚至可以对以下各项进行指针算术:

f(a);
a + 1;

在这两种情况下,数组都“衰减”到一个指针,并且结果也是一个指针。请注意,您可以将新值分配给指针,但不能分配给数组本身(可以直接或通过指针将新值分配给数组的元素),因此也无法执行类似++a的操作。

当数组衰减为指针时,它将获得指向其第一个元素的指针:

int* ptr = a;
int* ptr = &*a;    // only pointers can be dereferenced -> a decays!
int* ptr = &a[0];  // short for &*(a + 0)...

所有结果完全相同;但是,以下内容无效:

int* ptr = &a;

实际上可以获取整个数组的地址 ,但是结果指针既不是“指向元素的指针”类型,也不是“指向元素的指针”类型(int**在示例中),但类型为“指向特定大小的数组的指针”。尽管的语法很丑陋,但以下内容再次合法:

int(*aptr)[7] = &a;

您需要阅读:如果我取消引用ptr,我会得到int[7] ...

一旦衰减,仅剩下一个指向数组的指针(更精确的是:衰减后直接指向数组元素中的一个,指向第一个;数组和第一个元素始终共享相同的地址,因此,尽管类型不同,上面的两个指针ptraptr的值完全相同)。指针可以在数组内移动,但是指针所保存的信息不如数组本身,尤其是数组大小会丢失。这就是为什么需要将数组的长度与指向函数的指针一起传递的原因(如果需要;另一种变体是表示数组末尾的前哨值,例如字符串中的终止空字符或{{1 }}的参数列表):

main

可能将f设置为:

int a[7];
f(a, sizeof(a));

希望这有助于避免混乱。

答案 4 :(得分:0)

在C语言中,数组名称是指向数组第一个元素的指针,因此您的函数声明的名称为ball *b,并在您传递ball[]实例时起作用。

尝试使用malloc()动态分配内存并将该指针传递给函数。