R. Brock Lynn wrote:

> I'm really a newbie to C programming, don't know jack about style, convention,
> etc. So I'd like comments on a little app I recently wrote.

OK.

> #define MAX(a,b) a > b ? a : b
> #define MIN(a,b) a < b ? a : b

1. Macro arguments should be bracketed, in case they are complex
expressions containing infix operators with a lower precedence than
the ones in the macro.

2. If the macro is an expression, it should usually be enclosed in
parentheses; if it consists of multiple statements, it should be a
compound statement (in braces).

[1 and 2 provide equivalent semantics to a function call].

3. min and max are usually lowercase, and conditionally defined, in
case they are already defined in some header file.

So, I would have written:

#ifndef max
#define max(a,b) ((a) > (b) ? (a) : (b))
#endif

#ifndef min
#define min(a,b) ((a) < (b) ? (a) : (b))
#endif


>       char* usage = "\nRandomIt version 0.01, shell utility for generating 
>pseudo-random numbers.\nCopyright (C) 1998 R. Brock Lynn <[EMAIL PROTECTED]>. 
>RandomIt comes with\nABSOLUTELY NO WARRANTY; for details  type `%s --warranty'. This 
>is free\nsoftware, and you are welcome to redistribute it under certain 
>conditions;\ntype `%s --license' for details.\n\nUsage: %s <start> <end>\n\nExample: 
>%s  0  100\n(picks a random integer from 0 to 100 inclusive)\n\n<start> and <end> 
>must be integers,\nor you will get strange results.\n\n" ;
> 
>       char* warranty = 
>"\n----------------------------------------------------------------------------\n\nNO 
>WARRANTY\n\nBECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 
>FOR\nTHE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN\nOTHERWISE 
>STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\nPROVIDE THE PROGRAM 
>\"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\nOR IMPLIED, INCLUDING, BUT 
>NOT LIMITED TO, THE IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS FOR A 
>PARTICULAR PURPOSE. THE ENTIRE RISK AS TO\nTHE QUALITY AND PERFORMANCE OF THE PROGRAM 
>IS WITH YOU. SHOULD THE PROGRAM\nPROVE DEFECTIVE, YOU ASSUME THE COST OF ALL 
>NECESSARY SERVICING, REPAIR OR\nCORRECTION.\n\nIN NO EVENT UNLESS REQUIRED BY 
>APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY 
>WHO MAY MODIFY AND/OR\nREDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU 
>FOR DAMAGES,\nINCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONS!
EQUENTIAL DAMAGES ARISING\nOUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING 
BUT NOT LIMITED TO\nLOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED 
BY YOU OR\nTHIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY 
OTHER\nPROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF 
THE\nPOSSIBILITY OF SUCH 
DAMAGES.\n\n----------------------------------------------------------------------------\n\n"
 ;
