0

I was reading "The C programming language" by Dennis Ritchie and had a doubt in the following code for finding value of base raised to n-th power:

#include <stdio.h> 

/* test power function */ 
int power(int m, int n);
main() 
{   int i; 

    for (i = 0; i < 10; ++i) 
        printf("%d %d %d\n", i, power(2,i), power(-3,i)); 
    return 0; 
} 

/* power: raise base to n-th power; n >= 0 */ 
int power(int base, int n) 
{ 
    int i, p; 
    p = 1; 

    for (i = 1; i <= n; ++i) 

        //Code causing confusion
        p = p * base; 
    return p; 
        //end

} 

This code was working fine with the following output.

0 1 1
1 2 -3
2 4 9
3 8 -27
4 16 81
5 32 -243
6 64 729
7 128 -2187
8 256 6561
9 512 -19683

My doubt was that p is set to 1 yet why is p = p * base printing the values?

Ayush
  • 49
  • 7
  • 1
    Because the `i` variable in your power function is completely separate from the `i` variable in the calling function. – selbie Feb 02 '20 at 08:00
  • Popular question today, see [How to write a loop that calculates power?](https://stackoverflow.com/questions/60022757/how-to-write-a-loop-that-calculates-power) – David C. Rankin Feb 02 '20 at 08:45
  • Your question is unclear. You ask why `p = p * base` is “printing the incremented value,” but `p = p * base` does not print anything, and it multiplies; it does not increment. And it is unclear what relationship you think this has to `for (i = 1; i <= n; ++i)`. In spite of the spacing shown in your question, the statement `p = p * base;` is the body of the `for` loop started by `for (i = 1; i <= n; ++i)`. Is that what your question about, why `p = p * base;` is executed repeatedly? Or is it about using `i` in the `power` function as a separate entity from the `i` in `main`? – Eric Postpischil Feb 02 '20 at 11:54
  • My doubt was that **p** is initiated as 1 yet it outputs values from 1 to 9. How? (I've updated question now) – Ayush Feb 02 '20 at 16:29

2 Answers2

1

It's been a little while since I've read that book, but I'm sure you'll come upon a chapter in which you deal with the notion of scope.

The scope of a variable, in this case i, is the "lifetime" of that variable.

Much like I can name my friends Joe and Bob, but then speak directly to Bob and refer to him as he, him, or his, and then continue to use him in this sentence, and you will understand that I am talking about Bob. And then I can refer to Joe and speak to his actions and use he, him or his, and you will understand I am talking about Joe, and not Bob.

It is the same with functions. Think of a function like a sentence. The i in your power function does not refer to the same i in your main function.

This is the basic idea of scope.

If you have not read to that just yet, you should soon enough and I would suggest you read over that chapter a couple of times to fully grasp scope; especially in C, as it can lead to some interesting and confusing bugs down the road if not understood properly.

I hope that can help.

txtechhelp
  • 6,625
  • 1
  • 30
  • 39
  • I'm commenting on my own answer, as I don't want to add confusion, but for educations sake, and completeness, it's possible in some compilers and versions of C to have a variable `i` within one function, and then to use that same `i` variable elsewhere (albeit highly discouraged if you can do so). – txtechhelp Feb 02 '20 at 08:44
  • The notions of *Integer Overflow* and *Undefined Behavior* are equally important `:)` – David C. Rankin Feb 02 '20 at 08:47
  • @DavidC.Rankin .. The first rule of C is you do not talk about Undefined Behavior! The second rule of C is you _do not_ talk about Undefined Behavior! The third rule of C is if your code stops or core dumps, the application is complete. #4, only two files to compilation. #5, 1 instruction at a time. #6 no goto's, no magic numbers. #7 loops can be infinite if need be. #8 if this is your first C program .. you have to SIGSEGV ;) – txtechhelp Feb 02 '20 at 09:13
  • Those are good rules. Best to just bury the footnote to [C11 - 3.4.3(p3)](http://port70.net/~nsz/c/c11/n1570.html#3.4.3p3) somewhere out of sight `:)` – David C. Rankin Feb 02 '20 at 09:39
  • Scope is not lifetime. Scope is **where** in source code an **identifier** is visible. Lifetime is **when** during program execution an **object** exists. – Eric Postpischil Feb 02 '20 at 11:51
  • @txtechhelp: Are you saying some compilers make the `i` identifier visible outside of its scope as defined by the C standard? I doubt that. Can you name one of them? – Eric Postpischil Feb 02 '20 at 11:55
  • @DavidC.Rankin: There is no integer overflow or undefined behavior here. – Eric Postpischil Feb 02 '20 at 11:56
  • @EricPostpischil .. yes, older compilers which use some older versions of C will take advantage of hacks to reduce file size by allowing one to "reuse" a variable in not so obvious ways. It's not standard (obviously), but I've personally had to clean up older micro controller code in which a bug was introduced because of it :/ If I can find the reference to that, I'll pass it along. – txtechhelp Feb 02 '20 at 18:52
  • @EricPostpischil - I was addressing the potential for `p = p * base;` to overflow quite easily. – David C. Rankin Feb 03 '20 at 01:46
1

I missed the obvious fact that p = p * base will result in p's value constantly changing. Also,

for (i = 0; i < 10; ++i) 
        printf("%d %d %d\n", i, power(2,i), power(-3,i)); 
    return 0; 

will ensure that the output is printed 10 times.

Ayush
  • 49
  • 7