Newbie questions

B

Blue Ocean

I am definitely a C newbie, and I'm having some difficulty making a
structure. I must be missing something (or the manual I'm looking at
is missing something), but I can't figure out what.

Oh yeah, this is -not- for class of any kind, just my own curiosity.
My school does not begin teaching C or C++ until middle of sophmore
year on the CS track, so I'm trying to learn a little of my own on the
side.

struct registers
{
int bankSize;
int *progCounter;
int *instRegister;
int contents[REGISTERS];
/* contents[0] = 0;
*progCounter = &contents[0];
*instRegister = contents[1];*/
};

The commented part will not compile on my machine. In fact, none of
those three lines will compile. My sense of logic tells me that this
means that I cannot actually initialize variables in structures, but I
do not know how else I should initialize them; they will always be
what they are there. Do I create a function to do it for me and
return the new structure?

Another question. The manual that I was reading said that there was a
rule of thumb that semicolons never went to the right of a curly
brace. Nonetheless, a semicolon there is and the compiler seems to
have no trouble with it.

Does anyone have a link to a place that explains the preprocessor
directives well? I've read several versions of different FAQs and
online instructional pages and I still haven't really got a handle on
them.

Thanks anyone for any help in advance. Also, if I've messed up some
forum rule or anything, please tell me, since I'll need to know when I
have a new problem.

James
 
A

Artie Gold

Blue said:
I am definitely a C newbie, and I'm having some difficulty making a
structure. I must be missing something (or the manual I'm looking at
is missing something), but I can't figure out what.

Oh yeah, this is -not- for class of any kind, just my own curiosity.
My school does not begin teaching C or C++ until middle of sophmore
year on the CS track, so I'm trying to learn a little of my own on the
side.