> 
>       char* license = 
>"\n----------------------------------------------------------------------------\n\nGNU
> GENERAL PUBLIC LICENSE\n\n(This document also available via the Internet 
>at\nhttp://www.gnu.org/copyleft/gpl.html)\n\nVersion 2, June 1991\n\nCopyright (C) 
>1989, 1991 Free Software Foundation, Inc.\n59 Temple Place - Suite 330, Boston, MA  
>02111-1307, USA\n\nEveryone is permitted to copy and distribute verbatim copies\nof 
>this license document, but changing it is not allowed.\n\nPreamble\n\nThe licenses 
>for most software are designed to take away your freedom to\nshare and change it. By 
>contrast, the GNU General Public License is intended\nto guarantee your freedom to 
>share and change free software--to make sure\nthe software is free for all its users. 
>This General Public License applies\nto most of the Free Software Foundation's 
>software and to any other program\nwhose authors commit to using it. (Some other Free 
>Software Foundation\nsoftware is covered by the GNU Library!
 General Public License instead.) You\ncan apply it to your programs, too.\n\nWhen we 
speak of free software, we are referring to freedom, not price. Our\nGeneral Public 
Licenses are designed to make sure that you have the freedom\nto distribute copies of 
free software (and charge for this service if you\nwish), that you receive source code 
or can get it if you want it, that you\ncan change the software or use pieces of it in 
new free programs; and that\nyou know you can do these things.\n\nTo protect your 
rights, we need to make restrictions that forbid anyone to\ndeny you these rights or 
to ask you to surrender the rights. These\nrestrictions translate to certain 
responsibilities for you if you distribute\ncopies of the software, or if you modify 
it.\n\nFor example, if you distribute copies of such a program, whether gratis or\nfor 
a fee, you must give the recipients all the rights that you have. You\nmust make sure 
that they, too, receive or can get the source code. And you!
\nmust show them these terms so they know their rights.\n\nWe prot
ect your rights with two steps: (1) copyright the software, and (2)\noffer you this 
license which gives you legal permission to copy, distribute\nand/or modify the 
software.\n\nAlso, for each author's protection and ours, we want to make certain 
that\neveryone understands that there is no warranty for this free software. If\nthe 
software is modified by someone else and passed on, we want its\nrecipients to know 
that what they have is not the original, so that any\nproblems introduced by others 
will not reflect on the original authors'\nreputations.\n\nFinally, any free program 
is threatened constantly by software patents. We\nwish to avoid the danger that 
redistributors of a free program will\nindividually obtain patent licenses, in effect 
making the program\nproprietary. To prevent this, we have made it clear that any 
patent must be\nlicensed for everyone's free use or not licensed at all.\n\nThe 
precise terms and conditions for copying, distribution and modification\nfollow.!
\n\nTERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n\n0. This License 
applies to any program or other work which contains a notice\nplaced by the copyright 
holder saying it may be distributed under the terms\nof this General Public License. 
The \"Program\", below, refers to any such\nprogram or work, and a \"work based on the 
Program\" means either the Program\nor any derivative work under copyright law: that 
is to say, a work\ncontaining the Program or a portion of it, either verbatim or 
with\nmodifications and/or translated into another language. 
(Hereinafter,\ntranslation is included without limitation in the term 
\"modification\".) Each\nlicensee is addressed as \"you\".\n\nActivities other than 
copying, distribution and modification are not covered\nby this License; they are 
outside its scope. The act of running the Program\nis not restricted, and the output 
from the Program is covered only if its\ncontents constitute a work based on the 
Program (independ!
ent of having been\nmade by running the Program). Whether that is 
true depends on what the\nProgram does.\n\n1. You may copy and distribute verbatim 
copies of the Program's source code\nas you receive it, in any medium, provided that 
you conspicuously and\nappropriately publish on each copy an appropriate copyright 
notice and\ndisclaimer of warranty; keep intact all the notices that refer to 
this\nLicense and to the absence of any warranty; and give any other recipients 
of\nthe Program a copy of this License along with the Program.\n\nYou may charge a fee 
for the physical act of transferring a copy, and you\nmay at your option offer 
warranty protection in exchange for a fee.\n\n2. You may modify your copy or copies of 
the Program or any portion of it,\nthus forming a work based on the Program, and copy 
and distribute such\nmodifications or work under the terms of Section 1 above, 
provided that you\nalso meet all of these conditions:\n\n   * a) You must cause the 
modified files to carry prominent notices stating\n     that you changed the fil!
es and the date of any change.\n\n   * b) You must cause any work that you distribute 
or publish, that in\n     whole or in part contains or is derived from the Program or 
any part\n     thereof, to be licensed as a whole at no charge to all third parties\n  
   under the terms of this License.\n\n   * c) If the modified program normally reads 
