Reading a data file

B

blmblm

The two "i" variables are declared in different scopes.

Yes, exactly. (You said it better, though. No surprise there.)
It's
fundamentally no different than this:

#include <stdio.h>
int main(void) {
int i = 0;
printf("i = %d\n", i);
{
int i = 1;
printf("i = %d\n", i);
}
printf("i = %d\n", i);
}

which prints:

i = 0
i = 1
i = 0

In general, an identifier declared in an inner scope hides the same
identifier declared in an outer scope.

Quite. "Asking for trouble" [*], in my opinion, though I suppose it could
be useful in some contexts as well.

[*] Or, if [generic] you prefer, "questionable programming style".
I suppose you could have a rule forbidding that, but it would break
existing code.

Which would never do :). But an optional warning might be nice.
 
E

Eric Sosman

[...]
In general, an identifier declared in an inner scope hides the same
identifier declared in an outer scope.

Quite. "Asking for trouble" [*], in my opinion, though I suppose it could
be useful in some contexts as well.

[*] Or, if [generic] you prefer, "questionable programming style".
I suppose you could have a rule forbidding that, but it would break
existing code.

Which would never do :). But an optional warning might be nice.

You could probably add gcc option for this without much
difficulty. Call it, oh, I dunno, maybe "-Wshadow".
 
M

Malcolm McLean

/* count the number of space characters before the quote */
int count_pre_quote_spaces(char *str)
{
int i;
int N;
int answer = 0;

for(i=0;str;i++)
if(str == '\'')
break;
if(!str)
return -1;
N = i;
for(int i=0; i<N;i++)
if(str == ' ')
answer++;

return answer;
}

what do you reckon?



I reckon that the C language allows an inner scope declaration to hide
an outer scope declaration, which is useful, because it makes it easier
to move code from one context to another without accidentally breaking
it - but that it is rarely, if ever, a good idea to deliberately write
code that depends upon that fact.

So if we've got two parallel loops, one of which may terminate before
time, and i is used outside of the loop body, and another where i
is always N on loop termination, either we've got to use another
counting variable, or we've got to declare i globally in the
second loop in this case. Which solution do you plump for?
 
J

James Kuyper

/* count the number of space characters before the quote */
int count_pre_quote_spaces(char *str)
{
int i;
int N;
int answer = 0;

for(i=0;str;i++)
if(str == '\'')
break;
if(!str)
return -1;
N = i;
for(int i=0; i<N;i++)
if(str == ' ')
answer++;

return answer;
}

what do you reckon?



I reckon that the C language allows an inner scope declaration to hide
an outer scope declaration, which is useful, because it makes it easier
to move code from one context to another without accidentally breaking
it - but that it is rarely, if ever, a good idea to deliberately write
code that depends upon that fact.

So if we've got two parallel loops, one of which may terminate before
time, and i is used outside of the loop body, and another where i
is always N on loop termination, either we've got to use another
counting variable, or we've got to declare i globally in the
second loop in this case. Which solution do you plump for?


I'd use N for the first loop, removing the need for N=i;, and use i for
the second. Depending upon the context, I'd give both variables more
meaningful names - after having had many problems while searching for
occurrences of variables in my code, I've set myself a lower limit of 3
characters for variable names.
 
M

Malcolm McLean

I'd use N for the first loop, removing the need for N=i;, and
use i for the second. Depending upon the context, I'd give both
variables more meaningful names - after having had many problems
while searching for occurrences of variables in my code, I've set
myself a lower limit of 3 characters for variable names.
I've got exactly the opposite philosophy. A loop counter is
i, ii, iii, iv, v to represent levels of nesting. j is a secondary
loop counter (e.g. if you're removing spaces from a string, j
would represent the write position and i the read position).
N counts things, a string is str, a real is x (x is also obviously
an integer co-ordinate), an angle is theta.

Obviously sometimes you need more specific names. But usually I
find that conventions will cover most cases.
 
J

James Kuyper

I've got exactly the opposite philosophy. A loop counter is
i, ii, iii, iv, v to represent levels of nesting. j is a secondary
loop counter (e.g. if you're removing spaces from a string, j
would represent the write position and i the read position).
N counts things, a string is str, a real is x (x is also obviously
an integer co-ordinate), an angle is theta.

Obviously sometimes you need more specific names. But usually I
find that conventions will cover most cases.

I've found that meaningful names are far more useful than arbitrary
names for checking the validity of code. Here's a slightly simplified
example from the main program I'm responsible for: "orb" refers to the
ORBital reference frame, "ecr" refers to the Earth Centered Rotating
reference frame, and "sc" refers to the SpaceCraft reference frame. We
use the naming convention T_x2y for orthonormal rotation matrixes for
transforming vectors from reference frame x to reference frame y.

for (ecr=0; ecr<3; ecr++)
for (sc=0; sc<3; sc++)
{
T_sc2ecr[ecr][sc] = 0.0;
for(orb=0; orb<3; orb++)
T_sc2ecr[ecr][sc] +=
T_orb2ecr[ecr][orb] * T_sc2orb[orb][sc];
}

for(sc=0; sc<3; sc++)
{
sol_sc[sc] = 0.0;
for(ecr=0; ecr<3; ecr++)
sol_sc[sc] += T_sc2ecr[ecr][sc]*sol_ecr[ecr];
}

I can easily determine that each and every index used in those code
fragments is used correctly - with this naming convention, every T_x2y
matrix must be subscripted [y][x]; anything else is manifestly wrong.
Code like this occurs in many locations in my programs (we use about 6
different coordinate systems). Before I introduced those index naming
conventions, one of the most common mistakes in our code was indexing
rotation matrices with the wrong variables.

Such mistakes were often introduced indirectly by calling a matrix
multiplication function that calculated C=A*B, when what was actually
needed was C=A*transpose(B). The approach shown above can handle
A*transpose(B) as easily as A*B.
 

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

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,014
Latest member
BiancaFix3

Latest Threads

Top