Velocity Reviews > Is there a shorter solution ?

# Is there a shorter solution ?

HumbleWorker
Guest
Posts: n/a

 08-10-2011
On Aug 10, 10:17*pm, (E-Mail Removed) (Ben Pfaff) wrote:
> HumbleWorker <(E-Mail Removed)> writes:
> > On Aug 10, 9:57*pm, James Kuyper <(E-Mail Removed)> wrote:
> >> On 08/10/2011 12:51 PM, HumbleWorker wrote:

>
> >> > On Aug 10, 9:43 pm, tom st denis <(E-Mail Removed)> wrote:
> >> >> On Aug 6, 1:25 pm, HumbleWorker <(E-Mail Removed)> wrote:

>
> >> >> int main()
> >> >> {
> >> >> * *char *k = "abababababawhatever";
> >> >> * *while(*k) numA += *k++ == 'a';
> >> >> * *printf("Number of a's = %d\n", numA);
> >> >> * *return 0;

>
> >> >> }

>
> >> >>

>
> >> > Thanks ! Is it guaranteed that a logical true returns 1 ?

>
> >> All logical expressions in C indicate truth by having a result of 1.

>
> > As we have know that any non-zero int evaluates to logical true, so
> > vice-versa doesn't a compiler have the freedom to return anything non-
> > zero ? Is there some standard that enforces that it should be 1 only ?

>
> Yes, the C standard says so, e.g.:
>
> * * *6.5.13 Logical AND operator
>
> * * *The && operator shall yield 1 if both of its operands
> * * *compare unequal to 0; otherwise, it yields 0. The result has
> * * *type int.
>
> ...
>

That's nice. I learnt a new thing today !

James Kuyper
Guest
Posts: n/a

 08-10-2011
On 08/10/2011 01:13 PM, HumbleWorker wrote:
> On Aug 10, 9:57 pm, James Kuyper <(E-Mail Removed)> wrote:
>> On 08/10/2011 12:51 PM, HumbleWorker wrote:
>>
>>> On Aug 10, 9:43 pm, tom st denis <(E-Mail Removed)> wrote:
>>>> On Aug 6, 1:25 pm, HumbleWorker <(E-Mail Removed)> wrote:

>>
>>>> int main()
>>>> {
>>>> char *k = "abababababawhatever";
>>>> while(*k) numA += *k++ == 'a';
>>>> printf("Number of a's = %d\n", numA);
>>>> return 0;

>>
>>>> }

>>
>>>>

>>
>>> Thanks ! Is it guaranteed that a logical true returns 1 ?

>>
>> All logical expressions in C indicate truth by having a result of 1.

>
> As we have know that any non-zero int evaluates to logical true, so
> vice-versa doesn't a compiler have the freedom to return anything non-
> zero ? Is there some standard that enforces that it should be 1 only ?

It's not just "some" standard, it's specifically the C standard (ISO/IEC
9899:1999). There's no enforcement, just a mandate. It does indeed
mandate that the result is 1 for each logical expression. Citations:
6.5.3p5: !
6.5.8p6: < > <= >=
6.5.9p3: == !=
6.5.13p3: &&
6.5.14p3: ||

As shown above, this mandate allows logical expressions to be used in
numerical contexts in ways that could not be guaranteed to work if the
standard gave implementations more freedom in this matter.

Another common use of this feature is in the context of the comparison
functions used by the qsort() and bsearch() standard library functions;
when comparing ordinary numerical types, the body of that function can
be written quite simply as

return (*left > *right) - (*left < *right);

It's debatable whether this feature was a great idea; but it's been a
part of C from the very beginning, and a lot of existing code relies
upon this feature.

HumbleWorker
Guest
Posts: n/a

 08-10-2011
On Aug 10, 9:43*pm, tom st denis <(E-Mail Removed)> wrote:
> On Aug 6, 1:25*pm, HumbleWorker <(E-Mail Removed)> wrote:
>
> > Count the number of a in cX below

>
> > #include <stdio.h>

>
> > int main()
> > {
> > * * * * char cX[] = "ababcabcdabcaba", * k = cX;
> > * * * * int numA = 0;
> > * * * * while (*k && ('a' == *k++ ? ++numA : 1));
> > * * * * printf ("Number of a's = %u\n", numA);
> > * * * * return 0;
> > }

>
> Um shorter eh ...
>
> int numA;
> int main()
> {
> * *char *k = "abababababawhatever";
> * *while(*k) numA += *k++ == 'a';
> * *printf("Number of a's = %d\n", numA);
> * *return 0;
>
> }
>
>

I am curious about one more thing. What would be the considerations of
efficiency when we use a for loop like this instead of the while loop
above ?

int main()
{
int numA = 0;
char* k = "abababababawhatever";
for (; *k; numA += *k++ == 'a');
printf("Number of a's = %d\n", numA);
return 0;
}

tom st denis
Guest
Posts: n/a

 08-10-2011
