#include <stdio.h>
#include <string.h>				/* για memset()                      */
#include <stdlib.h>				/* για exit(), calloc(), free(), κλπ */

#define MAXINBUF		254+1		/* μέγιστο μήκος γραμμής εισόδου     */

#define TABLE_MINLEN		5		/* ελάχιστο πλήθος στοιχείων         */
#define TABLE_EMPTYCELL		-1		/* για μαρκάρισμα κενών στοιχείων    */

/* --------------------------------------------------------------------------------
 * Επιστρέφει το πλήθος των γεμάτων στοιχειων του πίνακα table
 * --------------------------------------------------------------------------------
 */
int tablen( int *table, const int maxtablen )
{
	register int i = 0;

	if ( !table )					/* έλεγχος ασφαλείας          */
		return 0;				/* ... πρόωρη έξοδος          */

	for (i=0; i < maxtablen; i++)
		if ( table[i] == TABLE_EMPTYCELL )
			return i;

	return 0;
}
/* --------------------------------------------------------------------------------
 * Τυπώνει στατιστικά σχετικά με τον πίνακα table ( μέγιστη χωρητικότητα σε στοιχεία,
 * πλήθος γεμάτων στοιχείων και μέγεθος που καταλαμβάνει ο πίνακας στη μνήμη )
 * --------------------------------------------------------------------------------
 */
void table_print_stats( int *table, const int maxtablen, const int tabsize )
{
	if ( !table )					/* έλεγχος ασφαλείας          */
		return;					/* ... πρόωρη έξοδος          */

	printf("\n\tΜέγιστη χωρητικότητα:\t\t%d στοιχεία\n", maxtablen);
	printf("\tΠλήθος γεμάτων στοιχείων:\t%d\n", tablen(table, maxtablen) );
	printf("\tΜέγεθος πίνακα στη μνήμη:\t%d bytes\n\n", tabsize );

	return;
}
/* --------------------------------------------------------------------------------
 * Τυπώνει τα μη κενά ατοιχεία του πίνακα table
 * --------------------------------------------------------------------------------
 */
void table_print_contents( int *table, const int maxtablen )
{
	register int i = 0;

	if ( !table )					/* έλεγχος ασφαλείας          */
		return;					/* ... πρόωρη έξοδος          */

	for (i=0; i < maxtablen; i++)
		if ( table[i] != TABLE_EMPTYCELL )
			printf("%d ", table[i] );

	putchar('\n');

	return;
}
/* --------------------------------------------------------------------------------  */
int main( void )
{
	char inbuf[ MAXINBUF ] = { '\0' };	/* δική μας γραμμή κύριας εισόδου    */
	int *table = NULL;			/* ο πίνακάς μας                     */
	int maxtablen = 0;			/* μέγιστο πλήθος στοιχείων          */
	int tabsize = 0;			/* μέγεθος του πίνακα στη μνήμη      */
						/* απαίτηση πλήθους στοιχείων...     */
	do {					/* ... μεγαλύτερου από TABLE_MINLEN  */
		printf("Μέγιστο πλήθος στοιχείων (τουλάχιστον %d): ", TABLE_MINLEN);
		fgets( inbuf, MAXINBUF, stdin );
		maxtablen = atoi( inbuf );
	} while ( maxtablen < TABLE_MINLEN );

	tabsize = maxtablen * sizeof(int);	/* υπολογισμός μεγέθους στη μνήμη    */

	table = malloc( tabsize );		/* δέσμευση μνήμης για τον πίνακα    */
	if ( !table ) {				/* αποτυχία δέσμευσης μνήμης         */
		puts("*** σφάλμα: ανεπαρκής μνήμη, τερματισμός προγράμματος..." );
		exit( EXIT_FAILURE );		/* ... τερματισμός προγράμματος      */
	}

	memset(table, TABLE_EMPTYCELL, tabsize);/* αρχικοποίηση όλων των στοιχείων   */

	puts("\nΟ πίνακας δημιουργήθηκε & αρχικοποιήθηκε επιτυχώς!");
	table_print_stats( table, maxtablen, tabsize );	/* τύπωμα στατιστικών        */

	table_print_contents( table, maxtablen );

	if ( table ) {				/* ο πίνακας δεν είναι NULL          */
		free( table );			/* ... αποδέσμευση της μνήμης του    */
		table = NULL;			/* ... κάνε έγκυρο τον δείκτη        */
	}

	exit( EXIT_SUCCESS );			/* επιτυχής τερματισμός προγράμματος */
}
