indentation

  • Thread starter Bill Cunningham
  • Start date
B

Bill Cunningham

I have had several complaints by some people who wish to help me and I
wish to get the problem straight. I wrote this small utility myself and
added some indentation and I wonder if it is acceptable. It does make source
easier to read.

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv) {
if (argc!=3) {
fprintf(stderr,"usage error\n");
return -1;
}
double x,y;
x=strtod(argv[1],NULL);
y=strtod(argv[2],NULL);
printf("%.2f\n",y/x);
return 0;
}

Is this a good example of a properly indended program?

Bill
 
K

Keith Thompson

Bill Cunningham said:
I have had several complaints by some people who wish to help me and I
wish to get the problem straight. I wrote this small utility myself and
added some indentation and I wonder if it is acceptable. It does make source
easier to read.

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv) {
if (argc!=3) {
fprintf(stderr,"usage error\n");
return -1;
}
double x,y;
x=strtod(argv[1],NULL);
y=strtod(argv[2],NULL);
printf("%.2f\n",y/x);
return 0;
}

Is this a good example of a properly indended program?

Better, but not yet good.

A single space per indentation level is IMHO insufficient.
It's still very hard to see what's indented. I like 4-column
indentation myself; I consider 2 to be the bare minimum. (Some
advocate 8-column indentation, which certainly encourages Any
decent text editor should do most of the work for you automatically
(":se ai" or ":set autoindent" in vi, for example).

There are several common styles for indentation and brace placement.
Your program exhibits none of them. That's not necessarily A Bad
Thing, but it's a bit jarring, and there's rarely any good reason
not to follow one of the existing styles.

Two of the most common styles are:

1. K&R style. An opening brace '{' goes at the end of a line,
preceded by a space (except possibly for the opening brace of a
function definition, for historical reasons). Enclosed lines are
indented by one level (e.g., by 4 columns). The closing brace is
aligned directly under the beginning of the line containing the
opening brace (this is where you go astray).

2. Opening and closing braces appear on lines by themselves.
Enclosed lines are indented by one level.

Rarer, but still valid, styles are:

3. Like 2, but the braces are aligned with the enclosed lines.

4. Like 2, but the braces are half-indented (e.g., by 2 columns).
I think this is the GNU-recommended style.

Personally, I prefer #1, and I've listed the others in order of my own
preference. Note that in all these styles, the closing brace is
aligned either with the opening brace or with the line on which the
opening brace appears.

At the bottom of this message, I've added a copy of your code in
each of the 4 styles (omitting the #include directives).

Some additional notes on your code:

Returning -1 from main() is non-portable. Use 0, EXIT_SUCCESS,
or EXIT_FAILURE.

Mixing declarations and statements is a C99-specific feature;
not all compilers support it. It's not wrong, but it may limit
the portability of your code.

(I'm tempted to mention the lack of error checking in your strtod()
calls, but this is obviously a toy program so I won't.)

Re-formatted code follows. Note that I've also inserted some
whitespace to make the code easier to read. Rules of thumb: use
spaces around operators, and always use a space after a comma.
Compare:

x=strtod(argv[1],NULL);

x = strtod(argv[1], NULL);

ThinkabouthowdifficultreadingEnglishwouldbewithoutwhitespace.

1.
int main(int argc, char **argv) {
if (argc != 3) {
fprintf(stderr, "usage error\n");
return -1;
}
double x, y;
x = strtod(argv[1], NULL);
y = strtod(argv[2], NULL);
printf("%.2f\n", y / x);
return 0;
}

1a.
int main(int argc, char **argv)
{
if (argc != 3) {
fprintf(stderr, "usage error\n");
return -1;
}
double x, y;
x = strtod(argv[1], NULL);
y = strtod(argv[2], NULL);
printf("%.2f\n", y / x);
return 0;
}

2.
int main(int argc, char **argv)
{
if (argc != 3)
{
fprintf(stderr, "usage error\n");
return -1;
}
double x, y;
x = strtod(argv[1], NULL);
y = strtod(argv[2], NULL);
printf("%.2f\n", y / x);
return 0;
}

3.
int main(int argc, char **argv)
{
if (argc != 3)
{
fprintf(stderr, "usage error\n");
return -1;
}
double x, y;
x = strtod(argv[1], NULL);
y = strtod(argv[2], NULL);
printf("%.2f\n", y / x);
return 0;
}

4.
int main(int argc, char **argv)
{
if (argc != 3)
{
fprintf(stderr, "usage error\n");
return -1;
}
double x, y;
x = strtod(argv[1], NULL);
y = strtod(argv[2], NULL);
printf("%.2f\n", y / x);
return 0;
}
 
B

Bill Cunningham

Joe Wright said:
..given your program as input. What do you think?

The first copy of the file I wrote has had its indentation changed by
the news server or client. It was indented when I posted it and the
indentation was removed. Maybe nntp does that. The progran was originally
indented like this.

if (argc!3) {
fprintf(stderr,"usage error\n");
return -1;
}

Thatis what was copied onto the post and it was posted without the
indentation.

Bill
 
I

Ian Collins

Bill said:
The first copy of the file I wrote has had its indentation changed by
the news server or client. It was indented when I posted it and the
indentation was removed. Maybe nntp does that. The progran was originally
indented like this.
You probably used tabs rather than spaces. Stick to (two) spaces and
your code will be left unmolested.
 
B

Bill Cunningham

You probably used tabs rather than spaces. Stick to (two) spaces and
your code will be left unmolested.
Exactly. I always do. Maybe it's a bad habit.

Bill
 
C

cr88192

Bill Cunningham said:
I have had several complaints by some people who wish to help me and I
wish to get the problem straight. I wrote this small utility myself and
added some indentation and I wonder if it is acceptable. It does make
source easier to read.

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv) {
if (argc!=3) {
fprintf(stderr,"usage error\n");
return -1;
}
double x,y;
x=strtod(argv[1],NULL);
y=strtod(argv[2],NULL);
printf("%.2f\n",y/x);
return 0;
}

Is this a good example of a properly indended program?

well, this gets into this big hairy area known as "coding style" (most have
opinions, few can completely agree...).


now, I usually code in notepad, which has inflexible 8-space tabs, so
usually I use this.
if the tab space is adjustable, usually I like 4 space tabs.

2 or 3 spaces is IMO too little.
1 space is just horrid (may as well not indent at all...).


usually, I put opening and closing braces on their own lines, and closing
braces are indended the same as the opening braces.

int main(int argc, char *argv[])
{
FILE *fd;
if(argv<2)
{
printf("usage: %s <filename>\n", argv[0]);
return(-1);
}

fd=fopen(argv[1], "rb");
...
return(0);
}

note that EXIT_SUCCESS and EXIT_FAILURE are considered "more correct" for
main return values, but 0 and -1 are more common/traditional.


IMO, both forms:
if(...)
{

and:
if(...) {

are fairly common and acceptable, but most people put the brace on its own
line for functions, and rarely for structs or unions.

it is common for commas to be followed by a space ("f(x, y);" but not
"f(x,y);").
some people precede/follow parens and/or operators with spaces.

if certain single-letter variable names are used (especially, i,j,k,s,t,...)
it is almost obligatory that they be certain types (i,j,k are int, s,t are
'char *', ...).

return is often/usually written as if it were a function call (common in C,
rare in C++).

and so on...
 
N

Nick Keighley

    I have had several complaints by some people who wish to help me
and I wish to get the problem straight. I wrote this small utility
myself and added some indentation and I wonder if it is acceptable.
It does make source easier to read.

that's the idea! :)
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv) {
 if (argc!=3) {
  fprintf(stderr,"usage error\n");
  return -1;
  }
 double x,y;
 x=strtod(argv[1],NULL);
 y=strtod(argv[2],NULL);
 printf("%.2f\n",y/x);
 return 0;
 }

    Is this a good example of a properly indended program?


well it's better! In fact it's good enough to prevent
me whining about indentation. Personnally I prefer the
braces to line up, but the above is ok. I definitly
prefer whitespace around binary operators (eg. =)
and I'd use more blank lines. But on usenet saving vertical
space can be a good thing.

#include <stdio.h>
#include <stdlib.h>

int main (int argc, char **argv)
{
double x;
double y;

if (argc != 3)
{
fprintf (stderr,"usage error\n");
return -1;
}

x = strtod (argv [1], NULL);
y = strtod (argv [2], NULL);

printf ("%.2f\n", y / x);

return 0;
}

the main thing is to group things together that
logically belong together, leave enough whitespace
(horizontal and vertical) to aid readability and
above all, be consistent.

Oh, and never use tabs!

[mutter, one project had a standard of 4 column indent
and 8 space tabs. So you mixed tabs and spaces. eek!]


--
Nick Keighley

"The Real Programmer wants a "you asked for it, you got it"
text editor--complicated, cryptic, powerful, unforgiving,
dangerous. TECO, to be precise."
 
B

brix99luftballons

Richard Heathfield ha scritto:
cr88192 said:



Oh dear. :)
Oh dear dear :)
And IMO 3 is too many. Vive la difference!
You forgot <stdio.h>
You meant argc.
A type , may be...
If argc is 0, the behaviour is undefined. If it is >= 1, argv[0] must
represent the program name in some way, but need not be a string
representing the invocation name for the program. It could even be a pid!
argc must be 1 (the program name ia always passed as argument), by
standard.
But, yes, it is best to check it...
This has no portable meaning (and the parentheses are redundantly
superfluous).
I'm not agree, it' more readable.
fd=fopen(argv[1], "rb");
...
return(0);

Again, the parentheses are superfluously redundant.
Question of style: for me it is better to place parentesis around the
returned value.
What about an horrible return like this one ????
return a*32 / b + c - d * e / oh_my_good ;
0 is fine - it means success.

Ok, it's a standard value
A -1 return value has no de jure meaning in C (which is, at least, in
keeping with the better kinds of tradition - if we knew why we did them,
they wouldn't be traditions!).

To indicate failure portably, use EXIT_FAILURE.
:)

brix
 
C

cr88192

Richard Heathfield said:
cr88192 said:



Oh dear. :)

