Did I do this right? I'm getting a strange error here...
linked.c: In function ‘push’:
linked.c:50:19: warning: assignment from incompatible pointer type [enabled by default]
linked.c: In function ‘main’:
linked.c:146:9: error: incompatible type for argument 1 of ‘push’
linked.c:45:6: note: expected ‘struct node **’ but argument is of type ‘struct node’
~/swen250/CLinkedList$ gcc -o linked linked.c
linked.c: In function ‘push’:
linked.c:50:19: warning: assignment from incompatible pointer type [enabled by default]
~/swen250/CLinkedList$ gcc -o linked linked.c
linked.c: In function ‘pop’:
linked.c:63:19: error: request for member ‘data’ in something not a structure or union
linked.c:64:20: error: request for member ‘next’ in something not a structure or union
linked.c: In function ‘copyList’:
linked.c:106:9: warning: passing argument 1 of ‘appendNode’ from incompatible pointer type [enabled by default]
linked.c:75:6: note: expected ‘struct node **’ but argument is of type ‘struct node *’
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node* next;
};
static int length(struct node** head);
static void push(struct node** head, int data);
static int pop(struct node** head);
static void appendNode(struct node** head, int data);
static struct node *copyList(struct node** head);
static void printList(struct node** head);
/************************************************************
length - return length of a list
************************************************************/
int length(struct node** head) {
int count = 0;
struct node* current = NULL;
current = *head;
while (current != NULL) {
current = current->next;
++count;
}
return count;
}
/************************************************************
push - add new node at beginning of list
************************************************************/
void push(struct node** head, int data) {
struct node* new_ptr = NULL;
new_ptr = (struct node*)malloc(sizeof(struct node));
new_ptr->data = data;
new_ptr->next = *head;
*head = new_ptr;
}
/************************************************************
pop - delete node at beginning of non-empty list and return its data
************************************************************/
int pop(struct node** head) {
int val = 0;
struct node* temp = NULL;
if (*head != NULL) {
val = head->data;
temp = head->next;
free(head);
*head = temp;
}
return(val);
}
/************************************************************
appendNode - add new node at end of list
************************************************************/
void appendNode(struct node** head, int data) {
struct node* current = NULL;
struct node* previous = NULL;
struct node* new_ptr = NULL;
current = *head;
previous = current;
while (current != NULL) {
previous = current;
current = current->next;
}
new_ptr = (struct node*)malloc(sizeof(struct node));
new_ptr->data = data;
new_ptr->next = NULL;
previous = new_ptr;
}
/************************************************************
copyList - return new copy of list
************************************************************/
struct node* copyList(struct node** head) {
struct node* copy = NULL;
struct node* current = NULL;
struct node* new_ptr = NULL;
/* Copy current head to copy */
current = *head;
while (current != NULL) {
appendNode(copy, current->data);
current = current->next;
}
return copy;
}
/************************************************************
printList - print linked list as "List: < 2, 5, 6 >" (example)
************************************************************/
void printList(struct node** head) {
struct node* current = NULL;
printf("List: < ");
current = *head;
if (current == NULL)
printf("none ");
while (current != NULL) {
printf("%d", current->data);
current = current->next;
if (current != NULL)
printf(", ");
}
printf(" >\n");
}
void main() {
int i; // index used for loops
struct node *list_a; // a new list
struct node *list_a_copy; // copy of list
list_a = NULL; // initialize empty list
list_a_copy = NULL; // initialize empy list
// test push
for (i = 0; i < 4; ++i)
push(&list_a, i);
// test length
printf("Length of list = %d\n", length(&list_a));
// test print head list
printf("head:\n");
printList(&list_a);
// test append node
for (i = 4; i < 8; ++i)
appendNode(&list_a, i);
// test print head list
printf("head(append):\n");
printList(&list_a);
// make a copy of list
list_a_copy = copyList(&list_a);
// test pop head list
for (i = 0; i < 4; ++i)
printf("%d popped\n", pop(&list_a));
// test print copy list
printf("head copy:\n");
printList(&list_a_copy);
// test pop copy list
for (i = 0; i < 4; ++i)
printf("%d popped\n", pop(&list_a_copy));
}
The issue is with the way how double pointers are used.
Here is the full working code:
I have made some changes on the way how double pointers were used.
You can see the changes in pop function and copyList function.
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node* next;
};
static int length(struct node** head);
static void push(struct node** head, int data);
static int pop(struct node** head);
static void appendNode(struct node** head, int data);
static struct node *copyList(struct node** head);
static void printList(struct node** head);
/************************************************************
length - return length of a list
************************************************************/
int length(struct node** head) {
int count = 0;
struct node* current = NULL;
current = *head;
while (current != NULL) {
current = current->next;
++count;
}
return count;
}
/************************************************************
push - add new node at beginning of list
************************************************************/
void push(struct node** head, int data) {
struct node* new_ptr = NULL;
new_ptr = (struct node*)malloc(sizeof(struct node));
new_ptr->data = data;
new_ptr->next = *head;
*head = new_ptr;
}
/************************************************************
pop - delete node at beginning of non-empty list and return its data
************************************************************/
int pop(struct node** head) {
int val = 0;
struct node* temp = NULL;
if (*head != NULL) {
val = (*head)->data;
temp = (*head)->next;
free(*head);
*head = temp;
}
return(val);
}
/************************************************************
appendNode - add new node at end of list
************************************************************/
void appendNode(struct node** head, int data) {
struct node* current = NULL;
struct node* previous = NULL;
struct node* new_ptr = NULL;
current = *head;
previous = current;
while (current != NULL) {
previous = current;
current = current->next;
}
new_ptr = (struct node*)malloc(sizeof(struct node));
new_ptr->data = data;
new_ptr->next = NULL;
previous = new_ptr;
}
/************************************************************
copyList - return new copy of list
************************************************************/
struct node* copyList(struct node** head) {
struct node* copy = NULL;
struct node* current = NULL;
struct node* new_ptr = NULL;
/* Copy current head to copy */
current = *head;
while (current != NULL) {
appendNode(©, current->data);
current = current->next;
}
return copy;
}
/************************************************************
printList - print linked list as "List: < 2, 5, 6 >" (example)
************************************************************/
void printList(struct node** head) {
struct node* current = NULL;
printf("List: < ");
current = *head;
if (current == NULL)
printf("none ");
while (current != NULL) {
printf("%d", current->data);
current = current->next;
if (current != NULL)
printf(", ");
}
printf(" >\n");
}
void main() {
int i; // index used for loops
struct node *list_a; // a new list
struct node *list_a_copy; // copy of list
list_a = NULL; // initialize empty list
list_a_copy = NULL; // initialize empy list
// test push
for (i = 0; i < 4; ++i)
push(&list_a, i);
// test length
printf("Length of list = %d\n", length(&list_a));
// test print head list
printf("head:\n");
printList(&list_a);
// test append node
for (i = 4; i < 8; ++i)
appendNode(&list_a, i);
// test print head list
printf("head(append):\n");
printList(&list_a);
// make a copy of list
list_a_copy = copyList(&list_a);
// test pop head list
for (i = 0; i < 4; ++i)
printf("%d popped\n", pop(&list_a));
// test print copy list
printf("head copy:\n");
printList(&list_a_copy);
// test pop copy list
for (i = 0; i < 4; ++i)
printf("%d popped\n", pop(&list_a_copy));
}
From the error log, I notice that you have incompatible types multiples time. It would help if you post your main.cpp as well.
p.s Like Mike G said, double pointer is really excessive. You can implement a linked list using a single pointer.
Problem is in your pop() function...take a look.
you are assigning
val=head->data;
temp = head->next;
also you are freeing the head and then reassigning.
you should do like this
val=(*head)->data;
temp=(*head)->next;
and while freeing memory...free the temp and reassign head to its next.
Related
I'm new to programming in C and taking a course. I'm having trouble with one of the tasks I'm practicing. I'm supposed to Write a program that creates a linked list of 10 characters, then creates a copy of the list in reverse order. I have written (mostly copied) a code, but it only reverses the contents of my linked list, doesn't copy them to a new linked list in reverse order. It's also not working with letters even though I'm using char data type. works fine with numbers.
Here's my code:
#include <stdio.h>
#include <malloc.h>
struct Node
{
char data;
struct Node *next;
};
static void reverse(struct Node **head_ref)
{
struct Node *previous = NULL;
struct Node *current = *head_ref;
struct Node *next;
while (current != NULL)
{
next = current->next;
current->next = previous;
previous = current;
current = next;
}
*head_ref = previous;
}
void push(struct Node **head_ref, char new_data)
{
struct Node *new_node =
(struct Node *)malloc(sizeof(struct Node));
new_node->data = new_data;
new_node->next = (*head_ref);
(*head_ref) = new_node;
}
void printList(struct Node *head)
{
struct Node *temp = head;
while (temp != NULL)
{
printf("%d ", temp->data);
temp = temp->next;
}
}
int main()
{
struct Node *head = NULL;
char element = NULL;
printf("Enter 10 characters:\n");
for (int i = 0; i <= 9; i++)
{
scanf_s("%d", &element);
push(&head, element);
}
printf("Given linked list\n");
printList(head);
reverse(&head);
printf("\nReversed Linked list \n");
printList(head);
getchar();
}
This for loop
for (int i = 0; i <= 9; i++)
{
scanf_s("%d", &element);
push(&head, element);
}
invokes undefined behavior because there is used an incorrect conversion specifier %d with an object of the type char,
You need to write
for (int i = 0; i <= 9; i++)
{
scanf_s( " %c", &element, 1 );
push(&head, element);
}
Pay attention to the blank before the conversion specifier %c in the format string. This allows to skip white space characters in the input stream.
As for the function then it can be declared and defined the following simple way using the function push that you already defined
struct Node * reverse_copy( const struct Node *head )
{
struct Node *new_head = NULL;
for ( ; head != NULL; head = head->next )
{
push( &new_head, head->data );
}
return new_head;
}
And in main you can write something like
struct Node *second_head = reverse_copy( head );
Take into account that the function push would be more safer if it would process the situation when memory allocation for a node failed.
To create a copy in reverse order, create a new list with the same values as the original list but prepend the new nodes using the push function.
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
struct Node {
char data;
struct Node *next;
};
void prepend(struct Node **head_ref, char new_data) {
struct Node *new_node = (struct Node *)malloc(sizeof(struct Node));
new_node->data = new_data;
new_node->next = (*head_ref);
(*head_ref) = new_node;
}
void append(struct Node **head_ref, char new_data) {
struct Node *new_node = (struct Node *)malloc(sizeof(struct Node));
struct Node *node = *head_ref;
new_node->data = new_data;
new_node->next = NULL;
if (!node) {
*head_ref = new_node;
} else {
while (node->next)
node = node->next;
node->next = new_node;
}
}
void printList(const struct Node *head) {
const struct Node *temp = head;
while (temp != NULL) {
printf("%c ", temp->data);
temp = temp->next;
}
printf("\n");
}
struct Node *copy_reverse(struct Node *list) {
struct Node *new_list = NULL;
while (list) {
prepend(&new_list, list->data);
list = list->next;
}
return new_list;
}
void freeList(struct Node *list) {
while (list) {
struct Node *node = list;
list = list->next;
free(node);
}
}
int main() {
struct Node *head = NULL;
char element;
printf("Enter 10 characters:\n");
for (int i = 0; i < 10; i++) {
scanf_s("%c", &element);
push(&head, element);
}
printf("Given linked list\n");
printList(head);
struct Node *copy = copy_reverse(head);
printf("\nReversed Linked list \n");
printList(copy);
freeList(head);
freeList(copy);
getchar();
}
You're almost there. All it needs is one tweak. In reverse, you need to create a new copy of the current node and use that instead. Also, since you'll be ending up with a second list and not altering the original, you should return the new list from reverse.
static struct Node* reverse(const struct Node* head_ref)
{
struct Node* previous = NULL;
const struct Node* current = head_ref;
struct Node* copy;
while (current != NULL) {
copy = malloc(sizeof(*copy));
if (copy == NULL) {
// handle error
}
copy->data = current->data;
copy->next = previous;
previous = copy;
current = current->next;
}
return previous;
}
You can also make the loop prettier by converting it to a for loop.
for (current = head_ref; current != NULL; current = current->next) {
Finally, when you print out the list, you're using %d in the printf format string. %d will print the char as an integer. To print out the actual character, use %c instead.
My program takes in any number of words from the user, and stops only when the user types three asterisks (***). These words will be stored in a linked list and sorted, but the elements in the list are not sorted when I try to print the list. Why is this happening?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_STRING_LEN 32 // Limit on length of each string
/* Link list node */
struct Node
{
int data;
struct Node* next;
};
// Function to insert a given node in a sorted linked list
void sortedInsert(struct Node**, struct Node*);
// function to sort a singly linked list using insertion sort
void insertionSort(struct Node **head_ref)
{
// Initialize sorted linked list
struct Node *sorted = NULL;
// Traverse the given linked list and insert every
// node to sorted
struct Node *current = *head_ref;
while (current != NULL)
{
// Store next for next iteration
struct Node *next = current->next;
// insert current in sorted linked list
sortedInsert(&sorted, current);
// Update current
current = next;
}
// Update head_ref to point to sorted linked list
*head_ref = sorted;
}
/* function to insert a new_node in a list. Note that this
function expects a pointer to head_ref as this can modify the
head of the input linked list (similar to push())*/
void sortedInsert(struct Node** head_ref, struct Node* new_node)
{
struct Node* current;
/* Special case for the head end */
if (*head_ref == NULL || (*head_ref)->data >= new_node->data)
{
new_node->next = *head_ref;
*head_ref = new_node;
}
else
{
/* Locate the node before the point of insertion */
current = *head_ref;
while (current->next!=NULL &&
current->next->data < new_node->data)
{
current = current->next;
}
new_node->next = current->next;
current->next = new_node;
}
}
/* BELOW FUNCTIONS ARE JUST UTILITY TO TEST sortedInsert */
/* Function to print linked list */
void printList(struct Node *head)
{
struct Node *temp = head;
while(temp != NULL)
{
printf("%s \n ", temp->data);
temp = temp->next;
}
}
/* A utility function to insert a node at the beginning of linked list */
void push(struct Node** head_ref, int new_data)
{
/* allocate node */
struct Node* new_node = (struct Node*)malloc(sizeof(struct Node));
/* put in the data */
new_node->data = new_data;
/* link the old list off the new node */
new_node->next = (*head_ref);
/* move the head to point to the new node */
(*head_ref) = new_node;
}
// Main function
int main()
{
struct Node *a = NULL;
int index=1;
int i;
char * strings[MAX_STRINGS]; // Array of pointers
do
{
strings[index] = malloc(MAX_STRING_LEN * sizeof(char));
printf("Please input a word : ", index);
fgets(strings[index],MAX_STRING_LEN,stdin);
strtok(strings[index], "\n")=='\0';
}
while(strcmp(strings[index++], "***")!=0);
printf("\nThe input set, in alphabetical order:\n");
for (i = 1; i < index-1; i++)
{
push(&a, strings[i]);
}
insertionSort(&a);
printList(a);
free(strings[i]);
return 0;
}
Input:
pear
apple
***
Given output:
pear
apple
Expected output:
apple
pear
Hii I spent some time thinking what you wanted to do. And saw many problems with your code. I think you want something like this.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_STRING_LEN 32 // Limit on length of each string
#define MAX_STRINGS 100 // Limit the number of strings
struct Node {
char *data;
struct Node *next;
};
void sortedInsert(struct Node **head_ref, struct Node* new_node) {
struct Node *counter = *head_ref;
struct Node *previous = NULL;
while (counter != NULL && strcmp(counter->data,new_node->data) < 0){
previous = counter;
counter = counter->next;
}
if (previous != NULL) {
previous->next = new_node;
new_node->next = counter;
} else {
new_node->next = *head_ref;
*head_ref = new_node;
}
}
void push(struct Node **head_ref, char *new_data) {
struct Node* new_node = (struct Node*)malloc(sizeof(struct Node));
new_node->data = new_data;
new_node->next = NULL;
if (!head_ref) {
*head_ref = new_node;
return;
}
sortedInsert(head_ref,new_node);
}
void printList(struct Node *head) {
struct Node *temp = head;
while(temp != NULL) {
printf("%s\n", temp->data);
temp = temp->next;
}
}
void freeLinkedList(struct Node *head) {
struct Node *next;
while(head) {
next = head;
head = head->next;
free(next);
}
}
// Main function
int main() {
struct Node *a = NULL;
int index = 0;
int i;
char * strings[MAX_STRINGS]; // Array of pointers
do {
strings[index] = malloc(MAX_STRING_LEN * sizeof(char));
printf("Please input a word %d: ", index);
scanf("%s",strings[index]);
fflush(stdin);
} while(strcmp(strings[index++], "***") != 0 && index < MAX_STRINGS);
printf("\nThe input set, in alphabetical order:\n");
for (i = 0; i < index-1; i++) push(&a, strings[i]);
printList(a);
return 0;
}
I have tested it and it works fine.
If you have any doubts I would like to clear them.
If you want to know what's buggy in your code please feel free to ask.
I found some odd behaviour in my C code last night.
I have a few base functions for creating and manipulating C Linked Lists.
The behaviour of my insert at nth position is odd though.
The first version works fine, but the second version does not insert at all into the list. Am I missing something?
//This works fine
void insert_nth(struct node** head, int data, int n_pos){
if (n_pos == 0){
insert_top(head, data);
return;
}
struct node* current = *head;
for(int i = 0; i < n_pos - 1 ; i++){
if(current == NULL) return;
else current = current->next;
}
if(current == NULL) return;
insert_top(&(current->next), data);
}
//This doesn't insert at all
void insert_nth(struct node** head, int data, int n_pos){
if (n_pos == 0){
insert_top(head, data);
return;
}
struct node* current = *head;
for(int i = 0; i < n_pos ; i++){
if(current == NULL) return;
else current = current->next;
}
if(current == NULL) return;
insert_top(&(current), data);
}
Here are the rest of the functions I'm using for reference.
int main(){
struct node* head = NULL;
build_rand_list(&head);
list_print(&head);
return 0;
}
void list_print(struct node** head){
printf("List size is %d: List: ", list_length(head));
for(struct node* current = *head; current!= NULL; current = current->next)
printf("%d ", current->data);
printf("\n");
}
void build_rand_list(struct node** head){
//Assume head is NULL
assert(*head == NULL);
srand(time(NULL));
for (int i = 0; i < 10; i++){
int random_num = rand() % 11;
insert_end(head, random_num);
}
}
void insert_top(struct node** head, int data){
struct node *new_node = (struct node *)malloc(sizeof(struct node));
new_node->data = data;
new_node->next = *head;
*head = new_node;
}
&(current) is the address of a local variable.
&(current->next) is the address of a pointer inside a node in the list.
Modifying the local variable current, which is what insert_top ultimately does, has no effect on the list's nodes.
For example if you pass the node with the value 2 to the insert_top function the result will be something like this
It seems like you don't handle the pointers correctly. For example there is no node that points to the new node you created.
A better implementation would be
void insert_nth(struct node *head, int data, int npos) {
struct node *current = head;
for (int i = 0; i < npos - 1; i++) {
current = current->next;
if (current == null) {
printf("%s\n", "Insert failed");
return;
}
}
struct node *new_node = (struct node *)malloc(sizeof(struct node *));
new_node->data = data;
new_node->next = current->next;
current->next = new_node;
return;
}
Where the head parameter is the actual head of the list.
The result will then me more satisfying. Hope this helps.
I don't get why this isn't working... For example I have this.
struct node {
int data;
struct node* next;
};
static int length(struct node* head) {
Does Stuff
};
void main() (
int i;
struct node* head;
i = length(head);
);
but the code doesn't want to work... I get the wrong output. I'm trying to send the pointer to my functions so that they can have access to the data that I malloc. I will post the full code bellow:
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node* next;
};
static int length(struct node* head);
static void push(struct node* head, int data);
static int pop(struct node* head);
static void appendNode(struct node* head, int data);
static struct node *copyList(struct node* head);
static void printList(struct node* head);
/************************************************************
length - return length of a list
************************************************************/
int length(struct node* head) {
int count = 0;
struct node* current = NULL;
current = head;
while (current != NULL) {
current = current->next;
++count;
}
return count;
}
/************************************************************
push - add new node at beginning of list
************************************************************/
void push(struct node* head, int data) {
struct node* new_ptr = NULL;
new_ptr = (struct node*)malloc(sizeof(struct node));
new_ptr->data = data;
new_ptr->next = head;
head = new_ptr;
}
/************************************************************
pop - delete node at beginning of non-empty list and return its data
************************************************************/
int pop(struct node* head) {
int val = 0;
struct node* temp = NULL;
if (head != NULL) {
val = head->data;
temp = head->next;
free(head);
head = temp;
}
return(val);
}
/************************************************************
appendNode - add new node at end of list
************************************************************/
void appendNode(struct node* head, int data) {
struct node* current = NULL;
struct node* previous = NULL;
struct node* new_ptr = NULL;
current = head;
previous = current;
while (current != NULL) {
previous = current;
current = current->next;
}
new_ptr = (struct node*)malloc(sizeof(struct node));
new_ptr->data = data;
new_ptr->next = NULL;
previous = new_ptr;
}
/************************************************************
copyList - return new copy of list
************************************************************/
struct node* copyList(struct node* head) {
struct node* copy = NULL;
struct node* current = NULL;
struct node* new_ptr = NULL;
/* Copy current head to copy */
current = head;
while (current != NULL) {
appendNode(copy, current->data);
current = current->next;
}
return copy;
}
/************************************************************
printList - print linked list as "List: < 2, 5, 6 >" (example)
************************************************************/
void printList(struct node* head) {
struct node* current = NULL;
printf("List: < ");
current = head;
if (current == NULL)
printf("none ");
while (current != NULL) {
printf("%d", current->data);
current = current->next;
if (current != NULL)
printf(", ");
}
printf(" >\n");
}
void main() {
int i; // index used for loops
struct node *list_a; // a new list
struct node *list_a_copy; // copy of list
list_a = NULL; // initialize empty list
list_a_copy = NULL; // initialize empy list
// test push
for (i = 0; i < 4; ++i)
push(list_a, i);
// test length
printf("Length of list = %d\n", length(list_a));
// test print head list
printf("head:\n");
printList(list_a);
// test append node
for (i = 4; i < 8; ++i)
appendNode(list_a, i);
// test print head list
printf("head(append):\n");
printList(list_a);
// make a copy of list
list_a_copy = copyList(list_a);
// test pop head list
for (i = 0; i < 4; ++i)
printf("%d popped\n", pop(list_a));
// test print copy list
printf("head copy:\n");
printList(list_a_copy);
// test pop copy list
for (i = 0; i < 4; ++i)
printf("%d popped\n", pop(list_a_copy));
}
Thank you for you help. I'm still learning these C pointers, and I know I'm close.
Cheers
I looked into function push():
void push(struct node* head, int data) {
struct node* new_ptr = NULL;
new_ptr = (struct node*)malloc(sizeof(struct node));
new_ptr->data = data;
new_ptr->next = head;
head = new_ptr;
}
The way you assign head = new_ptr; is wrong. Doing so only, head has effect within in the function, head won't be pointed to the memory you allocated after push() is called. So you need to fix your push() function:
void push(struct node **head, int data) {
if ((*head) == null)
(*head) = (struct node*)malloc(sizeof(struct node));
(*head)->data = data;
(*head)->next = head;
}
The problem is that you are passing a pointer to a node in your methods. This means that what you are modifying is a local parameter and not what you are passing to the method. Why is this? Because passing by value copies the parameter, to the address is directly copied.
struct Node *list_a = NULL;
push(list_a, 5);
When you call push, what happens is that a copy of the variable list_a is pushed onto the stack and then the function is called. The same thing, if you think about it, happens with simple cases:
int x = 5;
add(x, 5);
void add(int a, int b) { a += b; } // <-- this won't modify the x passed
So here
void push(struct Node *head, int value) {
head = something;
}
you are not modifying the original list_a but rather a copy of it which has been passed to the function.
To be able to modify the original pointer you need to pass the address to it, so a pointer to the pointer of the head of the list. This can be done easily:
struct Node *list_a = NULL;
push(&node, 5);
void push (struct Node **node, int value) {
...
*node = malloc(..);
}
So here the address of the variable list_a is passed to the function, dereferencing it allows you to modify the real value instead that just a copy.
#include<stdio.h>
#include<stdlib.h>
struct node {
int data;
struct node *next;
};
int insert (struct node *head, int data);
int print (struct node *head);
int main()
{
struct node *head;
head = NULL;
// printf("%d\n",head);
insert(&head,5);
insert(&head,4);
insert(&head,6);
print(&head);
print(&head);
print(&head);
}
int insert(struct node *head,int data) {
if(head == NULL) {
head = malloc(sizeof(struct node));
head->next = NULL;
head->data = data;
// printf("%d\n",data);
}
else {
struct node *tmp = head;
if(tmp->next!=NULL) {
tmp = tmp->next;
}
tmp->next = malloc(sizeof(struct node));
tmp->next->next = NULL;
tmp->next->data = data;
// printf("%d\n",data);
}
}
int print (struct node *head) {
printf("hello entered here\n");
struct node *tmp = head;
if (head == NULL) {
printf("entered null\n");
return;
}
while (tmp != NULL) {
if (tmp->next == NULL) {
printf("%0d", tmp->data);
} else {
printf("%0d -> ", tmp->data);
}
tmp = tmp->next;
}
printf("\n");
}
I got the following warning when i compile it
In function main:
insert.c:16: warning: passing argument 1 of insert from incompatible pointer type
insert.c:17: warning: passing argument 1 of insert from incompatible pointer type
insert.c:18: warning: passing argument 1 of insert from incompatible pointer type
insert.c:19: warning: passing argument 1 of print from incompatible pointer type
insert.c:20: warning: passing argument 1 of print from incompatible pointer type
insert.c:21: warning: passing argument 1 of print from incompatible pointer type
When i run it i will get following output
hello entered here
0 -> 5 -> 6
hello entered here
0 -> 5 -> 6
hello entered here
0 -> 5 -> 6
Please help me remove this warnings.
And can u also help me add a function to remove the node in C
What is the mistake I am doing?
Should i pass **head to the function?
Currently the functions print() and insert() expects to struct node* whereas you pass struct node **. If you want to pass a copy then drop the & in your function calls in your code.
If you want to modify the pointer head pass a pointer to pointer and modify the parameters accordingly:
#include<stdio.h>
#include<stdlib.h>
struct node {
int data;
struct node *next;
};
int insert (struct node **head, int data);
int print (struct node **head);
int main()
{
struct node *head;
head = NULL;
// printf("%d\n",head);
insert(&head,5);
insert(&head,4);
insert(&head,6);
print(&head);
print(&head);
print(&head);
}
int insert(struct node **head,int data){
if(*head == NULL){
*head = malloc(sizeof(struct node));
(*head)->next = NULL;
(*head)->data = data;
// printf("%d\n",data);
}
else {
struct node *tmp = *head;
if(tmp->next!=NULL){
tmp = tmp->next;
}
tmp->next = malloc(sizeof(struct node));
tmp->next->next = NULL;
tmp->next->data = data;
// printf("%d\n",data);
}
}
int print (struct node **head) {
printf("hello entered here\n");
struct node *tmp = *head;
if (*head == NULL) {
printf("entered null\n");
return;
}
while (tmp != NULL) {
if (tmp->next == NULL) {
printf("%0d", tmp->data);
} else {
printf("%0d -> ", tmp->data);
}
tmp = tmp->next;
}
printf("\n");
}
Your insert() smells - too complicated. This is some sort of OO actually.
Here is my way, direct typed:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
// class node_t
typedef struct __node_s *node_t; // Mind the pointer here.
struct __node_s {
int data;
node_t next;
};
node_t node_init(void); // Constructor.
void node_append(node_t, int);
void node_drop_last(node_t);
void node_print(node_t);
void node_fini(node_t); // Destructor.
// end class node_t
int main(void)
{
node_t head = node_init();
node_append(head, 5);
node_append(head, 4);
node_append(head, 6);
node_print(head);
node_drop_last(head);
node_print(head);
node_fini(head);
head = NULL;
return 0;
}
node_t node_init(void)
{
node_t node = malloc(sizeof(struct __node_s));
assert(node);
memset(node, 0, sizeof(struct __node_s));
return node;
}
void node_insert(node_t head, int data)
{
node_t last = head, new = node_init();
for (; last->next; last = last->next);
new->data = data;
last->next = new;
}
void node_drop_last(node_t head)
{
node_t last = head;
if (!head->next)
return;
for (; last->next->next; last - last->next);
node_fini(last->next);
last->next = NULL;
}
void node_print(node_t head)
{
for (node_t this = head->next; this; this = this->next)
{
printf("%d", this->data);
if (this->next)
putchar(' '); // A lot faster!
}
putchar('\n');
}
void node_fini(node_t head)
{
if (head->next)
{
node_fini(head->next);
head->next = NULL;
}
free(head);
}