prototypes and struct quest.

  • Thread starter Bill Cunningham
  • Start date
B

Bill Cunningham

Here is a list of prototypes and that's all I have so far for a program
I want to write. This should be simple for even me but since I am packing
the struct and I am then going to save it to file, well this is the first
time I've programmed stucts myself. I have used them in things like the
sockets API for unix but that's about it. I have never really designed them.
Well I am looking for feedback in these function's design as far as the
prototypes go since I am using the struct. Are all these parameters after
the first one that is going to take a struct stk*; necessary?

//sread is for reading in securities data.
//swrite is for obtaining it.

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

struct stk {
int volume;
int date[9];
double price;
char *name;
};

void *sread(struct stk *, int, int, double, char *);
void *swrite(struct stk *, int, int, double, char *);

/* There's really nothing of course here to compile yet but are the 2 ints,
doubles and the char * needed to pack the struct? They would be if I was
going to not use a struct but are they needed to pack the struct using
pointers?
*/

B
 
B

Bill Cunningham

Bill Cunningham wrote:

....

Oops one of the ints in each of these functions I think should be int *. As
such:
 
M

Michael Angelo Ravera

    Here is a list of prototypes and that's all I have so far for a program
I want to write. This should be simple for even me but since I am packing
the struct and I am then going to save it to file, well this is the first
time I've programmed stucts myself. I have used them in things like the
sockets API for unix but that's about it. I have never really designed them.
Well I am looking for feedback in these function's design as far as the
prototypes go since I am using the struct. Are all these parameters after
the first one that is going to take a struct stk*; necessary?

//sread is for reading in securities data.
//swrite is for obtaining it.

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

struct stk {
    int volume;
    int date[9];
    double price;
    char *name;

};

void *sread(struct stk *, int, int, double, char *);
void *swrite(struct stk *, int, int, double, char *);

/* There's really nothing of course here to compile yet but are the 2 ints,
doubles and the char * needed to pack the struct? They would be if I was
going to not use a struct but are they needed to pack the struct using
pointers?
*/

B

1) I don't know why you need 9 inits in a date. Most of the time you
can use a number of days offset from a given date in history or use
just 3-8 short ints to make a date down to microseconds.

2) Most of the time, price should be either a 32- or 64-bit integer
with a fixed decimal point (standard is to divide dolars,pounds, or
euros by 10000). You can use a float or double, but you may not like
the results.

3) The struct won't save to a medium, transmit on a socket, or even
make a true copy to memory very well with the char * in it. You either
need a char array that is null terminated or a length word that tells
you how many characters are in the name. If you are writing several
structs in succession, you will need a length word prefixed on to each
struct to allow sequential reading of them or to write them at a
maximum fixed length with the null terminated (or space padded) name.
 
B

Bill Cunningham

Michael said:
1) I don't know why you need 9 inits in a date. Most of the time you
can use a number of days offset from a given date in history or use
just 3-8 short ints to make a date down to microseconds.

I have changed that in my source a drew up roughly in a .c file to int
date[6]={0}; No need to make space for a \0 so I can just put into the data
020711 as a date. I will work out some kind of loop later to iterate through
these numbers I call 'date'
2) Most of the time, price should be either a 32- or 64-bit integer
with a fixed decimal point (standard is to divide dolars,pounds, or
euros by 10000). You can use a float or double, but you may not like
the results.

Ok how would I go about getting double floating point precision with an
int?
3) The struct won't save to a medium, transmit on a socket, or even
make a true copy to memory very well with the char * in it. You either
need a char array that is null terminated or a length word that tells
you how many characters are in the name. If you are writing several
structs in succession, you will need a length word prefixed on to each
struct to allow sequential reading of them or to write them at a
maximum fixed length with the null terminated (or space padded) name.

My new code I have cooked up-

struct stk * {
int volume=0;
double price=0.0;
int date[6]={0};
};

struct stk name;
name *pn;
int date[6]=020711;
int volume=372500;
double price=32.50;
//struct stk*sread(struct stk *);
//new definition and this code is all untested btw

pn=sread(pn->date);
pn=sread(pn->price);
pn=sread(pn->volume);

/* Like I said this is untested and I would an code that would store the
name of the security as the struct stk *. This struct will be a struct of a
struct. Called 'data' for example. And there would be code such as,

FILE *fp;
fopen("data","w+");
w+ to create the file if it doesn't exist and truncate if it does.*/

Thanks much for the 'pointers' :)

B
 
R

Ralph Spitzner

Bill Cunningham wrote:
pace padded) name.
My new code I have cooked up-