all in all it is a good and simple editor...

Tab/space wars are so 1990s, though, aren't they?

yeah...
anymore, it is mostly forgotten, but I still usually use 4 or 8...

And IMO 3 is too many. Vive la difference!

yeah, it is a matter of taste I guess. 2 or 3 spaces IMO is painful to read
or skim...
Agreed again.

You forgot <stdio.h>

yeah, I inferred this, since my point was more about demonstrating style
than actually working code.
int main(int argc, char *argv[])
{
FILE *fd;
if(argv<2)

You meant argc.

yes, typing does not always work perfectly...

{
printf("usage: %s <filename>\n", argv[0]);

If argc is 0, the behaviour is undefined. If it is >= 1, argv[0] must
represent the program name in some way, but need not be a string
representing the invocation name for the program. It could even be a pid!

this is a common practice though, and also I don't personally know of any OS
where argc is not at least 1...

This has no portable meaning (and the parentheses are redundantly
superfluous).

return(-1);
is the same as:
return -1;

only, the parens are a matter of style and tradition...
}

fd=fopen(argv[1], "rb");
...
return(0);

Again, the parentheses are superfluously redundant.
}

note that EXIT_SUCCESS and EXIT_FAILURE are considered "more correct" for
main return values,

0 is fine - it means success.

