简体   繁体   English

从一个结构数组解析一个结构以起作用

[英]parse one struct to function from an array of structs

I am new to C, but not to programming. 我是C语言的新手,但不是编程人员。 I have been roped into modifying a C program to make it gather multiple pieces of data and put them in an array. 我一直被迫修改C程序,使其收集多个数据并将它们放置在数组中。 I am not allowed to post actual source code, so I have made the following example which illustrates what I am trying to do: 我不允许发布实际的源代码,因此我制作了以下示例来说明我要执行的操作:

#include <windows.h>

typedef struct 
{
    int size;
    long rpm;
} ENGINE;


typedef struct 
{
    int doors;
    int wheels;
    ENGINE engine;
} CAR;

int newCar(CAR *car)
{
    ENGINE eng;
    eng.rpm=30000;
    eng.size=1600;
    car->doors=4;
    car->wheels=4;
    car->engine=eng;
    return 0;

}


int getCars(CAR *cars[], int n)
{
    int i = 0;
    for (i=0; i<n; i++)
    {
        newCar(cars[i]);
    }

    return 0;
}

int carCount(int *count)
{
    *count = 4;
    return 0;
}

int main()
{
    int n = 0;
    CAR *cars = (CAR*) malloc(sizeof(CAR));
    carCount(&n);

    cars = (CAR*)realloc(cars, n * sizeof(CAR));
    cars[1].doors = 2;
    getCars(&cars,n);

}

The code above compiles but fails when I try to set members of the car struct inside the newCar routine. 上面的代码可以编译,但是当我尝试在newCar例程中设置car结构的成员时失败。 I'm not sure whether my realloc on the cars array is doing what I want it to, I based it on some other posts on stackoverflow. 我不确定我在cars数组上的重新分配是否正在执行我想要的操作,我基于在stackoverflow上发布的其他文章进行了此操作。 Does it look ok? 看起来还好吗? How can I access the members of car from the newcar routine? 如何从newcar例程访问汽车成员? Is this a reasonable way of doing this? 这是这样做的合理方法吗? Many thanks :) 非常感谢 :)

You don't need double indirections! 您不需要双重间接! A simple pointer to CAR can point to different CARs. 一个简单的指向CAR的指针可以指向不同的CAR。

Create space for the number of CARs you need: ok 为您需要的汽车数量创建空间:确定

A pointer to the first CAR in that space can easily be made to point to the other CARs. 可以很容易地使该空间中第一个CAR的指针指向其他CAR。

    CAR *cars = malloc(sizeof(CAR));

if malloc didn't fail cars points to a space large enough to hold 1 CAR 如果malloc没有失败,则 cars指向一个足以容纳1个汽车的空间

    cars = realloc(cars, n * sizeof(CAR));

if realloc didn't fail cars now points to a space large enough to hold n cars 如果重新分配没有失败,那么 cars现在指向一个足以容纳n辆汽车的空间
pass that pointer to your functions, along with how many cars it points to 将该指针传递给您的功能,以及它指向多少辆汽车

    getCars(cars, n);

and use the pointer in the functions 并在函数中使用指针

int getCars(CAR *cars, int n)
{
    int i = 0;
    for (i=0; i<n; i++)
    {
        /* here, cars[0] is the first car; cars[1] is the second ... */
        /* we can pass the address with &cars[i]                     */
        /* or make arithmetic with the pointer itself:               */
        newCar(cars+i);
    }
    return 0;
}

In getCars , you define cars as CAR *cars[] , that is, array of pointers to CAR . getCars ,定义cars作为CAR *cars[]也就是说,指针数组CAR

In main , &cars is a pointer to array of CAR s. main&cars指向 CAR 数组指针

The code happens to compile perhaps because both resolve to CAR** . 该代码恰好编译,可能是因为两者都解析为CAR**

I would rewrite the code in the following way: 我将以以下方式重写代码:

int newCar(CAR** car)
{
    *car = (CAR*)malloc(sizeof(CAR));
    ENGINE eng;
    eng.rpm=30000;
    eng.size=1600;
    (*car)->doors=4;
    (*car)->wheels=4;
    (*car)->engine=eng;
    return 0;
}

int getCars(CAR *cars[], int n)
{
    int i = 0;
    for (i=0; i<n; i++)
    {
        newCar(&cars[i]);
    }

    return 0;
}

int main()
{
    int n = 0;
    CAR** cars = (CAR**) malloc(sizeof(CAR*));
    carCount(&n);

    cars = (CAR**)realloc(cars, n * sizeof(CAR*));
    getCars(cars,n);
    cars[1]->doors = 2;
}

etc. 等等

In order to use malloc for example you need the stdlib.h header. 例如,为了使用malloc,您需要stdlib.h标头。 Since you are casting the pointer from malloc to (CAR*) the compiler assumes that malloc is returning an int and no warning is generated. 由于您是将指针从malloc强制转换为(CAR *),因此编译器假定malloc返回的是int并且不会生成警告。

The reason why your code fails, is that in main , cars is a simple scalar variable, and you call a subroutine with its address as argument. 代码失败的原因是,在maincars是一个简单的标量变量,并且您以其地址作为参数调用了子例程。 In getCars , cars is an array of pointer, so cars[i] , read ahead of the address you passed as argument. getCarscars是一个指针数组,因此cars[i]在您作为参数传递的地址之前读取。 And this is where its wrong, because the address is an address of a single scalar variable, not the address of a table. 这是错误的地方,因为该地址是单个标量变量的地址,而不是表的地址。

To get right, you should call the subroutine with the value of main 's cars , which is exactly the address of the table your created with malloc/realloc. 为了正确起见,您应该使用maincars值调用子例程,该值恰好是您使用malloc / realloc创建的表的地址。 Note that in that case, the subroutine prototype will simply be 请注意,在这种情况下,子例程原型将简单地为

int getCars(CAR *cars, int n)

You would typically use malloc(n * sizeof(CAR)) . 您通常会使用malloc(n * sizeof(CAR)) The realloc function is only useful for over-the-moon-kind of programming. realloc函数仅适用于非常realloc的编程。

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

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