Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #102269 > unrolled thread

Access structure members via pointer to an array of structures

Started byAlla _ <modelling.data@gmail.com>
First post2017-01-21 02:00 -0800
Last post2017-01-30 22:04 +1100
Articles 12 on this page of 32 — 15 participants

Back to article view | Back to comp.lang.c


Contents

  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]


#102322

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-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]


#102332

FromKeith Thompson <kst-u@mib.org>
Date2017-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]


#102321

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-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]


#102324

FromGareth Owen <gwowen@gmail.com>
Date2017-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]


#102329

FromKeith Thompson <kst-u@mib.org>
Date2017-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]


#102279

FromManfred <noname@invalid.add>
Date2017-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]


#102282

FromDavid Brown <david.brown@hesbynett.no>
Date2017-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, &not_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]


#102285

FromAlla _ <modelling.data@gmail.com>
Date2017-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, &not_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]


#102289

FromBarry Schwarz <schwarzb@dqel.com>
Date2017-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]


#102290

FromAlla _ <modelling.data@gmail.com>
Date2017-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]


#102288

FromAlla _ <modelling.data@gmail.com>
Date2017-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, &not_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]


#102943

From"Peter \"Shaggy\" Haywood" <phaywood@alphalink.com.au>
Date2017-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, &not_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