yeah.
but 0 and -1 are more common/traditional.

A -1 return value has no de jure meaning in C (which is, at least, in
keeping with the better kinds of tradition - if we knew why we did them,
they wouldn't be traditions!).

To indicate failure portably, use EXIT_FAILURE.

it is more correct, but -1 is a very common value for indicating error as
well.
I think usually any value other than 0 counts as an error.

The word "most" is arguable. K&R's style is perniciously persistent even
now. And a significant number of Allman adherents /do/ put a struct brace
on its own line.

I comment based on what I have most often seen, but these conventions are by
no means universal.

True, and wise.


True, and a matter of taste, I think. My own taste is for parentheses not
to "command" any whitespace, but for binary operators to be separated from
their operands by a space.

yeah, my case I don't usually use a space either (since to me the paren is
'strong', and putting a space there makes it seem 'weak'...).

my case, whether or not I use spaces around operators is a matter of
situation, where usually they are used for breaking up expressions into
recognizable parts, and sometimes for aligning groups of regularized
expressions.

sometimes terms for polynomial expressions can be broken up like this as
well.

4*a*c - 2*b

No, not really. Common, yes. Obligatory? Hardly.

sufficiently common patterns are almost obligatory.
if one is going to use different types, they are better off avoiding these
names, for sake of reducing possible confusion.

