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


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

solution allocation of memory and composite numbers

Started byDexterr <dejangru@gmail.com>
First post2014-12-24 05:52 -0800
Last post2014-12-24 11:42 -0800
Articles 20 on this page of 66 — 19 participants

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


Contents

  solution allocation of memory and composite numbers Dexterr <dejangru@gmail.com> - 2014-12-24 05:52 -0800
    Re: solution allocation of memory and composite numbers Dexterr <dejangru@gmail.com> - 2014-12-24 05:55 -0800
      Re: solution allocation of memory and composite numbers Malcolm McLean <malcolm.mclean5@btinternet.com> - 2014-12-24 06:41 -0800
        Re: solution allocation of memory and composite numbers Ben Bacarisse <ben.usenet@bsb.me.uk> - 2014-12-24 20:16 +0000
          Re: solution allocation of memory and composite numbers Malcolm McLean <malcolm.mclean5@btinternet.com> - 2014-12-24 12:39 -0800
            Re: solution allocation of memory and composite numbers Richard Heathfield <invalid@see.sig.invalid> - 2014-12-24 21:22 +0000
              Re: solution allocation of memory and composite numbers Ben Bacarisse <ben.usenet@bsb.me.uk> - 2014-12-24 22:33 +0000
                Re: solution allocation of memory and composite numbers Richard Heathfield <invalid@see.sig.invalid> - 2014-12-25 00:54 +0000
                  Re: solution allocation of memory and composite numbers Malcolm McLean <malcolm.mclean5@btinternet.com> - 2014-12-24 18:38 -0800
                  Re: solution allocation of memory and composite numbers Vincenzo Mercuri <nomail@yahoo.it> - 2014-12-25 12:07 +0100
                  Re: solution allocation of memory and composite numbers Ben Bacarisse <ben.usenet@bsb.me.uk> - 2014-12-26 22:05 +0000
                    Re: solution allocation of memory and composite numbers BartC <bc@freeuk.com> - 2014-12-26 22:33 +0000
                      Re: solution allocation of memory and composite numbers Ben Bacarisse <ben.usenet@bsb.me.uk> - 2014-12-27 22:08 +0000
                        Re: solution allocation of memory and composite numbers BartC <bc@freeuk.com> - 2014-12-27 23:28 +0000
                        Re: solution allocation of memory and composite numbers BartC <bc@freeuk.com> - 2014-12-29 18:34 +0000
                          Re: solution allocation of memory and composite numbers raltbos@xs4all.nl (Richard Bos) - 2014-12-30 19:23 +0000
                    Re: solution allocation of memory and composite numbers Malcolm McLean <malcolm.mclean5@btinternet.com> - 2014-12-26 15:43 -0800
                      Re: solution allocation of memory and composite numbers Keith Thompson <kst-u@mib.org> - 2014-12-26 15:59 -0800
                      Re: solution allocation of memory and composite numbers Vincenzo Mercuri <nomail@yahoo.it> - 2014-12-27 14:45 +0100
                      Re: solution allocation of memory and composite numbers Ben Bacarisse <ben.usenet@bsb.me.uk> - 2014-12-27 21:55 +0000
                        Re: solution allocation of memory and composite numbers Malcolm McLean <malcolm.mclean5@btinternet.com> - 2014-12-27 14:07 -0800
                          Re: solution allocation of memory and composite numbers Vincenzo Mercuri <nomail@yahoo.it> - 2014-12-27 23:44 +0100
                            Re: solution allocation of memory and composite numbers Malcolm McLean <malcolm.mclean5@btinternet.com> - 2014-12-27 15:49 -0800
                            Re: solution allocation of memory and composite numbers Keith Thompson <kst-u@mib.org> - 2014-12-27 21:52 -0800
                              Re: solution allocation of memory and composite numbers Vincenzo Mercuri <nomail@yahoo.it> - 2014-12-28 15:54 +0100
                          Re: solution allocation of memory and composite numbers Ben Bacarisse <ben.usenet@bsb.me.uk> - 2014-12-28 00:03 +0000
                    Re: solution allocation of memory and composite numbers Keith Thompson <kst-u@mib.org> - 2014-12-26 17:13 -0800
                      Re: solution allocation of memory and composite numbers Geoff <geoff@invalid.invalid> - 2014-12-27 10:23 -0800
                        Re: solution allocation of memory and composite numbers Stephen Sprunk <stephen@sprunk.org> - 2014-12-27 13:03 -0600
                          Re: solution allocation of memory and composite numbers Keith Thompson <kst-u@mib.org> - 2014-12-27 12:24 -0800
                        Re: solution allocation of memory and composite numbers Keith Thompson <kst-u@mib.org> - 2014-12-27 12:23 -0800
                        Re: solution allocation of memory and composite numbers Malcolm McLean <malcolm.mclean5@btinternet.com> - 2014-12-27 13:31 -0800
                        Re: solution allocation of memory and composite numbers Öö Tiib <ootiib@hot.ee> - 2014-12-27 18:42 -0800
                          Re: solution allocation of memory and composite numbers Keith Thompson <kst-u@mib.org> - 2014-12-27 22:07 -0800
                        Re: solution allocation of memory and composite numbers raltbos@xs4all.nl (Richard Bos) - 2014-12-30 19:26 +0000
                          Re: solution allocation of memory and composite numbers Kaz Kylheku <kaz@kylheku.com> - 2014-12-30 20:01 +0000
                            Re: solution allocation of memory and composite numbers Malcolm McLean <malcolm.mclean5@btinternet.com> - 2014-12-30 12:18 -0800
                              Re: solution allocation of memory and composite numbers Kaz Kylheku <kaz@kylheku.com> - 2014-12-30 21:15 +0000
                                Re: solution allocation of memory and composite numbers Malcolm McLean <malcolm.mclean5@btinternet.com> - 2014-12-30 13:49 -0800
                                  Re: solution allocation of memory and composite numbers Kaz Kylheku <kaz@kylheku.com> - 2014-12-30 22:03 +0000
                                    Re: solution allocation of memory and composite numbers Kaz Kylheku <kaz@kylheku.com> - 2014-12-30 23:57 +0000
                                Re: solution allocation of memory and composite numbers BartC <bc@freeuk.com> - 2014-12-30 22:35 +0000
                            Re: solution allocation of memory and composite numbers Dr Nick <nospam-4@temporary-address.org.uk> - 2014-12-31 12:24 +0000
                              Re: solution allocation of memory and composite numbers Kaz Kylheku <kaz@kylheku.com> - 2014-12-31 17:08 +0000
                                Re: solution allocation of memory and composite numbers Dr Nick <nospam-4@temporary-address.org.uk> - 2014-12-31 17:37 +0000
                        Re: solution allocation of memory and composite numbers Kaz Kylheku <kaz@kylheku.com> - 2014-12-30 20:09 +0000
                          Re: solution allocation of memory and composite numbers Malcolm McLean <malcolm.mclean5@btinternet.com> - 2014-12-30 12:24 -0800
                            Re: solution allocation of memory and composite numbers Kaz Kylheku <kaz@kylheku.com> - 2014-12-30 21:28 +0000
                              Re: solution allocation of memory and composite numbers Malcolm McLean <malcolm.mclean5@btinternet.com> - 2014-12-30 13:53 -0800
                                Re: solution allocation of memory and composite numbers Kaz Kylheku <kaz@kylheku.com> - 2015-01-04 02:22 +0000
                        Re: solution allocation of memory and composite numbers Xavier Roche <xroche@free.fr.NOSPAM.invalid> - 2014-12-31 13:32 +0100
                    Re: solution allocation of memory and composite numbers BartC <bc@freeuk.com> - 2014-12-27 01:37 +0000
                    Re: solution allocation of memory and composite numbers raltbos@xs4all.nl (Richard Bos) - 2014-12-27 12:19 +0000
                      Re: solution allocation of memory and composite numbers gazelle@shell.xmission.com (Kenny McCormack) - 2014-12-27 14:39 +0000
            Re: solution allocation of memory and composite numbers Ben Bacarisse <ben.usenet@bsb.me.uk> - 2014-12-24 22:29 +0000
      Re: solution allocation of memory and composite numbers BartC <bc@freeuk.com> - 2014-12-24 15:05 +0000
    Re: solution allocation of memory and composite numbers Richard Heathfield <invalid@see.sig.invalid> - 2014-12-24 16:55 +0000
      iso646.h Noob <root@127.0.0.1> - 2014-12-25 18:26 +0100
        Re: iso646.h Geoff <geoff@invalid.invalid> - 2014-12-25 18:31 -0800
          Re: iso646.h Noob <root@127.0.0.1> - 2014-12-26 18:23 +0100
        Re: iso646.h Keith Thompson <kst-u@mib.org> - 2014-12-25 21:31 -0800
          Re: iso646.h fir <profesor.fir@gmail.com> - 2014-12-26 09:42 -0800
    Re: solution allocation of memory and composite numbers Barry Schwarz <schwarzb@dqel.com> - 2014-12-24 09:06 -0800
    Re: solution allocation of memory and composite numbers Richard Heathfield <invalid@see.sig.invalid> - 2014-12-24 16:59 +0000
    Re: solution allocation of memory and composite numbers BartC <bc@freeuk.com> - 2014-12-24 17:26 +0000
      Re: solution allocation of memory and composite numbers asetofsymbols@gmail.com - 2014-12-24 11:42 -0800

