From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: 103376,edafb2ab7e8839bc X-Google-Attributes: gid103376,public X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news2.google.com!postnews.google.com!i42g2000cwa.googlegroups.com!not-for-mail From: "Adam Beneschan" Newsgroups: comp.lang.ada Subject: Re: Char type verification Date: 15 Nov 2006 15:36:23 -0800 Organization: http://groups.google.com Message-ID: <1163633783.126843.241410@i42g2000cwa.googlegroups.com> References: <1163628033.606530.190550@i42g2000cwa.googlegroups.com> NNTP-Posting-Host: 66.126.103.122 Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" X-Trace: posting.google.com 1163633788 19525 127.0.0.1 (15 Nov 2006 23:36:28 GMT) X-Complaints-To: groups-abuse@google.com NNTP-Posting-Date: Wed, 15 Nov 2006 23:36:28 +0000 (UTC) User-Agent: G2/1.0 X-HTTP-UserAgent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.7.12) Gecko/20050922 Fedora/1.7.12-1.3.1,gzip(gfe),gzip(gfe) Complaints-To: groups-abuse@google.com Injection-Info: i42g2000cwa.googlegroups.com; posting-host=66.126.103.122; posting-account=cw1zeQwAAABOY2vF_g6V_9cdsyY_wV9w Xref: g2news2.google.com comp.lang.ada:7484 Date: 2006-11-15T15:36:23-08:00 List-Id: KE wrote: > Hi > > Assume that I have the following C code: > > #include > > #define uchar unsigned char > > > static uchar UCASE[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; > > int _isupper(uchar c) > { > return (c==UCASE[(c%'A')%26]); > } > > int main(int argc, char *argv[]) > { > uchar c = (uchar) *argv[1]; > printf("_isupper('%c')? = %d\n",c,_isupper(c)); > > return 0; > } > > (I don't claim this is terribly safe, localizable, transparent, etc. > It's just practical within the confines of ASCII, and efficient since > it uses a table-lookup technique.) Uhhhmmm. It sounds like you've heard somewhere that doing a table lookup always makes things efficient. Sorry, no. There are cases where table lookups are superior to other ways of doing things. This is not one of them. If you really wanted a table lookup here, it would have been far better to set up an array indexed by all 256 characters whose values were 1 or 0 (1 for the upper-case letters and 0 for the rest), and just loaded the result from that array. Even then, that would be at best only marginally more efficient than c>='A' && c<='Z', and probably less efficient on many processors. The way you've coded it is certainly less efficient, plus it's really hard to figure out what it does. I had to stare at it for a minute to convince myself it was correct. > Now, how would you convert this to Ada. As you can imagine, Ada > complains loudly with my fast and loose conversions of data types (char > to uchar, that to int, etc.) > > (This is not some class assignment or anything. I'm a 40-something > coder new to Ada, and I'd like to see in how many different ways you > gentlemen will attempt to solve this.) > > NB: The question's intent is, what would be the safest *and* the most > transparent way to marshall the details of this in Ada-95? The first bit of rethinking you need to do: In C, a character is just a kind of integer; "signed char" is an integer that's normally in the range -128..127, and "unsigned char" is an integer in the range 0..255, and "char" can be either one if I recall correctly. Also, 'A' is an integer that means exactly the same thing as 65. In Ada, the standard Character type is not an integer type; it's an "enumeration" type. The possible values of an object of an enumeration type come from a list---in this case, a list of characters---but the values are not integers. To convert to and from integers, use the 'Pos and 'Val attributes. If C is a Character and N is an Integer, N := Character'Pos(C); C := Character'Val(N); will do the conversions you want. Georg pointed out a couple ways to implement "isupper". I've already mentioned that your implementation seems poor. But assuming you wanted to implement it in Ada exactly the same way as you did above, try something like: function IsUpper (C : Character) return Boolean is UCASE : constant String := "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; begin return C = UCASE (UCASE'First + (Character'Pos(C) mod Character'Pos('A')) mod 26); end IsUpper; Note that arrays do not automatically begin at offset 0 (and String types cannot begin at offset 0), which is why UCASE'First is added to the index. Note also that this function returns a Boolean, not an Integer---Boolean is another enumeration type with values (FALSE, TRUE). To output this, you can use Boolean'Image(IsUpper(C)), which outputs either FALSE or TRUE which is a lot nicer than 1 or 0 in my opinion. This isn't a complete translation of your program---I haven't gone into how to get at the command-line arguments---but hopefully it will get you started. -- Adam