如何在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); //
首先,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); //