Page 3 of 4 — ← Prev page 1 2 [3] 4  Next page →


#55617

FromKaz Kylheku <kaz@kylheku.com>
Date2014-12-30 23:57 +0000
Message-ID<20141230155500.503@kylheku.com>
In reply to#55609
On 2014-12-30, Stefan Ram <ram@zedat.fu-berlin.de> wrote:
> Kaz Kylheku <kaz@kylheku.com> writes:
>>Both are correct grammar and semantically equivalent. The second one
>>fails to be euphonic, which is just an esthetic judgment.
>
>   When I introduce the if statement, I start with a very simple
>   example (copied from my course):
>
> #include <stdio.h>
> int main( void )
> { if(  0 )printf( "%d\n",  0 ); 
>   if( -2 )printf( "%d\n", -2 ); }
>
>   students: That's impossible! You can't say »if 0«!
>   It makes no sense!
>
>   me: It makes no sense in English, but C is not English.
>   C has its own rules. (And then I continue to explain
>   these rules.)

Moreover, you can say "if zero" in English, due to processes
like extraposition and elision:

"The denominator, if zero, leads to an exception."

"If the result is one, overwrite the file. If zero, then delete it."



-- 
Music DIY Mailing List: http://www.kylheku.com/diy
ADA MP-1 Mailing List:  http://www.kylheku.com/mp1

[toc] | [prev] | [next] | [standalone]


#55611

FromBartC <bc@freeuk.com>
Date2014-12-30 22:35 +0000
Message-ID<gNFow.332982$RM2.217463@fx43.am4>
In reply to#55602
On 30/12/2014 21:15, Kaz Kylheku wrote:
> On 2014-12-30, Malcolm McLean <malcolm.mclean5@btinternet.com> wrote:
>> On Tuesday, December 30, 2014 8:01:38 PM UTC, Kaz Kylheku wrote:
>>> On 2014-12-30, Richard Bos <raltbos@xs4all.nl> wrote:
>>>
>>>> That bug is a very good reason _not_ to use this hack. Try it when both
>>>> operands are variables... introducing a bug in _some_ of your
>>>
>>> Huh? When both operands are variables, the conding convention doesn't apply.
>>> So it provides neither benfit, nor harm.
>>>
>> The reason for not doing it is that it makes the code harder to read.
>>
>> You can still read it, just as if you write without capitals or in d00d-spk text is
>> still comprehensible. But it makes it harder to spot logic errors when scanning code.
>
> How so? Equality is a symmetric property. (foo == bar) means exactly
> the same thing as (bar == foo).