On Aug 10, 1:29*pm, HumbleWorker <(E-Mail Removed)> wrote:
> On Aug 10, 10:17*pm, (E-Mail Removed) (Ben Pfaff) wrote:
>
>
>
>
>
>
>
> > HumbleWorker <(E-Mail Removed)> writes:
> > > On Aug 10, 9:57*pm, James Kuyper <(E-Mail Removed)> wrote:
> > >> On 08/10/2011 12:51 PM, HumbleWorker wrote:

>
> > >> > On Aug 10, 9:43 pm, tom st denis <(E-Mail Removed)> wrote:
> > >> >> On Aug 6, 1:25 pm, HumbleWorker <(E-Mail Removed)> wrote:

>
> > >> >> int main()
> > >> >> {
> > >> >> * *char *k = "abababababawhatever";
> > >> >> * *while(*k) numA += *k++ == 'a';
> > >> >> * *printf("Number of a's = %d\n", numA);
> > >> >> * *return 0;

>
> > >> >> }

>
> > >> >>

>
> > >> > Thanks ! Is it guaranteed that a logical true returns 1 ?

>
> > >> All logical expressions in C indicate truth by having a result of 1.

>
> > > As we have know that any non-zero int evaluates to logical true, so
> > > vice-versa doesn't a compiler have the freedom to return anything non-
> > > zero ? Is there some standard that enforces that it should be 1 only ?

>
> > Yes, the C standard says so, e.g.:

>
> > * * *6.5.13 Logical AND operator

>
> > * * *The && operator shall yield 1 if both of its operands
> > * * *compare unequal to 0; otherwise, it yields 0. The result has
> > * * *type int.

>
> > ...

>
> That's nice. I learnt a new thing today !

That being said, if you wrote code like "a += b == 4;" for a project I
was working on I might have words with you. But yes, they eval to 1
or 0.

The ideal way to write that is something like

if (b == 4) ++a;

or if you must ...

a += (b == 4) ? 1 : 0;

Though it's redundant it's a heck of a lot quicker to read... I
suppose

a += (b == 4);

With the brackets is ok to read ... still not my preferred style and
most don't write like that either.

Tom

Keith Thompson
Guest
Posts: n/a

 08-10-2011
James Kuyper <(E-Mail Removed)> writes:
> On 08/10/2011 12:51 PM, HumbleWorker wrote:
>> On Aug 10, 9:43 pm, tom st denis <(E-Mail Removed)> wrote:
>>> On Aug 6, 1:25 pm, HumbleWorker <(E-Mail Removed)> wrote:
>>>
>>> int main()
>>> {
>>> char *k = "abababababawhatever";
>>> while(*k) numA += *k++ == 'a';
>>> printf("Number of a's = %d\n", numA);
>>> return 0;
>>>
>>> }
>>>
>>>

>>
>> Thanks ! Is it guaranteed that a logical true returns 1 ?

>
> All logical expressions in C indicate truth by having a result of 1.

For certain meanings of the phrase "logical expressions".

The <, <=, >, >=, ==, !=, !, &&, and || operators are all defined to
yield either 0 or 1. I believe that's an exhaustive list.

On the other hand, of course, a scalar expression used as a condition is
treated as false if it compares equal to 0, true otherwise.

The is*() functions declared in <ctype.h> are only defined to return 0
for false, and some unspecified non-zero value for true. The same can
potentially apply to any expression used as a condition, unless its
top-level operator is one of the 9 listed above *or* it's specifically
written to yield only 0 or 1.

So:

if (x < y) count ++; // ok
count += (x < y); // ok and equivalent to the above

if (isdigit(c)) count ++; // ok
count += !!isdigit(c); // ok and equivalent to the above
count += isdigit(c); // legal but *not* equivalent to the above

#define FALSE 0
#define TRUE 1 // useful if you don't have <stdbool.h>
int cond = isdigit(c);
if (cond == FALSE) ...; // works, but unnecessarily verbose
if (cond == TRUE) ...; // dangerous, fails if cond < 0 or cond > 1
if (cond) ...; // the best way

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

James Kuyper
Guest
Posts: n/a

 08-10-2011
On 08/10/2011 02:49 PM, Keith Thompson wrote:
> James Kuyper <(E-Mail Removed)> writes:

....
>> All logical expressions in C indicate truth by having a result of 1.

>
> For certain meanings of the phrase "logical expressions".
>
> The <, <=, >, >=, ==, !=, !, &&, and || operators are all defined to
> yield either 0 or 1. I believe that's an exhaustive list.

That's the meaning that I intended for "logical expressions".

> On the other hand, of course, a scalar expression used as a condition is
> treated as false if it compares equal to 0, true otherwise.

And that is not. I'd refer to those as conditions, not logical
expressions. It's a distinction between what the value of an expression
means (0: false, 1: true) and how the value of the expression is used
(0: false, non-0: true).