commands interactively when\n     run, you must cause it, when started running for 
such interactive use\n     in the most ordinary way, to print or display an 
announcement including\n     an appropriate copyright notice and a notice that there 
is no warranty\n     (or else, saying that you provide a warranty) and that users 
may\n     redistribute the program under these conditions, and telling the user\n     
how to view a copy of this License. (Exception: if the Program itself\n     is 
interactive but does not normally print such an announcement, your\n     work based on 
the Program is not required to print an announcement.)\n\nThese requ!
irements apply to the modified work as a whole. If identifiable\ns
ections of that work are not derived from the Program, and can be\nreasonably 
considered independent and separate works in themselves, then\nthis License, and its 
terms, do not apply to those sections when you\ndistribute them as separate works. But 
when you distribute the same sections\nas part of a whole which is a work based on the 
Program, the distribution of\nthe whole must be on the terms of this License, whose 
permissions for other\nlicensees extend to the entire whole, and thus to each and 
every part\nregardless of who wrote it.\n\nThus, it is not the intent of this section 
to claim rights or contest your\nrights to work written entirely by you; rather, the 
intent is to exercise\nthe right to control the distribution of derivative or 
collective works\nbased on the Program.\n\nIn addition, mere aggregation of another 
work not based on the Program with\nthe Program (or with a work based on the Program) 
on a volume of a storage\nor distribution medium does not bring the o!
ther work under the scope of this\nLicense.\n\n3. You may copy and distribute the 
Program (or a work based on it, under\nSection 2) in object code or executable form 
under the terms of Sections 1\nand 2 above provided that you also do one of the 
following:\n\n   * a) Accompany it with the complete corresponding machine-readable 
source\n     code, which must be distributed under the terms of Sections 1 and 2\n     
above on a medium customarily used for software interchange; or,\n\n   * b) Accompany 
it with a written offer, valid for at least three years,\n     to give any third 
party, for a charge no more than your cost of\n     physically performing source 
distribution, a complete machine-readable\n     copy of the corresponding source code, 
to be distributed under the\n     terms of Sections 1 and 2 above on a medium 
customarily used for\n     software interchange; or,\n\n   * c) Accompany it with the 
information you received as to the offer to\n     distribute corresponding !
source code. (This alternative is allowed only\n     for noncommer
cial distribution and only if you received the program in\n     object code or 
executable form with such an offer, in accord with\n     Subsection b above.)\n\nThe 
source code for a work means the preferred form of the work for making\nmodifications 
to it. For an executable work, complete source code means all\nthe source code for all 
modules it contains, plus any associated interface\ndefinition files, plus the scripts 
used to control compilation and\ninstallation of the executable. However, as a special 
exception, the source\ncode distributed need not include anything that is normally 
distributed (in\neither source or binary form) with the major components (compiler, 
kernel,\nand so on) of the operating system on which the executable runs, unless 
that\ncomponent itself accompanies the executable.\n\nIf distribution of executable or 
object code is made by offering access to\ncopy from a designated place, then offering 
equivalent access to copy the\nsource code from the same p!
lace counts as distribution of the source code,\neven though third parties are not 
compelled to copy the source along with\nthe object code.\n\n4. You may not copy, 
modify, sublicense, or distribute the Program except as\nexpressly provided under this 
License. Any attempt otherwise to copy,\nmodify, sublicense or distribute the Program 
is void, and will automatically\nterminate your rights under this License. However, 
parties who have received\ncopies, or rights, from you under this License will not 
have their licenses\nterminated so long as such parties remain in full 
compliance.\n\n5. You are not required to accept this License, since you have not 
signed\nit. However, nothing else grants you permission to modify or distribute 
the\nProgram or its derivative works. These actions are prohibited by law if you\ndo 
not accept this License. Therefore, by modifying or distributing the\nProgram (or any 
work based on the Program), you indicate your acceptance of\nthis License to do so!
, and all its terms and conditions for copying,\ndistributing or m
odifying the Program or works based on it.\n\n6. Each time you redistribute the 
Program (or any work based on the\nProgram), the recipient automatically receives a 
license from the original\nlicensor to copy, distribute or modify the Program subject 
to these terms\nand conditions. You may not impose any further restrictions on 
the\nrecipients' exercise of the rights granted herein. You are not responsible\nfor 
enforcing compliance by third parties to this License.\n\n7. If, as a consequence of a 
court judgment or allegation of patent\ninfringement or for any other reason (not 
limited to patent issues),\nconditions are imposed on you (whether by court order, 
agreement or\notherwise) that contradict the conditions of this License, they do 
not\nexcuse you from the conditions of this License. If you cannot distribute so\nas 
to satisfy simultaneously your obligations under this License and any\nother pertinent 
obligations, then as a consequence you may not distribute\nthe Program a!
t all. For example, if a patent license would not permit\nroyalty-free redistribution 
of the Program by all those who receive copies\ndirectly or indirectly through you, 
then the only way you could satisfy both\nit and this License would be to refrain 
entirely from distribution of the\nProgram.\n\nIf any portion of this section is held 
invalid or unenforceable under any\nparticular circumstance, the balance of the 
section is intended to apply and\nthe section as a whole is intended to apply in other 
circumstances.\n\nIt is not the purpose of this section to induce you to infringe any 
patents\nor other property right claims or to contest validity of any such 
claims;\nthis section has the sole purpose of protecting the integrity of the 
free\nsoftware distribution system, which is implemented by public license\npractices. 
Many people have made generous contributions to the wide range of\nsoftware 
distributed through that system in reliance on consistent\napplication of that syste!
m; it is up to the author/donor to decide if he or\nshe is willing
 to distribute software through any other system and a\nlicensee cannot impose that 
