Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ.

Κι εγώ σου λέω για αυτό εδώ...

 

Question 6.3

...

Saying that arrays and pointers are ``equivalent'' means neither that they are identical nor even interchangeable. What it means is that array and pointer arithmetic is defined such that a pointer can be conveniently used to access an array or to simulate an array.

...

  • Απαντ. 1,6k
  • Δημ.
  • Τελ. απάντηση

Συχνή συμμετοχή στο θέμα

Δημοσ.

Κι εγώ σου λέω για αυτό εδώ...

 

Kαι εγω μπορω να σου παραθέσω αυτο που έχει προκυψει απο αυτο που μου παραθετεις εσυ αλλα εχουν καταληξει

σε διαφορετικο συμπέρασμα.

 

Οι 2 πρωτοι συμφωνουν μαζι σου ωστοσο. Αυτο με κανει να καταληγω στο οτι οντως το προτυπο της C αφηνει ανοικτα παραθυρακια για να ερμηνεύουμε καμια φορα οπως θέλουμε τα πραγματα.

 

http://www.velocityr...-and-array.html

 

> How do you use a double pointer to access a two dimensional array.

>

> ie int a[3][3];

> int **p;

 

You don't. If you want to work with the sub-arrays of a (which is rare),

you need a pointer to an array: int (*p)[3]. If, OTOH, you want to work

with the individual int members, you need a simple int *.

The declaration int ** p means that p is a pointer _to a pointer_ to

int. You have no pointers to int to point at, so you should not be using

an int **.

 

έχω και άλλα πολλα... οπως θα εχεις και εσυ. Οποτε αστο καλυτερα. Δεν ειναι οτι δεν εχω καταλαβει εγω παντως κατι.

 

Οταν ο a χρησιμοποιειται σαν δεικτης έχει τύπο (*) σε πινακα μηκους αριθμου στηλων... το λεει ξεκαθαρα και ο King αυτο... δεν λεει οτι εχει τυπο δεικτη σε δεικτη. Πουθενα στο προτυπο δεν το λεει αυτο.

 

Μια ερμηνεια που δινω εγω σε αυτΗ ΤΗ συναρτηση

 

> int sum_two_dimensional_array(int arr2d[][COLS] , int nrows)
{
int *p = NULL , sum=0 ;

for( p = (int *) arr2d ; p < ( (int *) arr2d + nrows*COLS); p++)
sum+= *p;

printf(" %zu , %zu , %zu " , sizeof(arr2d) , sizeof(*p) , sizeof( *( (int * ) arr2d ) ) );

return sum;
} 

 

ειναι οτι το casting γίνεται επειδή συμφωνα και με την θεωρία o arr2d είδαμε οτι είναι τύπου δείκτη σε πίνακα #COLS στοιχείων και οχι δείκτης σε απλο στοιχείο πίνακα. Ο arr2d περναει ουτως η άλλως σαν δεικτης τυπου σε πινακα #COLS αρα τον αλλαζει με το cast που κανει σε ενα στοιχειο... ενα int οπως ακριβως εχει δηλωθει και ο p εξαρχης. Χωρις casting θα μπορουσε να παιξει η εκχωρηση στον p με *arr2d ή και arr2d[0] :)

Δημοσ.

Όσο και να επιμένεις Κώστα, η πραγματικότητα είναι πως δεν έχεις καταλάβει την διαφορά μεταξύ ισοδυναμίας και ισότητας.

 

Σου έδωσα παράδειγμα παρμένο αυτούσιο μέσα από το πρότυπο (μου δίνεις links από φόρουμς), μου λες πως ο compiler χτυπάει αν επιχειρήσεις να περάσεις σε συνάρτηση ως διπλό δείκτη έναν 2Δ πίνακα λέγοντας μάλιστα "οποτε καταλαβαινει κανεις περαιτερω οτι αυτη η γενικη θεωρια δεν μπορει να εφαρμοστει και περισσοτερο", σου έδωσα κώδικα που κάνει ακριβώς αυτό και δουλεύει παντού και πάντα (αφού ήδη σε έχω διαβεβαιώσει πως από την πείρα μου το συγκεκριμένο είναι πολύ κοινή πρακτική, σου έχω δώσει και ψαγμένο link).

 

Έχω προσπαθήσει να σου το εξηγήσω με 1000 διαφορετικούς τρόπους, κι εσύ επιμένεις σε τι ακριβώς δεν έχω καταλάβει.

 

