Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

for loop without statement 1

Status
Not open for further replies.

Strogian

Technical User
Nov 11, 2000
36
US
Okay, I'm having an odd problem. I'm trying to make a program to test out the ranges of all the datatypes (exercise 2-1 in The C Programming Language, 2nd ed.). Here's what I wrote (from memory, but I think it's exact):

#include <stdio.h>

int main()
{
short si;
int i;
long li;

for (si = -1; si < 0; --si)
;
++si; // overflow si back to negative
printf(&quot;short integer range is %d to &quot;, si);
for (si = 1; si > 0; ++si)
;
--si; // overflow si back to positive
printf(&quot;%d.\n&quot;, si);

for (li = -1; li < 0; --li)
;
++li;
printf(&quot;long integer range is %d to &quot;, li);
for (li = 1; li > 0; ++li)
;
--li;
printf(&quot;%d.\n&quot;, li);

return 0;
}


Now, that program would output this:
short integer range is 1 to 32767.
(I think it output something about long integers, but not sure)

BUT, if I changed my first for loop to this:
for (si = -1; si < 0; --si)
putchar('\0');

it would output this:
short integer range is -32768 to 32767.
And then it would just sit there, not doing anything. I tried putting the putchar('\0'); in the other loops, but it didn't seem to have any effect.

Anyone know why this happens, or how to fix it? Thanks.
 
Heh, are you serious? Wow, I guess I didn't realize longs were that big. (the short int loop completes just about instantly =)
 
o...k....

what's with this?
for (si = -1; si < 0; --si)
;
++si;

that loop doesn't do ANYTHING, the ; is ignored and the ++si; is executed as part of the for loop, making si = 0 exiting the loop. no offece but that's vey bad code man
first of all if you want a for loop to have no statements you MUST include the {} braces..

you would have to do this to get what you want:
for (si = -1; i < 0; si--) {}
printf(...

for (si = 1; i > 0; si++) {}
printf(...

or even better, just do this:
#include <limits.h>
#include <float.h>
#include <stdio.h>

int main () {
printf(&quot;Short Int: %d to %d\n&quot;, SHRT_MIN, SHRT_MAX);
printf(&quot;Long: %d to %d\n&quot;, LONG_MIN, LONG_MAX);
printf(&quot;Float: %f to %f\n&quot;, FLT_MIN, FLTMAX);
}

 
Hehe, the book actually told me to compute the ranges, (and also use the limits.h stuff). Also, are you SURE that you need the {}? In the book I'm reading, it said that the semicolon was a &quot;null statement,&quot; and it would work like that. And I did a search on it just now:
(by the way, I'm not writing commercial software here. I'm trying to learn exactly how the language works, so I'm not too worried about &quot;bad code&quot; just yet. =)
 
Oh, and now there seems to be another (probably related) weird problem. Here's the newest code I've written:

#include <stdio.h>

/* prints the ranges of char, short int, int, long int, and various floats */
int main()
{
signed short int ssi;
signed int si;
signed long int sli;
unsigned short int usi;
unsigned int ui;
unsigned long int uli;
signed char sc;
unsigned char uc;

// find ranges for ssi
for (ssi = 0; ssi <= 0; --ssi)
;
++ssi;
printf(&quot;signed short int range is from %d to &quot;, ssi);
--ssi;
printf(&quot;%d\n&quot;, ssi);

// find ranges for si
for (si = 0; si <= 0; --si)
;
++si;
printf(&quot;signed int range is from %d to &quot;, si);
--si;
printf(&quot;%d\n&quot;, si);

// find ranges for sli
for (sli = 0; sli <= 0; --sli)
;
++sli;
printf(&quot;signed long int range is from %d to &quot;, sli);
--sli;
printf(&quot;%d\n&quot;, sli);

// find ranges for usi
for (usi = 0; usi <= 0; --usi)
;
++usi;
printf(&quot;unsigned short int range is from %d to &quot;, usi);
--usi;
printf(&quot;%d\n&quot;, usi);

// find ranges for ui
for (ui = 0; ui <= 0; --ui)
;
++ui;
printf(&quot;unsigned int range is from %d to &quot;, ui);
--ui;
printf(&quot;%d\n&quot;, ui);

// find ranges for uli
for (uli = 0; uli <= 0; --uli)
;
++uli;
printf(&quot;unsigned long int range is from %d to &quot;, uli);
--uli;
printf(&quot;%d\n&quot;, uli);

// find ranges for sc
for (sc = 0; sc <= 0; --sc)
;
++sc;
printf(&quot;signed char range is from %d to &quot;, sc);
--sc;
printf(&quot;%d\n&quot;, sc);

// find ranges for uc
for (uc = 0; uc <= 0; --uc)
;
++uc;
printf(&quot;unsigned char range is from %d to &quot;, uc);
--uc;
printf(&quot;%d\n&quot;, uc);
}


Now, everything works just fine, except when I try to find the ranges for uli and ui. (unsigned long int and unsigned int) When I try to print the ranges for them, it says that it's from like -1 up to something else. Is it even possible to have an unsigned number be negative?
 
Just tested it and the problem output is:

unsigned long int range is from 0 to -1
unsigned int range is from 0 to -1
 
First, a for loop can have a null statement, and it can be terminated with a
semicolon, so that

for (si = -1; si < 0; --si)
;

is legal, and basically executes --si until it is no longer true that si < 0. It is
good style here to make the fact that this is a loop with empty body readily
apparent, such as by putting the semicolon on the next line. Braces are
not needed.

(There are, in fact, better ways to find ranges. Don't do this in production code.)

Second, if you're going to print unsigned integers in meaningful ways, you need
to tell printf that they're unsigned. A format like &quot;%d&quot; means signed. Try
&quot;%ud&quot; for unsigned int or &quot;%ul&quot; for unsigned long.

And use &quot;%l&quot; and &quot;%ul&quot; for printing longs and unsigned longs, since those are
the proper format characters. Using the wrong one may work for a long time,
and then bite you suddenly when you've gotten out of the habit of checking.
 
Ohhhhhhhh okay! (I was actually starting to wonder if I needed to do something like that) Thank you!
 
zfx is wrong. Using a semi-colon creates a loop with a null statement just as you claim. Don't know where he/she got this idea. This is NOT bad programming style--it is used all the time and offsetting the semi-colon on the next line like you've done is perfect. It makes it clear what you are doing (as opposed to putting the semi-colon on the same line as the statement, which is hard to see).

Regards,

Charles
 
I agree that it is bad programming style, the ; just looks like a typo there, it's not very structured, i'd say that the { } method is better, it's more apparent that it's an empty loop. MOstly a matter of opinion mind you, but i'm oldschool dammit! :)

Aside from look, {} is easier for the compiler to parse, it is less ambiguous. It minimizes decision making. Depends just HOW efficient you want to be.
 
xGrob,

K&R use this style extensively in their book (as I recall) and many would consider this the bible of modern C programming. As far as the rest goes, just how is it easier for the compiler to parse? How does it minimize decision making? In my opinion it is perfectly clear and many (including my C instructors) would agree.

In any event, you say tomato....
 
There is a MUCH easier way if you dont mind using bitwise operators

for a short it would look like this

short sh;
sh = 1<<(sizeof(short))*8-1;
printf(&quot;short integer range is %d to %d&quot;, sh,~sh);

no need for the big loops. Also... this could be a simple macro as well.

Matt


 
meadandale,
you take an advanced compilers program, learn how to write a compiler w/code optimization and you'll know what i'm taking about ;-)

No, not tomato! Unpleasant RedFruit :p

---

Zyrenthian,
Impressive, I never even thought of that! Fast too.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top