I have below code.
I am getting error as 'list' undeclared (first use in this function).
Please help me
#include <stdio.h>
#include <stdlib.h>
struct list{
int data;
struct list *next;
};
typedef struct list *head;
int main()
{
struct list *start;
int i;
start = (list *) malloc(sizeof(struct list));
printf("\nEnter the data : \n");
scanf("%d", &i);
start->data = i;
start->next = NULL;
while(list->next != NULL)
{
printf("%d ", list->data);
list = list->next;
}
return 0;
}
You're using the type list instead of variable name start. Proper code:
while (start->next != NULL)
{
start = start->next;
// etc.
}
Don't cast the return type of malloc - there's no benefit of it and in this case you did it wrong!
start = (list *) malloc(sizeof(struct list));
should be
start = malloc(sizeof(struct list));
the type list * doesn't exist; you meant struct list *.
You can make it even more safe by writing
start = malloc(sizeof(*start));
this way you automatically malloc enough bytes for the (pointer) type of start, which is useful when you later change the type of start - the malloc call doesn't change a bit.
The
start = (list *) malloc(sizeof(struct list));
includes an unnecessary typecast. Just do
start = malloc(sizeof(struct list));
However, your code has more trouble than this. I can answer your question best by asking a question of my own: in your mind, is list a type or an object?
If you answer this question, one suspects that you can fix your code. Good luck.
#include <stdio.h>
#include <stdlib.h>
typedef struct list{
int data;
struct list *next;
} list;
typedef struct list *head;
int main()
{
struct list *start;
int i;
start = (list *) malloc(sizeof(struct list));
printf("\nEnter the data : \n");
scanf("%d", &i);
start->data = i;
start->next = NULL;
while(start->next != NULL)
{
start = start->next;
}
return 0;
}
you can define the type (list *)
Your variable is named « start » and you called it « list ».
start = (struct list *) malloc ...
You've missed struct in casting.
Which is not neccessary at all as Anthales pointed out.
start = malloc ...
One problem you had is you were re-using struct in declaring your struct pointer after you had created a typedef, struct list *start;. Also the struct and typedef cannot have the same name. You get this:
cc -Wall test.c -o test
test.c: In function ‘main’:
test.c:13: error: ‘list_t’ undeclared (first use in this function)
test.c:13: error: (Each undeclared identifier is reported only once
test.c:13: error: for each function it appears in.)
test.c:13: error: ‘start’ undeclared (first use in this function)
test.c:13: error: ‘cur’ undeclared (first use in this function)
test.c:13: warning: left-hand operand of comma expression has no effect
test.c:16: error: expected expression before ‘)’ token
You can choose to use struct list everywhere and skip making using typedef. Use of typedef simplifies how your code reads as noted here: http://en.wikipedia.org/wiki/Struct_%28C_programming_language%29#typedef
I've rewritten what you have just so I could compile it and understand it a little better, and so I could put some data into one node. I remember the whole struct typedef concept taking a little time to sink in, when I was learning C. So, don't give up.
#include <stdio.h>
#include <stdlib.h>
struct list {
int data;
struct list *next;
};
typedef struct list list_t;
int main()
{
list_t *start, *cur;
int i;
start = (list_t *) malloc(sizeof(list_t));
if (NULL != start)
{
cur = start; /* Preserve list head, and assign to cur for list trarversal. */
printf("\nEnter the data : ");
scanf("%d", &i);
cur->data = i;
cur->next = NULL;
cur = start;
while(cur != NULL)
{
printf("%d ", cur->data);
cur = cur->next;
}
}
else
{
printf("Malloc failed. Program ending.");
}
return 0;
}
Related
I would like to know if design of my program is correct, as well as to understand if my commented area is doing what it supposed to be doing. I get these compile errors that are associated probably with commented segments of my code, and I would lie to receive some help. THANKS!
part1.c:15:6: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'insert'
part1.c: In function 'main':
part1.c:43:14: error: incompatible types when assigning to type 'struct point' from type 'int'
part1.c:49:44: error: invalid type argument of '->' (have 'struct point')
part1.c:49:59: error: invalid type argument of '->' (have 'struct point')
part1.c:55:5: error: incompatible type for argument 1 of 'free'
/usr/include/stdlib.h:488:13: note: expected 'void *' but argument is of type 'struct point'
char *chars[3]= {"a","b","c"};
int nums[3]= {5,8,9};
struct point {char *letter;
int number;
struct point *next;};
struct point* insert(struct point list[],char *rqdLetters, int rqdNums)
{
struct point *new;
new = (struct point*)malloc(sizeof(struct point));
if(new == NULL)
fprintf(stderr,"error!");
new->letter = rqdLetters;
new->number = rqdNums;
new->next = head;
head = new;
//not sure if i'm returning the a pointer to the start of new list
return head;
}
int main(int argc, char **argv)
{
//not sure if i need to declare these here or in the insert
struct point list[3];
struct point *head = NULL;
struct point *next;
struct point *new;
int i;
for (i = 0; i < 3; i++)
{
//return result put back into the pointer to the start of the list
head[i] = insert(list[i], chars[i], nums[i]);
}
int j;
for(j = 0; j < 3; j++)
{
printf("letter %s and number %d\n", list[j]->letter, list[j]->number);
}
int z;
for(z = 0; z < 3; z++)
{
free(list[z]);
}
return 0;
}
At a glance, there are several issues with your code. Firstly, you're not declaring your variables correctly.
new = list;
should be:
struct point* new;
Your function signature also looks a little suspect. If you're returning a pointer to your data structure, it should be something like:
struct point* insert(...) { ... }
At a more general level, I does seem like your idea of a linked list may be a little off. To represent a list, you should only need to hold on to the head and tail of the list, instead of keep an array of your points.
It usually helps if you create a data structure to hold these pointers. You can then pass this structure around to functions that operate on the list e.g. the insert() function.
As a quick example (untested):
struct node {
struct node *next;
char letter;
int number;
}
struct list {
struct node *head;
struct node *tail;
}
/* create a new list */
struct list* list_new(void) {
struct list *L = malloc(sizeof(struct list));
L->head = NULL;
L->tail = NULL;
}
/* add a new node to the list */
void list_insert(struct list *list, char in_letter, int in_number) {
struct node *node = malloc(sizeof(struct node));
node->letter = in_letter;
node->number = in_number;
node->next = NULL;
if (list->head == NULL) { /* empty list */
list->head = node;
list->tail = node;
} else { /* append to list */
list->tail->next = node;
list->tail = node;
}
}
You can then use it as such:
int i;
char chars[3]= {"a","b","c"};
int nums[3]= {5,8,9};
struct list *mylist = list_new();
for (i = 0; i < 3; i++)
{
list_insert(mylist, chars[i], nums[i]);
}
In response to:
... and i am not sure if i am supposed to declare it inside insert or main, i did in the main however
This depends on where you intend to use the variables and the intended lifespan of these variables. As stated in the comments above, you might want to polish up on your understanding of scoping rules.
So I'm trying to implement a cache in C. I have included a very slimmed down version of my code.
I keep getting this error:
prog.c: In function ‘addtolist’:
prog.c:29: warning: assignment from incompatible pointer type
prog.c:40: warning: assignment from incompatible pointer type
prog.c: In function ‘main’:
prog.c:72: warning: assignment from incompatible pointer type
from this code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
struct node_
{
char * word;
int filenumber;
struct node * next;
};
typedef struct node_ * node;
node createnode()
{
node head;
head = malloc(sizeof(struct node_));
head->word = NULL;
head->next = NULL;
return head;
}
unsigned int addtolist(node head, char * word, unsigned int limit, int fileno)
{
unsigned int templimit = limit;
node temp;
node temphead = head;
while(temphead->next != NULL)
{
temphead = temphead->next;
}
temp = malloc(sizeof(struct node_));
temp->word =(char*) malloc(strlen(word)+ 1);
strcpy(temp->word, word);
temp->next = NULL;
temp->filenumber = fileno;
templimit = templimit - (strlen(word) + 1) - sizeof(struct node_)- sizeof(int);
printf("templimit is size %u\n", templimit);
if (templimit < limit && templimit > 0)
{
temphead->next = temp;
limit = limit - strlen(word) - 1 - sizeof(struct node_)- sizeof(int);
return limit;
}
else
{
free(temp->word);
free(temp);
return 0;
}
}
int main()
{
node newlist = createnode();
int i = 0;
unsigned int limit = 65;
unsigned int temp = limit;
while(temp > 0 && temp <= limit)
{
temp = addtolist(newlist, "Hello", temp, i);
i++;
printf("new limit is - \t%u\nfilenumber is - \t%d\n", temp,i);
}
node ptr = newlist;
while(ptr->next != NULL)
{
printf("node %d contains the word %s\n", ptr->filenumber, ptr->word);
ptr = ptr->next;
}
return 1;
}
I honestly can't figure out what I'm doing wrong... My logic was that, since I was typedef'ing my struct as a pointer, after I created the struct in memory, I would be able to easily step through the ensuing list. Where was the flaw in my logic?
EDIT the initial problem was fixed (I forgot an underscore in my type declaration for struct node_ next;.
Now I'm having another problem: when I try to step through the list at the bottom of my code to print out the words contained in the list, I'm basically not able to step through the list. I keep outputting:
templimit is size 43
new limit is - 43
filenumber is - 1
templimit is size 21
new limit is - 21
filenumber is - 2
templimit is size 4294967295
new limit is - 0
filenumber is - 3
node 0 contains the word (null)
node 0 contains the word Hello
For some reason, it seems that my program isn't storing my changes to my list in memory after the first iteration. Any ideas on what I'm doing wrong?
Once again, any help would be appreciated, and thanks.
Inside your structure definition you have struct node without the underscore.
you'd better have a forward declaration
typedef struct node node;
and then declare your structure
struct node {
...
node *next;
};
no need to have this underscore stuff and hiding the * in a typedef. That only makes you mix things up easily.
String literals "like this" have type const char*, not char*, because they're immutable.
Fix your declarations to have const char* and the warnings will go away.
I think the struct member 'next' has to be declared as a (node_ *) type. As written it is currently (node_ **)
I did my whole project in NetBeans on my mac and it works fine. Then I go to put it into terminal to submit it on our ssh server for school and its giving me a bunch of compilation errors. Did netbeans compile in c++ or something? I'm new to c so any help is certainly appreciated. Here's the code.
/*
* File: LinkedList.c
* Author: dpiganell
*
* Created on October 17, 2011, 2:31 PM
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct element{
int i;
struct element *next;
};
void insert(struct element**, struct element*);
void purge (struct element*, struct element*);
void printList(struct element*);
void printListBackwards(struct element*);
struct element *h;
int main()
{
// HEAD
h = (element *) malloc(sizeof(element));
h = NULL;
// NEW VALUE
struct element *n = NULL;
// POINTER TO THE POINTER OF HEAD
struct element **headPointer;
headPointer = (element **) malloc(sizeof(element));
int a;
a = 1;
while(a >= 0)
{
n = (element *) malloc(sizeof(element));
printf("\nPlease enter an integer value: ");
scanf("%d", &a);
if(a >= 0)
{
n->i = a;
n->next = NULL;
headPointer = &h;
insert(headPointer, n);
n = n++;
}
printList(h);
printListBackwards(h);
}
return 0;
}
void insert(struct element **head, struct element *n)
{
element *nptr, *pptr, *cptr;
// NEW POINTER, PREVIOUS POINTER, CURRENT POINTER
nptr = (element *) malloc(sizeof(element));
int purged;
purged = -1;
if(nptr != NULL)
{
nptr->i = n->i;
nptr->next = NULL;
cptr = *head;
pptr = NULL;
}
while(cptr != NULL && n->i >= cptr->i)
{
if(cptr->i == n->i && purged != 1)
{
purged = 1;
purge(cptr, pptr);
}
else
{
pptr = cptr;
cptr = cptr->next;
}
}
if(pptr == NULL && purged < 0)
{
nptr->next = *head;
*head = nptr;
}
else if(purged < 0)
{
pptr->next = nptr;
nptr->next = cptr;
}
}
void purge(struct element *current, struct element *predecessor)
{
element *ptr = (element *) malloc(sizeof(element));
// ERASING THE HEAD
if(predecessor == NULL)
{
if(current->next == NULL)
{
current->next = NULL;
current->i = NULL;
current = NULL;
free(current);
h = NULL;
}
else
memcpy(current, current->next, sizeof(element));
}
// ERASING THE TAIL
else if(current->next == NULL)
{
current->i = NULL;
free(current->next);
free(current);
predecessor->next = NULL;
}
// ERASING ANYTHING IN THE MIDDLE OF THE LIST
else
{
ptr = current->next;
predecessor->next = ptr;
current->i = NULL;
free(current->next);
}
}
void printList(struct element *head)
{
if(head == NULL)
printf("The list is empty.");
else
{
struct element *ptr;
ptr = (element*) malloc(sizeof(element));
ptr = head;
int a;
a = 1;
printf("Forwards: ");
while(a > 0)
{
printf("%d ", ptr->i);
if((ptr->next) == NULL)
a = -1;
else
ptr = ptr->next;
}
}
}
void printListBackwards(struct element *ptr)
{
if(ptr == NULL)
{
// DO NOTHING BECAUSE IT WILL BE PRINTED ALREADY THAT IT IS EMPTIED
}
else
{
element *cptr = (element *) malloc(sizeof(element));
cptr = ptr;
if(ptr->next == NULL)
printf("\nBackwards: %d ", ptr->i);
else
{
printListBackwards(ptr->next);
printf("%d ", ptr->i);
}
}
}
Also, here are the errors. It works fine and compiles fine in netbeans.
LinkedList.c:14: warning: useless keyword or type name in empty declaration
LinkedList.c: In function `main':
LinkedList.c:26: error: `element' undeclared (first use in this function)
LinkedList.c:26: error: (Each undeclared identifier is reported only once
LinkedList.c:26: error: for each function it appears in.)
LinkedList.c:26: error: syntax error before ')' token
LinkedList.c:34: error: syntax error before ')' token
LinkedList.c:40: error: syntax error before ')' token
LinkedList.c: In function `insert':
LinkedList.c:65: error: `element' undeclared (first use in this function)
LinkedList.c:65: error: `nptr' undeclared (first use in this function)
LinkedList.c:65: error: `pptr' undeclared (first use in this function)
LinkedList.c:65: error: `cptr' undeclared (first use in this function)
LinkedList.c:68: error: syntax error before ')' token
LinkedList.c: In function `purge':
LinkedList.c:110: error: `element' undeclared (first use in this function)
LinkedList.c:110: error: `ptr' undeclared (first use in this function)
LinkedList.c:110: error: syntax error before ')' token
LinkedList.c: In function `printList':
LinkedList.c:153: error: `element' undeclared (first use in this function)
LinkedList.c:153: error: syntax error before ')' token
LinkedList.c: In function `printListBackwards':
LinkedList.c:179: error: `element' undeclared (first use in this function)
LinkedList.c:179: error: `cptr' undeclared (first use in this function)
LinkedList.c:179: error: syntax error before ')' token
In C, this definition
struct element{
int i;
struct element *next;
};
has to be referred to as struct element. You get that right in some places, not all. A known idiom is:
typedef struct element {
int i;
struct element *next;
} element;
Which typedefs element as struct element so you don't need to place struct in front of the type. This was so common that C++ kind of "does this for you" so struct is no longer needed.
It's C, you cannot use bare element, it's struct element.
Your issues are related to how you declare your struct element vs. how you use it.
typedef struct element{
int i;
struct element *next;
} element;
will give you more satisfactory results.
Alternately, you can leave your struct as it is, wherever you use a bare element, instead write struct element.
BTW:
This isn't related to your exact problem, but I thought I would share (as my compiler gave me a warning about it); you sometimes write:
current->i = NULL;
In this case, i is an integer. In C, NULL is traditionally used only for pointer types. So as not to confuse, you should either change the assignment to:
current->i = 0;
...or, if i actually is meant to point to memory somewhere (which given the context above, I presume it is not), declare it as a pointer type.
You need to typedef your struct if you're going to use it that way. Otherwise you need to use the struct keyword everywhere. Check documentation
So you want to say:
typedef struct element {
int i;
element *next;
} element;
when you declare element. Otherwise the compiler doesn't know that element is a structure every time you use it.
h = (element *) malloc(sizeof(element));
h = NULL;
headPointer = (element **) malloc(sizeof(element));
This is your first error. element is a struct tag, not a typedef. (this has been handled by the others.)
in the loop:
headPointer = &h;
Both pointers have been assigned (malloc()d) values. By re-assigning them, you lose the stuff what was previously malloc()d.
The 'headPointer' stuff is a good idea. It is a pointer that can point to other pointers. You can use it to let a called function alter the the value of on of the callers pointers. But your usage is not right. Normally the caller should do:
struct clown *pipo=NULL;
...
my_function( &pipo);
Inside the function, the caller's pointer can than be altered:
void my_function (struct clown **ppp) {
...
*ppp = malloc (sizeof (struct clown));
...
}
After the function returned, the caller can use the pointer, and it will hopefully point at the new clown.
That's all.
this is probably a simple solution I am not that familiar with C just trying to port my java data structure assignments to C.
this is the error i am getting:
test.c:4: error: expected ‘)’ before ‘*’ token
test.c:11: error: expected ‘)’ before ‘*’ token
#include <stdio.h>
#include <stdlib.h>
void to_screen(NODE *cur){
while(cur->next != NULL){
printf("%d\n", cur->data);
cur = cur->next;
}
}
void add_first(NODE *head, int data){
NODE *cur;
int i;
for(i=0; i<10; i++){
cur = malloc(sizeof(NODE));
cur->data = data;
cur->next = (*head).next;
head->next = cur;
}
}
typedef struct node{
int data;
struct element *next;
}NODE;
int main(){
int i;
NODE *head;
for(i=0; i<10; i++){
add_first(head, i);
}
to_screen(head);
}
You need to move the definition of your struct above the to_screen function. The compiler is saying that it doesn't know what NODE is.
You need to define NODE before it is used. Move the definition to the top.
You need to move this block to the top as 2 other answers recommend.
typedef struct node{
int data;
struct element *next;
}NODE;
You may ask for the reason. The reason is that C language specification is not like Java. So it kinds of compiling from the top to the bottom. So, if it see something undefined, it will look for definition above that point, and if it sees the definition it gets it. It doesn't look below the line of code
I've been trying to figure out pointers in C most of today, even asked a question earlier, but now I'm stuck on something else. I've got the following code:
typedef struct listnode *Node;
typedef struct listnode {
void *data;
Node next;
Node previous;
} Listnode;
typedef struct listhead *LIST;
typedef struct listhead {
int size;
Node first;
Node last;
Node current;
} Listhead;
#define MAXLISTS 50
static Listhead headpool[MAXLISTS];
static Listhead *headpoolp = headpool;
#define MAXNODES 1000
static Listnode nodepool[MAXNODES];
static Listnode *nodepoolp = nodepool;
LIST *ListCreate()
{
if(headpool + MAXLISTS - headpoolp >= 1)
{
headpoolp->size = 0;
headpoolp->first = NULL;
headpoolp->last = NULL;
headpoolp->current = NULL;
headpoolp++;
return &headpoolp-1; /* reference to old pointer */
}else
return NULL;
}
int ListCount(LIST list)
{
return list->size;
}
Now in a new file I have:
#include <stdio.h>
#include "the above file"
main()
{
/* Make a new LIST */
LIST *newlist;
newlist = ListCreate();
int i = ListCount(newlist);
printf("%d\n", i);
}
When I compile, I get the following warning (the printf statement prints what it should):
file.c:9: warning: passing argument 1 of ‘ListCount’ from incompatible pointer type
Should I be worried about this warning? The code seems to do what I want it to, but I'm obviously very confused about pointers in C. After browsing questions on this site, I found that if I make the argument to ListCount (void *) newlist, I don't get the warning, and I don't understand why, nor what (void *) really does...
Any help would be appreciated, thanks.
You're getting confused because of multiple typedefs. LIST is a type representing a pointer to struct listhead. So, you want your ListCreate function to return a LIST, not a LIST *:
LIST ListCreate(void)
The above says: ListCreate() function will return a pointer to a new list's head if it can.
Then you need to change the return statement in the function definition from return &headpoolp-1; to return headpoolp-1;. This is because you want to return the last available head pointer, and you have just incremented headpoolp. So now you want to subtract 1 from it and return that.
Finally, your main() needs to be update to reflect the above changes:
int main(void)
{
/* Make a new LIST */
LIST newlist; /* a pointer */
newlist = ListCreate();
int i = ListCount(newlist);
printf("%d\n", i);
return 0;
}