如何在c中将参数作为指向数组的指针传递

how to pass parameter as a pointer to an array in c

首先,none 我查看过的现有解决方案将参数作为数组,例如:

void inputCars(Car * cars[], int size);

这是我目前拥有的代码。

/******************************************************************************
WE WANT:
dynamic array of pointers to a
car structure
*******************************************************************************/
#include <string.h>
#include <stdio.h>

typedef struct {
 char make[60];
 double price;
 int year;
}Car;

int size;

void inputCars(Car* cars[], int size);

int main(int argc , char** args)
{
    printf("Enter how many Cars you wish to take inventory of: ");
    scanf("%d", &size); 
    Car cars[size];
    inputCars(&(cars), size);

}

void inputCars(Car * cars[], int size)
{
    for(int i = 0; i < size; i++)
    {
           // TODO
    }
    
}

当我尝试通过 cars 数组时,出现以下错误:

 expected 'struct Car**' but argument is of type 'struct Car(*)[(sizetype)(size)]'

我明白 Car * cars[] 的要求,感谢您的帮助,但我对如何通过它感到困惑。

我不会大声改变参数在函数中的方式,并且对于如何传递数组完全感到困惑。

因为作为参数传递的数组衰减到指向该数组第一个元素的指针,所以您在这里拥有:

void inputCars(Car* cars[], int size);

有效:

void inputCars(Car** cars, int size);

因此您需要传递 Car** 类型的参数,而 Car[size] 不是。你取car的地址(&car)没有区别,参数还是不兼容。

您作为函数的参数提供的是指向 Car 结构的数组(长度 size)的指针,而函数需要指向指向 [=11= 的指针的指针]:

'expected struct Car**'.

  • &(cars)(或简称&cars)是指向可变长度数组(VLA)的变量的地址Car - Car (*)[size].
  • 简单地传递 cars 会使它衰减为 Car*,而不是函数所需的 Car*[](或 Car**)。

我怀疑您应该动态分配内存并将指针传递给拥有该内存的指针。

示例:

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

typedef struct {
    char make[60];
    double price;
    int year;
} Car;

void inputCars(Car *cars[], int size) {
    // (*cars) below dereferences the Car** and gives a Car*
    for(int i = 0; i < size; i++) {
        // TODO
        (*cars)[i].year = i; // just an example value to fill it with
    }
}

int main() {
    printf("Enter how many Cars you wish to take inventory of: ");
    
    int size;
    if(scanf("%d", &size) != 1 || size < 1) return 1;    

    Car* cars = malloc(size * sizeof(Car)); // or sizeof(*cars) - allocate

    inputCars(&cars, size);                 // &cars is now a Car** (or Car*[])
 
    free(cars);                             // release allocated memory
}

注意:这个回答激起了关于 &cars 是否是 Car** 的讨论。如果它不是 Car** 程序将有 未定义的行为 (非常糟糕) - 但我说 &cars a Car** 并且程序已经定义了行为,直到证明不是这样。

但是:尽管这是正确工作的代码,但它可能不是您所期望的。如果这不能解决问题,请查看 Vlads 的替代答案。

在此声明中

Car cars[size];

声明了一个可变长度数组。

在本次通话中

inputCars(&(cars), size);

表达式 &cars 的类型为 Car( * )[size]。但是对应的函数参数

void inputCars(Car* cars[], int size);

Car * cars[] 一样被声明为由编译器调整为类型 Car ** 并且没有从一种指针类型到另一种指针类型的隐式转换。所以编译器发出错误信息。

在你的程序的评论中写着

WE WANT:
dynamic array of pointers to a
car structure

因此,您无需声明可变长度数组,而是需要动态分配指向类型 Car 对象的指针数组。像

Car **cars = malloc( size * sizeof( Car * ) );

for ( int i = 0; i < size; i++ )
{
    cars[i] = malloc( sizeof( Car ) );
}

在这种情况下,可以像这样调用函数

inputCars( cars, size );

如果要将指针传递给给定长度的可变长度数组,需要按如下方式对其进行原型设计:

void inputCars(int size, Car (*cars)[size]);

或如:

void inputCars(int size, Car (*cars)[*]);

后面的定义提供维度 ([*]) 表达式:

void inputCars(int size, Car (*cars)[size]) { /*...*/ }

[*] 表达式可能更复杂,包括例如函数调用,并且它可能完全是定义私有的,这就是为什么它可以通过原型中的 * 符号省略。

无论如何,如果维度表达式要基于size参数,那么size参数需要放在第一位。

示例程序:

#include <string.h>
#include <stdio.h>

typedef struct {
 char make[60];
 double price;
 int year;
}Car;


void inputCars(int size, Car (*cars)[size]);

int main(int argc , char** args)
{
    int size;
    printf("Enter how many Cars you wish to take inventory of: ");
    if(1!=scanf("%d", &size)) return 1;
    Car cars[size];
    inputCars(size, &(cars));

}

void inputCars(int size, Car (*cars)[size])
{
    //prints the same number twice
    printf("size=%d count=%zu\n", size,sizeof(*cars)/sizeof((*cars)[0]));
}

请记住,不建议使用像这样不受限制的 VLA。您正在打开您的程序以面临堆栈溢出的风险(真实情况)。

如果不能更改原型,则需要分配指针数组,然后为汽车分配 space。

void inputCars(Car *cars[], int size) {
    // (*cars) below dereferences the Car** and gives a Car*
    for(int i = 0; i < size; i++) {
        // TODO
        cars[i] -> year = i; // just an example value to fill it with
    }
}

int main() {
    printf("Enter how many Cars you wish to take inventory of: ");
    
    size_t size;
    if(scanf("%zu", &size) != 1 || size < 1) return 1;    

    Car **cars = malloc(size*sizeof(*cars));
    for(size_t n = 0; n < size; n++)
    {
        cars[n] = malloc(sizeof(*cars[0]));
    }
    inputCars(cars, size);                 //