That's exactly the reason why it shouldn't be necessary to mess with the 
natural order of the operands. If it's something that isn't normally 
encountered, it affects the readability, puts you off the rest of the 
code because you're wondering what other annoying habits the author has, 
but most importantly it's a distraction. It's also ugly.

Being legal C doesn't mean it's fine.

I could for example write a program with uses only the letters a and  A 
in identifiers (depending on case, and length, to distinguish them). 
It'll work, but no-one would be able to see past it.

-- 
Bartc

[toc] | [prev] | [next] | [standalone]


#55631

FromDr Nick <nospam-4@temporary-address.org.uk>
Date2014-12-31 12:24 +0000
Message-ID<87r3vgdn27.fsf@temporary-address.org.uk>
In reply to#55597
Kaz Kylheku <kaz@kylheku.com> writes:

> On 2014-12-30, Richard Bos <raltbos@xs4all.nl> wrote:
>> Geoff <geoff@invalid.invalid> wrote:
>>
>>> On Fri, 26 Dec 2014 17:13:47 -0800, Keith Thompson <kst-u@mib.org>
>>> >ram@zedat.fu-berlin.de (Stefan Ram) writes:
>>> >
>>> >> if( 1 == scanf( "%d", &i ))
>>> >
>>> >Personally, I would never advise beginners to write their equality tests
>>> >backwards like that.  There's some risk I might have to read their code
>>> >some day.
>>> 
>>> Some shops require it. There's a very good reason for doing it that
>>> way, namely the = vs == bug in conditionals.
>>
>> That bug is a very good reason _not_ to use this hack. Try it when both
>> operands are variables... introducing a bug in _some_ of your
>
> Huh? When both operands are variables, the conding convention doesn't apply.
> So it provides neither benfit, nor harm.

I disagree.  You have just the same issue with making the flow of the
code match the intent of the tests, with no savings.

If you adopt the "if(3 == counter)" convention, do you also adopt
"if(limit > counter)" rather than "if(counter < limit)"?

If so, you seem to be making your code deliberately less easy to
understand.  And for no benefit in this case.  I believe in Kernigan's
law of Debugging and so don't do that.

If you don't, but you do for the == case, you could end up with a series
of comparison, some of which compare your counter against some constants
and some variables against counter which is just odd.  

What do you do when you have "if(MAXSIZE == OBJECTLIMIT)" and either of
them might just, in some builds, turn out to a variable loaded from a
configuration file but in other builds are numeric constants?

It still seems to me that you need to apply so much thought to this not
to confuse yourself that you'd be better applying the same effort to
checking whether you meant = or ==.  Or even applying a small fraction
of it to configuring your compiler.

[toc] | [prev] | [next] | [standalone]


#55638

FromKaz Kylheku <kaz@kylheku.com>
Date2014-12-31 17:08 +0000
Message-ID<20141231085746.522@kylheku.com>
In reply to#55631
On 2014-12-31, Dr Nick <nospam-4@temporary-address.org.uk> wrote:
> Kaz Kylheku <kaz@kylheku.com> writes:
>
>> On 2014-12-30, Richard Bos <raltbos@xs4all.nl> wrote:
>>> Geoff <geoff@invalid.invalid> wrote:
>>>
>>>> On Fri, 26 Dec 2014 17:13:47 -0800, Keith Thompson <kst-u@mib.org>
>>>> >ram@zedat.fu-berlin.de (Stefan Ram) writes:
>>>> >
>>>> >> if( 1 == scanf( "%d", &i ))
>>>> >
>>>> >Personally, I would never advise beginners to write their equality tests
>>>> >backwards like that.  There's some risk I might have to read their code
>>>> >some day.
>>>> 
>>>> Some shops require it. There's a very good reason for doing it that
>>>> way, namely the = vs == bug in conditionals.
>>>
>>> That bug is a very good reason _not_ to use this hack. Try it when both
>>> operands are variables... introducing a bug in _some_ of your
>>
>> Huh? When both operands are variables, the conding convention doesn't apply.
>> So it provides neither benfit, nor harm.
>
> I disagree.  You have just the same issue with making the flow of the
> code match the intent of the tests, with no savings.
>
> If you adopt the "if(3 == counter)" convention, do you also adopt
> "if(limit > counter)" rather than "if(counter < limit)"?

No, because in this case, flipping the two expressions requires
a change of operator; the operator is not symmetric.

Whereas if a == b, then b == a, it is not the case that if a < b then b < a.

Inequality has direction, and a mixup in the understanding of the direction
has consequences, whereas equality is directionless, so it has no such
issue.

Also, < is not easily misspelled into some similar operator that
clobbers storage locations.

[toc] | [prev] | [next] | [standalone]


#55641

FromDr Nick <nospam-4@temporary-address.org.uk>
Date2014-12-31 17:37 +0000
Message-ID<871tnfen4w.fsf@temporary-address.org.uk>
In reply to#55638
Kaz Kylheku <kaz@kylheku.com> writes:

> On 2014-12-31, Dr Nick <nospam-4@temporary-address.org.uk> wrote:
>> Kaz Kylheku <kaz@kylheku.com> writes:
>>
>>> On 2014-12-30, Richard Bos <raltbos@xs4all.nl> wrote:
>>>> Geoff <geoff@invalid.invalid> wrote:
>>>>
>>>>> On Fri, 26 Dec 2014 17:13:47 -0800, Keith Thompson <kst-u@mib.org>
>>>>> >ram@zedat.fu-berlin.de (Stefan Ram) writes:
>>>>> >
>>>>> >> if( 1 == scanf( "%d", &i ))
>>>>> >
>>>>> >Personally, I would never advise beginners to write their equality tests
>>>>> >backwards like that.  There's some risk I might have to read their code
>>>>> >some day.
>>>>> 
>>>>> Some shops require it. There's a very good reason for doing it that
>>>>> way, namely the = vs == bug in conditionals.
>>>>
>>>> That bug is a very good reason _not_ to use this hack. Try it when both
>>>> operands are variables... introducing a bug in _some_ of your
>>>
>>> Huh? When both operands are variables, the conding convention doesn't apply.
>>> So it provides neither benfit, nor harm.
>>
>> I disagree.  You have just the same issue with making the flow of the
>> code match the intent of the tests, with no savings.
>>
>> If you adopt the "if(3 == counter)" convention, do you also adopt
>> "if(limit > counter)" rather than "if(counter < limit)"?
>
> No, because in this case, flipping the two expressions requires
> a change of operator; the operator is not symmetric.
>
> Whereas if a == b, then b == a, it is not the case that if a < b then b < a.
>
> Inequality has direction, and a mixup in the understanding of the direction
> has consequences, whereas equality is directionless, so it has no such
> issue.
>
> Also, < is not easily misspelled into some similar operator that
> clobbers storage locations.

