I recently toke a test about the C language and there was an exercise for which I would like to ask for your help since I didn't do well. The entire test revolved around two struct, "point" and "polygon": point had two double values for the x and y coordinate, and polygon had a int value for the number of point it has and a pointer to point for the list of its points.
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};
I was then asked to create various functions to solve different tasks, one of witch was "aggiungiPunto" (add a point), that took a point and a polygon as input and added the given point to "polygon.punti". My attempt to create this function is the following
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];
}
...witch didn't work: if I try to print the polygon inside the function (I have a "stampapoligono", printPolygon function that just list all the point and work correctly)i see that the code did what i wanted, but if i try to print the polygon inside my main function it is like nothing append. I belive it has to do with how a function in c takes a copy of the parameters, but i don't know how to work around it.
Just for more context here is the main function and how i tested:
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;
}
And here is how stampapoligono work
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");
}
}
}
EDIT: I also tried this code which use realloc for aggiungipunto, but the result is the same:
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 ;
}
CodePudding user response:
The function aggiungipunto
shall access the original object prova
by reference through a pointer to it. Otherwise the function will deal with a copy of the original object and change the copy. The original object will stay unchanged.
Also the function should report for the caller where a new point was added successfully.
And the first parameter should have the type poligono *
.
So the function declaration should look like
int aggiungipunto( poligono *poli, punto p );
As the memory for points is allocated dynamically then you should use the function realloc
.
The function can look like
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;
}
And the function is called like
aggiungipunto( &prova, c );
or
if ( !aggiungipunto( &prova, c ) )
{
puts( "Error. No enough memory." );
}
Also the function stampapoligono
should be declared like
void stampapoligono( const poligono *poli );
that is the original object should be passed by reference as a constant object through a pointer to it.
And my advice use English words for identifier names.