struct stk * { what's the pointer for ?
int volume=0; can have -1 volume here
double price=0.0;
where exactly will your decimal point be ?
int date[6]={0};
have a 'year 3000' problem here :p

So why not just:

typedef struct stk
{
uint16_t volume;
/* just calculate in cents alas milli or microdollars */
uint32_t price;
/* seconds since jan 1st, 1970 */
uint64_t date;
/* as for the name either have */
#ifdef VARNAME
uint16_t nlen;
char *name;
#else
/* this is easier for flatfiles etc. */
char name[255];
#endif
}STK;

If youre using a pointer for <name> then you'll
have to malloc() evertime you want to put something
in it.
When using an array you just have to malloc(sizeof(STK)); and
watch that you don't put more than 255 bytes in it.


just my 0.02EUR :p

-rasp

Oh, and don't forget to bzero() or memset() so name will be
either filled with '\0' or (ifdef VARNAME) NULL....
 
R

Rob

Ok how would I go about getting double floating point precision with an
int?

You don't. Assume for the moment you're working in US dollars. The idea
is to keep the price in cents, then divide by 100 to get dollars. OK, you
have the division there, but integer arithmetic is usually fast.

If you use floating-point variables for money units, you will sooner or
later lose precision, which means that the prices you end up with won't
add up - there will be a missing couple of cents/whatever.

HTH,

Rob.
 
M

Michael Angelo Ravera

Michael said:
1) I don't know why you need 9 inits in a date. Most of the time you
can use a number of days offset from a given date in history or use
just 3-8 short ints to make a date down to microseconds.

    I have changed that in my source a drew up roughly in a .c file to int
date[6]={0}; No need to make space for a \0 so I can just put into the data
020711 as a date. I will work out some kind of loop later to iterate through
these numbers I call 'date'
2) Most of the time, price should be either a 32- or 64-bit integer
with a fixed decimal point (standard is to divide dolars,pounds, or
euros by 10000). You can use a float or double, but you may not like
the results.

 Ok how would I go about getting double floating point precision with an
int?
3) The struct won't save to a medium, transmit on a socket, or even
make a true copy to memory very well with the char * in it. You either
need a char array that is null terminated or a length word that tells
you how many characters are in the name. If you are writing several
structs in succession, you will need a length word prefixed on to each
struct to allow sequential reading of them or to write them at a
maximum fixed length with the null terminated (or space padded) name.

    My new code I have cooked up-

struct stk * {
    int volume=0;
    double price=0.0;
    int date[6]={0};
    };

struct stk name;
name *pn;
int date[6]=020711;
int volume=372500;
double price=32.50;
//struct stk*sread(struct stk *);
//new definition and this code is all untested btw

pn=sread(pn->date);
pn=sread(pn->price);
pn=sread(pn->volume);

/* Like I said this is untested and I would an code that would store the
name of the security as the struct stk *. This struct will be a struct of a
struct. Called 'data' for example. And there would be code such as,

FILE *fp;
fopen("data","w+");
w+ to create the file if it doesn't exist and truncate if it does.*/

Thanks much for the 'pointers' :)

B

If you are going to use fopen(), you want to do do bionary "wb+", or
you won't like the results.

As others have indicated, you probably want just one binary uint32_t
or uint64_t as date. A uint32_t will handle the number of days since
the last calendrical convergence back at the time of the Phaeroes.
There is one system where short date_and_time [8] makes sense, but
that separates year, month, day, hour, minute, second, millis, and
micros. an uint64_t will handle the number of microseconds since that
same convergence.

if no unit prices or taxes thereon are smaler than cents, centimes, or
pence, you can use an uint32_t to hold the number cents for values up
to about 400 milion dollars. If you might have to deal with quantity
prices that are smaller (or tax on them), the STANDARD for currency is
to use 100ths of cents, pence, or centimes (dollars, pounds, or euros
divided by 10000) and to use an uint64_t.

It seems, however, that you are not clear on the concept of how memory
is allocated or how to look at or think about contiguous blocks of
memory.
 
B

Bill Cunningham

Rob said:
You don't. Assume for the moment you're working in US dollars. The
idea is to keep the price in cents, then divide by 100 to get
dollars. OK, you have the division there, but integer arithmetic is
usually fast.

If you use floating-point variables for money units, you will sooner
or later lose precision, which means that the prices you end up with
won't add up - there will be a missing couple of cents/whatever.

Hum ok. Say then for example,

int price=2000;
now int is 2000
printf("%d\n",2000/10); ?

To make 20 USD ? Thanks for all these experience tips. I could probably
code this but the problems you mention are were not forseen by me. Like
losing precision.

Bill
 
B

Bill Cunningham

