I am reviewing material i have covered in c and i wrote up some notes and i am getting an error, i was hoping if someone could help me with this

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

struct node{
       int data;
       struct node *next;

};

void addtobegining(int);
void traverse();
struct node *head;

int main()
{
    head = (struct node*)malloc(sizeof(struct node));
    addtobegining(3);
    addtobegining(2);
    addtobegining(1);
    traverse();
}

void addtobegining(int i)
{
     struct node*p;
     p = malloc(sizeof(struct node));
     p ->next = i;
     head = p;
}

void traverse()
{
     struct node *p;
     p = head;
     while(p);
     {
              printf("%d\n",p ->data);
              p=p ->next;
     }
}

i am getting an error at function addtobegining

warning assignment makes pointer to interger without a cast

thanks in advance

Look at this function:

void addtobegining(int i)
{
     struct node*p;
     p = malloc(sizeof(struct node));
     p ->next = i;
     head = p;
}

Note that you are setting p->next to i. Try this instead:

void addtobegining(int i)
{
     struct node*p;
     p = malloc(sizeof(struct node));
     p->data = i;
     p->next = head;
     head = p;
}

The error is because you did not assign a value to the data element of the structure. So when you refer to data as p->data in traverse() function, it gives an error. In traverse() function, you have used semicolonin front of while() which doesn't allow the program flow to enter into loop's body.
Solution:
assign value to data part of head.
assign value of i to data part of p in addtobegining() function
the warning "assignment makes pointer to integer without cast" is coming because you are assigining integer value i to the next pointer.
The correct program is as follows:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node{
         int data;
         struct node *next;
};
void addtobegining(int);
void traverse();
struct node *head;
int main()
{
     head = (struct node*)malloc(sizeof(struct node));
     printf("Enter data for head:");
     scanf("%d",&head->data);
     head->next=NULL;
     addtobegining(3);
     addtobegining(2);
     addtobegining(1);
     traverse();
}
void addtobegining(int i)
{
      struct node *p;
      p = (struct node *)malloc(sizeof(struct node));
      p->data = i;
      p->next=head;
      head = p;
}
void traverse()
{
      struct node *p;
      p=head;
      while(p!=NULL)
      {
                  printf("%d\n",p->data);
                  p=p->next;
      }
}

ok lets say now i wanted to create a function that would start removing from the end with the struct node above, how would i proceed with this?

i cant use next because i want it to go backwards and not forward

in main i would have to add

stuct node *end;

then create a function such as

void removefromend()
{
    struct node*p;
    p = malloc(sizeof(struct node));
    p->data = '\0';
    end = p; // i knw this part is incorrect
 }

Edited 4 Years Ago by peste19

There is no need to go back.Instead while constructing the linked list, make another pointer *tail to point to the last node. So for removing an element from the end, you can write

struct node *curr, *prev;
curr=head;
prev=NULL;
while(curr!=tail)
{
  prev=curr;
  curr=curr->next;
}

Now when the loop terminates, curr will point to tail and prev will point to the node just before tail.
After doing this,write the following:

    free(curr); //deallocates the memory
    tail=prev;
    tail->next=NULL;

So ultimately, I have removed the node from end.

Edited 4 Years Ago by Mr.Angry

i just tried doing that but it is still printing the same output

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

struct node
{
       int data;
       struct node *next;

};

void addtobegining(int);
void traverse();
struct node *head;
struct node *tail;
void removefromend();

int main()
{
    head = '\0';
    addtobegining(3);
    addtobegining(2);
    addtobegining(1);
    traverse();
    removefromend();
    traverse();
    system("pause");
}

void addtobegining(int i)
{
     struct node*p;
     p = malloc(sizeof(struct node));
     p ->data = i;
     p ->next = head;
     head = p;
}

void traverse()
{
     struct node *p;
     p = head;
     while(p)
     {
              printf("%d\n",p ->data);
              p=p ->next;
     }
}


void removefromend()
{
    struct node *curr, *prev;
    curr=head;
    prev='\0';
    while(curr!=tail)
    {
                     prev=curr;
                     curr=curr->next;
    }
    free(curr); 
    tail=prev;
    tail->next=NULL;
}

Try this.It works perfectly. The mistake that you did in your program is you did not make the tail point to the end of the list..
Just copy and paste below program in C and check the output

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node
{
         int data;
         struct node *next;
};
void addtobegining(int);
void traverse();
struct node *head;
struct node *tail;
void removefromend();
int main()
{
     head = (struct node *)malloc(sizeof(struct node));
     printf("Enter data element: ");
     scanf("%d",&head->data);
     tail=head; //as this is the first and the only node
     tail->next=NULL;
     addtobegining(3);
     printf("\n Added 3 in beginning");
     addtobegining(2);
     printf("\nAdded 2 in beginning");
     addtobegining(1);
     printf("\nAdded 1 in beginning");
     printf("\nList traversal\n");
     traverse();
     printf("\nRemoving element from end");
     removefromend();
     printf("\nList after removal:\n");
     traverse();
}
void addtobegining(int i)
{
      struct node *p;
      p = (struct node *)malloc(sizeof(struct node));
      p ->data = i;
      p ->next = head;
      head = p;
}
void traverse()
{
      struct node *p;
      p = head;
      while(p)
      {
                  printf("%d\t",p ->data);
                  p=p ->next;
      }
}
void removefromend()
{
     struct node *curr, *prev;
     curr=head;
     prev='\0';
     while(curr!=tail)
     {
                    prev=curr;
                    curr=curr->next;
     }
     free(curr);
     tail=prev;
     tail->next=NULL;
}

your program actually does the same thing as mine, prints the same list, i tried 123 as input and after shows 123

additionally i want to say thanks for helping me reviewing this material, i am struggling to understand linked lists and pointers

Edited 4 Years Ago by peste19

It works perfectly man.. The output that I get is as follows

Enter data element: 5
Added 3 in beginning
Added 2 in beginning
Added 1 in beginning
List traversal
 1     2     3     5
 Removing element from end
 1     2     3

As you can see above the last element has been removed perfectly...I want you to execute my programand check rather than just seeing it

nevermind i interpreted it wrong with the data element which was adding another element to the list. additionally for example i deleted lines 17 & 18 from your program to print and i noticed when printing list traversal it prints

1 2 3 7088664

where did this number come from?

If i wanted to know the # of nodes in the linked list, couldnt i do something of genre

printf("%d",*p)

Edited 4 Years Ago by peste19

If you delete lines 17 &18 then there will not be any data element for the head and hence you get a random garbage value

i thought that for example in my case the 3 would be the data element for the head since it's the last value in the list

please can any one tell me the program for linked list to print up to 10 numbers in c. Thanks in advance

This article has been dead for over six months. Start a new discussion instead.