提问人:Prio216 提问时间:9/26/2022 最后编辑:Vlad from MoscowPrio216 更新时间:9/26/2022 访问量:69
如何更改函数内数组的大小?
How can I change the size of an array inside a function?
问:
我最近参加了一个关于C语言的测试,有一个练习我想请你帮忙,因为我做得不好。整个测试围绕着两个结构,“点”和“多边形”:point 有两个双精度值表示 x 和 y 坐标,而 polygon 有一个 int 值表示它拥有的点数,一个指向点的指针表示它的点列表。
typedef struct Punto{
double x;
double y;
}punto;
punto origine = {.x =0, .y =0};
typedef struct Poligono{
int numeroPunti; //numbers of points
punto *punti;
}poligono;
poligono poligonoNullo = {.numeroPunti = 0, .punti = NULL};
然后我被要求创建各种函数来解决不同的任务,其中一个是“aggiungiPunto”(添加一个点),它以一个点和一个多边形作为输入,并将给定的点添加到“polygon.punti”中。我创建此函数的尝试如下
void aggiungipunto(punto p, poligono poli){
punto *prova;
prova = calloc(poli.numeroPunti +1, sizeof(punto));
for(int i=0; i<poli.numeroPunti;i++){
prova[i]=poli.punti[i];
}
poli.numeroPunti++;
prova[poli.numeroPunti -1] = p;
poli.punti = &prova[0];
}
...女巫不起作用:如果我尝试在函数内打印多边形(我有一个“stampapoligono”,printPolygon 函数,它只是列出所有点并正常工作)我看到 代码做了我想要的,但是如果我尝试在我的主函数中打印多边形,它就像没有附加一样。我认为这与 c 中的函数如何获取参数的副本有关,但我不知道如何解决它。
只是为了获得更多上下文,这里是主要功能以及我如何测试:
int main(){
punto a = {.x =1, .y = 2};
punto b = {.x = -1, .y = 2};
punto arraystatico[] = {origine, a, b};
poligono prova = poligonoNullo;
prova.numeroPunti = 3;
prova.punti = (punto *)calloc(prova.numeroPunti, sizeof(punto));
for(int i=0;i < prova.numeroPunti ;i++){
prova.punti[i] = arraystatico[i];
}
printf("Poligono iniziale:\n");
stampapoligono(prova);
punto c = {.x = 12, .y =3};
aggiungipunto(c, prova);
printf("Stampa esterna: \n");
stampapoligono(prova);
free(prova.punti);
return 0;
}
这就是 stampapoligono 的工作原理
void stampapunto(punto p){
printf("Coordinata x: %lf\tCoordinata y: %lf\n", p.x, p.y);
}
void stampapoligono(poligono poli){
if (poli.numeroPunti ==0){
printf("Il poligono non ha punti\n");
}
else{
for(int i=0; i<poli.numeroPunti;i++){
stampapunto((poli.punti)[i]);
printf("\n");
}
}
}
编辑:我也尝试了这个代码,它使用realloc进行aggiungipunto,但结果是一样的:
void aggiungipunto(punto p, poligono poli){
punto *prova;
prova = calloc(poli.numeroPunti, sizeof(punto));
for(int i=0; i<poli.numeroPunti;i++){
prova[i]=poli.punti[i];
}
poli.punti = (punto *)realloc(poli.punti, poli.numeroPunti+1);
for(int i=0; i<poli.numeroPunti;i++){
poli.punti[i]=prova[i];
}
(poli.punti)[poli.numeroPunti] = p;
poli.numeroPunti++;
}
答:
该函数应通过指向原始对象的指针通过引用访问原始对象。否则,该函数将处理原始对象的副本并更改副本。原始对象将保持不变。aggiungipunto
prova
此外,该函数应向调用方报告成功添加新点的位置。
第一个参数的类型应为 .poligono *
所以函数声明应该看起来像
int aggiungipunto( poligono *poli, punto p );
由于点的内存是动态分配的,因此您应该使用函数 。realloc
该函数可能如下所示
int aggiungipunto( poligono *poli, punto p )
{
punto *tmp = realloc( poli->punti, ( poli->numeroPunti + 1 ) * sizeof( punto ) );
int success = tmp != NULL;
if ( success )
{
poli->punti = tmp;
poli->punti[poli->numeroPunti++] = p;
}
return success;
}
该函数的调用方式如下
aggiungipunto( &prova, c );
或
if ( !aggiungipunto( &prova, c ) )
{
puts( "Error. No enough memory." );
}
此外,该函数应声明如下stampapoligono
void stampapoligono( const poligono *poli );
也就是说,原始对象应通过指向它的指针作为常量对象通过引用传递。
我的建议使用英语单词作为标识符名称。
评论
malloc
calloc
realloc
poli.punti