Ή μάλλον έχω καταλάβει. Έχω καταλάβει ότι δεν έχεις καταλάβει πως ισοδυναμία δεν σημαίνει ισότητα.

 

Απλώς please μην προσπαθείς να με πείσεις πως αρμενίζει στραβά ο γυαλός :P Και please μη βάζεις στο στόμα μου λόγια που δεν έχω πει... ουδέποτε υποστήριξα πως ως τύποι είναι ίδιοι ο διπλός δείκτης με τον 2δ πίνακα, είπα πως κατά περιπτώσεις ισοδυναμούν.

 

Ακόμα και στον κώδικα που έδωσα, δεν έγραψα πουθενά:

 

int **walk = arr2d;

 

Έγραψα:

 

int *walk = (int *)arr2d;

 

Αν έγραφα το πρώτο τότε ο walk δεν θα ήταν lvalue.

 

ΥΓ. Τα 'χει παίξει γενικώς το φόρουμ ή μόνο σε μένα; 4 φορές το έχω γράψει το ποστ.

Δημοσ.

Λοιπον....Για να δουμε αν θα μου βρειτε που ειναι το προβλημα γιατι εγω δεν παιζει να το βρω...Εψαξα αρκετα αλλα τιποτα...

 

Θελω να σβησω καποιον κομβο της λιστας οταν κανω προσπελαση σε αυτη (στη λιστα), ο κωδικας μου ειναι αυτος

 

>
typedef struct node {
struct node *next;
struct node *prev;
int data;
} NODE;
int main() {
NODE *list = NULL;
NODE *cur = NULL;

Insert(&list, 4);
Insert(&list, 4);
Insert(&list, 14);
Insert(&list, 12);
Insert(&list, 4);
Insert(&list, 1);
Print(list);
cur = list;
while (cur != NULL ) {
if (cur->data == 4) {
Del(&list, cur);
}
cur = cur->next;
}
return 0;
}

 

οριστε και η συναρτηση διαγραφης

 

>
void Del(NODE **list, NODE *node) {
if (*list == node)
*list = node->next;
if (node->next != NULL )
node->next->prev = node->prev;
if (node->prev != NULL ) {
node->prev->next = node->next;
}
free(node);
return;
}

 

Ξερω που ειναι το λαθος...Εχω δοκιμασει διαφορα αλλα δεν αλαζει κατι....

Δημοσ.

Έχω καιρο να ασχοληθω με λιστες.... αλλα δοκιμασε να τσεκαρεις αμα κατα λαθος πας να εκχωρησεις

τα περιεχομενα της μνήμης που εχεις βαλει να δειχνει ο δεικτης.... με εναν δεικτη που περιμενει διευθυνση πχ ο *list... που ειναι μεταβλητη διπλου δεικτη. Καταρχην τι error σου βγαζει

ή warning ? Παρεθεσε και αυτο.

Δημοσ.

Έχω καιρο να ασχοληθω με λιστες.... αλλα δοκιμασε να τσεκαρεις αμα κατα λαθος πας να εκχωρησεις

τα περιεχομενα της μνήμης που εχεις βαλει να δειχνει ο δεικτης.... με εναν δεικτη που περιμενει διευθυνση πχ ο *list... που ειναι μεταβλητη διπλου δεικτη. Καταρχην τι error σου βγαζει

ή warning ? Παρεθεσε και αυτο.

Εχω προβλημα με τον eclipse...Δεν μου βγαζει τιποτα....Για καποιο λογο δεν μου βγαζει τα segmentations...

Δημοσ.

Εχω προβλημα με τον eclipse...Δεν μου βγαζει τιποτα....Για καποιο λογο δεν μου βγαζει τα segmentations...

 

Δωσε ολο τον κωδικα να τον πάρω και να τον βάλω στο δικο μου να δουμε τι λαθη βγαζει.

Δημοσ.

>
int main() {
   NODE *list = NULL;
   NODE *cur = NULL;

   Insert(&list, 4);
   Insert(&list, 4);
   Insert(&list, 14);
   Insert(&list, 12);
   Insert(&list, 4);
   Insert(&list, 1);
   Print(list);
   cur = list;
   while (cur != NULL ) {
       if (cur->data == 4) {
           cur = Del(&list, cur);
       }
       cur = cur->next;
   }
   Print(list);
   return 0;
}

NODE *Del(NODE **list, NODE *node) {
   NODE *tmp;
   NODE *tmp2;
   tmp = node->prev;
   tmp2 = node->next;

   if (tmp == NULL) {
       *list = node->next;
       free(node);
       return *list;
   }

   node->prev->next = tmp2;
   if (tmp2 != NULL) {
   tmp2->prev = tmp;
   }
   free(node);
   return tmp;
}

