Is it possible to express the following statement in Delphi 7:
if x=1 or 2 or 4 then begin
.
.
.
end;
so the code within the if statement is executed if x equals 1, 2 or 4?
Thanks
Mark
There are several ways to do this..
Example 1:
if ((x = 1) or (x=2) or (x=4)) then
begin
...
end;
Example 2:
case x of 1,2,4:
begin
...
end;
>There are several ways to do this..
>
>Example 1:
>
>if ((x = 1) or (x=2) or (x=4)) then
the outer pair of parentheses are not needed. Another way, if the
numbers are small (< 256) is
if x in[ 1, 2, 4] then ...
---
Replace you know what by j to email
Try:
if (x=1) or (x=2) or (x=4) then begin
Your statement will always evaluate to true. I'll put some parenthesis to
make it more clear how your version works:
if (x=1) or (2) or (4) then begin
So the (2) and (4) will always evaluate to true, since false is defined as
0, which basicially makes your statement:
if (x=1) or true or true then begin
and obviously or-ing with true is always true. There should be a chapter
in the help (most likely in the pascal language section) about logical
expressions than might clear things up. It's unclear to me if your
confusion is due to being new to pascal syntax or new to programming in
general although I don't know any other languages off the top of my head
in which your version would work.
Then again everything else I've done today has been utter crap so I could
be wrong in which case someone will hopefully swiftly correct my folly.
Dave
>if (x=1) or (2) or (4) then begin
You can't do that..
You can't just leave numbers by themselves in brackets because the
compiler won't know what you're trying to do, and the code won't
compile.
>>if ((x = 1) or (x=2) or (x=4)) then
>
>the outer pair of parentheses are not needed.
I know...
Force of habit from working with long equations over the years..
Yep, you're right. This got me to playing around a bit. It seems that
this compiles:
if x=1 or 2 or 4 then begin
//foo
end;
but this does not:
if (x=1) or 2 or 4 then begin
//foo
end;
and the first one failed the check and //foo is never executed. So I'm
assuming that contrary to my first post what is happening is instead:
if x = (1 or 2 or 4) then begin
in the first case, and or is treated as a logical/bitwise rather than
boolean operator, so x is being compared to 7 (00000111). Have I finally
gotten it right or am I still confused?
As to the not compilable nonsense I posted above, can someone tell me if
((x == 1) || (2) || (4))
is a legal C expression, as I have neither a C compiler or K&R handy. I'd
like to think I was just thinking in a different language rather than I'm
losing it completely.
In defense of my sanity the suggestion I gave to the OP
if (x=1) or (x=2) or (x=4) then begin
was correct even if all the additional crap was hogwash.
Dave
Not in this particular case but in some more complex cases I feel the
extra parens can make things much more readable, so this could be easily
justified IMO as a reasonable matter of preference.
Dave
>Not in this particular case but in some more complex cases I feel the
>extra parens can make things much more readable
I agree - sometimes they do.
OR, AND etc. always have high priority
Nico
>Have I finally gotten it right or am I still confused?
Yep, you got it right.
>As to the not compilable nonsense I posted above, can someone tell me if
>
>((x == 1) || (2) || (4))
>
>is a legal C expression
Yes, it's legal nonsense in C, evaluating to TRUE ;-)
The Pascal transcription is:
(x = 1) or (2 <> 0) or (4 <> 0)
Obviously such an expression doesn't reveal any reasonable intention. It might
make sense when variable or macro names are used instead of constant values. In
this case a C compiler silently expands all names into (name != 0).
Some time ago I came across C expressions of the form
(SOMETHING + 0)
This will prevent some ill behaved C compiler (do you know of sane C compilers?
;-) from mocking when SOMETHING is not a defined symbol. The reason is that a
preprocessor will silently remove undefined names, so that the remaining "+0"
will evaluate to FALSE. That's why ANSI requires that the preprocessor has to
be incorporated into an C compiler, so that undefined symbols will evaluate to
zero instead of being removed from the code.
>In defense of my sanity...
Better you don't try to understand C thoroughly, such attempts are dangerous to
the mental health of sensible humans <gd&r>
DoDi
I got your first example to compile but not the second one. Let me give you
my real world example:
if
(piecetype='c1')or(piecetype='c4')or(piecetype='s1')or(piecetype='s3')
or(piecetype='t1')or(piecetype='t3')or(piecetype='t4')
then ottt:=true;
compiles ok, and if piecetype is equal to c1,c4,s1,s3,t1,t3 or t4 then ottt
is set to true.
case piecetype of 'c1','c4','s1','s3','t1','t3','t4' begin
ottt:=true;end;
Does not compile - I get error "Ordinal type required".
The case method looks a lot tidier and appears more "efficient" (maybe this
is crap) so I would like to get it working - any further clues?
Thanks
Mark
"John E. Doe" <nobody...@dontneedspam.com> wrote in message
news:lv66t0d32lsk9i0lo...@4ax.com...
A case statement is defined for ordinal types only. And a string is not an
ordinal type. A char is, so if you can distinguish between strings by
testing on the first char then you could do something like:
if myString<>'' then // to prevent error in next line when empty
case MyString[1] of
'a' : if MyString='a1' then do this else do that;
'd' : ...
end;
Tom
>Hi John
>
>I got your first example to compile but not the second one. Let me give you
>my real world example:
>
> if
>(piecetype='c1')or(piecetype='c4')or(piecetype='s1')or(piecetype='s3')
> or(piecetype='t1')or(piecetype='t3')or(piecetype='t4')
> then ottt:=true;
>
>compiles ok, and if piecetype is equal to c1,c4,s1,s3,t1,t3 or t4 then ottt
>is set to true.
>
> case piecetype of 'c1','c4','s1','s3','t1','t3','t4' begin
>ottt:=true;end;
>
>Does not compile - I get error "Ordinal type required".
>
>The case method looks a lot tidier and appears more "efficient" (maybe this
>is crap) so I would like to get it working - any further clues?
The Case method is, indeed, a much tidier way of coding
- well in my view anyway
The problem is that Case does not work with Strings
For the example shown,
ottt := pos('c1.c4.s1.s3.t1.t3.t4.', piecetype) <> 0
gives the result desired assuming that the possible values of piecetype
cannot match the pattern in any other way. This can generally be
arranged by using some delimiter (I've used period) that does not occur
in the substring being matched. But if piecetype = '1', a substring of
the embedded strings, pos matches erroneously. One way to handle this
is to force the match across two delimiters,
ottt := pos('.c1.c4.s1.s3.t1.t3.t4.', '.' + piecetype + '.') <> 0
or you may wish to write your own version of pos with an open array
constructor, e.g.,
ottt := mypos(['c1','c4','s1','s3','t1','t3','t4'], piecetype) <> 0
and mypos can be used in a case statement if you wish.
Another technique that may be appropriate is to create a TStringlist
initialized with the all the strings by the CommaText property and use
IndexOf to identify the string. This is an easy way to create a name
table for repeated use.
> case piecetype of 'c1','c4','s1','s3','t1','t3','t4' begin
>The case method looks a lot tidier and appears more "efficient" (maybe this
>is crap) so I would like to get it working - any further clues?
You can put your patterns into a (sorted) TStringList, search for the index of
your text there, and then use the index in a case statement.
DoDi
>For the example shown,
>
> ottt := pos('c1.c4.s1.s3.t1.t3.t4.', piecetype) <> 0
I'd suggest to make all substrings equal in length, so that the Pos can be
converted immediately into an piece index (Pos(...)-1 div Len).
>gives the result desired assuming that the possible values of piecetype
>cannot match the pattern in any other way.
This can be achieved by delimiting the search string:
iPiece := (Pos('.c1.c4.' {etc.}, '.' + piecetype + '.')-1) div 3;
For patterns of different size the patterns should be arranged by length
(shortest first), padded with delimiters to the common maximum pattern size.
'.1..x..c1.c4.'
DoDi
Good idea!