Michael said:
It seems, however, that you are not clear on the concept of how memory
is allocated or how to look at or think about contiguous blocks of
memory.

I have never used this unit_32 or uint_64. I will have to look this up.
Is it C99 because I've never really gotten into that because of
compatibility issues.
No I don't know much about data types except that ints hold whole
numbers while with float and double you can use the %f specifier for
fractions of number say a quarter USD. (.25). And I know their size in bytes
because of the sizeof operator. That's about it. As far as stack and heap
(memory) I think kernels handle that pretty well anyymore.

B
 
B

Bill Cunningham

Ralph said:
Bill Cunningham wrote:
pace padded) name.
what's the pointer for ?

Made sense at the time. I guess it isn't really necessary.
can have -1 volume here

I don't understand. Can have -1 value?
double price=0.0;
where exactly will your decimal point be ?
int date[6]={0};
have a 'year 3000' problem here :p

So why not just:

typedef struct stk
{
uint16_t volume;
/* just calculate in cents alas milli or microdollars */
uint32_t price;
/* seconds since jan 1st, 1970 */
uint64_t date;
/* as for the name either have */
#ifdef VARNAME
uint16_t nlen;
char *name;
#else
/* this is easier for flatfiles etc. */
char name[255];
#endif
}STK;

If youre using a pointer for <name> then you'll
have to malloc() evertime you want to put something
in it.
When using an array you just have to malloc(sizeof(STK)); and
watch that you don't put more than 255 bytes in it.


just my 0.02EUR :p

-rasp

Oh, and don't forget to bzero() or memset() so name

I thought bzero was depreciated and memset is now the thing to use.

will be
 
B

Bill Cunningham

Ok I tried this code and it wouldn't compile. The error says line 8
incompatable types. I am probably looking right at it. I think I might
rewrite and use pointers so I know I can get this idea to work. But I want
to post what I tried. This is all C89.


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

#define TYPE unsigned int

struct stk {
TYPE volume;
TYPE price;
TYPE date[6];
};

struct stk swrite(struct stk name);
struct stk sread(struct stk name);

struct stk sread(struct stk name)
{
TYPE date[6];
TYPE price;
TYPE volume;
date = name.date;
volume = name.volume;
price = name.price;
}

B
 
R

Ralph Spitzner

Bill said:
I thought bzero was depreciated and memset is now the thing to use.

Although it *is* marked as gone in POSIX.1-2008, I still use it :p
Probably it eventually it will just become

#define bzero(x,z) memset(x,0,z)

since a bazillion of programs refer to it ....

-rasp
 
R

Ralph Spitzner

Bill said:
I don't understand. Can have -1 value?

Sorry, missed that one.

int is is defined as *something* (depending on your architecture
8,16,32,64 bits) _signed_. So although it might holt that many bits
the upper one is reserved for the sign.
If your int is 8 bits long and and you have and order of 129 units
you may end up sending them -1 units + receipt :p

-rasp
 
R

Ralph Spitzner

Bill said:
I have never used this unit_32 or uint_64. I will have to look this up.
Is it C99 because I've never really gotten into that because of
compatibility issues.

Yes, it's C99 #include <stdint.h>, but I haven't come across a system
not recognizing this in the last 15 odd years....
Alternatively write

unsigned int blah;

and you probably get something that can hold 32bits, or maybe 16 :)
No I don't know much about data types except that ints hold whole
numbers

.... from a negative to a positive maximum, mileage may vary due to
register/bus width...
while with float and double you can use the %f specifier for
fractions of number say a quarter USD. (.25). And I know their size in bytes
because of the sizeof operator. That's about it.

Yes, but you let the <whatever>math library do the rounding, where
the <whatever>math library knows *nothing* about the currency used in
your country.
Nowadays computers are pretty fast so:

{
unsigned int dollar,cent;

dollar = price / 100;
cent = price % 100;

printf("You have to pay $%3d.2d\n",dollar,cent);

}

Will give you something a person can read/understand...
As far as stack and heap
(memory) I think kernels handle that pretty well anyymore.

That was in my last reply, it's far easier for memory management if
you just allocate large chunks of continuous memory, instead
of having small chunks all pointing to each other, hence the
char array I mentioned...
i.e. your struct is @0xffe0 whereas your name is @ 0x00fa,
so memory can't be read in one go....


-rasp
 
T

Tom St Denis

    Ok I tried this code and it wouldn't compile. The error says line 8
incompatable types. I am probably looking right at it. I think I might
rewrite and use pointers so I know I can get this idea to work. But I want
to post what I tried. This is all C89.

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

#define TYPE unsigned int