Ένας μπακάλικος κώδικας για να βελτιστοποιήσεις είναι ο παραπάνω.

>
Έξοδος:
Πριν
1(0x958b058) ->  4(0x958b048) -> 12(0x958b038) -> 14(0x958b028) ->  4(0x958b018) ->  4(0x958b008) -> NULL
Μετά
1(0x958b058) -> 12(0x958b038) -> 14(0x958b028) -> NULL
Για διαγραφή της τιμής 1 παίρνουμε:
Πριν
1(0x8caa058) ->  4(0x8caa048) -> 12(0x8caa038) -> 14(0x8caa028) ->  4(0x8caa018) ->  4(0x8caa008) -> NULL
Μετά
4(0x8caa048) -> 12(0x8caa038) -> 14(0x8caa028) ->  4(0x8caa018) ->  4(0x8caa008) -> NULL

 

Δες αν σου κάνει. Επίσης θα βοηθηθείς αν κρατάς μια δομή με head και tail αντί να έχεις μόνο τα nodes.

 

Edit: Είδες το screenshot που έκανα για το eclipse 3-4 μηνύματα πριν ?

Δημοσ.

Δείχνει να δουλεύει as expected (αλλά δεν το τεστάρισα εξαντλητικά)

 

 

 

>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

typedef struct node {
int data;
struct node *next;
struct node *prev;
} NODE;

/*************************************************//**
*
*****************************************************
*/
bool node_print_data( NODE *node )
{
if ( !node ) {
	puts( "NULL" );
	return false;
}

printf( "%d ", node->data );
return true;
}

/*************************************************//**
*
*****************************************************
*/
bool list_free( NODE **list )
{
NODE *dummy = NULL;

if ( !list )
	return false;
if ( !*list )
	return true;

dummy = *list;
while ( dummy ) {
	dummy = dummy->next;
	free(*list);
	*list = dummy;		
}

return true;
}


/*************************************************//**
*
*****************************************************
*/
bool list_prepend( NODE **list, int data )
{
NODE *newNode = NULL;

if ( !list ) {
	puts( "*** INTERNAL ERROR (invalid pointer) ***" );
	return false;
}

newNode = malloc( sizeof(NODE) );
if ( !newNode )
	return false;

newNode->data = data;
newNode->next = newNode->prev = NULL;

// when list is empty
if ( NULL == *list ) {
	*list = newNode;
	return true;
}

// when list in NOT empty (prepend newNode)
newNode->next 	= *list;
(*list)->prev 	= newNode;
*list		= newNode;
return true;

}

/*************************************************//**
*
*****************************************************
*/
NODE *list_lookup_data( NODE *list, int data )
{
if ( !list )
	return NULL;

while ( list && data != list->data )
	list = list->next;

return list;
}

/*************************************************//**
*
*****************************************************
*/
bool list_delete_node( NODE **list, NODE *node )
{
if ( !list || !node )
	return false;

if ( *list == node ) {
	*list = (*list)->next;
	(*list)->prev = NULL;
	free( node );
	return true;
}

node->prev->next = node->next;
if (node->next )
	node->next->prev = node->prev;
free( node );

return true;
}

/*************************************************//**
*
*****************************************************
*/
bool list_print( NODE *list )
{
if ( !list )
	return false;

while ( list ) {
	printf( "%d ", list->data );
	list = list->next;
}
putchar('\n');

return true;
}

/*************************************************//**
*
*****************************************************
*/
int main( void )
{
NODE *list = NULL;
NODE *cur  = NULL;

list_prepend( &list, 4 );
list_prepend( &list, 4 );
list_prepend( &list, 14 );
list_prepend( &list, 12 );
list_prepend( &list, 4 );
list_prepend( &list, 1 );

list_print( list );

//	node_print_data( list_lookup_data(list, 12) );
list_delete_node( &list, list_lookup_data(list, 1) );
putchar('\n');

list_print( list );

while ( NULL != (cur=list_lookup_data(list,4)) )
	list_delete_node(&list, cur);

list_print( list );

list_free( &list );

system( "pause" );
return 0;
}

 

 

 

ΥΓ. Πάω να φαω :)

 

Δημοσ.

Έφαγα μια ωραιότατη σαλάτα του Καίσαρα, και... γλάρωσα :lol:

 

