Suppose we have something along these lines
int f(int n);
....
do{
int a = b;
int b = f(a);
}
Is there any risk to saying
do{
int b = f(b);
}
instead, assuming a is not used elsewhere? Would it be stylistically preferable to do the former?
It is important to understand that you're not "altering" any variables here, just changing the meaning of a name.
The important concept is called the point of declaration.
Let's look at your example:
int b = 42;
{
int a = b;
int b = 23 * a;
printf("%d\n", b);
}
printf("%d\n", b);
or
int b = 42;
{
int b = 23 * b;
printf("%d\n", b);
}
printf("%d\n", b);
The name b references two objects, depending on where you are in the code, let's call them b1 and b2. This is unsurprising in case 1:
int b1 = 42;
{
int a = b1;
int b2 = 23 * a;
printf("%d\n", b2);
}
printf("%d\n", b1);
Since in C the point of declaration is before the initializer, the second example resolves differently:
int b1 = 42;
{
int b2 = 23 * b2;
printf("%d\n", b2);
}
printf("%d\n", b1);
Note that here there's no link between b1 and b2, you're initializing b2 with its own (undefined) value. A diligent compiler will warn you about this, like
x.c:7:13: warning: 'b' is used uninitialized in this function [-Wuninitialized]