But that then leads you to absurdities like this:

#include "filethatdefinesomeconstants.h"

if (a <= LOWERVALUE)
     dosomething();
if (a > LOWERVALUE && a < MAXVALUE)
     dosomethingelse();
if (MAXVALUE == a)
     doanotherthing();
     
I'd accept any number of debugging problems not to code like this -
because I genuinely believe that examples like this genuinely make the
code harder to understand.

Add modern compilers and there's no justification for it.

[toc] | [prev] | [next] | [standalone]


#55599

FromKaz Kylheku <kaz@kylheku.com>
Date2014-12-30 20:09 +0000
Message-ID<20141230120228.685@kylheku.com>
In reply to#55501
On 2014-12-27, Geoff <geoff@invalid.invalid> wrote:
> On Fri, 26 Dec 2014 17:13:47 -0800, Keith Thompson <kst-u@mib.org>
> wrote:
>
>>ram@zedat.fu-berlin.de (Stefan Ram) writes:
>>
>>>>The experience I have of the trouble beginners have with scanf tells me
>>>>that it's not as bad as you seem to suggest (what else could I have
>>>>meant?).  It doesn't seem to me to "astoundingly difficult" to use
>>>>safely and correctly.
>>>
>>>   One could give as a recipe that to read an int value i 
>>>   the students should use this snippet:
>>>
>>> if( 1 == scanf( "%d", &i ))
>>
>>Personally, I would never advise beginners to write their equality tests
>>backwards like that.  There's some risk I might have to read their code
>>some day.
>>
>
> Some shops require it. There's a very good reason for doing it that
> way, namely the = vs == bug in conditionals.

If you want to banish errors due to assignments, you should minimize
assignments. Assignments are potentially harmful even when they are intended.

For instance, a coding convention could banish all "naked" appearances
of the = punctuator from C code.

#define SET(X, Y) ((X) = (Y))
#define INI(D, I) (D) = I

  {
    int INI(x, 3);   /* int x = 3; */
    SET(x, 4);       /* x = 4; */
  }

Now if someone has:

  if (situation = UNDER_NUCLEAR_ATTACK)

this is easily unearthed by a regular expression search for the = token.

Nobody will mistakenly write SET(x, y) when they intend x == y.

Another approach is compiler diagnosis. It is easy in a C compiler to diagnose
any expression which contains an assignment and is not the full expresssion
of an assignment statement.

GCC has a warning which finds code like if (a = b) and suggests an extra
level of parentheses. That alone makes the (1 == b) coding convention
superfluous, if you can port your code to GCC.

[toc] | [prev] | [next] | [standalone]


#55601

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2014-12-30 12:24 -0800
Message-ID<f12b3ffc-969f-41d7-b9d6-c7a4a87c4399@googlegroups.com>
In reply to#55599
On Tuesday, December 30, 2014 8:10:00 PM UTC, Kaz Kylheku wrote:
>
> #define SET(X, Y) ((X) = (Y))
> #define INI(D, I) (D) = I
> 
>   {
>     int INI(x, 3);   /* int x = 3; */
>     SET(x, 4);       /* x = 4; */
>   }
> 
should be

#define INI(D, I) D = (I)

surely.

[toc] | [prev] | [next] | [standalone]


#55603

FromKaz Kylheku <kaz@kylheku.com>
Date2014-12-30 21:28 +0000
Message-ID<20141230131542.654@kylheku.com>
In reply to#55601
On 2014-12-30, Malcolm McLean <malcolm.mclean5@btinternet.com> wrote:
> On Tuesday, December 30, 2014 8:10:00 PM UTC, Kaz Kylheku wrote:
>>
>> #define SET(X, Y) ((X) = (Y))
>> #define INI(D, I) (D) = I
>> 
>>   {
>>     int INI(x, 3);   /* int x = 3; */
>>     SET(x, 4);       /* x = 4; */
>>   }
>> 
> should be
>
> #define INI(D, I) D = (I)

I was thinking that without the parens on D, you can do this:

  int INI(x = 3, 4)   /* int x = 3 = (4) */

Of course, this will not pass the code check which banishes naked = signs,
and the following is not only unlikely, but inserts parens of its own:

  int INI(SET(x, 3), 4)

Ha!

Not sure what the parens on the initializer achieve. They are needed
when there is a comma operator ambiguity.

  int x = (y, z), y = 42;

This cannot arise in the INI macro, because INI(x, y, z) looks like
a macro call with three args. You have to write INI(x, (y, z))
which renders the (I) parentheses moot.

I can't think of any other situations in which parens go around an initializer,
because an initializer can only be followed by a comma or a semicolon.
Any token which is not a comma or semicolon is either a continuation of the
initializer or a syntax error.

[toc] | [prev] | [next] | [standalone]