return /isn't/ a function call, and it seems to me from perusing this
group
and from what I've seen of good C code (in well-regarded literature, in
workplaces, and on the Web) that few if any experienced C programmers
treat it like one.

well, as noted, it is a lot more common in C IME, but it is almost never
done in C++.

however, I have personally seen a lot more code with the parens than without
the parens...
 
E

Eligiusz Narutowicz

Bill Cunningham said:
I have had several complaints by some people who wish to help me and I
wish to get the problem straight. I wrote this small utility myself and
added some indentation and I wonder if it is acceptable. It does make source
easier to read.

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv) {
if (argc!=3) {
fprintf(stderr,"usage error\n");
return -1;
}
double x,y;
x=strtod(argv[1],NULL);
y=strtod(argv[2],NULL);
printf("%.2f\n",y/x);
return 0;
}

Is this a good example of a properly indended program?

Bill

You are a very good troll I think! :)
 
E

Eligiusz Narutowicz

cr88192 said:
Richard Heathfield said:
cr88192 said:



Oh dear. :)

all in all it is a good and simple editor...

Tab/space wars are so 1990s, though, aren't they?

yeah...
anymore, it is mostly forgotten, but I still usually use 4 or 8...

And IMO 3 is too many. Vive la difference!

yeah, it is a matter of taste I guess. 2 or 3 spaces IMO is painful to read
or skim...
Agreed again.

You forgot <stdio.h>

yeah, I inferred this, since my point was more about demonstrating style
than actually working code.
int main(int argc, char *argv[])
{
FILE *fd;
if(argv<2)

You meant argc.

yes, typing does not always work perfectly...

{
printf("usage: %s <filename>\n", argv[0]);

If argc is 0, the behaviour is undefined. If it is >= 1, argv[0] must
represent the program name in some way, but need not be a string
representing the invocation name for the program. It could even be a pid!

this is a common practice though, and also I don't personally know of any OS
where argc is not at least 1...

This has no portable meaning (and the parentheses are redundantly
superfluous).

return(-1);
is the same as:
return -1;

only, the parens are a matter of style and tradition...
}

fd=fopen(argv[1], "rb");
...
return(0);

Again, the parentheses are superfluously redundant.
}

note that EXIT_SUCCESS and EXIT_FAILURE are considered "more correct" for
main return values,

0 is fine - it means success.

yeah.
but 0 and -1 are more common/traditional.

