My book gives an example of a linked list algorithm. To test my understanding I memorized the logic of "insert" and rewrote it. It looked the same except for one thing. The book example has a double pointer parameter, whereas mine used only a single pointer. My insert didn't work until I modified it to also use two points of indirection. I think I figured out why but I want you guys to confirm or deny.
When I use a single point of indirection and pass the value in a pointer variable it is being passed call by value. When I use a double pointer I get to use the address operator (&) to pass the pointer which tells the compiler it is to be passed call by reference.
If this is the case, it sure wasn't mentioned in the book! Does a primitive type only get passed call by reference when it has the address operator input in the function argument?
Code:#include <stdio.h> #include <stdlib.h> struct listNode { char data; struct listNode *nextPtr; }; typedef struct listNode ListNode; typedef ListNode *ListNodePtr; /* Does this mean any structure declared using ListNodePtr will automatically be a pointer without using the * cast? */ //void insert( ListNodePtr *, char ); void insert( ListNode **sPtr, char value ); char delete( ListNodePtr *, char ); int isEmpty( ListNodePtr ); void printList( ListNodePtr ); void instructions( void ); int main() { ListNode *startPtr = NULL; int choice; char item; instructions(); printf( "? " ); scanf( "%d", &choice ); while( choice != 3 ) { switch( choice ) { case 1: printf( "Enter a character: " ); scanf( "\n%c", &item ); /* startPtr is a pointer. What does it mean to use the address operator on a pointer? */ insert( &startPtr, item ); printList( startPtr ); break; case 2: if ( !isEmpty( startPtr ) ) { printf( "Enter character to be deleted: " ); scanf( "\n%c", &item ); if ( delete( &startPtr, item ) ) { printf( "%c deleted.\n", item ); printList( startPtr ); } else printf( "%c not found.\n\n", item ); } else printf( "List is empty.\n\n" ); break; default: printf( "Invalid choice.\n\n" ); instructions(); break; } printf( "? " ); scanf( "%d", &choice ); } printf( "%c\n", startPtr->data ); printf( "End of run.\n" ); return 0; } void insert( ListNode **sPtr, char value ) { ListNode *newPtr, *previousPtr, *currentPtr; newPtr = malloc( sizeof( ListNode ) ); if ( newPtr != NULL ) { newPtr->data = value; newPtr->nextPtr = NULL; currentPtr = *sPtr; previousPtr = NULL; while ( currentPtr != NULL && value > currentPtr->data ) { previousPtr = currentPtr; currentPtr = currentPtr->nextPtr; } if ( previousPtr == NULL ) { newPtr->nextPtr = *sPtr; *sPtr = newPtr; } else { previousPtr->nextPtr = newPtr; newPtr->nextPtr = currentPtr; } } } void instructions( void ) { printf( "Enter your choice:\n" " 1 to insert an element into the lsit.\n" " 2 to delete an element from the list.\n" " 3 to end.\n" ); } /* void insert( ListNode *sPtr, char value ) { ListNodePtr newPtr, previousPtr, currentPtr; newPtr = malloc( sizeof( ListNode ) ); if ( newPtr != NULL ) { // data is not a pointer, why is the -> used to access it then? newPtr->data = value; newPtr->nextPtr = NULL; previousPtr = NULL; currentPtr = sPtr; // Is currentPtr pointing to the value at sPtr or the address of sPtr? while ( currentPtr != NULL && value > currentPtr->data ) { previousPtr = currentPtr; currentPtr = currentPtr->nextPtr; } if ( previousPtr == NULL ) { newPtr->nextPtr = sPtr; sPtr = newPtr; } else { previousPtr->nextPtr = newPtr; newPtr->nextPtr = currentPtr; } } else printf( "%c not inserted. No memory available.\n", value ); } */ char delete( ListNodePtr *sPtr, char value ) { ListNodePtr previousPtr, currentPtr, tempPtr; /* Does this mean the value of a struct name is the memory address? */ /* Could I use a non-pointer struct and change the mem address it points to? */ if ( value == ( *sPtr )->data ) { tempPtr = *sPtr; *sPtr = ( *sPtr )->nextPtr; free( tempPtr ); return value; } else { previousPtr = *sPtr; currentPtr = ( *sPtr )->nextPtr; while ( currentPtr != NULL && currentPtr->data != value ) { previousPtr = currentPtr; currentPtr = currentPtr->nextPtr; } if ( currentPtr != NULL ) { tempPtr = currentPtr; previousPtr->nextPtr = currentPtr->nextPtr; free( tempPtr ); return value; } } return '\0'; } int isEmpty( ListNodePtr sPtr ) { return sPtr == NULL; } void printList( ListNodePtr currentPtr ) { if ( currentPtr == NULL ) printf( "List is empty.\n\n" ); else { printf( "The list is:\n" ); while ( currentPtr != NULL ) { printf( "%c --> ", currentPtr->data ); currentPtr = currentPtr->nextPtr; } printf( "NULL\n\n" ); } }



LinkBack URL
About LinkBacks