struct registers
{
int bankSize;
int *progCounter;
int *instRegister;
int contents[REGISTERS];

We'll assume that `REGISTERS' is a `#define'd value...
/* contents[0] = 0;
*progCounter = &contents[0];
*instRegister = contents[1];*/
};

The commented part will not compile on my machine. In fact, none of
those three lines will compile. My sense of logic tells me that this
means that I cannot actually initialize variables in structures, but I
do not know how else I should initialize them; they will always be
what they are there. Do I create a function to do it for me and
return the new structure?

That is essentially correct. You cannot have any `executable' code in a
structure declaration. [There are some other problems with the proposed
code you commented out, but we'll leave that for later. ;-)]
Another question. The manual that I was reading said that there was a
rule of thumb that semicolons never went to the right of a curly
brace. Nonetheless, a semicolon there is and the compiler seems to
have no trouble with it.

The `rule of thumb' relates to using semicolons in actual code;
structure and union definitions *always* end with a semicolon.
Does anyone have a link to a place that explains the preprocessor
directives well? I've read several versions of different FAQs and
online instructional pages and I still haven't really got a handle on
them.

Your best bet is to ask more specific questions when you run into
something in particular you don't understand.
Thanks anyone for any help in advance. Also, if I've messed up some
forum rule or anything, please tell me, since I'll need to know when I
have a new problem.

You're doing fine. ;-)

HTH,
--ag
 
D

Dave Vandervies

I am definitely a C newbie, and I'm having some difficulty making a
structure. I must be missing something (or the manual I'm looking at
is missing something), but I can't figure out what.

Oh yeah, this is -not- for class of any kind, just my own curiosity.
My school does not begin teaching C or C++ until middle of sophmore
year on the CS track, so I'm trying to learn a little of my own on the
side.

struct registers
{
int bankSize;
int *progCounter;
int *instRegister;
int contents[REGISTERS];
/* contents[0] = 0;
*progCounter = &contents[0];
*instRegister = contents[1];*/
};

The commented part will not compile on my machine. In fact, none of
those three lines will compile. My sense of logic tells me that this
means that I cannot actually initialize variables in structures,

Correct.
The struct definition doesn't create a variable, it only defines a type
that can be used for variables; you can only initialize when you're
creating the variable.
but I
do not know how else I should initialize them; they will always be
what they are there. Do I create a function to do it for me and
return the new structure?

That's one way to do it, roughly comparable to a constructor in Java
or C++.

You can also just stuff values into it in the function where you want
to use it:

--------
void run_something(int initial_pc)
{
/*Here's where you're actually creating a variable of the type
you defined earlier.
*/
struct registers my_regs;
int i;

my_regs.bankSize=256;
/*Are you sure you want this to be a pointer? Something appropriate
for an array index looks more reasonable to me.
*/
my_regs.progCounter=initial_pc;
my_regs.instRegister=NULL;
for(i=0;i<REGISTERS;i++)
my_regs.contents=0;

/*Now you can do something with my_regs*/
start_run(&my_regs);
}
--------
Another question. The manual that I was reading said that there was a
rule of thumb that semicolons never went to the right of a curly
brace. Nonetheless, a semicolon there is and the compiler seems to
have no trouble with it.

Which manual would that be?
Curly braces are used to group a few different things (code blocks,
struct and union definitions, enum definitions, and initialization lists
come to mind; I'm sure if I missed any some pedant will point them out),
and code blocks are the only ones that *don't* get semicolons after them.
(Code blocks are also the most common uses of curly braces, which might
be what's causing the author's confusion.)

Does anyone have a link to a place that explains the preprocessor
directives well? I've read several versions of different FAQs and
online instructional pages and I still haven't really got a handle on
them.

There's not really that much you need to know, unless you're planning
on abusing the preprocessor to do something interesting or creative.
A good reference book (K&R2 is Highly Recommended) should tell you what
you need to know.

Thanks anyone for any help in advance. Also, if I've messed up some
forum rule or anything, please tell me, since I'll need to know when I
have a new problem.

Our tolerance for grovelling goes down pretty quickly. If you're doing
something wrong, you'll hear about it, so no need to keep checking. :)


dave
 
R

Russell Hanneken

Blue said:
struct registers
{
int bankSize;
int *progCounter;
int *instRegister;
int contents[REGISTERS];
/* contents[0] = 0;
*progCounter = &contents[0];
*instRegister = contents[1];*/
};

The commented part will not compile on my machine. In fact, none of
those three lines will compile. My sense of logic tells me that this
means that I cannot actually initialize variables in structures,

That's right.
but I do not know how else I should initialize them; they will always be
what they are there. Do I create a function to do it for me and
return the new structure?

You might do something like this:

void initRegisters (struct registers *pRegisters)
{
pRegisters->contents[0] = 0;
/* other initialization code here */
}

I was going to convert your

*progCounter = &contents[0];

to

*(pRegisters->progCounter) = &(pRegisters->contents[0]);

or, (I think) better:

*pRegisters->progCounter = pRegisters->contents;

but *(pRegisters->progCounter) is an int, while &(pRegisters->contents[0])
is an int *. You can't assign an int * to an int, and I don't understand
what you intend.

Similarly, I was going to convert your

*instRegister = contents[1];

to

*(pRegisters->instRegister) = pRegisters->contents[1];

but that would dereference instRegister without first assigning it an
address.
Another question. The manual that I was reading said that there was a
rule of thumb that semicolons never went to the right of a curly
brace. Nonetheless, a semicolon there is and the compiler seems to
have no trouble with it.

A semicolon has to follow a struct definition. It's just a rule in C.
Does anyone have a link to a place that explains the preprocessor
directives well? I've read several versions of different FAQs and
online instructional pages and I still haven't really got a handle on
them.

I don't know of an online resource, but I like K. N. King's explanation in
_C Programming: A Modern Approach_. In general, I think King's book is the
best book for learning C. In any case, it was the best book for me; your
mileage may vary.
 
B

Barry Schwarz

I am definitely a C newbie, and I'm having some difficulty making a
structure. I must be missing something (or the manual I'm looking at
is missing something), but I can't figure out what.

Oh yeah, this is -not- for class of any kind, just my own curiosity.
My school does not begin teaching C or C++ until middle of sophmore
year on the CS track, so I'm trying to learn a little of my own on the
side.

struct registers
{
int bankSize;
int *progCounter;
int *instRegister;
int contents[REGISTERS];
/* contents[0] = 0;
*progCounter = &contents[0];
*instRegister = contents[1];*/
};

This merely creates the type struct registers. It does not create an
object of that type. This is a little like saying
int = 5;
Which int is to be initialized to 5?
The commented part will not compile on my machine. In fact, none of
those three lines will compile. My sense of logic tells me that this
means that I cannot actually initialize variables in structures, but I
do not know how else I should initialize them; they will always be

Even if you had defined an object of this type (by changing the last
line to
} mystruct;
this is not how you initialize a structure. You could include
initialization by changing the last line to
} mystruct = {val1, val2, val3, val4};
where the initialization constants are in the same order as the
members of the structure. However, you want progCounter to contain
&mystruct.contents[0] but my compiler says this is not a legal
initialization value. You can initialize mystruct with compile time
constants (I used 0 to test).
what they are there. Do I create a function to do it for me and
return the new structure?

So the remaining option is to initialize mystruct with code:
mystruct.contents[0] = 0;
mystruct.progCounter = &mystruct.contents[0];
mystruct.instRegister = &mystruct.contents[1];
Note the absence of * on the last two and the additional & on the
last.

You can do this in the same function that defines the structure or you
can do it in a separate initialization function. In the latter case,
you would do something like
mystruct = initfunction(mystruct);
Another question. The manual that I was reading said that there was a
rule of thumb that semicolons never went to the right of a curly
brace. Nonetheless, a semicolon there is and the compiler seems to
have no trouble with it.

When the curly brace is the boundary for a block or compound
statement, that is true. However, with structures, unions, and
initializations within definitions, a ; following a } is pretty
common.
Does anyone have a link to a place that explains the preprocessor
directives well? I've read several versions of different FAQs and
online instructional pages and I still haven't really got a handle on
them.

Have you tried K&R II?
Thanks anyone for any help in advance. Also, if I've messed up some
forum rule or anything, please tell me, since I'll need to know when I
have a new problem.



<<Remove the del for email>>
 
A

Al Bowers

Blue said:
I am definitely a C newbie, and I'm having some difficulty making a
structure. I must be missing something (or the manual I'm looking at
is missing something), but I can't figure out what.

Oh yeah, this is -not- for class of any kind, just my own curiosity.
My school does not begin teaching C or C++ until middle of sophmore
year on the CS track, so I'm trying to learn a little of my own on the
side.

struct registers
{
int bankSize;
int *progCounter;
int *instRegister;
int contents[REGISTERS];
/* contents[0] = 0;
*progCounter = &contents[0];
*instRegister = contents[1];*/
};

The commented part will not compile on my machine. In fact, none of
those three lines will compile. My sense of logic tells me that this
means that I cannot actually initialize variables in structures, but I
do not know how else I should initialize them; they will always be
what they are there. Do I create a function to do it for me and
return the new structure?
Yes, you can write a function or macro to assign values to the struct
members.

Here is an example using your struct definition.

#include <stdio.h>
#include <stddef.h>

#define REGISTERS 2
#define INIT(NAME,X,Y,Z) {X,&NAME.contents[0],&NAME.contents[1],{Y,Z}}

struct registers
{
int bankSize;
int *progCounter;
int *instRegister;
int contents[REGISTERS];
/* contents[0] = 0;
*progCounter = &contents[0];
*instRegister = contents[1];*/
};

size_t offsetCounter = offsetof(struct registers,contents[0]);
size_t offsetRegister = offsetof(struct registers, contents[1]);

struct registers AssignStruct(struct registers *p, int bankSize,
int contentCount, int contentReg);

int main(void)
{
/* struct registers myreg = INIT(myreg,3,4,5); */
struct registers myreg = AssignStruct(&myreg,3,4,5);
printf("myreg.bankSize = %d\n"
"myreg.contents[0] = %d\n"
"*myreg.progCounter = %d\n"
"myreg.contents[1] = %d\n"
"*myreg.instRegister = %d\n",myreg.bankSize ,
myreg.contents[0],*myreg.progCounter,
myreg.contents[1], *myreg.instRegister);

myreg = AssignStruct(&myreg,6,7,8);
printf("\nmyreg.bankSize = %d\n"
"myreg.contents[0] = %d\n"
"*myreg.progCounter = %d\n"
"myreg.contents[1] = %d\n"
"*myreg.instRegister = %d\n",myreg.bankSize ,
myreg.contents[0],*myreg.progCounter,
myreg.contents[1], *myreg.instRegister);
return 0;
}

struct registers AssignStruct(struct registers *p, int bankSize,
int contentCount, int contentReg)
{
p->bankSize = bankSize;
p->progCounter = (int *)((char *)p + offsetCounter);
p->instRegister = (int *)((char *)p + offsetRegister);
p->contents[0] = contentCount;
p->contents[1] = contentReg;
return *p;
}
 
S

Sidney Cadot

Artie said:
[...snip...]
Another question. The manual that I was reading said that there was a
rule of thumb that semicolons never went to the right of a curly
brace. Nonetheless, a semicolon there is and the compiler seems to
have no trouble with it.


The `rule of thumb' relates to using semicolons in actual code;
structure and union definitions *always* end with a semicolon.

For the sake of completeness: the same goes for "enum" definitions.

Best regards,

Sidney
 
T

Toni Uusitalo

Blue Ocean said:
do not know how else I should initialize them; they will always be
what they are there. Do I create a function to do it for me and
return the new structure?

You can use somekind of "oop paradigm" for creating and initializing your
structures.
One thing I have learned from using oop languages is that using object
oriented approach in C can be beneficial too and helps me to write reusable
and more maintainable code.

Here's an example. You can initialize your "object" in "create method" or
write separate "init method" etc.

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

typedef struct tagMYOBJECT {
int data;
} MYOBJECT;

MYOBJECT *myobject_create();
void myobject_destroy(MYOBJECT *obj);
MYOBJECT *myobject_copy(MYOBJECT *obj);

MYOBJECT *myobject_create()
{
MYOBJECT *obj = malloc(sizeof(MYOBJECT));
if (obj) {
obj->data = 0;
}
return obj;
}

void myobject_destroy(MYOBJECT *obj)
{
free(obj);
}

MYOBJECT *myobject_copy(MYOBJECT *obj)
{
MYOBJECT *new = myobject_create();
if (new) {
new->data = obj->data;
}
return new;
}

int main (int argc, char* argv[])
{
MYOBJECT *o1;
MYOBJECT *o2;

o1 = myobject_create();
if (!o1) return 1;
o1->data = 1;

o2 = myobject_copy(o1);
if (!o2) return 1;

printf("o1 data: %d\n", o1->data);
printf("o2 data after copy: %d\n", o2->data);

o2->data = 2;

printf("o1 data: %d\n", o1->data);
printf("o2 data modified: %d\n", o2->data);

myobject_destroy(o1);
myobject_destroy(o2);

return 0;
}

with respect,
Toni Uusitalo
 
J

Joe Wright

Sidney said:
Artie said:
[...snip...]
Another question. The manual that I was reading said that there was a
rule of thumb that semicolons never went to the right of a curly
brace. Nonetheless, a semicolon there is and the compiler seems to
have no trouble with it.


The `rule of thumb' relates to using semicolons in actual code;
structure and union definitions *always* end with a semicolon.

For the sake of completeness: the same goes for "enum" definitions.
I think both you and Artie mean 'declarations'. The construct ..

struct foo {
int a;
int b;
};

... is a declaration. While ..

struct foo {
int a;
int b;
} foo;

... is a 'definition'.
 

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
474,135
Messages
2,570,783
Members
47,341
Latest member
hanifree

Latest Threads

Top