Ξέχασα λοιπόν να πω πως ο κώδικας που έδωσα είναι inefficient όταν καλείται να διαγράψει κόμβους με ίδια data (εκείνο το loop δηλαδή) διότι σε κάθε επανάληψη πιάνει την λίστα από την αρχή.

 

Σε κανονικό πρόγραμμα (και αν για κάποιον λόγο είχε την συγκεκριμένη υλοποίηση για τη λίστα), είτε θα έφτιαχνα ξεχωριστή συνάρτηση εξειδικευμένα για αυτή τη δουλειά (π.χ. list_delete_dupNodes() που θα ενσωμάτωνε το loop που τώρα είναι στην main, και προφανώς θα συνέχιζε από τον επόμενο του διαγραμμένου κόμβο) είτε θα έβαζα ένα 3o όρισμα στην list_lookup_data() το οποίο θα μου επέστρεφε τον επόμενο από τον διαγραμμένο κόμβο, τον οποίο και θα περνούσα αντί για list ως όρισμα στη list_delete_node() στο σώμα του loop, στη main().

 

 

 

Δημοσ.

Λοιπον παιδια σας ευχαριστω για τις απαντησεις σας, testara των κωδικα και δειχνει μια χαρα....Θα τα μελετησω υπομονετικα το μεσημερακι που ελπιζω να εχω τελειωσει με κατι αλλες ασκησεις...