A -1 return value has no de jure meaning in C (which is, at least, in
keeping with the better kinds of tradition - if we knew why we did them,
they wouldn't be traditions!).

To indicate failure portably, use EXIT_FAILURE.

it is more correct, but -1 is a very common value for indicating error as
well.
I think usually any value other than 0 counts as an error.

The word "most" is arguable. K&R's style is perniciously persistent even
now. And a significant number of Allman adherents /do/ put a struct brace
on its own line.

I comment based on what I have most often seen, but these conventions are by
no means universal.

True, and wise.


True, and a matter of taste, I think. My own taste is for parentheses not
to "command" any whitespace, but for binary operators to be separated from
their operands by a space.

yeah, my case I don't usually use a space either (since to me the paren is
'strong', and putting a space there makes it seem 'weak'...).

my case, whether or not I use spaces around operators is a matter of
situation, where usually they are used for breaking up expressions into
recognizable parts, and sometimes for aligning groups of regularized
expressions.

sometimes terms for polynomial expressions can be broken up like this as
well.

4*a*c - 2*b

No, not really. Common, yes. Obligatory? Hardly.

sufficiently common patterns are almost obligatory.
if one is going to use different types, they are better off avoiding these
names, for sake of reducing possible confusion.

return /isn't/ a function call, and it seems to me from perusing this
group
and from what I've seen of good C code (in well-regarded literature, in
workplaces, and on the Web) that few if any experienced C programmers
treat it like one.

well, as noted, it is a lot more common in C IME, but it is almost never
done in C++.

however, I have personally seen a lot more code with the parens than without
the parens...


I agree with people who write real apps accessed by many peoples. And
these are:

It is clear and it works.

http://www.linuxjournal.com/article/5780
 
B

Bart

all in all it is a good and simple editor...

(So you can write some very complex software but not an editor better
than notepad?..)