choice.\n\nThis section is intended to make thoroughly clear what is believed to be 
a\nconsequence of the rest of this License.\n\n8. If the distribution and/or use of 
the Program is restricted in certain\ncountries either by patents or by copyrighted 
interfaces, the original\ncopyright holder who places the Program under this License 
may add an\nexplicit geographical distribution limitation excluding those countries, 
so\nthat distribution is permitted only in or among countries not thus excluded.\nIn 
such case, this License incorporates the limitation as if written in the\nbody of this 
License.\n\n9. The Free Software Foundation may publish revised and/or new versions 
of\nthe General Public License from time to time. Such new versions will be\nsimilar 
in spirit to the present version, but may differ in detail to\naddress new problems or 
concerns.\n\nEach version is given a distinguishing versi!
on number. If the Program\nspecifies a version number of this License which applies to 
it and \"any\nlater version\", you have the option of following the terms and 
conditions\neither of that version or of any later version published by the 
Free\nSoftware Foundation. If the Program does not specify a version number of\nthis 
License, you may choose any version ever published by the Free 
Software\nFoundation.\n\n10. If you wish to incorporate parts of the Program into 
other free programs\nwhose distribution conditions are different, write to the author 
to ask for\npermission. For software which is copyrighted by the Free 
Software\nFoundation, write to the Free Software Foundation; we sometimes 
make\nexceptions for this. Our decision will be guided by the two goals of\npreserving 
the free status of all derivatives of our free software and of\npromoting the sharing 
and reuse of software generally.\n\nNO WARRANTY\n\n11. BECAUSE THE PROGRAM IS LICENSED 
FREE OF CHARGE, THERE IS NO WA!
RRANTY FOR\nTHE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW
. EXCEPT WHEN\nOTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER 
PARTIES\nPROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER 
EXPRESSED\nOR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
OF\nMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO\nTHE 
QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM\nPROVE 
DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR 
OR\nCORRECTION.\n\n12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN 
WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY 
AND/OR\nREDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR 
DAMAGES,\nINCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES 
ARISING\nOUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 
TO\nLOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU 
OR\nTHIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH !
ANY OTHER\nPROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF 
THE\nPOSSIBILITY OF SUCH DAMAGES.\n\nEND OF TERMS AND 
CONDITIONS\n\n----------------------------------------------------------------------------\n\n"
 ;

It is common practice to format source code to 80 columns. You can
take advantage of the fact that adjacent string literals are
concatenated to split the string over multiple lines.

Constant strings would normally be declared as `static const char *'.

I.e.:

static const char* usage =
"\n"
"RandomIt version 0.01, shell utility for generating pseudo-random numbers.\n"
"Copyright (C) 1998 R. Brock Lynn <[EMAIL PROTECTED]>. RandomIt comes with\n"
"ABSOLUTELY NO WARRANTY; for details  type `%s --warranty'. This is free\n"
"software, and you are welcome to redistribute it under certain conditions;\n"
"type `%s --license' for details.\n\n"
"Usage: %s <start> <end>\n\nExample: %s  0  100\n"
"(picks a random integer from 0 to 100 inclusive)\n\n"
"<start> and <end> must be integers,\nor you will get strange results.\n\n" ;

Whilst using %s to substitute argv[0] as the program name is
generally a good idea, using it repeatedly within a given string is a
bit messy (IMHO).

Also, I wouldn't have bothered embedding the copyright/warranty
information in the program, and particularly not in the `usage'
string. And I definitely wouldn't embed a complete copy of the GPL in
the program.

>       /* Get basename of how the program was called,
>      if argv[0] == "/this/is/the/path/to/the/prog" then we want "prog" */
>       name = argv[0] + strlen ( argv[0] ) - 1 ;
>       while ( name > argv[0] && *(name - 1) != '/' ) -- name ;

I wouldn't have bothered with this; most programs just use argv[0].

>       switch ( argc ) {
>               
>               case 3: {

You don't have to enclose the cases of a switch statement within
braces.

>                       start = (long) MIN ( atoi ( argv[1] ) , atoi ( argv[2] ) ) ;
>                       end   = (long) MAX ( atoi ( argv[1] ) , atoi ( argv[2] ) ) ;

I would have stored the results of atoi(argv[1]) and atoi(argv[2]) in
variables, rather than calling atoi() repeatedly.

>                       srand ( time ( 0 ) ) ;

The problems with this have already been pointed out by Jakob and
Dave.

>                       randy = ( (float) rand() / (float) RAND_MAX ) * ( end - start 
>+ 1 ) + start ;
>                       printf ( "%d\n", randy ) ;

You don't really need to use floating point for this; RAND_MAX is
usually 2^15-1, so using

        rand() * (end - start + 1) / RAND_MAX

should be OK.

>                       if ( ! strcmp ( argv[1], "--license" ) ) printf ( license ) ;

Personally, I avoid using `!strcmp(...)'; I find `strcmp(...) == 0' to
be more intuitive.

> My program does give an error on the printf saying it can't print long ints, or
> something, why is that? (it converts my longs to ints, how do I do a format
> statement for longs in printf?)

Use "%ld". It doesn't make any difference on an i386, where both int
and long are 32 bits.

-- 
Glynn Clements <[EMAIL PROTECTED]>

Reply via email to