% inside if(), confused (help)

S

sathyashrayan

Please look at the following code:


static char *text[] = {"th", "st", "nd", "rd"};
char *ordinal_text(int number)
{

if (((number %= 100) > 9 && number < 20) || (number %= 10) > 3)
number = 0;
return text[number];
}

#include <stdio.h>
int main(void)
{
int i;
for (i = 0; i < 26; ++i)
printf("%d%s\n", i, ordinal_text(i));
return 0;
}


According the code above the out put is as follows:

0th
1st
2nd
3rd
4th
5th
6th
7th
8th
9th
10th
11th
12th
13th
14th
15th
16th
17th
18th
19th
20th
21st
22nd
23rd
24th
25th

Which is exactly what is expected.But don't understand output.How come
the output occurred as expected.

if (((number %= 100) > 9 && number < 20) || (number %= 10) > 3)

The number should be less than 20 but greater than 9. But how each
element in the iteration of array prints accordingly. Can any one help
me to understand this simple program? Thanks.

--
"combination is the heart of chess"

A.Alekhine

Mail to:
sathyashrayan AT gmail DOT com
 
P

Puneet

I think you are getting confused here. This code is ok. In this code
there is two conditions.

first is (number %= 100) > 9 && number < 20
-- in this condition they are caring for numbers like 11,12, 13 ...
and second condition ofcourse necessary .

I think you got the answer .

-- Puneet
 
W

Walter Roberson

: if (((number %= 100) > 9 && number < 20) || (number %= 10) > 3)
: number = 0;

That code appears to violate ANSI standards. X3.159-1989 section 3.3:

Between the previous and next sequence points an object shall
have its stored value modified at most once by the evaluation
of an expression. Furthermore, the prior value shall be
accessed only to determined teh avlaue to be stored.

and according to 3.6, the expression controlling an 'if' statement
is a "full expression" that has a sequence point after it, but
the note attached to section 3.3 makes it fairly clear by example
that within a full expression there aren't any sequence points.
 
N

Niranjan Tulpule

sathyashrayan said:
Please look at the following code:


static char *text[] = {"th", "st", "nd", "rd"};
char *ordinal_text(int number)
{

if (((number %= 100) > 9 && number < 20) || (number %= 10) > 3)
number = 0;
return text[number];
}

#include <stdio.h>
int main(void)
{
int i;
for (i = 0; i < 26; ++i)
printf("%d%s\n", i, ordinal_text(i));
return 0;
}


According the code above the out put is as follows:

0th
1st
2nd
3rd
4th
5th
6th
7th
8th
9th
10th
11th
12th
13th
14th
15th
16th
17th
18th
19th
20th
21st
22nd
23rd
24th
25th

Which is exactly what is expected.But don't understand output.How come
the output occurred as expected.

if (((number %= 100) > 9 && number < 20) || (number %= 10) > 3)

The number should be less than 20 but greater than 9. But how each
element in the iteration of array prints accordingly. Can any one help
me to understand this simple program? Thanks.

--
"combination is the heart of chess"

A.Alekhine

Mail to:
sathyashrayan AT gmail DOT com


if (((number %= 100) > 9 && number < 20) || (number %= 10) > 3)
number = 0;

The 'if' condition checks if the number qualifies for a "th" suffix.
The numbers which satify are 4 (fourth, fourteenth, twenty-fourth etc)
to 9 (ninth) in every block of 10 numbers. Numbers with last digits 1,
2 and three have special suffixes. However numbers from 11 (eleventh)
to 19 (nineteenth) are an exception to this rule.

So the 'if' loops checks whether:
1. Is the units-digit greater than 3 (if so attach a 'th' prefix by
setting number = 0.)
2. OR Is the units-digit between 9 and 20 (again chose the 'th' prefix)
3. If both above conditions are not true, then suffix should be the one
indicated by result of (number = number %10).

For Example:
If you pass 21, then first two conditions are not satisfied. But while
executing the 'if' loop number = number % 10 got executed, which
changed the value of number to 1. So the method returns 1. The printf
simply appends number with the text in the array at location base +
(sizeof(element) + 1) which is 'st'. Therefore '21st' is printed.

Does this help?

- EnTee
 
S

sathyashrayan

Niranjan said:
sathyashrayan said:
Please look at the following code:


static char *text[] = {"th", "st", "nd", "rd"};
char *ordinal_text(int number)
{

if (((number %= 100) > 9 && number < 20) || (number %= 10) >
3)

number = 0;
return text[number];
}

#include <stdio.h>
int main(void)
{
int i;
for (i = 0; i < 26; ++i)
printf("%d%s\n", i, ordinal_text(i));
return 0;
}


According the code above the out put is as follows:

0th
1st
2nd
3rd
4th
5th
6th
7th
8th
9th
10th
11th
12th
13th
14th
15th
16th
17th
18th
19th
20th
21st
22nd
23rd
24th
25th

Which is exactly what is expected.But don't understand output.How
come

the output occurred as expected.

if (((number %= 100) > 9 && number < 20) || (number %= 10) > 3)

The number should be less than 20 but greater than 9. But how
each

element in the iteration of array prints accordingly. Can any one
help

me to understand this simple program? Thanks.

--
"combination is the heart of chess"

A.Alekhine

Mail to:
sathyashrayan AT gmail DOT com