#55606

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2014-12-30 13:53 -0800
Message-ID<91f292ce-cd84-4850-bc15-ead24bbe9f29@googlegroups.com>
In reply to#55603
On Tuesday, December 30, 2014 9:28:25 PM UTC, Kaz Kylheku wrote:
> On 2014-12-30, Malcolm McLean <malcolm.mclean5@btinternet.com> wrote:
> > On Tuesday, December 30, 2014 8:10:00 PM UTC, Kaz Kylheku wrote:
> >>
> >> #define SET(X, Y) ((X) = (Y))
> >> #define INI(D, I) (D) = I
> >> 
> >>   {
> >>     int INI(x, 3);   /* int x = 3; */
> >>     SET(x, 4);       /* x = 4; */
> >>   }
> >> 
> > should be
> >
> > #define INI(D, I) D = (I)
> 
> I was thinking that without the parens on D, you can do this:
> 
>   int INI(x = 3, 4)   /* int x = 3 = (4) */
> 
> Of course, this will not pass the code check which banishes naked = signs,
> and the following is not only unlikely, but inserts parens of its own:
> 
>   int INI(SET(x, 3), 4)
> 
> Ha!
> 
> Not sure what the parens on the initializer achieve. They are needed
> when there is a comma operator ambiguity.
> 
>   int x = (y, z), y = 42;
> 
> This cannot arise in the INI macro, because INI(x, y, z) looks like
> a macro call with three args. You have to write INI(x, (y, z))
> which renders the (I) parentheses moot.
> 
> I can't think of any other situations in which parens go around an initializer,
> because an initializer can only be followed by a comma or a semicolon.
> Any token which is not a comma or semicolon is either a continuation of the
> initializer or a syntax error.
>

int INI(*x, (y));

[toc] | [prev] | [next] | [standalone]


#55797

FromKaz Kylheku <kaz@kylheku.com>
Date2015-01-04 02:22 +0000
Message-ID<20150103180845.722@kylheku.com>
In reply to#55606
On 2014-12-30, Malcolm McLean <malcolm.mclean5@btinternet.com> wrote:
> On Tuesday, December 30, 2014 9:28:25 PM UTC, Kaz Kylheku wrote:
>> Not sure what the parens on the initializer achieve. They are needed
>> when there is a comma operator ambiguity.
>> 
>>   int x = (y, z), y = 42;
>> 
>> This cannot arise in the INI macro, because INI(x, y, z) looks like
>> a macro call with three args. You have to write INI(x, (y, z))
>> which renders the (I) parentheses moot.
>> 
>> I can't think of any other situations in which parens go around an initializer,
>> because an initializer can only be followed by a comma or a semicolon.
>> Any token which is not a comma or semicolon is either a continuation of the
>> initializer or a syntax error.
>>
>
> int INI(*x, (y));

I am afraid I don't follow.

[toc] | [prev] | [next] | [standalone]


#55632

FromXavier Roche <xroche@free.fr.NOSPAM.invalid>
Date2014-12-31 13:32 +0100
Message-ID<m80qdk$491$1@news.httrack.net>
In reply to#55501
Le 27/12/2014 19:23, Geoff a écrit :
> Some shops require it. There's a very good reason for doing it that
> way, namely the = vs == bug in conditionals.

This is an anachronistic reason with -Wall and -Werror (or similar) IMHO.

Ie.:

foo.c: In function ‘foo’:
foo.c:2:3: error: suggest parentheses around assignment used as truth
value [-Werror=parentheses]
   if (a = 1) {
   ^
cc1: all warnings being treated as errors

[toc] | [prev] | [next] | [standalone]


#55471

FromBartC <bc@freeuk.com>
Date2014-12-27 01:37 +0000
Message-ID<Q3onw.333609$td6.40600@fx30.am4>
In reply to#55465
On 27/12/2014 00:47, Stefan Ram wrote:
> Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
>> The experience I have of the trouble beginners have with scanf tells me
>> that it's not as bad as you seem to suggest (what else could I have
>> meant?).  It doesn't seem to me to "astoundingly difficult" to use
>> safely and correctly.
>
>    One could give as a recipe that to read an int value i
>    the students should use this snippet:
>
> if( 1 == scanf( "%d", &i ))
>
>    and tell them one of two things: either
>
>        - »The & will be explained later.«, or
>
>        - »The & means "address of". scanf needs to know
>          the address of the variable so that it can store
>          the value read there.«.
>
>    So, when the whole & thing can be explained in like 30
>    seconds than why not do it en passant?
>
>    The only confusing thing then  is, why one does /not/
>    have to write
>
> &i = i + 1


>
>    to write i + 1 into i?
>
>    In a hypothetical consistent language »i« whould always mean
>    what we write »&i« today, so to increment »i«, one would write
>
> i =  *i + 1

No, i is written the same way on both sides:

*i = *i + 1

or:

  *&i = *&i + 1;

depending on what the rules are when the name of variable appears in the 
language. The last is legal C when i is the name of a simple scalar 
variable (and not an enum name, an alias for a constant using #define or 
etc. Array names cause complications too.).

In the scanf parameter, the &i part is calculated by the caller, and the 
* part completed in the function.

The *& illustrate how variable names are treated in a typical high-level 
language: the name is actually a reference to the variable's address or 
location, and it's automatically dereferenced to yield the contents, it 
it's an rvalue, or to write to them, if it's an lvalue.

(Because a language like C will apply the equivalent of *& 
automatically, explicitly adding *& as above is like doing:

  *&*&i = *&*&i + 1;

But superfluous *& or &* pairs cancel each other out.)

-- 
Bartc

[toc] | [prev] | [next] | [standalone]


#55484

Fromraltbos@xs4all.nl (Richard Bos)
Date2014-12-27 12:19 +0000
Message-ID<549ea36f.5921375@news.xs4all.nl>
In reply to#55465
ram@zedat.fu-berlin.de (Stefan Ram) wrote:

>   the students should use this snippet:
> 
> if( 1 == scanf( "%d", &i ))

Please don't teach your students this dreadful hack. Have them put the
operands to == in the psychologically right order, and then make them
_pay attention_.

Richard

[toc] | [prev] | [next] | [standalone]


#55487

