tree errors

M

Morris Keesan

Here is my latest attempt and error message.

#include <stdio.h>

int main(void) {
struct tree *p,*tp;
tp=insert(p,2,"name",3,"color");
printf("%s\n",(struct tree)tp);
}
a.c: In function `main':
a.c:5: warning: assignment makes pointer from integer without a cast
a.c:6: conversion to non-scalar type requested

There's no declaration of insert() in scope, so it's implicitly
declared to be a function returning int. At line 5, the compiler
is complaining because you're attempting to assign that int to a pointer.

Line 6 is total garbage. You're trying to take a pointer-to-struct,
cast it to a struct (this is the "conversion to non-scalar type"),
and then pass that struct to printf, where printf is expecting a
pointer-to-char, i.e. a string. If you want to print some string
member of the struct that tp might point to, then it would be something
like
printf("%s\n", tp->stringmember);
where stringmember is a member of struct tree.
 
B

Bill Cunningham

There's no declaration of insert() in scope, so it's implicitly
declared to be a function returning int. At line 5, the compiler
is complaining because you're attempting to assign that int to a pointer.

Line 6 is total garbage. You're trying to take a pointer-to-struct,
cast it to a struct (this is the "conversion to non-scalar type"),
and then pass that struct to printf, where printf is expecting a
pointer-to-char, i.e. a string. If you want to print some string
member of the struct that tp might point to, then it would be something
like
printf("%s\n", tp->stringmember);
where stringmember is a member of struct tree.

Thanks much. I declared and defined struct tree *tp insert() in an
object file and compiled it with my source. I guess it needs to be declared
also in the source file.

Bill
 
K

Keith Thompson

Bill Cunningham said:
Thanks much. I declared and defined struct tree *tp insert() in an
object file and compiled it with my source.

No, you declared and defined it in a *source* file.
I guess it needs to be declared
also in the source file.

It needs to be declared in a header file.
 
M

Morris Keesan

No, you declared and defined it in a *source* file.


It needs to be declared in a header file.

It *should* be declared in a header file, but it doesn't *need to* be.
Technically, it will work fine if there's a correct declaration in the file
which is using the function.
 
B

Barry Schwarz

<sigh> I know but I'm pretty excited about C. There are so many things I
want to do with it. Write a parser, eventually compiler, databases. I don't
see where a parser would be difficult especially using strtok().

It's good to aim high. But since you repeatedly demonstrate that you
can't program anything more complicated than Hello World with any
expectation of success, you have taken the principle to an absurd and
unattainable level.
 
N

Nick Keighley

[...]  The fact that
it's difficult for you to copy-and-paste the error message doesn't
diminish the need to do so.  (Incidentally, I think you'll find
that Linux is also capable of networking.)

and XP of compiling C programs. Even of running gcc
 
N

Nick Keighley

    Ok then I should use this?

struct tree *pt;
insert(pt,1,"cocoa",2.5,"tabby");

right?

go and read my last post.

really, what is the point of dealing with this cretin?
 
B

Bill Cunningham

It *should* be declared in a header file, but it doesn't *need to* be.
Technically, it will work fine if there's a correct declaration in the
file
which is using the function.

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

struct tree {
int num;
struct tree *right, *left;
};

struct tree *insert(struct tree *tp, int v)
{
if (tp) {
if (tp->num > v)
tp->left = insert(tp->left, v);
else if (tp->num < v)
tp->right = insert(tp->right, v);
} else if (tp = malloc(sizeof *tp)) {
tp->num = v;
tp->left = tp->right = NULL;
}
return tp;
}

int main(void) {
struct tree *p;
insert(p->left,4);
return 0;}

I started this and I might as well finish it. I am beginning to
understand the insert function but in main I keep getting a segmentation
fault. I have tried various different things and keep getting segmentation
fault. I want to make this work. I am not seeing something.
Bill
 
B

Bill Cunningham

Do you remember I told you that you need to point p to a valid struct
of the proper type? You still haven't done this. The above code is
therefore still broken.

Yes very much. I guess I haven't done that. Point with -> ?
 
B

Bill Cunningham

Richard Heathfield said:
To point a pointer at a structure:

struct tree instance = {0}; /*I don't think I've seen this */
struct tree *p = &instance; I know this
 
M

Morris Keesan

Bill Cunningham said:



Do you remember I told you that you need to point p to a valid struct
of the proper type? You still haven't done this. The above code is
therefore still broken.

Rather than initializing the tree in main() with a dummy node, it would
make as much sense to initialize p to NULL, and pass p to the initial
call to insert(), or simply pass a literal NULL:

int main(void)
{
struct tree *p;
p = insert(NULL, 4);
return 0;
}
 
M

Morris Keesan

This is a confusing way of posting. This makes it look as if Richard
Heathfield
wrote the /* */ comment above. Put your own text on a different line from
what you're quoting.

The above line of code declares instance as a variable of type (struct
tree),
and initializes it to contain all zeros. It's equivalent to this:

struct tree instance = {0, 0, 0};

which, since the 2nd and 3rd elements of the structure are pointers, might
be
clearer as

struct tree instance = {0, NULL, NULL};

If any members of a structure are explicitly initialized, any trailing
members
without explicit initializers are set to 0 (as if 0 were assigned to them
by
an assignment operator, so doubles will be set to 0.0, pointers will be set
to a null pointer, etc. Structure members with non-integer types might end
up with values which are not all-zero-bits.
 
B

Bill Cunningham

The above line of code declares instance as a variable of type (struct
tree),
and initializes it to contain all zeros. It's equivalent to this:

struct tree instance = {0, 0, 0};

which, since the 2nd and 3rd elements of the structure are pointers, might
be
clearer as

struct tree instance = {0, NULL, NULL};

If any members of a structure are explicitly initialized, any trailing
members
without explicit initializers are set to 0 (as if 0 were assigned to them
by
an assignment operator, so doubles will be set to 0.0, pointers will be
set
to a null pointer, etc. Structure members with non-integer types might
end
up with values which are not all-zero-bits.

Something's wrong here.

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

struct tree {
int num;
struct tree *right, *left;
};

struct tree *insert(struct tree *tp, int v)
{
if (tp) {
if (tp->num > v)
tp->left = insert(tp->left, v);
else if (tp->num < v)
tp->right = insert(tp->right, v);
} else if (tp = malloc(sizeof *tp)) {
tp->num = v;
tp->left = tp->right = NULL;
}
return tp;
}

int main(void) {
struct tree inst={0};
struct tree *p=&inst;
insert(inst,1);
return 0;}

p.c: In function `main':
p.c:26: error: incompatible type for argument 1 of `insert'

Bill
 
B

Bill Cunningham

Something's wrong here.

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

struct tree {
int num;
struct tree *right, *left;
};

struct tree *insert(struct tree *tp, int v)
{
if (tp) {
if (tp->num > v)
tp->left = insert(tp->left, v);
else if (tp->num < v)
tp->right = insert(tp->right, v);
} else if (tp = malloc(sizeof *tp)) {
tp->num = v;
tp->left = tp->right = NULL;
}
return tp;
}

int main(void) {
struct tree inst={0};
struct tree *p=&inst;
insert(inst,1);
return 0;}

Ok let's see.

struct tree *p=NULL;
p=insert(NULL,1);
return p;

right?

Bill
 
M

Morris Keesan

Something's wrong here.
struct tree *insert(struct tree *tp, int v)
int main(void) {
struct tree inst={0};
struct tree *p=&inst;
insert(inst,1);
return 0;}

p.c: In function `main':
p.c:26: error: incompatible type for argument 1 of `insert'

Argument 1 of insert should be a pointer, right?

inst is not a pointer. It's a structure.
 
K

Keith Thompson

Bill Cunningham said:
Something's wrong here.
Yes.

struct tree { [...]
};

struct tree *insert(struct tree *tp, int v) [...]
}

int main(void) {
struct tree inst={0};
struct tree *p=&inst;
insert(inst,1);
return 0;}

p.c: In function `main':
p.c:26: error: incompatible type for argument 1 of `insert'

inst is of type "struct tree".
insert expects its first argument to be of type "struct tree*".
"struct tree" and "struct tree*" are incompatible types.

p is of type "struct tree*", and you're not even using it.

This is the kind of thing you need to be able to figure out on your
own.
 
N

Nick Keighley

Morris Keesan said:




How, precisely, does that make sense? What is the point of passing a
null pointer to insert()? What will it do with such a pointer that it
can't do without?

the code for insert is

struct tree *insert(struct tree *tp, int v)
{
if (tp) {
if (tp->num > v)
tp->left = insert(tp->left, v);
else if (tp->num < v)
tp->right = insert(tp->right, v);
} else if (tp = malloc(sizeof *tp)) {
tp->num = v;
tp->left = tp->right = NULL;
}
return tp;
}

so passing it a null pointer causes it to allocate memory.
This is why I asked him to post the code for insert()...

Since he's irritated me again I'll not respond for another
week or so
 
B

Ben Bacarisse

Richard Heathfield said:
Morris Keesan said:

I think this was cleared up a few posts ago, but there is no need to
point p at a struct tree. For this code, a null pointer is also fine.

[Aside: I have used the technique where a tree pointer must always be
"valid" so that every recursive type has its own empty pointer:

struct tree { struct tree *left, *right; int num; };

static struct tree empty_tree = { &empty_tree, &empty_tree };
struct tree *tree_null = &empty_tree;

but I though that would over-complicate things here.]
How, precisely, does that make sense? What is the point of passing a
null pointer to insert()? What will it do with such a pointer that it
can't do without?

A null pointer is a fine thing to pass -- it represents an empty tree
and means that the insert function will know immediately that the item
to be inserted (4) is not there.
 
B

Bill Cunningham

Ben Bacarisse said:
[Aside: I have used the technique where a tree pointer must always be
"valid" so that every recursive type has its own empty pointer:

struct tree { struct tree *left, *right; int num; };

static struct tree empty_tree = { &empty_tree, &empty_tree };
struct tree *tree_null = &empty_tree;

but I though that would over-complicate things here.]

Ben were you the one that gave me the original code I've been working
with. When I run into trouble is with main. I get much from the tree and
tree functions set up but your main confuses me.

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

struct tree
{
int val;
struct tree *left, *right;
};

struct tree *tree_insert(struct tree *tp, int v)
{
if (tp) {
if (tp->val > v)
tp->left = tree_insert(tp->left, v);
else if (tp->val < v)
tp->right = tree_insert(tp->right, v);
}
else if (tp = malloc(sizeof *tp)) {
tp->val = v;
tp->left = tp->right = NULL;
}
return tp;
}

int tree_has(struct tree *tp, int v)
{
if (tp) {
if (tp->val > v)
return tree_has(tp->left, v);
else if (tp->val < v)
return tree_has(tp->right, v);
else return 1;
}
else return 0;
}

void tree_print(struct tree *tp)
{
if (tp) {
putchar('(');
tree_print(tp->left);
printf("%d", tp->val);
tree_print(tp->right);
putchar(')');
}
}

int main(int argc, char *argv[])
{
struct tree *tp = NULL;
while (--argc > 0) {
int v = atoi(*++argv);
if (strchr(*argv, '?'))
printf("%d%s found\n", v, tree_has(tp, v) ? "" : " not");
else {
tp = tree_insert(tp, atoi(*argv));
printf("T = ");
tree_print(tp);
putchar('\n');
}
}
return 0;
}

This compiles no problem and you countdowns of argc I've never seen before.
The use of a poiunter in atoi knocks me off a bit. This code reaks of
experience. I could read all of kandr2 and still not use code this well.

Bill
 
O

osmium

Bill Cunningham said:
Ben Bacarisse said:
[Aside: I have used the technique where a tree pointer must always be
"valid" so that every recursive type has its own empty pointer:

struct tree { struct tree *left, *right; int num; };

static struct tree empty_tree = { &empty_tree, &empty_tree };
struct tree *tree_null = &empty_tree;

but I though that would over-complicate things here.]

Ben were you the one that gave me the original code I've been working
with. When I run into trouble is with main. I get much from the tree and
tree functions set up but your main confuses me.

Most news readers have a method of reading old posts so YOU can see who
helped you. If your newsreader can't do that, Google does and is available
to anyone in the world with an internet connection.

Usenet is not a replacement for scratch paper. Go to Office Max or Office
Depot or Staples or Walmart or Target for scratch paper.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,780
Messages
2,569,607
Members
45,241
Latest member
Lisa1997

Latest Threads

Top