Path: csiph.com!eternal-september.org!feeder.eternal-september.org!reader01.eternal-september.org!.POSTED!not-for-mail From: Keith Thompson Newsgroups: comp.lang.c Subject: Re: max of 3 Date: Sat, 22 Aug 2020 16:41:57 -0700 Organization: None to speak of Lines: 221 Message-ID: <87o8n25jui.fsf@nosuchdomain.example.com> References: <87d03j57lg.fsf@bsb.me.uk> <4e0bd5c4-6cf2-4ed2-993b-9df9801296ean@googlegroups.com> <875z9a701d.fsf@nosuchdomain.example.com> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Injection-Info: reader02.eternal-september.org; posting-host="44a91dfa258afe1f3bd0fee7c04ac4ad"; logging-data="26456"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+dB3gOorpE4RIXT5WJKlXo" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux) Cancel-Lock: sha1:zbmqOLZTokYv6pgpmh/C1/6PW5k= sha1:PlDtOZdeFa/TL8syfhvNEzFMfxA= Xref: csiph.com comp.lang.c:153916 Keith Thompson writes: > axel porin writes: >> Le samedi 22 août 2020 à 12:25:07 UTC+2, Bart a écrit : >>> On 22/08/2020 10:54, Ben Bacarisse wrote: >>> > axel porin writes: >>> >>> >> int main(){ >>> >> int a=2,b=-4,c=6; >>> >> printf("%d ",max3(a,b,c)); >>> > >>> > I'm curious. Why not write >>> > >>> > printf("%d\n", max3(2, -4, 6)); >>> > >>> > ? >>> I'm surprised at this advice. Presumably the intention is to eventually >>> have a, b and c populated by other means (eg. from the user), but values >>> are currently hardcoded. >>> >>> And maybe the values will be printed out first, or as part of the output: >>> >>> printf("Max3(%d, %d, %d) = %d\n", a,b,c, max3(a,b,c)); >>> >>> This all becomes harder with your suggestion. >> what should i write to get the warnings > > It depends on what compiler and programming environment you're using, > and you haven't told us that. > > Following this thread, you're still posting code that isn't > indented properly. If you're on a Unix/Linux-like system, read > the documentation for the "indent" command; I suggest "indent -kr". > Other systems are likely to have code formatters (perhaps even your > text editor can do this). > > Here's your original program from the top of this thread: > > int max3(int a,int b,int c){ > if(a if(b return c; > else > return b; > } > > int main(){ > int a=2,b=-4,c=6; > printf("%d ",max3(a,b,c)); > } > > Note that within the body of max3, every line is at the same indentation > level, even though there are several logical levels. > > Here's my second draft of your program, with no semantic changes other > than adding the required "#include ". (If your actual program > doesn't have that and you didn't get a warning for the call to printf, > you also need to crank up the diagnostics on your compiler. If you did > have "#include ", please include it when you post.) > > #include > > int max3(int a, int b, int c) { > if (a < b) > if (b < c) > return c; > else > return b; > } > > int main(void) { > int a = 2, b = -4, c = 6; > printf("%d ", max3(a, b, c)); > } > > The indentation makes it much more obvious that you don't do anything if > the first (a < b) condition is false. And knowing that a < b doesn't > tell you whether b or c is the maximum value. > > Some of the changes I've made are a matter of personal taste. The > language doesn't require white space in most contexts, but I like to add > a certain amount to make the code clearer. Others prefer or or less > white space. I like spaces around most operators ("a < b" rather than > "a (primarily so that "if (condition)" doesn't look like a function call). > > "int main()" is better written as "int main(void)". This is a minor > point, and your compiler probably doesn't care. (I could expound on > this point at some length, but it's not relevant for now.) > > My personal preference is to (almost) *always* use curly braces for > control statements (if, for, while, etc.). It makes the code easier to > read (at least for me), and can prevent errors when you later add more > statements. (It's a habit I picked up from Perl, which requires it.) > > Here's the program again with curly braces added: > > #include > > int max3(int a, int b, int c) { > if (a < b) { > if (b < c) { > return c; > } > else { > return b; > } > } > } > > int main(void) { > int a = 2, b = -4, c = 6; > printf("%d ", max3(a, b, c)); > } > > Using curly braces *and* correct indentation is a belt-and-suspenders > approach. It's not strictly necessary, but it means that an error in > either the indentation or in the braces is likely to stand out. It's > for the benefit of the human reader, not for the compiler. This version > is still incorrect. > > Note that some programmers prefer to put the opening "{" on a line by > itself, aligned with the closing "}". Both styles are valid. > Personally, I prefer putting the "{" on the end of the line. > > Now let's fix the code so it actually works. I've taken the liberty of > pretty much rewriting max3() from scratch. > > #include > > int max3(int a, int b, int c) { > if (a >= b && a >= c) { > return a; > } > else if (b >= c) { > return b; > } > else { > return c; > } > } > > int main(void) { > int a = 2, b = -4, c = 6; > printf("%d\n", max3(a, b, c)); > } > > Look at the way the logic flows. Either a, b, or c has the maximum > value (perhaps more than one of them if there are duplicates). > We first check whether a has the maximum value. If it doesn't, > we check whether b has the maximum value. If it doesn't, c does. > > Note that I've added a newline "\n" to the printf call. Output should > (almost) always end with a newline character. > > As others have pointed out, you can also build max3 on top of a simpler > max2 function: > > #include > > int max2(int a, int b) { > if (a >= b) { > return a; > } > else { > return b; > } > // could also be: > // return a >= b ? a : b; > } > > int max3(int a, int b, int c) { > return max2(max2(a, b), c); > } > > int main(void) { > int a = 2, b = -4, c = 6; > printf("%d\n", max3(a, b, c)); > } Here's another approach: #include int max3(int a, int b, int c) { int result = a; if (b > result) result = b; if (c > result) result = c; return result; } void try(int a, int b, int c) { // Assumes arguments are 1, 2, and 3 in any order int result = max3(a, b, c); printf("max3(%d, %d, %d) = %d ", a, b, c, result); if (result == 3) { printf("OK\n"); } else { printf("FAIL\n"); } } int main(void) { try(1, 2, 3); try(1, 3, 2); try(2, 1, 3); try(2, 3, 1); try(3, 1, 2); try(3, 2, 1); } You'll notice that I didn't use curly braces in the if statements, something I said I always do. I sometimes make an exception for statements that fit cleanly on one line, especially if there are several of them in a row and I can format them legibly. -- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com Working, but not speaking, for Philips Healthcare void Void(void) { Void(); } /* The recursive call of the void */