If you like notepad, you might like to try qed.exe, if you can still
find it. (I think an updated version here http://www.movsd.com/qed.htm).
It has some useful indent commands. And I believe still smaller than
notepad.
 
E

Eligiusz Narutowicz

Bart said:
(So you can write some very complex software but not an editor better
than notepad?..)

If you like notepad, you might like to try qed.exe, if you can still
find it. (I think an updated version here http://www.movsd.com/qed.htm).
It has some useful indent commands. And I believe still smaller than
notepad.

Anyone using notepad to write C should be fired. There are lots of
productivity tools which make programming more sure fire and certainly
easier - not to use at least some of them is silly.
 
F

Flash Gordon

cr88192 said:
Richard Heathfield said:
cr88192 said:
{
printf("usage: %s <filename>\n", argv[0]);
If argc is 0, the behaviour is undefined. If it is >= 1, argv[0] must
represent the program name in some way, but need not be a string
representing the invocation name for the program. It could even be a pid!

this is a common practice though, and also I don't personally know of any OS
where argc is not at least 1...

<snip>

Any Unix if the exec* call used to invoke the program provides a
parameter list with argv[0]=NULL. In Unix programs other than your shell
are allowed to exec your program, so you cannot guarantee you will get a
program name.
it is more correct, but -1 is a very common value for indicating error as
well.
I think usually any value other than 0 counts as an error.

<snip>

Not on VMS. IIRC on VMS odd return values indicate success and even
return values indicate failure with the C compiler using some magic to
make returning 0 actually return an odd number to the environment.

There *are* good reasons for using non-C-standard return values from
main, but in my experience they only apply when you have return return
values indicating something more than simple success/failure.
 
B

brix99luftballons

Right, so let's do that. See 2.1.2.2 of C89 or 5.1.2.2.1 of C99:

* The value of argc shall be nonnegative.

* argv[argc] shall be a null pointer.

* If the value of argc is greater than zero, the array members
argv[0] through argv[argc-1] inclusive shall contain pointers to
strings, which are given implementation-defined values by the host
environment prior to program startup. The intent is to supply to the
program information determined prior to program startup from elsewhere
in the hosted environment. [...]

It is clear from the above that argc may be 0.
You are rigth... till now i've never found a system that pass a 0 as
argc, but it should exist,
maybe on a very small controllers environment...
Please explain why parentheses make the return code more readable. Does
this apply to every expression, or just to the expression that
(optionally) follows a return statement? If so, why is return special?
It's just a question of style. I prefer to place parentheses. Return is
not special, so it
is trated in the same way of all other cases where parentheses should be
used also
when they are superfluous.
What makes you think that adding parentheses helps? If the reader can't
comprehend a*32 / b + c - d * e / oh_my_good, why are they more likely to
comprehend (a*32 / b + c - d * e / oh_my_good)?
Yea, but of couse for me is much better to use parentheses:
retun( (((z*100)/y)+((w-r)*k)) / u );

That it is a non-ambiguous form, readable also from people with little
knowledge
of the language and not familiar with the specific operator's precedence.

b.
 
B

Ben Bacarisse

Richard Heathfield said:
brix99luftballons said:

<snip>

till now i've never found a system that pass a 0 as

Macs and Unices aren't that small.

Most systems can be made to pass a zero, but Unices (I prefer *nix)
don't do so as a matter of course.

If they are superfluous, why use them at all? I can understand why you
might add them in places where the precedence isn't obvious, e.g. in
something like (a << b) + c - but surrounding an expression with
parentheses does nothing to clarify precedence within the expression
itself.

You are being your usual argumentative self! Can't you see a reason
why return (E); could be seen as a reasonable generalisation? if,
while, switch etc all have syntactic ()s that at least *look*
superfluous (yes, I know they are not so). From that point of view a
return without them look out of place.

The language designers certainly thought so. I, for one, had to
*un-learn* return (E); since it was always thus in B and it was also
required in very early C. To be portable, you wrote return (E); just in
case your code got near an ancient compiler.

Of course those days are long gone and I now prefer a minimal use of
parentheses.
 
B

Bill Cunningham

i like below

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{double x, y;

if (argc!=3) { fprintf(stderr,"usage error\n"); return -1;}

x=strtod(argv[1], 0);
y=strtod(argv[2], 0);

return (x!=0.0) ?
(printf("%.2f\n", y/x), 0): (printf("Error: x==0\n"), -1) ;
}

This is the part that goes over my head with my knowledge.

return (x!=0.0) ? /*what's the ? and 0.0 for */

There are things in C, shortcuts that I haven't grasped yet like += and ?: I
do things the long way right now.

Bill
 
B

Bill Cunningham

CBFalconer said:
There is a program around called indent (GNU version 2.2.9 here)
which does all this for you. It is configurable. I use the
following configuration for it (really just one long line in
indent.pro):

-kr -l66 -i3 -bad -di16 -lc66 -nce -ncs -cbi0 -bbo -pmt -psl -ts1
-cdw -ppi 3

This is the results of my program using "indent div.c" which is the name
of the source code.

#include <stdio.h>
#include <stdlib.h>

int
main (int argc, char **argv)
{
if (argc != 3)
{
fprintf (stderr, "usage error\n");
return -1;
}
double x, y;
x = strtod (argv[1], NULL);
y = strtod (argv[2], NULL);
printf ("%.2f\n", y / x);
return 0;
}

Believe me I didn't do this myself. Indent did it for me!

Bill
 
K

Keith Thompson

Bill Cunningham said:
rio said:
i like below

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{double x, y;

if (argc!=3) { fprintf(stderr,"usage error\n"); return -1;}

x=strtod(argv[1], 0);
y=strtod(argv[2], 0);

return (x!=0.0) ?
(printf("%.2f\n", y/x), 0): (printf("Error: x==0\n"), -1) ;
}

This is the part that goes over my head with my knowledge.

return (x!=0.0) ? /*what's the ? and 0.0 for */

There are things in C, shortcuts that I haven't grasped yet like += and ?: I
do things the long way right now.

I believe "rio" is pulling your leg. His code is gratuitously
obfuscated.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

pow type problem 6
sh?tpile of errors 82
code question 74
Linux: using "clone3" and "waitid" 0
z error 12
root(s) 6
[C language] Issue in the Lotka-Volterra model. 0
completely stuck 14

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top