if (((number %= 100) > 9 && number < 20) || (number %= 10) > 3)
number = 0;

The 'if' condition checks if the number qualifies for a "th" suffix.
The numbers which satify are 4 (fourth, fourteenth, twenty-fourth etc)
to 9 (ninth) in every block of 10 numbers. Numbers with last digits 1,
2 and three have special suffixes. However numbers from 11 (eleventh)
to 19 (nineteenth) are an exception to this rule.

So the 'if' loops checks whether:
1. Is the units-digit greater than 3 (if so attach a 'th' prefix by
setting number = 0.)
2. OR Is the units-digit between 9 and 20 (again chose the 'th' prefix)
3. If both above conditions are not true, then suffix should be the one
indicated by result of (number = number %10).

For Example:
If you pass 21, then first two conditions are not satisfied. But while
executing the 'if' loop number = number % 10 got executed, which
changed the value of number to 1. So the method returns 1. The printf
simply appends number with the text in the array at location base +
(sizeof(element) + 1) which is 'st'. Therefore '21st' is printed.

Does this help?

Yes a lot. Thanks.

--
"combination is the heart of chess"

A.Alekhine

Mail to:
sathyashrayan AT gmail DOT com
 
S

sathyashrayan

Walter said:
: if (((number %= 100) > 9 && number < 20) || (number %= 10) > 3)
: number = 0;

That code appears to violate ANSI standards. X3.159-1989 section 3.3:

Between the previous and next sequence points an object shall
have its stored value modified at most once by the evaluation
of an expression. Furthermore, the prior value shall be
accessed only to determined teh avlaue to be stored.

and according to 3.6, the expression controlling an 'if' statement
is a "full expression" that has a sequence point after it, but
the note attached to section 3.3 makes it fairly clear by example
that within a full expression there aren't any sequence points.

I am not a expert in C but I feel that in the above there is no sequence
point and UB does not occur since the compound assignment does not
modify the value twice. If I say number %= number there is a sequence
point involved. May be I am wrong. Experts will help.

--
"combination is the heart of chess"

A.Alekhine

Mail to:
sathyashrayan AT gmail DOT com
 
C

Chris Dollin

Walter said:
: if (((number %= 100) > 9 && number < 20) || (number %= 10) > 3)
: number = 0;

That code appears to violate ANSI standards. X3.159-1989 section 3.3:

Between the previous and next sequence points an object shall
have its stored value modified at most once by the evaluation
of an expression. Furthermore, the prior value shall be
accessed only to determined teh avlaue to be stored.

and according to 3.6, the expression controlling an 'if' statement
is a "full expression" that has a sequence point after it, but
the note attached to section 3.3 makes it fairly clear by example
that within a full expression there aren't any sequence points.

&& and || both introduce sequence points, as does the ? in a ?:, and
the comma in a comma-expression.
 
M

Michael Mair

Walter said:
: if (((number %= 100) > 9 && number < 20) || (number %= 10) > 3)
: number = 0;

That code appears to violate ANSI standards. X3.159-1989 section 3.3:

It does not.
Between the previous and next sequence points an object shall
have its stored value modified at most once by the evaluation
of an expression. Furthermore, the prior value shall be
accessed only to determined teh avlaue to be stored.

There is a sequencepoint after && and after ||.
and according to 3.6, the expression controlling an 'if' statement
is a "full expression" that has a sequence point after it, but
the note attached to section 3.3 makes it fairly clear by example
that within a full expression there aren't any sequence points.

Is this note/example normative? Probably not. The C99 standard
only states

6.8
"4
A full expression is an expression that is not part of another
expression or of a declarator.
Each of the following is a full expression: an initializer; the
expression in an expression statement; the controlling expression of
a selection statement (if or switch); the controlling expression of a
while or do statement; each of the (optional) expressions of
a for statement; the (optional) expression in a return statement. The
end of a full expression is a sequence point."

And with if, I find "if ( expression ) statement".


Cheers
Michael
 
C

Chris Dollin

sathyashrayan wrote:
I am not a expert in C but I feel that in the above there is no sequence
point and UB does not occur since the compound assignment does not
modify the value twice. If I say number %= number there is a sequence
point involved. May be I am wrong. Experts will help.

There is no sequence point in the expression E1 %= E2.

(Unless E1 or E2 have sequence points.)
 
L

Lawrence Kirby

It does not.


There is a sequencepoint after && and after ||.

There is a sequence point after the evaluation of the *first operand* of
&& and ||, as well as ?: and , (when it appears as the comma operator),
and in some other circumstances.

Lawrence
 
L

Lawrence Kirby

....

I am not a expert in C but I feel that in the above there is no sequence
point and UB does not occur since the compound assignment does not
modify the value twice. If I say number %= number there is a sequence
point involved. May be I am wrong. Experts will help.

There are sequence points defined by the && and || operators. If there
weren't the behaviour would be undefined because there are 2 %= operators
in the expression both modifying number, as well as a separate access to
number.

Lawrence
 
M

Michael Mair

Lawrence said:
There is a sequence point after the evaluation of the *first operand* of
&& and ||, as well as ?: and , (when it appears as the comma operator),
and in some other circumstances.

Thanks for correcting my sloppy way of expressing it.
Next time I will just refer to FAQ 3.8 and 3.9...


-Michael
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,810
Latest member
Kassie0918

Latest Threads

Top