Fromgazelle@shell.xmission.com (Kenny McCormack)
Date2014-12-27 14:39 +0000
Message-ID<m7mgb7$7l6$1@news.xmission.com>
In reply to#55484
In article <549ea36f.5921375@news.xs4all.nl>,
Richard Bos <rlbos@xs4all.nl> wrote:
>ram@zedat.fu-berlin.de (Stefan Ram) wrote:
>
>>   the students should use this snippet:
>> 
>> if( 1 == scanf( "%d", &i ))
>
>Please don't teach your students this dreadful hack. Have them put the
>operands to == in the psychologically right order, and then make them
>_pay attention_.

+1

This is a classic instance of something that *may* have been a good idea
back before compilers were able to warn about the problem (i.e., in the
80s), but just looks silly today.

The problem is that some CLC regs actually got in the habit of doing it,
back in the 80s - when it *may* actually have had some validity - and are
still stuck in the time warp and are doing it still today.

-- 
The scent of awk programmers is a lot more attractive to women than
the scent of perl programmers.

      (Mike Brennan, quoted in the "GAWK" manual)

[toc] | [prev] | [next] | [standalone]


#55415

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2014-12-24 22:29 +0000
Message-ID<87zjacel74.fsf@bsb.me.uk>
In reply to#55405
Malcolm McLean <malcolm.mclean5@btinternet.com> writes:

> On Wednesday, December 24, 2014 8:16:59 PM UTC, Ben Bacarisse wrote:
>> Malcolm McLean <malcolm.mclean5@btinternet.com> writes:
>> <snip>
>> > It's quite involved, unfortunately there's just no good way to
>> > handle erroneous input, whatever you do it's difficult to program
>> > robustly and give useful messages to the user.
>> 
>> Yes, it is.  So why not write
>> 
>>   if (scanf("%d", &number) == 1 && /* other checks... */) {
>>      /* use the input */
>>   }
>> 
>> ?  For this sort of program, beginners often get better code using
>> scanf.  There's plenty of time to learn abut parsing mini input
>> languages later.  The whole "you must use fgets & strtol" (both hard to
>> use correctly) just puts a huge barrier up to getting started.
>> 
> Richard Heathfield banned scanf().

I know.  I don't want to join in the exercise of making learning C
harder than it needs to be.  I am un-banning it!

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#55386

FromBartC <bc@freeuk.com>
Date2014-12-24 15:05 +0000
Message-ID<rDAmw.235436$6H3.122615@fx35.am4>
In reply to#55384
On 24/12/2014 13:55, Dexterr wrote:
> On Wednesday, December 24, 2014 2:52:32 PM UTC+1, Dexterr wrote:
>> Hello for all gentleman.
>>
>> YES, this is a homework !!!
>> This is a homework from this "usenet"
>> and my teacher is Mr Richard Heathfield,
>> probably the best one in my whole life.
>>
>> The task was:
>> "Write a program that accepts a number in the
>> range 100-200 from the user WITHOUT using scanf (hint: fgets, strtoul).
>> Allocate as many ints as he asks for (hint: malloc). If the allocation
>> fails, print an explanation and quit. Otherwise, fill the array with numbers
>> from 0 up to (but not including - why not?) the number he typed. Replace all
>> composite numbers (and 1) with 0. Then print out the non-zero values (the
>> primes). Don't forget to free the memory at the end."

>>    // Allocate as many ints as he asks for (hint: malloc).
>>    char *buffer = malloc(sizeof(char) * SIZE);

>> 	  fgets(buffer, SIZE, stdin);
>> 	
>> 	  ul = strtoul(buffer, NULL, 0);
>> 	  printf("You entered %lu", ul);
>> 	  printf("\n");
>> 	
>> 	  if(ul < 100 OR ul > 200)

>>
>> How can I improve if someone input a string more then 125 chars as I defined
>> at the beginning ?
>>
>> Here i have allocated SIZE of 125 chars:
>>
>> char *buffer = malloc(sizeof(char) * SIZE);
>>
>> But what is going on if someone type for instance > 125 fajkdsajfajfafdasflöfj
>>   .... a string with more than 125.

This is not what the task is asking.

You don't need to allocate a large buffer just for someone to type in a 
number from 100 to 200. A suitable buffer might be:

  char buffer[32];

  fgets(buffer, sizof(buffer), ...

No malloc() (or associated error-handling) is needed. Someone *can* type 
nonsense, or a number to big to fit into an int. You will need to look 
at the docs for strtoul() to see if it can help with that. You can test 
by giving it all sorts of wrong input (eg. try it with 0000000235 and 
see what happens; on my machine, I get the value 157).

But once the ul 100..200 input has been input and checked, *now* you 
will need to allocate space for ul ints, although you've chosen to do 
this without using malloc(), using variable-length arrays. This is fine, 
but not what the hint suggests.

>> OK I now for realloc but I am not smart how to implement realloc in this situation ?

That shouldn't come into it. In theory, someone could type the input as 
"                                 ......               123", that is, 
preceded by possibly a billion space characters. Should the machine's 
entire memory to be exhausted by allowing that or not? You decide...

-- 
Bartc

[toc] | [prev] | [next] | [standalone]


#55388

FromRichard Heathfield <invalid@see.sig.invalid>
Date2014-12-24 16:55 +0000
Message-ID<peCmw.281622$EJ7.95270@fx18.am4>
In reply to#55383
Dexterr wrote:

<snip>
> YES, this is a homework !!!
<snip>

Honesty is the best policy. :-)

> The task was:
> "Write a program that accepts a number in the
> range 100-200 from the user WITHOUT using scanf (hint: fgets, strtoul).
> Allocate as many ints as he asks for (hint: malloc). If the allocation
> fails, print an explanation and quit. Otherwise, fill the array with
> numbers from 0 up to (but not including - why not?) the number he typed.
> Replace all composite numbers (and 1) with 0. Then print out the non-zero
> values (the primes). Don't forget to free the memory at the end."
> 
> ---------------------------- first solution