In a very different but somewhat C-like language, it would be
philosophically cleaner to have logical expressions give results of
boolean type; conditions constrained to take values of boolean type; and
no conversions (neither implicit nor explicit) to or from the boolean
type. The equivalent of C's implicit conversions could be done by
non-boolean_value != 0
boolean_value ? 1 : 0
It would break way too much existing code to make any such change to C
itself, of course.

James Kuyper
Guest
Posts: n/a

 08-10-2011
On 08/10/2011 02:26 PM, HumbleWorker wrote:
> On Aug 10, 9:43 pm, tom st denis <(E-Mail Removed)> wrote:

....
>> int numA;
>> int main()
>> {
>> char *k = "abababababawhatever";
>> while(*k) numA += *k++ == 'a';
>> printf("Number of a's = %d\n", numA);
>> return 0;
>>
>> }
>>
>>

>
> I am curious about one more thing. What would be the considerations of
> efficiency when we use a for loop like this instead of the while loop
> above ?
>
> int main()
> {
> int numA = 0;
> char* k = "abababababawhatever";
> for (; *k; numA += *k++ == 'a');
> printf("Number of a's = %d\n", numA);
> return 0;
> }

The while-for conversion has no efficiency implications. Those parts of
the two programs are precisely equivalent, and if you're using a
compiler that isn't smart enough to recognize that fact and optimize
them the same way, you've got much bigger problems than simple

Keith Thompson
Guest
Posts: n/a

 08-10-2011
James Kuyper <(E-Mail Removed)> writes:
> On 08/10/2011 02:49 PM, Keith Thompson wrote:
>> James Kuyper <(E-Mail Removed)> writes:

> ...
>>> All logical expressions in C indicate truth by having a result of 1.

>>
>> For certain meanings of the phrase "logical expressions".
>>
>> The <, <=, >, >=, ==, !=, !, &&, and || operators are all defined to
>> yield either 0 or 1. I believe that's an exhaustive list.

>
> That's the meaning that I intended for "logical expressions".

I assumed so, but it's not clear from the phrase itself just what it
means; someone else might easily think of ``isdigit(c)'' as a logical
expression. (The standard doesn't define the term.)

>> On the other hand, of course, a scalar expression used as a condition is
>> treated as false if it compares equal to 0, true otherwise.

>
> And that is not. I'd refer to those as conditions, not logical
> expressions. It's a distinction between what the value of an expression
> means (0: false, 1: true) and how the value of the expression is used
> (0: false, non-0: true).

That's a useful distinction, and it would be nice to have universally
agreed terms make that distinction.

> In a very different but somewhat C-like language, it would be
> philosophically cleaner to have logical expressions give results of
> boolean type; conditions constrained to take values of boolean type; and
> no conversions (neither implicit nor explicit) to or from the boolean
> type. The equivalent of C's implicit conversions could be done by
> non-boolean_value != 0
> boolean_value ? 1 : 0
> It would break way too much existing code to make any such change to C
> itself, of course.

Yes, and there are plenty of languages like that, though most of them
aren't particularly C-like (Pascal, Ada). To avoid triggering a
language war, I'll just mention that I do personally prefer one approach
over the other without saying which.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Seebs
Guest
Posts: n/a

 08-11-2011
On 2011-08-10, HumbleWorker <(E-Mail Removed)> wrote:
> As we have know that any non-zero int evaluates to logical true, so
> vice-versa doesn't a compiler have the freedom to return anything non-
> zero?

No.

> Is there some standard that enforces that it should be 1 only ?

Yes. It is called the language specification. The logical operators are
defined as yielding 0 or 1.

-s
--
Copyright 2011, all wrongs reversed. Peter Seebach / (E-Mail Removed)
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
I am not speaking for my employer, although they do rent some of my opinions.

J. J. Farrell
Guest
Posts: n/a

 08-11-2011
tom st denis wrote:
> On Aug 10, 1:29 pm, HumbleWorker <(E-Mail Removed)> wrote:
>>>>>> On Aug 10, 9:43 pm, tom st denis <(E-Mail Removed)> wrote:
>>>>>>>
>>>>>>> while(*k) numA += *k++ == 'a';

>
> That being said, if you wrote code like "a += b == 4;" for a project I
> was working on I might have words with you. But yes, they eval to 1
> or 0.
>
> The ideal way to write that is something like
>
> if (b == 4) ++a;
>
> or if you must ...
>
> a += (b == 4) ? 1 : 0;
>
> Though it's redundant it's a heck of a lot quicker to read...

Quicker to read? The exact opposite for me - this one is about the worst
of all the possibilities you give. I find the one below much clearer and
quicker and easier to read reliably than the one above. When looking at
the above I'd tend to assume the conditional expression was doing
something useful, requiring me to read it carefully to be sure of what
it did - and then check again even more carefully when the first reading
said it didn't do anything useful.

> I suppose
>
> a += (b == 4);
>
> With the brackets is ok to read ... still not my preferred style and
> most don't write like that either.
>
> Tom