Τα screenshot δεν τα βρισκω :(

Δημοσ.

Καλημέρα,

 

τα screenshots που έβαλε ο imitheos από το Eclipse πρέπει να είναι 2-3 σελίδες προς τα πίσω, στο παρόν νήμα. Btw, έχει βλέπω θεματάκια στον κώδικά μου σήμερα, π.χ. στην list_delete() δεν ελέγχω αν είναι NULL ο *list, οπότε αν την καλέσεις με NULL στον 1ο της όρισμα θα κρασάρει.

 

Θα τα κοιτάξω λίγο αργότερα πιο προσεκτικά (αν έχω χρόνο θα σου φτιάξω και τις εναλλακτικές που σου γράφω παραπάνω).

 

EDIT:

 

Εδώ είναι το ποστ με το Eclipse screenshot (μέσα στο spoiler): http://www.insomnia.gr/topic/437533-%ce%b5%cf%81%cf%89%cf%84%ce%ae%cf%83%ce%b5%ce%b9%cf%82-%ce%b3%ce%b9%ce%b1-c/page__st__990#entry5065270

Δημοσ.

Καλημέρα,

 

τα screenshots που έβαλε ο imitheos από το Eclipse πρέπει να είναι 2-3 σελίδες προς τα πίσω, στο παρόν νήμα. Btw, έχει βλέπω θεματάκια στον κώδικά μου σήμερα, π.χ. στην list_delete() δεν ελέγχω αν είναι NULL ο *list, οπότε αν την καλέσεις με NULL στον 1ο της όρισμα θα κρασάρει.

 

Θα τα κοιτάξω λίγο αργότερα πιο προσεκτικά (αν έχω χρόνο θα σου φτιάξω και τις εναλλακτικές που σου γράφω παραπάνω).

 

EDIT:

 

Εδώ είναι το ποστ με το Eclipse screenshot (μέσα στο spoiler): http://www.insomnia....90#entry5065270

 

Δεν ειναι αναγκη να βασανιζεσε...Θα το κοιταξω και εγω και αν κατι δεν παει καλα θα ξανα στειλω...Ετσι και αλλιως αυτο θα το προσαρμοσω σε πολλες πολλες γραμμες κωδικα....

Δημοσ.

Δεν βασανίζομαι ρε συ, τα περισσότερα από αυτά τα έχω (σχεδόν) έτοιμα (και σε διάφορες εκδόσεις ) οπότε το βασικό που κάνω είναι να τα προσαρμόζω στις ερωτήσεις.

 

Λοιπόν, ο παρακάτω κώδικας πρέπει να είναι πιο efficient και πιο bug-free από τον χτεσινοβραδινό. Κυρίως επειδή τον δοκίμασα με διάφορες περιπτώσεις, τις οποίες κι έχω συμπεριλάβει στην main() ... διόλου απίθανο όμως να μου 'χουν ξεφύγει και μερικές.

 

 

 

>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

#define DELMODE_ALL        1

#define ERRMSG_INVPOINTER    "*** INTERNAL ERROR (invalid pointer)"
#define ERRMSG(msg)        \
   fprintf(stderr, "*** %s:%d|%s()\n%s\n\n", __FILE__, __LINE__, __func__, (msg) )

typedef struct node {
   int data;
   struct node *next;
   struct node *prev;
} NODE;

/*************************************************//**
*
*****************************************************
*/
bool node_print_data( NODE *node )
{
   if ( !node ) {
       ERRMSG( ERRMSG_INVPOINTER );
       return false;
   }

   printf( "%d ", node->data );
   return true;
}

/*************************************************//**
*
*****************************************************
*/
bool node_delete( NODE *node )
{
   if ( !node ) {
       ERRMSG( ERRMSG_INVPOINTER );
       return false;
   }

   if ( node->prev )
       node->prev->next = node->next;
   if ( node->next )
       node->next->prev = node->prev;
   free( node );

   return true;
}

/*************************************************//**
*
*****************************************************
*/
bool list_free( NODE **list )
{
   NODE *dummy = NULL;

   if ( !list ) {
       ERRMSG( ERRMSG_INVPOINTER );
       return false;
   }
   if ( !*list )
       return true;

   dummy = *list;
   while ( dummy ) {
       dummy = dummy->next;
       free(*list);
       *list = dummy;          
   }

   return true;
}


/*************************************************//**
*
*****************************************************
*/
bool list_prepend( NODE **list, int data )
{
   NODE *newNode = NULL;

   if ( !list ) {
       ERRMSG( ERRMSG_INVPOINTER );
       return false;
   }

   newNode = malloc( sizeof(NODE) );
   if ( !newNode )
       return false;

   newNode->data = data;
   newNode->next = newNode->prev = NULL;

   // when list is empty
   if ( NULL == *list ) {
       *list = newNode;
       return true;
   }

   // when list in NOT empty (prepend newNode)
   newNode->next   = *list;
   (*list)->prev   = newNode;
   *list           = newNode;
   return true;
}

/*************************************************//**
*
*****************************************************
*/
NODE *list_lookup_data( NODE *list, int data )
{
   if ( !list ) {
       ERRMSG( ERRMSG_INVPOINTER );
       return NULL;
   }

   while ( list && data != list->data )
       list = list->next;

   return list;
}

/*************************************************//**
*
*****************************************************
*/
bool list_delete_node( NODE **list, NODE *node )
{
   if ( !list || !node )
       return false;

   // empty list?
   if ( NULL == *list )
       return false;

   // non-empty list?

   if ( *list == node )
       *list = node->next;

   return node_delete( node );
}

/*************************************************//**
*
*****************************************************
*/
bool list_delete_data_allOccurrences( NODE **list, int data )
{
   NODE *walk = NULL, *temp = NULL;

   if ( !list ) {
       ERRMSG( ERRMSG_INVPOINTER );
       return false;
   }
   if ( NULL == *list )
       return true;

   walk = *list;
   while ( walk )
   {
       temp = walk->next;    // save address of walk's next node
       if ( data == walk->data ) {
           if ( walk == *list )
               *list = temp;
           node_delete( walk );
       }
       walk = temp;
   }

   return true;
}

/*************************************************//**
*
*****************************************************
*/
void list_print( NODE *list )
{
   if ( !list ) {
       puts( "NULL" );
       return;
   }

   while ( list ) {
       printf( "%d ", list->data );
       list = list->next;
   }
   putchar('\n');
}

/*************************************************//**
*
*****************************************************
*/
int main( void )
{
   NODE *list = NULL;

   list_prepend( &list, 2 );
   list_prepend( &list, 4 );
   list_prepend( &list, 4 );
   list_prepend( &list, 14 );
   list_prepend( &list, 12 );
   list_prepend( &list, 4 );
   list_prepend( &list, 1 );
   list_print( list );

#if !DELMODE_ALL
   printf( "deleting 99 ... " );        // 99 does NOT exist in list
   list_delete_node( &list, list_lookup_data(list, 99) );
   list_print( list );

   printf( "deleting  1 ... " );
   list_delete_node( &list, list_lookup_data(list, 1) );
   list_print( list );

   printf( "deleting  2 ... " );
   list_delete_node( &list, list_lookup_data(list, 2) );
   list_print( list );

   printf( "deleting 12 ... " );
   list_delete_node( &list, list_lookup_data(list, 12) );
   list_print( list );

   printf( "deleting  4 ... " );
   list_delete_node( &list, list_lookup_data(list, 4) );
   list_print( list );

   printf( "deleting 14 ... " );
   list_delete_node( &list, list_lookup_data(list, 14) );
   list_print( list );

#else
   printf( "deleting all 99s ... " );    // no 99s exist in list
   list_delete_data_allOccurrences( &list, 99 );
   list_print( list );

   printf( "deleting all  1s ... " );
   list_delete_data_allOccurrences( &list, 1 );
   list_print( list );

   printf( "deleting all  2s ... " );
   list_delete_data_allOccurrences( &list, 2 );
   list_print( list );

   printf( "deleting all 12s ... " );
   list_delete_data_allOccurrences( &list, 12);
   list_print( list );

   printf( "deleting all  4s ... " );
   list_delete_data_allOccurrences( &list, 4);
   list_print( list );

   printf( "deleting all 14s ... " );
   list_delete_data_allOccurrences( &list, 14);
   list_print( list );

#endif

   list_free( &list );

   system( "pause" );
   return 0;
}

 

 

 

Έξοδος με #define DELMODE_ALL 1 ...

 

 

>
1 4 12 14 4 4 2
deleting all 99s ... 1 4 12 14 4 4 2
deleting all  1s ... 4 12 14 4 4 2
deleting all  2s ... 4 12 14 4 4
deleting all 12s ... 4 14 4 4
deleting all  4s ... 14
deleting all 14s ... NULL
Πιέστε ένα πλήκτρο για συνέχεια. . .

 

 

 

Έξοδος με #define DELMODE_ALL 0 ...

 

 

>
1 4 12 14 4 4 2
deleting 99 ... 1 4 12 14 4 4 2
deleting  1 ... 4 12 14 4 4 2
deleting  2 ... 4 12 14 4 4
deleting 12 ... 4 14 4 4
deleting  4 ... 14 4 4
deleting 14 ... 4 4
Πιέστε ένα πλήκτρο για συνέχεια. . .

 

 

 

Σχετικά με το πρόβλημα που παρέθεσες με κώδικα (δηλαδή στη διαγραφή κόμβων) οι σχετικές συναρτήσεις στον δικό μου κώδικα είναι οι παρακάτω:

  • bool node_delete( NODE *node );
  • bool list_delete_node( NODE **list, NODE *node );
  • bool list_delete_data_allOccurrences( NODE **list, int data );

 

Ότι απορία έχεις ρώτα. Σημείωσε πως ο προηγούμενος κώδικάς μου είχε κι άλλα bugs.

 

 

EDIT:

 

Ξέχασα, τα "tricky parts" στον κώδικα είναι η συνθήκη...

 

>        if ( *list == node )
               *list = node->next;

 

στον κώδικα της list_delete_node(), καθώς και η συνθήκη...

 

>
           if ( walk == *list )
               *list = temp;

 

στον κώδικα της list_delete_data_allOccurrences().

 

Ουσιαστικά αυτό που κάνουν είναι όταν ο προς διαγραφή κόμβος ισούται με τον 1ο της λίστας, τότε τον κρατάνε σε μια ξεχωριστή μεταβλητή-δείκτη (για να μπορέσουμε να τον κάνουμε free μετά) και προχωράνε τον *list στον επόμενο κόμβο.

Δημοσ.

Έστω μια άσκησουλα που ζητάει απο τον χρήστη να δωσει μια προταση και την εκτυπώνει με αντιστροφη σειρα των γραμματων των λέξεων..... δοκιμασα να την κανω με πινακες και δεικτες... νομιζω ενταξει βγηκε ... πως σας φαινεται η υλοποιηση ?

 

(δεν ειναι κατι το τρομερο φυσικα 2 λεπτα μου πηρε)....

 

>
// (c)

#include <stdio.h>
#define MAXLEN 10
void read_input( char [] );

   int main(void)
   {
       char arr[MAXLEN]={0} ;
      
       printf(" Enter a message : ");
      
       read_input(arr);
  
return 0;
}
void read_input( char arr[MAXLEN] )
{
   int c  , i=0 ;
   char *p=arr;
  
   while( ( c = getchar() ) != '\n' && i < MAXLEN  )
   {
   	 *p++ = c;
   	  i++;
    }

   printf(" The reversal is : ");
  
   while( (p--) != arr )
  
       printf("%c" , *p);
  
   return;
  
}


 

Εξαιρουμε τα check για εγκυρη εισοδο που δεν υπάρχουν....

Επισκέπτης
Αυτό το θέμα είναι πλέον κλειστό για περαιτέρω απαντήσεις.

  • Δημιουργία νέου...