This suggests at least two solutions. That's good. Very often, the first 
time we try to solve a problem, we're just feeling our way, and we make all 
kinds of design mistakes. We can learn from those mistakes, and very often 
produce a better program the second time around. Fred Brooks once wrote: 
"Plan to throw one away. You will anyway."

So let's take a look at the first solution.

> ---------------------------------
> 
> /* hw_richard_v2.c - proba */
> 
> #include <stdio.h>
> #include <stdlib.h>
> 
> #define SIZE  125

I'm not sure why you need this. Maybe it will become clear.

> #define OR    ||

Better not to do that. Just learn that || means OR, because you'll see || a 
LOT in other people's C programs.

> 
> void inArray(int *inNumber)

Why is this a pointer? It doesn't need to be. Let's make this:

void sieve(unsigned long range)

Why 'sieve'? Because we will be using an algorithm named the Sieve of 
Eratosthenes.

> {
>   int size;

We can just use range, so we don't need size.

>   size = *inNumber;
>   int array[size];

Well, I actually suggested using malloc, but this will do for now. Make it:

unsigned long array[range] = {0}; /* a technique for filling the entire 
array with 0s. It works because C uses any values you give it inside the 
braces - you don't have to specify them all, just one - and it will fill all 
the rest of the elements with 0. This is known as "partial initialisation".

>   int i;

unsigned long i;

>   
>   for(i = 0; i < size; i++) {
> array[i] = i;
>   }

Good. (We'll use range, though.)

>   
>   for(i = 0; i < size; i++) {
>     if(array[i] % 2 == 0)
> {
> array[i] = 0;
> }
> else {
> array[i] = i;
> }
>   }

Not a bad try, but this doesn't do the job that was asked of you. What you 
need to do is remove all *composites* (non-primes) from the list. I'm going 
to show you a very simple way to do that. It is not the best way, but it's 
easy to understand.

We have an array of 'range' elements, where 'range' is somewhere between 100 
and 200, and this array is filled with the numbers from 0 to range-1.

We want to keep the primes, but remove multiples of the primes. This means 
that we need to remove all numbers n that have factors f where f != n and f 
!= 1.

Here's an easy way to do it:

unsigned long maxfactor = sqrt(range) + 1;

Okay, let's unpack that a bit. Firstly, you'll need to #include <math.h> to 
make sqrt work. You may also have to adjust your command line compilation by 
adding -lm to the end (if you're using gcc).

Let's use a subset of the problem to illustrate the technique - we'll take 
the first 50 integers. sqrt(50) is just over 7, so sqrt(50) + 1 is just over 
8, which will be truncated to 8 when we feed it to an integer type (because 
integer types can only store whole numbers).

Here's our array:

 0  1  2  3  4  5  6  7  8  9
10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
30 31 32 33 34 35 36 37 38 39
40 41 42 43 44 45 46 47 48 49

(Remember, your array will be bigger, but the principle is the same.)

Let's start by removing 1, because 1 is not prime. We remove it by changing 
it to 0.

 0  0  2  3  4  5  6  7  8  9
10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
30 31 32 33 34 35 36 37 38 39
40 41 42 43 44 45 46 47 48 49

We have maxfactor = 8, so what we're going to do is start at 2, and go up to 
8, leaving the first multiple of that number alone, and setting all 
subsequent multiples to 0.

We'll start with 2. Leave array[2] alone, and remove array[4], array[6], 
array[8], and so on. That leaves us with:

0  0 2  3 0  5 0  7 0  9
0 11 0 13 0 15 0 17 0 19
0 21 0 23 0 25 0 27 0 29
0 31 0 33 0 35 0 37 0 39
0 41 0 43 0 45 0 47 0 49

Now we move on to 3. Leave array[3] alone, and remove array[6], array[9], 
array[12], array[15], and so on. (Don't worry that we've already removed 
array[6] and array[12], because they still have slots in the array - we just 
changed them to 0, that's all.)

0  0 2  3 0  5 0  7 0  0
0 11 0 13 0  0 0 17 0 19
0  0 0 23 0 25 0  0 0 29
0 31 0  0 0 35 0 37 0  0
0 41 0 43 0  0 0 47 0 49

Now we move on to 4. Actually, this won't change the array, because we 
already caught everything relevant on the 2-pass. So now we move to 5. Leave 
5 alone, and remove every 5th element after that:

0  0 2  3 0 5 0  7 0  0
0 11 0 13 0 0 0 17 0 19
0  0 0 23 0 0 0  0 0 29
0 31 0  0 0 0 0 37 0  0
0 41 0 43 0 0 0 47 0 49

Now for 6, except that the 2-pass dealt with that as well, so we can move 
onto 7:

0  0 2  3 0 5 0  7 0  0
0 11 0 13 0 0 0 17 0 19
0  0 0 23 0 0 0  0 0 29
0 31 0  0 0 0 0 37 0  0
0 41 0 43 0 0 0 47 0  0

And now for the 8-pass - except that the 2-pass already dealt with that, so 
we're done. And what we now have is all the primes in the range 0-49.

Let's put that into C code - we'll need a couple more unsigned longs, so 
you'll need to define those. They are 'factor' and 'multiple'.

for(factor = 2; factor <= maxfactor; factor++)
{
  for(multiple = 2 * factor; multiple < size; multiple += factor)
  {
    array[multiple] = 0;
  }
}

And that will do the whole thing! The outer loop controls the factor we are 
considering, and the inner loop deals with the multiples: 2 * factor, 3 * 
factor, 4 * factor, and so on. We are now ready to print.

>   for(i = 0; i < size; i++)

We didn't need 'size', so we'll use 'range' here instead.

>   {
>     if(array[i] != 0)
> {
> printf("%d ", array[i]);

Since we're printing unsigned longs, we'll use %lu instead of %d.

> }

And that will be fine for the printing. Let's move on.

> int main(void)
> {
>   unsigned long ul;
>   int inputNum;
>   // Allocate as many ints as he asks for (hint: malloc).
>   char *buffer = malloc(sizeof(char) * SIZE);
>   
>   printf("Enter some number between 100 and 200: ");
>   
>   if (buffer == NULL) {
>     printf("Out of memory");
> return 1;
>   }
>   fgets(buffer, SIZE, stdin);
>   
>   ul = strtoul(buffer, NULL, 0);
>   printf("You entered %lu", ul);
>   printf("\n");
>   
>   if(ul < 100 OR ul > 200)
>   {
>     printf("You entered a wrong number!");
> return 0;
>   }

Okay, let's turn this into a function. Note that you don't need 125 bytes of 
storage to capture a three-digit number.

/* get a number in the range low to high - return 0 if the number is out of 
range. low must be >= 0, high must be >= low but we'll fix that if we have 
to */
unsigned long get_value_in_range(unsigned long low, unsigned long high)
{
  char inputstring[8] = "";
  unsigned long range = 0;
  if(low > high)
  {
    int t = low; low = high; high = t;
  }
  if(low > 0)
  {
    if(fgets(inputstring, sizeof inputstring, stdin) != NULL)
    {
      range = strtoul(inputstring, NULL, 10);
    }
    if(range < low || range > high)
    {
      fprintf(stderr, "Data missing or out of range.\n");
      range = 0;
    }
  }
  return range;
}

Now we can call this function as follows:

int main(void)
{
  unsigned long range = get_value_in_range(100, 200);
  if(range > 0)
  {
    sieve(range);
  }
  return 0;
}

Actually, sieve() does too much work. What we should really have in main() 
is:

1) get the range from the user (function call, like we have already)
2) create and initialise the array (again, this should be a function call)
3) do the sieve (another function call)
4) print the results (another function call)
5) destroy the array (another function call)
6) quit

