Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #102269 > unrolled thread
| Started by | Alla _ <modelling.data@gmail.com> |
|---|---|
| First post | 2017-01-21 02:00 -0800 |
| Last post | 2017-01-30 22:04 +1100 |
| Articles | 12 on this page of 32 — 15 participants |
Back to article view | Back to comp.lang.c
Access structure members via pointer to an array of structures Alla _ <modelling.data@gmail.com> - 2017-01-21 02:00 -0800
Re: Access structure members via pointer to an array of structures Alla _ <modelling.data@gmail.com> - 2017-01-21 02:08 -0800
Re: Access structure members via pointer to an array of structures Chad <cdalten@gmail.com> - 2017-01-21 07:36 -0800
Re: Access structure members via pointer to an array of structures Jerry Stuckle <jstucklex@attglobal.net> - 2017-01-21 11:13 -0500
Re: Access structure members via pointer to an array of structures Jerry Stuckle <jstucklex@attglobal.net> - 2017-01-21 11:08 -0500
Re: Access structure members via pointer to an array of structures Chad <cdalten@gmail.com> - 2017-01-21 09:09 -0800
Re: Access structure members via pointer to an array of structures Jerry Stuckle <jstucklex@attglobal.net> - 2017-01-21 14:32 -0500
Re: Access structure members via pointer to an array of structures Chad <cdalten@gmail.com> - 2017-01-21 12:57 -0800
Re: Access structure members via pointer to an array of structures Chad <cdalten@gmail.com> - 2017-01-21 13:04 -0800
Re: Access structure members via pointer to an array of structures Jerry Stuckle <jstucklex@attglobal.net> - 2017-01-21 17:59 -0500
Re: Access structure members via pointer to an array of structures cross@spitfire.i.gajendra.net (Dan Cross) - 2017-01-22 14:02 +0000
Re: Access structure members via pointer to an array of structures raltbos@xs4all.nl (Richard Bos) - 2017-01-22 14:17 +0000
Re: Access structure members via pointer to an array of structures Tim Rentsch <txr@alumni.caltech.edu> - 2017-01-30 05:25 -0800
Re: Access structure members via pointer to an array of structures Jerry Stuckle <jstucklex@attglobal.net> - 2017-01-21 17:57 -0500
Re: Access structure members via pointer to an array of structures Malcolm McLean <malcolm.mclean5@btinternet.com> - 2017-01-21 08:09 -0800
Re: Access structure members via pointer to an array of structures Keith Thompson <kst-u@mib.org> - 2017-01-21 15:15 -0800
Re: Access structure members via pointer to an array of structures Gareth Owen <gwowen@gmail.com> - 2017-01-22 08:27 +0000
Re: Access structure members via pointer to an array of structures Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-22 11:17 +0000
Re: Access structure members via pointer to an array of structures BartC <bc@freeuk.com> - 2017-01-22 11:44 +0000
Re: Access structure members via pointer to an array of structures Malcolm McLean <malcolm.mclean5@btinternet.com> - 2017-01-22 04:27 -0800
Re: Access structure members via pointer to an array of structures Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-22 13:32 +0000
Re: Access structure members via pointer to an array of structures Keith Thompson <kst-u@mib.org> - 2017-01-22 07:54 -0800
Re: Access structure members via pointer to an array of structures Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-22 13:31 +0000
Re: Access structure members via pointer to an array of structures Gareth Owen <gwowen@gmail.com> - 2017-01-22 14:02 +0000
Re: Access structure members via pointer to an array of structures Keith Thompson <kst-u@mib.org> - 2017-01-22 07:50 -0800
Re: Access structure members via pointer to an array of structures Manfred <noname@invalid.add> - 2017-01-21 17:15 +0100
Re: Access structure members via pointer to an array of structures David Brown <david.brown@hesbynett.no> - 2017-01-21 17:59 +0100
Re: Access structure members via pointer to an array of structures Alla _ <modelling.data@gmail.com> - 2017-01-21 09:09 -0800
Re: Access structure members via pointer to an array of structures Barry Schwarz <schwarzb@dqel.com> - 2017-01-21 09:27 -0800
Re: Access structure members via pointer to an array of structures Alla _ <modelling.data@gmail.com> - 2017-01-21 09:30 -0800
Re: Access structure members via pointer to an array of structures Alla _ <modelling.data@gmail.com> - 2017-01-21 09:25 -0800
Re: Access structure members via pointer to an array of structures "Peter \"Shaggy\" Haywood" <phaywood@alphalink.com.au> - 2017-01-30 22:04 +1100
Page 2 of 2 — ← Prev page 1 [2]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2017-01-22 13:32 +0000 |
| Message-ID | <8737gbxlse.fsf@bsb.me.uk> |
| In reply to | #102316 |
Malcolm McLean <malcolm.mclean5@btinternet.com> writes: > On Sunday, January 22, 2017 at 11:44:26 AM UTC, Bart wrote: <snip> >> data years[DATA_SIZE]; // [an array] >> data *dat_years = years; // [a pointer] >> > Yes, that was in Alla's code. > Someone who writes that probably doesn't understand array pointer > equivalence. You are going to keep saying it, aren't you? <snip> -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2017-01-22 07:54 -0800 |
| Message-ID | <lnd1fff5uh.fsf@kst-u.example.com> |
| In reply to | #102316 |
Malcolm McLean <malcolm.mclean5@btinternet.com> writes:
> On Sunday, January 22, 2017 at 11:44:26 AM UTC, Bart wrote:
>> On 22/01/2017 11:17, Ben Bacarisse wrote:
>> > Gareth Owen <gwowen@gmail.com> writes:
>> >
>> >> Keith Thompson <kst-u@mib.org> writes:
>> >>
>> >>> Why would you tell someone trying to learn C about "array pointer
>> >>> equivalence"? Arrays and pointers are not equivalent.
>> >>
>> >> They are occasionally
>> >
>> > "array pointer equivalence" does not suggest something occasional!
>> >
>> > There are a number of people here determined to avoid any explanation
>> > that simplified the issue. Just refer to the "array to pointer
>> > conversion" and you are much closer to the truth without implying any
>> > false equivalence.
>> >
>> >> f(char *ptr){
>> >> printf("%s - %u\n",ptr,(unsigned)sizeof(ptr));
>> >> }
>> >>
>> >> f(char arr[10]){
>> >> printf("%s - %u\n",arr,(unsigned)sizeof(arr));
>> >> }
>> >
>> > There are no arrays in this code and I don't think Malcolm was talking
>> > about the interchangeability of * and [] syntax in a parameter list.
>>
>> Maybe he was talking about the equivalence of 'years' and '*dat_years'
>> here when used in most expression contexts:
>>
>> data years[DATA_SIZE]; // [an array]
>> data *dat_years = years; // [a pointer]
As you surely know by now, the `years` in the initializer is *converted*
(IMHO "adjusted" would have been a better word) to a pointer expression.
> Yes, that was in Alla's code.
> Someone who writes that probably doesn't understand array pointer
> equivalence. (So it's far to early to bring up a technical nit about
> the situations they are not equivalent).
Arrays and pointers are never equivalent. Someone who writes "array
pointer equivalence" probably doesn't understand the relationship
between arrays and pointers.
Again, expressions of array type are *converted* to pointer type in most
contexts. If they were "equivalent", no such conversion would be
necessary.
Stop spreading confusion and misinformation. I'm sure Alla is able to
understand the actual language rules.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2017-01-22 13:31 +0000 |
| Message-ID | <878tq3xluk.fsf@bsb.me.uk> |
| In reply to | #102315 |
BartC <bc@freeuk.com> writes:
> On 22/01/2017 11:17, Ben Bacarisse wrote:
>> Gareth Owen <gwowen@gmail.com> writes:
>>
>>> Keith Thompson <kst-u@mib.org> writes:
>>>
>>>> Why would you tell someone trying to learn C about "array pointer
>>>> equivalence"? Arrays and pointers are not equivalent.
>>>
>>> They are occasionally
>>
>> "array pointer equivalence" does not suggest something occasional!
>>
>> There are a number of people here determined to avoid any explanation
>> that simplified the issue. Just refer to the "array to pointer
>> conversion" and you are much closer to the truth without implying any
>> false equivalence.
>>
>>> f(char *ptr){
>>> printf("%s - %u\n",ptr,(unsigned)sizeof(ptr));
>>> }
>>>
>>> f(char arr[10]){
>>> printf("%s - %u\n",arr,(unsigned)sizeof(arr));
>>> }
>>
>> There are no arrays in this code and I don't think Malcolm was talking
>> about the interchangeability of * and [] syntax in a parameter list.
>
> Maybe he was talking about the equivalence of 'years' and '*dat_years'
I think he knows C better than that!
> here when used in most expression contexts:
>
> data years[DATA_SIZE]; // [an array]
> data *dat_years = years; // [a pointer]
He was clearly taking about the fact that years converts to a pointer in
most contexts. When talking to people learning C, that's better than
suggesting an equivalence that does not exist.
<snip>
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | Gareth Owen <gwowen@gmail.com> |
|---|---|
| Date | 2017-01-22 14:02 +0000 |
| Message-ID | <87inp78a5u.fsf@gmail.com> |
| In reply to | #102311 |
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
>> f(char arr[10]){
>> printf("%s - %u\n",arr,(unsigned)sizeof(arr));
>> }
>
> There are no arrays in this code
You are technically correct - the best sort of correct.
Nevertheless, I think you know what I mean.
> and I don't think Malcolm was talking about the interchangeability of
> * and [] syntax in a parameter list.
I have long since stopped worrying about discerning Malcolm is talking
about.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2017-01-22 07:50 -0800 |
| Message-ID | <lnh94rf60d.fsf@kst-u.example.com> |
| In reply to | #102308 |
Gareth Owen <gwowen@gmail.com> writes:
> Keith Thompson <kst-u@mib.org> writes:
>> Why would you tell someone trying to learn C about "array pointer
>> equivalence"? Arrays and pointers are not equivalent.
>
> They are occasionally
Nope.
> f(char *ptr){
> printf("%s - %u\n",ptr,(unsigned)sizeof(ptr));
> }
>
> f(char arr[10]){
> printf("%s - %u\n",arr,(unsigned)sizeof(arr));
> }
arr is a pointer parameter that happens to be defined using array
syntax. A parameter defined with an array type is adjusted to have a
pointer type. The parameter definitions `char *ptr` and `char ptr[]`
are equivalent, but calling that "array pointer equivalence" is
misleading.
[...]
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Manfred <noname@invalid.add> |
|---|---|
| Date | 2017-01-21 17:15 +0100 |
| Message-ID | <o601e9$12p9$1@gioia.aioe.org> |
| In reply to | #102269 |
On 1/21/2017 11:00 AM, Alla _ wrote:
> Hello!
>
> Please, help me to find my mistake; it seems I do everything correctly
> but, most likely, I am mistaken.
<snip>
>
> fprintf(stderr, "Loop beg: sales num %f; count %i\n", dat_years->sales, count);
> fprintf(stderr, "Loop beg2: sales[%i] %f\n", count, dat_years[count].sales);
>
> if (not_converted > ptr)
> {
> count++;
> dat_years += (count != DATA_SIZE);
> ptr = not_converted + (*not_converted != '\0');
> }
<snip>
The first fprintf above uses dat_years that points to the correct array
element.
The second fprintf uses dat_years[count] that does not refer to the
correct element.
>
> Thank you!
>
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2017-01-21 17:59 +0100 |
| Message-ID | <o603v2$udn$1@dont-email.me> |
| In reply to | #102269 |
On 21/01/17 11:00, Alla _ wrote:
> Hello!
>
> Please, help me to find my mistake; it seems I do everything correctly
> but, most likely, I am mistaken.
>
> I will show only a part of code to explain my issue.
> I have declared an array of structures and a pointer to
> that array. Then I use the pointer to populate, for now,
> one member of each structure. No problems here: values
> land in their correct places. But when I try to print out
> those values using a pointer, I don't get those values,
> only zeros. Please, see the code for clarification.
>
> #define DATA_SIZE 5
> typedef struct data {
> int year;
> double sales;
> int cs_cogs;
> int cs_gross_profit;
> int cs_sga;
> int cs_oper_inc;
> int cs_dep_amor;
> int cs_oper_prof;
> int cs_int_exp;
> int cs_gain_loss;
> int cs_pretax_inc;
> int cs_tax_exp;
> int cs_net_inc;
> } data;
>
> in the main function I have this declaration
> (I will later use malloc here, not now):
>
> data years[DATA_SIZE];
> data *dat_years = years;
>
It's not a good idea to make a global variable like this initialised at
the start (before main() starts) and then change it during your
"numbers" function. It means that "numbers" will only work once in the
lifetime of the program. But in this case, you are mixing up the global
variable and the functions parameter - it is bound to cause confusion.
> Then I pass the pointer dat_years into a function:
> /** Parse numbers **/
> bool numbers(char *line, struct data *dat_years)
Don't use the same names for a parameter and a global variable.
And try to be consistent with your type names. If you want to call your
struct "data" using a typedef, that's fine. If you want to call it
"struct data" to emphasis that it's a struct, that's also fine. Both
methods are common. But try to stick to one method.
> {
> char *ptr = line;
> char *not_converted = NULL;
> int count = 0;
>
> while(count < DATA_SIZE)
> {
> dat_years->sales = strtod(ptr, ¬_converted);
>
> /****** Comment only for explanatory purpose (not part of my code):
> here I try to print out values; the first fprintf with dat_years->sales
> works perfectly because it is a standard access to a member via
> a pointer; but the second one doesn't: I wonder why?
>
> dat_years[count].sales equals the correct number only at the beginning,
> when count = 0; as soon as I increment the count and move pointer to
> the next address dat_years[count].sales shows me only zeros as its values:
> Loop beg: sales num 1062.000000; count 0
> Loop beg2: sales[0] 1062.000000
>
> Loop beg: sales num 1252.000000; count 1
> Loop beg2: sales[1] 0.000000
>
> Loop beg: sales num 1587.000000; count 2
> Loop beg2: sales[2] 0.000000
>
> etc.
> But this member in each structure has the correct value after this
> function, and when the main function calls
> fprintf(stderr, "Main fun: sales[%i] num %f; sales[0] num %f;\n", DATA_SIZE-1, years[DATA_SIZE-1].sales, years[0].sales);
> it produces a correct output:
> Main fun: sales[4] num 2519.000000; sales[0] num 1062.000000;
>
> ******/
>
> fprintf(stderr, "Loop beg: sales num %f; count %i\n", dat_years->sales, count);
Here, "sales" refers to the "data" object pointed to by dat_years, and
will loop through the data as dat_years gets incremented each round.
> fprintf(stderr, "Loop beg2: sales[%i] %f\n", count, dat_years[count].sales);
Here, "sales" refers to the "data" object pointed to by dat_years plus
an offset of "count" items. This will step through twice as fast.
>
> if (not_converted > ptr)
> {
> count++;
> dat_years += (count != DATA_SIZE);
You don't need the "(count != DATA_SIZE)" bit. It's fine to make your
pointer go to the address just beyond the end of the data. It's just
not okay to try to de-reference such pointers. So use the far simpler
and clearer "dat_years++;".
> ptr = not_converted + (*not_converted != '\0');
> }
> else
> {
> fprintf(stderr, "Incorrect data on line %s at count %i\n", line, count);
> return false;
> }
> }
> return count == DATA_SIZE;
> }
>
> Thank you!
>
Your main problem is mixing your array syntax and pointer syntax.
As a general rule, if you have an array of data and it is reasonably
"natural" to access it as an array, then do that as preference to using
a pointer or using pointer syntax. It can make the code's intention
clearer to you (the programmer), to your reader, and to your compiler.
(Making code clearer to the compiler leads to better static error
checking, and more efficient object code.)
[toc] | [prev] | [next] | [standalone]
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2017-01-21 09:09 -0800 |
| Message-ID | <caf4fc7a-1fb3-427e-b21d-99962b8e2b71@googlegroups.com> |
| In reply to | #102282 |
On Saturday, January 21, 2017 at 7:59:56 PM UTC+3, David Brown wrote:
> On 21/01/17 11:00, Alla _ wrote:
> > Hello!
> >
> > Please, help me to find my mistake; it seems I do everything correctly
> > but, most likely, I am mistaken.
> >
> > I will show only a part of code to explain my issue.
> > I have declared an array of structures and a pointer to
> > that array. Then I use the pointer to populate, for now,
> > one member of each structure. No problems here: values
> > land in their correct places. But when I try to print out
> > those values using a pointer, I don't get those values,
> > only zeros. Please, see the code for clarification.
> >
> > #define DATA_SIZE 5
> > typedef struct data {
> > int year;
> > double sales;
> > int cs_cogs;
> > int cs_gross_profit;
> > int cs_sga;
> > int cs_oper_inc;
> > int cs_dep_amor;
> > int cs_oper_prof;
> > int cs_int_exp;
> > int cs_gain_loss;
> > int cs_pretax_inc;
> > int cs_tax_exp;
> > int cs_net_inc;
> > } data;
> >
> > in the main function I have this declaration
> > (I will later use malloc here, not now):
> >
> > data years[DATA_SIZE];
> > data *dat_years = years;
> >
>
> It's not a good idea to make a global variable like this initialised at
> the start (before main() starts) and then change it during your
> "numbers" function. It means that "numbers" will only work once in the
> lifetime of the program. But in this case, you are mixing up the global
> variable and the functions parameter - it is bound to cause confusion.
>
No no, these are not global variables. Richard has taught me long long
time ago to avoid these guys, so I never even think about creating
globals. Both a structure and a pointer are within the main function.
> > Then I pass the pointer dat_years into a function:
> > /** Parse numbers **/
> > bool numbers(char *line, struct data *dat_years)
>
> Don't use the same names for a parameter and a global variable.
>
> And try to be consistent with your type names. If you want to call your
> struct "data" using a typedef, that's fine. If you want to call it
> "struct data" to emphasis that it's a struct, that's also fine. Both
> methods are common. But try to stick to one method.
>
> > {
> > char *ptr = line;
> > char *not_converted = NULL;
> > int count = 0;
> >
> > while(count < DATA_SIZE)
> > {
> > dat_years->sales = strtod(ptr, ¬_converted);
> >
> > /****** Comment only for explanatory purpose (not part of my code):
> > here I try to print out values; the first fprintf with dat_years->sales
> > works perfectly because it is a standard access to a member via
> > a pointer; but the second one doesn't: I wonder why?
> >
> > dat_years[count].sales equals the correct number only at the beginning,
> > when count = 0; as soon as I increment the count and move pointer to
> > the next address dat_years[count].sales shows me only zeros as its values:
> > Loop beg: sales num 1062.000000; count 0
> > Loop beg2: sales[0] 1062.000000
> >
> > Loop beg: sales num 1252.000000; count 1
> > Loop beg2: sales[1] 0.000000
> >
> > Loop beg: sales num 1587.000000; count 2
> > Loop beg2: sales[2] 0.000000
> >
> > etc.
> > But this member in each structure has the correct value after this
> > function, and when the main function calls
> > fprintf(stderr, "Main fun: sales[%i] num %f; sales[0] num %f;\n", DATA_SIZE-1, years[DATA_SIZE-1].sales, years[0].sales);
> > it produces a correct output:
> > Main fun: sales[4] num 2519.000000; sales[0] num 1062.000000;
> >
> > ******/
> >
> > fprintf(stderr, "Loop beg: sales num %f; count %i\n", dat_years->sales, count);
>
> Here, "sales" refers to the "data" object pointed to by dat_years, and
> will loop through the data as dat_years gets incremented each round.
>
> > fprintf(stderr, "Loop beg2: sales[%i] %f\n", count, dat_years[count].sales);
>
> Here, "sales" refers to the "data" object pointed to by dat_years plus
> an offset of "count" items. This will step through twice as fast.
>
> >
> > if (not_converted > ptr)
> > {
> > count++;
> > dat_years += (count != DATA_SIZE);
>
> You don't need the "(count != DATA_SIZE)" bit. It's fine to make your
> pointer go to the address just beyond the end of the data. It's just
> not okay to try to de-reference such pointers. So use the far simpler
> and clearer "dat_years++;".
>
> > ptr = not_converted + (*not_converted != '\0');
> > }
> > else
> > {
> > fprintf(stderr, "Incorrect data on line %s at count %i\n", line, count);
> > return false;
> > }
> > }
> > return count == DATA_SIZE;
> > }
> >
> > Thank you!
> >
>
> Your main problem is mixing your array syntax and pointer syntax.
>
> As a general rule, if you have an array of data and it is reasonably
> "natural" to access it as an array, then do that as preference to using
> a pointer or using pointer syntax. It can make the code's intention
> clearer to you (the programmer), to your reader, and to your compiler.
> (Making code clearer to the compiler leads to better static error
> checking, and more efficient object code.)
[toc] | [prev] | [next] | [standalone]
| From | Barry Schwarz <schwarzb@dqel.com> |
|---|---|
| Date | 2017-01-21 09:27 -0800 |
| Message-ID | <3e678c5ds70l527rm7u1n7ikhppin1tkqc@4ax.com> |
| In reply to | #102285 |
On Sat, 21 Jan 2017 09:09:30 -0800 (PST), Alla _
<modelling.data@gmail.com> wrote:
>On Saturday, January 21, 2017 at 7:59:56 PM UTC+3, David Brown wrote:
>> On 21/01/17 11:00, Alla _ wrote:
>> > Hello!
>> >
>> > Please, help me to find my mistake; it seems I do everything correctly
>> > but, most likely, I am mistaken.
>> >
>> > I will show only a part of code to explain my issue.
>> > I have declared an array of structures and a pointer to
>> > that array. Then I use the pointer to populate, for now,
>> > one member of each structure. No problems here: values
>> > land in their correct places. But when I try to print out
>> > those values using a pointer, I don't get those values,
>> > only zeros. Please, see the code for clarification.
>> >
>> > #define DATA_SIZE 5
>> > typedef struct data {
>> > int year;
>> > double sales;
>> > int cs_cogs;
>> > int cs_gross_profit;
>> > int cs_sga;
>> > int cs_oper_inc;
>> > int cs_dep_amor;
>> > int cs_oper_prof;
>> > int cs_int_exp;
>> > int cs_gain_loss;
>> > int cs_pretax_inc;
>> > int cs_tax_exp;
>> > int cs_net_inc;
>> > } data;
>> >
>> > in the main function I have this declaration
>> > (I will later use malloc here, not now):
>> >
>> > data years[DATA_SIZE];
>> > data *dat_years = years;
>> >
>>
>> It's not a good idea to make a global variable like this initialised at
>> the start (before main() starts) and then change it during your
>> "numbers" function. It means that "numbers" will only work once in the
>> lifetime of the program. But in this case, you are mixing up the global
>> variable and the functions parameter - it is bound to cause confusion.
>>
>No no, these are not global variables. Richard has taught me long long
>time ago to avoid these guys, so I never even think about creating
>globals. Both a structure and a pointer are within the main function.
Please learn to trim your text. This response included 90 lines of
redundant discussion that you did not comment on at all.
--
Remove del for email
[toc] | [prev] | [next] | [standalone]
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2017-01-21 09:30 -0800 |
| Message-ID | <03cc9001-5e2c-4258-908f-5f06fe933634@googlegroups.com> |
| In reply to | #102289 |
On Saturday, January 21, 2017 at 8:27:45 PM UTC+3, Barry Schwarz wrote: > On Sat, 21 Jan 2017 09:09:30 -0800 (PST), Alla _ > <modelling.data@gmail.com> wrote: <snip> > Please learn to trim your text. This response included 90 lines of > redundant discussion that you did not comment on at all. I did it again, didn't I? I apologize.
[toc] | [prev] | [next] | [standalone]
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2017-01-21 09:25 -0800 |
| Message-ID | <691e58eb-026f-40f1-a7df-e73a67925f14@googlegroups.com> |
| In reply to | #102282 |
On Saturday, January 21, 2017 at 7:59:56 PM UTC+3, David Brown wrote:
> On 21/01/17 11:00, Alla _ wrote:
> > Hello!
> >
> > Please, help me to find my mistake; it seems I do everything correctly
> > but, most likely, I am mistaken.
> >
> > I will show only a part of code to explain my issue.
> > I have declared an array of structures and a pointer to
> > that array. Then I use the pointer to populate, for now,
> > one member of each structure. No problems here: values
> > land in their correct places. But when I try to print out
> > those values using a pointer, I don't get those values,
> > only zeros. Please, see the code for clarification.
> >
> > #define DATA_SIZE 5
> > typedef struct data {
> > int year;
> > double sales;
> > int cs_cogs;
> > int cs_gross_profit;
> > int cs_sga;
> > int cs_oper_inc;
> > int cs_dep_amor;
> > int cs_oper_prof;
> > int cs_int_exp;
> > int cs_gain_loss;
> > int cs_pretax_inc;
> > int cs_tax_exp;
> > int cs_net_inc;
> > } data;
> >
> > in the main function I have this declaration
> > (I will later use malloc here, not now):
> >
> > data years[DATA_SIZE];
> > data *dat_years = years;
> >
>
> It's not a good idea to make a global variable like this initialised at
> the start (before main() starts) and then change it during your
> "numbers" function. It means that "numbers" will only work once in the
> lifetime of the program. But in this case, you are mixing up the global
> variable and the functions parameter - it is bound to cause confusion.
>
> > Then I pass the pointer dat_years into a function:
> > /** Parse numbers **/
> > bool numbers(char *line, struct data *dat_years)
>
> Don't use the same names for a parameter and a global variable.
>
> And try to be consistent with your type names. If you want to call your
> struct "data" using a typedef, that's fine. If you want to call it
> "struct data" to emphasis that it's a struct, that's also fine. Both
> methods are common. But try to stick to one method.
Yes, thank you! I have completely forgotten to delete additional
word 'struct' after I have added typedef. Sorry, and thank you
for showing it.
>
> > {
> > char *ptr = line;
> > char *not_converted = NULL;
> > int count = 0;
> >
> > while(count < DATA_SIZE)
> > {
> > dat_years->sales = strtod(ptr, ¬_converted);
> >
> > /****** Comment only for explanatory purpose (not part of my code):
> > here I try to print out values; the first fprintf with dat_years->sales
> > works perfectly because it is a standard access to a member via
> > a pointer; but the second one doesn't: I wonder why?
> >
> > dat_years[count].sales equals the correct number only at the beginning,
> > when count = 0; as soon as I increment the count and move pointer to
> > the next address dat_years[count].sales shows me only zeros as its values:
> > Loop beg: sales num 1062.000000; count 0
> > Loop beg2: sales[0] 1062.000000
> >
> > Loop beg: sales num 1252.000000; count 1
> > Loop beg2: sales[1] 0.000000
> >
> > Loop beg: sales num 1587.000000; count 2
> > Loop beg2: sales[2] 0.000000
> >
> > etc.
> > But this member in each structure has the correct value after this
> > function, and when the main function calls
> > fprintf(stderr, "Main fun: sales[%i] num %f; sales[0] num %f;\n", DATA_SIZE-1, years[DATA_SIZE-1].sales, years[0].sales);
> > it produces a correct output:
> > Main fun: sales[4] num 2519.000000; sales[0] num 1062.000000;
> >
> > ******/
> >
> > fprintf(stderr, "Loop beg: sales num %f; count %i\n", dat_years->sales, count);
>
> Here, "sales" refers to the "data" object pointed to by dat_years, and
> will loop through the data as dat_years gets incremented each round.
>
> > fprintf(stderr, "Loop beg2: sales[%i] %f\n", count, dat_years[count].sales);
>
> Here, "sales" refers to the "data" object pointed to by dat_years plus
> an offset of "count" items. This will step through twice as fast.
>
> >
> > if (not_converted > ptr)
> > {
> > count++;
> > dat_years += (count != DATA_SIZE);
>
> You don't need the "(count != DATA_SIZE)" bit. It's fine to make your
> pointer go to the address just beyond the end of the data. It's just
> not okay to try to de-reference such pointers. So use the far simpler
> and clearer "dat_years++;".
That's the one I had before, and Ben has also told me today that
it's not a good idea to use this idiom here; but I have just learned
it yesterday, so, as I was amused by it, I have added it here )
Also, I did de-reference this pointer in another code, so in fact
I needed to make sure I don't get pass the array.
>
> > ptr = not_converted + (*not_converted != '\0');
> > }
> > else
> > {
> > fprintf(stderr, "Incorrect data on line %s at count %i\n", line, count);
> > return false;
> > }
> > }
> > return count == DATA_SIZE;
> > }
> >
> > Thank you!
> >
>
> Your main problem is mixing your array syntax and pointer syntax.
>
> As a general rule, if you have an array of data and it is reasonably
> "natural" to access it as an array, then do that as preference to using
> a pointer or using pointer syntax. It can make the code's intention
> clearer to you (the programmer), to your reader, and to your compiler.
> (Making code clearer to the compiler leads to better static error
> checking, and more efficient object code.)
[toc] | [prev] | [next] | [standalone]
| From | "Peter \"Shaggy\" Haywood" <phaywood@alphalink.com.au> |
|---|---|
| Date | 2017-01-30 22:04 +1100 |
| Message-ID | <m7j3md-aa6.ln1@walter.foo> |
| In reply to | #102269 |
Groovy hepcat Alla _ was jivin' in comp.lang.c on Sat, 21 Jan 2017 9:00
pm. It's a cool scene! Dig it.
> Hello!
>
> Please, help me to find my mistake; it seems I do everything correctly
> but, most likely, I am mistaken.
You are mistaken.
> I will show only a part of code to explain my issue.
Usually we prefer you to post the smallest complete, compileable
program that demonstrates the problem. But in this case the problem is
fairly obvious.
> I have declared an array of structures and a pointer to
> that array. Then I use the pointer to populate, for now,
> one member of each structure.
No, you don't. Please try to think about what you are actually doing,
not merely what you intended.
> No problems here: values
> land in their correct places. But when I try to print out
> those values using a pointer, I don't get those values,
> only zeros. Please, see the code for clarification.
What you get is undefined behaviour, because you a) read uninitialised
data which is b) beyond the end of an array, in unknown memory.
> #define DATA_SIZE 5
> typedef struct data {
...
> double sales;
...
> } data;
>
> in the main function I have this declaration
> (I will later use malloc here, not now):
>
> data years[DATA_SIZE];
> data *dat_years = years;
>
> Then I pass the pointer dat_years into a function:
> /** Parse numbers **/
> bool numbers(char *line, struct data *dat_years)
> {
> char *ptr = line;
> char *not_converted = NULL;
> int count = 0;
>
> while(count < DATA_SIZE)
> {
> dat_years->sales = strtod(ptr, ¬_converted);
What are you doing here? Well, I'll explain it to you. You're
accessing dat_years->sales. (More below.)
> /****** Comment only for explanatory purpose (not part of my
> code):
> here I try to print out values; the first fprintf with
> dat_years->sales works perfectly because it is a standard
> access to a member via a pointer; but the second one doesn't: I
> wonder why?
>
> dat_years[count].sales equals the correct number only at the
> beginning, when count = 0; as soon as I increment the count and move
> pointer to the next address dat_years[count].sales shows me only zeros
> as its values: Loop beg: sales num 1062.000000; count 0
> Loop beg2: sales[0] 1062.000000
>
> Loop beg: sales num 1252.000000; count 1
> Loop beg2: sales[1] 0.000000
>
> Loop beg: sales num 1587.000000; count 2
> Loop beg2: sales[2] 0.000000
>
> etc.
> But this member in each structure has the correct value after this
> function, and when the main function calls
> fprintf(stderr, "Main fun: sales[%i] num %f; sales[0] num %f;\n",
> DATA_SIZE-1, years[DATA_SIZE-1].sales, years[0].sales); it produces a
> correct output: Main fun: sales[4] num 2519.000000; sales[0] num
> 1062.000000;
>
> ******/
>
> fprintf(stderr, "Loop beg: sales num %f; count %i\n",
> dat_years->sales, count); fprintf(stderr, "Loop beg2:
> sales[%i] %f\n", count, dat_years[count].sales);
Are you intending to enter the International Obfuscated C Coding
Contest? If not, then you need to lay out your code better so we can
read it more easily. I've taken the liberty to rearrange these lines...
fprintf(stderr, "Loop beg: sales num %f; count %i\n",
dat_years->sales, count);
fprintf(stderr, "Loop beg2: sales[%i] %f\n",
count, dat_years[count].sales);
Now, here you're accessing dat_years[count].sales. Now, how does this
differ from what you are doing above, hmmm? Now think about it. How
does dat_years->sales differ from dat_years[count].sales?
Understand this and you will understand why your code is not working.
> if (not_converted > ptr)
> {
> count++;
> dat_years += (count != DATA_SIZE);
Here you are updating dat_years, obviously. However, since you are
accessing dat_years[count].sales above, you're going beyond the end of
the array, into no man's land!
> ptr = not_converted + (*not_converted != '\0');
> }
> else
> {
> fprintf(stderr, "Incorrect data on line %s at count %i\n",
> line, count); return false;
> }
> }
> return count == DATA_SIZE;
> }
There are other issues here, but I'll leave those for now so you can
concentrate on one problem at a time.
> Thank you!
You're welcome!
--
----- Dig the NEW and IMPROVED news sig!! -----
-------------- Shaggy was here! ---------------
Ain't I'm a dawg!!
[toc] | [prev] | [standalone]
Page 2 of 2 — ← Prev page 1 [2]
Back to top | Article view | comp.lang.c
csiph-web