struct stk {
    TYPE volume;
    TYPE price;
    TYPE date[6];

};

struct stk swrite(struct stk name);
struct stk sread(struct stk name);

struct stk sread(struct stk name)
{
    TYPE date[6];
    TYPE price;
    TYPE volume;
    date = name.date;
    volume = name.volume;
    price = name.price;

}

I don't get what this function is supposed to accomplish. I was
wondering though, do you think before you post? Or do you enter some
zen-like thought-free state before posting?

Your "read" function copies out members of a structure, then proceeds
to return to the caller without an actual return value. What is that
supposed to accomplish?

It would also help to get the actual output from the compiler as
opposed to your filtered rendering of it. Though, what would actually
really help is for you to plan out what your program is supposed to do
BEFORE you write it.

Tom
 
B

Bill Cunningham

Tom said:
Ok I tried this code and it wouldn't compile. The error says line 8
incompatable types. I am probably looking right at it. I think I
might rewrite and use pointers so I know I can get this idea to
work. But I want to post what I tried. This is all C89.

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

#define TYPE unsigned int

struct stk {
TYPE volume;
TYPE price;
TYPE date[6];

};

struct stk swrite(struct stk name);
struct stk sread(struct stk name);

struct stk sread(struct stk name)
{
TYPE date[6];
TYPE price;
TYPE volume;
date = name.date;
volume = name.volume;
price = name.price;

}

I don't get what this function is supposed to accomplish. I was
wondering though, do you think before you post? Or do you enter some
zen-like thought-free state before posting?

Your "read" function copies out members of a structure, then proceeds
to return to the caller without an actual return value. What is that
supposed to accomplish?

It would also help to get the actual output from the compiler as
opposed to your filtered rendering of it. Though, what would actually
really help is for you to plan out what your program is supposed to do
BEFORE you write it.

Tom

sread is supposed to take as it's parameter one value at a time and and put
it into the struct stk type called name. I obviously don't remember how to
do it correctly or neverlearned right. Hence my inexperience with structs. I
do believe I can do this with pointers though.

struct stk name;

name.date=020811;
name.price=20.00; //In USD.
name.volume=232987;

This is how I would load a struct. Now swrite is supposed to do that for
me. Instead of typing all this manually, I want to pass to swrite data and
have swrite write it into the struct. sread would fetch it back. Simple
concept. I don't know for sure how to code it.

B
 
B

Bill Cunningham

Bill said:
Tom said:
Ok I tried this code and it wouldn't compile. The error says line 8
incompatable types. I am probably looking right at it. I think I
might rewrite and use pointers so I know I can get this idea to
work. But I want to post what I tried. This is all C89.

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

#define TYPE unsigned int

struct stk {
TYPE volume;
TYPE price;
TYPE date[6];

};

struct stk swrite(struct stk name);
struct stk sread(struct stk name);

struct stk sread(struct stk name)
{
TYPE date[6];
TYPE price;
TYPE volume;
date = name.date;
volume = name.volume;
price = name.price;

}

I don't get what this function is supposed to accomplish. I was
wondering though, do you think before you post? Or do you enter some
zen-like thought-free state before posting?

Your "read" function copies out members of a structure, then proceeds
to return to the caller without an actual return value. What is that
supposed to accomplish?

It would also help to get the actual output from the compiler as
opposed to your filtered rendering of it. Though, what would
actually really help is for you to plan out what your program is
supposed to do BEFORE you write it.

Tom

sread is supposed to take as it's parameter one value at a time and
and put it into the struct stk type called name. I obviously don't
remember how to do it correctly or neverlearned right. Hence my
inexperience with structs. I do believe I can do this with pointers
though.
struct stk name;

name.date=020811;
name.price=20.00; //In USD.
name.volume=232987;

This is how I would load a struct. Now swrite is supposed to do that
for me. Instead of typing all this manually, I want to pass to swrite
data and have swrite write it into the struct. sread would fetch it
back. Simple concept. I don't know for sure how to code it.

B

swrite() should write to struct. sread() read the data from it. Yes that's
right.
 
J

Joel C. Salomon

int price=2000;
now int is 2000
printf("%d\n",2000/10); ?

To make 20 USD ?

No, because the expression 2000/100 is an integer expression. It’ll
give you the right answer here, but the wrong type. Worse, by rules of
integer arithmetic, 2054/100 gives 20, not 20.54.

Try
printf("%f\n", price/100.0);
instead. Dividing by an explicitly floating-point number yields a
floating-point number, and the “%f†format is what’s needed then.

(Then look up printf() format flags to learn how to print a number with
exactly two digits past the decimal point.)

—Joel
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top