> --------------------------------- the second solution

No doubt there was a difference in the second solution, but it passed me by. 
In any case, there's plenty of stuff above for you to get your teeth into.

> My question ?
> 
> How can I improve if someone input a string more then 125 chars as I
> defined at the beginning ?

You only need to capture three digits. If someone types in 125 chars, 
they're having a laugh. Print some instructions (e.g. "type a number in the 
range 100-200") and quit.

> Here i have allocated SIZE of 125 chars:
> 
> char *buffer = malloc(sizeof(char) * SIZE);
> 
> But what is going on if someone type for instance > 125
> fajkdsajfajfafdasflöfj
>  .... a string with more than 125.

It's an important question, because it raises the question of a "buffer 
overrun" - where you try to shove more data into an array than it can hold. 
This is a constant source of security issues in modern software, as I'm sure 
you're aware. Fortunately, fgets() WILL NOT ALLOW the user to overrun the 
buffer. If the line is too long to fit in your buffer, then AS LONG AS YOU 
TOLD THE TRUTH TO fgets() ABOUT YOUR BUFFER SIZE, fgets() will simply return 
when the buffer is full - to get the rest of the line, call fgets() again.

> 
> OK I now for realloc but I am not smart how to implement realloc in this
> situation ?

You don't need realloc yet. The realloc function is very, very powerful, but 
at this stage it would be like climbing into a racing car when you're still 
trying to remember which pedal is the brake. Leave realloc for a while.

-- 
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within

[toc] | [prev] | [next] | [standalone]


#55436 — iso646.h

FromNoob <root@127.0.0.1>
Date2014-12-25 18:26 +0100
Subjectiso646.h
Message-ID<m7hhcb$p81$1@dont-email.me>
In reply to#55388
Richard Heathfield wrote:

> Dexterr wrote:
> 
>> #define OR    ||
> 
> Better not to do that. Just learn that || means OR, because you'll see ||
> a LOT in other people's C programs.

I'm guessing you're not a big fan of C95's "alternative tokens"
from iso646.h ;-p

https://en.wikipedia.org/wiki/C_alternative_tokens

Regards.

[toc] | [prev] | [next] | [standalone]


#55441 — Re: iso646.h

FromGeoff <geoff@invalid.invalid>
Date2014-12-25 18:31 -0800
SubjectRe: iso646.h
Message-ID<8khp9ath8vl41v7s48uen7n0e1onu7a0im@4ax.com>
In reply to#55436
On Thu, 25 Dec 2014 18:26:55 +0100, Noob <root@127.0.0.1> wrote:

>Richard Heathfield wrote:
>
>> Dexterr wrote:
>> 
>>> #define OR    ||
>> 
>> Better not to do that. Just learn that || means OR, because you'll see ||
>> a LOT in other people's C programs.
>
>I'm guessing you're not a big fan of C95's "alternative tokens"
>from iso646.h ;-p
>
>https://en.wikipedia.org/wiki/C_alternative_tokens
>
>Regards.

OR isn't an ISO646 alternative spelling. The correct usage is
lower-case "or". If you're going to adopt a portion of the standard
then it's necessary to adopt it correctly. If you want to use the
alternatives then by all means include the standard header for them.

Besides, the usage of OR occurred exactly once in each version of the
OP's solution, it took more typing to write the macro than it did to
use || in both instances.

[toc] | [prev] | [next] | [standalone]


#55454 — Re: iso646.h

FromNoob <root@127.0.0.1>
Date2014-12-26 18:23 +0100
SubjectRe: iso646.h
Message-ID<m7k5h6$peq$1@dont-email.me>
In reply to#55441
Geoff wrote:

> OR isn't an ISO646 alternative spelling. The correct usage is
> lower-case "or". If you're going to adopt a portion of the standard
> then it's necessary to adopt it correctly.

Thank you for pointing that out, Captain Obvious!

> If you want to use the alternatives then by all means include the
> standard header for them.

If one objects to "OR", I was guessing they'd object to "or".

> Besides, the usage of OR occurred exactly once in each version of the
> OP's solution, it took more typing to write the macro than it did to
> use || in both instances.

I'm not sure why you think anyone would use the alternate spellings
to save typing...

[toc] | [prev] | [next] | [standalone]


Page 3 of 4 — ← Prev page 1 2 [3] 4  Next page →

Back to top | Article view | comp.lang.c


csiph-web