I puntatori a Struct in C e agli array di Record

L’uso di puntatori prima nel linguaggio C e in seguito nel linguaggio C++, ha dei vantaggi quando le strutture dati da utilizzare sono di dimension non presumibili, e quindi il programmatore non può a priori allocare risorse importanti in termini di memoria RAM.
La flessibilità nel loro uso si scontra con la possibilità di introdurre degli errori gravi nella gestione della memoria RAM con conseguenze non sempre prevedibili.
E’ importante comprendere che l’allocazione e la de allocazione deve essere sempre fatta secondo quelle che sono le specifiche del programma; ovvero allocare memoria per le strutture quando necessario e de allocare tale spazio quando quei dati non sono più necessari all’elaborazione.

Le struct in C

La struct è un modello di dati personalizzato composto da tipi di dati differenti la cui definizione generale è del tipo:

struct nome
{  tipo 1 campo 1;
     tipo 2 campo 2;
  ….
  tipo N campo N;
};


In questa definizione è definito una struct di nome “nome” e composta dai campi del tipo tipo 1, tipo 2, tipo 3, .., tipo N, con nome “campo 1”, “campo 2”, …, “campo N” ad esempio:

struct persona
{  char nome[30];
   char cognome[30];
int age;;
};

Un’altra dichiarazione è possibile con la clausola typedef per definire un alias a struct “nome struct” per non ripetere nel codice ove server sempre la parola struct, ad esempio nei parametri di una funzione o procedura.
Ad esempio:

typedef struct s
{  char nome[40];
  char cognome[40];
  int age;
  char classe[10];
} studente;

In questo modo la parola chiave “struct” è inglobata nella definizione dell’alias “studente”.

Per definire un array di struct sono possibili diverse dichiarazioni:

±Dichiarazione statica
  struct nome   identificatore[dimensione];

Dichiarazione con i puntatori e allocazione;
  struct nome struct *identificatore;

Dichiarazione alternativa con l’uso della clausola typedef:
  nome alias *identificatore

Allocazione:
  identificatore =(struct nome struct*)malloc(sizeof(nome struct));

Allocazione con alias (typedef)
  identificatore = (nome alias*)malloca(sizeof(nome alias));

Nel primo caso la dichiarazione e allocazione avviene usando la parola chiave “struct” nel secondo caso essendo che il puntatore è dichiarato ad una struttura fornita di alias è dichiarato il puntatore che punta direttamente al tipo dati che è il nome dell’alias.

Il Codice C di un esempio da completare è:

#include <stdio.h>
#include <stdlib.h>
typedef struct r
{
	char nome[30];
	char cognome[30];
	int age;
	float reddito;
} persona;
void creaTabella(int d, persona *tb);
void stampaTabella(int d, persona *tb);
persona cercaPersona(char *n,char *cg);
float ageMedia(int d, persona *tb);
int cancellaPeronsa(char *n,char *cg);
int distruggiTabella(persona* tb);
int main()
{
	persona *tabella;
	int np;
	printf("\n Qaunte persone ?:-->");
	scanf("%d",&np);
	tabella = (persona*)malloc(sizeof(persona));
	if (tabella==NULL)
		{
			perror("\nErrore nell'allocazione della tabella in memoria !'");
			exit(EXIT_FAILURE);
		}
	creaTabella(np,tabella);
	int scelta;
	while (1)
	{
		do {
		printf("\nMenu' di Scelta:\n");
		printf("1->Stampa l'elenco\n");
		printf("2->Cerca una persona di cui conosci il nome e il cognome\n");
		printf("3->Stampa l'eta' media:\n");
		printf("4->Cancella una persona dall'elenco:\n");
		printf("5->Distruggi la tabella:\n");
		printf("6->Esci dal programma:\b");
		printf("Scegli voce da 1 a 6: sceglie ?\n");
		scanf("%d",&scelta);
		if ((scelta<1)||(scelta>6))
			{
				printf("\nErrore nella scelta !");
				printf("Riprova \n");
			}
		}
		while ((scelta<1)||(scelta>6));
	switch (scelta)	
	{
		case 1:
			{
				stampaTabella(np,tabella);
				break;			
			}
		case 2:
			{
				
				break; 
			}
		case 3:
			{
				
			}
		case 4:
			{
				
			}
		case 5:
			{
				
			}
		case 6:
			{
				printf("\n Arrivederci !\n");
				return 0;			
			}
	}	
	}
}
void creaTabella(int d, persona* tb)
{int k;
	for (k=0;k<d;k++)
	{
		printf("\n Inserisci il cognome:-->");
		scanf("%s",&tb->cognome);
		printf("\n Inserisci il nome:-->");
		scanf("%s",&tb->nome);
		printf("\n Inserisci l'eta' :-->");
		scanf("%d",&tb->age);
		printf("\n Inserisci il reddito:-->");
		scanf("%f",&tb->reddito);
		tb++;
	}
}
void stampaTabella(int d, persona* tb)
{
	int k;
	printf("\n Stampa Elenco delle Persone:\n");
	printf("Nome:\t\tCongome\t\tEta'\t\tReddito:\n");
	for (k=0;k<d;k++)
	{
		printf("%s\t\t%s\t\t%d\t\t%f\n",tb->nome,tb->cognome,tb->age,tb->reddito);
		tb++;
	}
}
persona cercaPersona(char *n,char *cg)
{
	
}
float ageMedia(int d, persona *tb)
{
	
}
int cancellaPeronsa(char *n,char *cg)
{
	
}
int distruggiTabella(persona* tb)
{
	
}

 

Video della lezione n.15 i puntatori a struct e array di struct in C

Codice C prelevabile su GitHub