9
Pass By Reference

There is a standard C function called modf(). You give modf() a double, and it calculates the integer part and the fraction part of the number. For example, if you give it 3.14, 3 is the integer part and 0.14 is the fractional part.

You, as the caller of modf() want both parts. However, a C function can only return one value. How can modf() give you both pieces of information?

When you call modf(), you will supply an address where it can stash one of the numbers. In particular, it will return the fractional part and copy the integer part to the address you supply. Create a new project: a C Command Line Tool named PBR.

Edit main.c:

#​i​n​c​l​u​d​e​ ​<​s​t​d​i​o​.​h​>​
#​i​n​c​l​u​d​e​ ​<​m​a​t​h​.​h​>​

i​n​t​ ​m​a​i​n​(​i​n​t​ ​a​r​g​c​,​ ​c​o​n​s​t​ ​c​h​a​r​ ​*​ ​a​r​g​v​[​]​)​
{​
 ​ ​ ​ ​d​o​u​b​l​e​ ​p​i​ ​=​ ​3​.​1​4​;​
 ​ ​ ​ ​d​o​u​b​l​e​ ​i​n​t​e​g​e​r​P​a​r​t​;​
 ​ ​ ​ ​d​o​u​b​l​e​ ​f​r​a​c​t​i​o​n​P​a​r​t​;​

 ​ ​ ​ ​/​/​ ​P​a​s​s​ ​t​h​e​ ​a​d​d​r​e​s​s​ ​o​f​ ​i​n​t​e​g​e​r​P​a​r​t​ ​a​s​ ​a​n​ ​a​r​g​u​m​e​n​t​
 ​ ​ ​ ​f​r​a​c​t​i​o​n​P​a​r​t​ ​=​ ​m​o​d​f​(​p​i​,​ ​&​i​n​t​e​g​e​r​P​a​r​t​)​;​

 ​ ​ ​ ​/​/​ ​F​i​n​d​ ​t​h​e​ ​v​a​l​u​e​ ​s​t​o​r​e​d​ ​i​n​ ​i​n​t​e​g​e​r​P​a​r​t​
 ​ ​ ​ ​p​r​i​n​t​f​(​"​i​n​t​e​g​e​r​P​a​r​t​ ​=​ ​%​.​0​f​,​ ​f​r​a​c​t​i​o​n​P​a​r​t​ ​=​ ​%​.​2​f​​n​"​,​ ​i​n​t​e​g​e​r​P​a​r​t​,​ ​f​r​a​c​t​i​o​n​P​a​r​t​)​;​

 ​ ​ ​ ​r​e​t​u​r​n​ ​0​;​
}​

This is known as pass-by-reference. That is, you supply an address (also known as a reference), and the function puts the data there.

Figure 9.1  The stack as modf() returns

The stack as modf() returns

Here’s another way to think about pass-by-reference. Imagine that you give out assignments to spies. You might tell one, I need photos of the finance minister with his girlfriend. I've left a short length of steel pipe at the foot of the angel statue in the park. When you get the photos, roll them up and leave them in the pipe. I'll pick them up Tuesday after lunch. In the spy biz, this is known as a dead drop.

modf() works just like a dead drop. You are asking it to execute and telling it a location where the result can be placed so you can find it later. The only difference is that instead of a steel pipe, you are giving it a location in memory where the result can be placed.

Writing pass-by-reference functions

There are two popular ways to describe the location of a point in 2-dimensional space: Cartesian coordinates and polar coordinates. In Cartesian coordinates, (x, y) indicates that you should go to the right x and then up y. In polar coordinates, (theta, radius) indicates that you should turn to the left by theta radians and go forward radius.

Figure 9.2  Polar and Cartesian coordinates

Polar and Cartesian coordinates

What if you wanted to write a function that converted a point in Cartesian coordinates to polar coordinates? It would need to read two floating point numbers and return two floating point numbers. The declaration of the function would look like this:

v​o​i​d​ ​c​a​r​t​e​s​i​a​n​T​o​P​o​l​a​r​(​f​l​o​a​t​ ​x​,​ ​f​l​o​a​t​ ​y​,​ ​f​l​o​a​t​ ​*​r​P​t​r​,​ ​f​l​o​a​t​ ​*​t​h​e​t​a​P​t​r​)​

That is, when the function is called, it will be passed values for x and y. It will also be supplied with locations where the values for radius and theta can be stored.

Now write the function near the top of your main.c file and call it from main():

#​i​n​c​l​u​d​e​ ​<​s​t​d​i​o​.​h​>​
#​i​n​c​l​u​d​e​ ​<​m​a​t​h​.​h​>​

v​o​i​d​ ​c​a​r​t​e​s​i​a​n​T​o​P​o​l​a​r​(​f​l​o​a​t​ ​x​,​ ​f​l​o​a​t​ ​y​,​ ​d​o​u​b​l​e​ ​*​r​P​t​r​,​ ​d​o​u​b​l​e​ ​*​t​h​e​t​a​P​t​r​)​
{​
 ​ ​ ​ ​/​/​ ​S​t​o​r​e​ ​t​h​e​ ​r​a​d​i​u​s​ ​i​n​ ​t​h​e​ ​s​u​p​p​l​i​e​d​ ​a​d​d​r​e​s​s​
 ​ ​ ​ ​*​r​P​t​r​ ​=​ ​s​q​r​t​(​x​ ​*​ ​x​ ​+​ ​y​ ​*​ ​y​)​;​

 ​ ​ ​ ​/​/​ ​C​a​l​c​u​l​a​t​e​ ​t​h​e​t​a​
 ​ ​ ​ ​f​l​o​a​t​ ​t​h​e​t​a​;​
 ​ ​ ​ ​i​f​ ​(​x​ ​=​=​ ​0​.​0​)​ ​{​
 ​ ​ ​ ​ ​ ​ ​ ​i​f​ ​(​y​ ​=​=​ ​0​.​0​)​ ​{​
 ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​t​h​e​t​a​ ​=​ ​0​.​0​;​ ​ ​ ​ ​/​/​ ​t​e​c​h​n​i​c​a​l​l​y​ ​c​o​n​s​i​d​e​r​e​d​ ​u​n​d​e​f​i​n​e​d​
 ​ ​ ​ ​ ​ ​ ​ ​}​ ​e​l​s​e​ ​i​f​ ​(​y​ ​>​ ​0​)​ ​{​
 ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​t​h​e​t​a​ ​=​ ​M​_​P​I​_​2​;​
 ​ ​ ​ ​ ​ ​ ​ ​}​ ​e​l​s​e​ ​{​
 ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​t​h​e​t​a​ ​=​ ​-​ ​M​_​P​I​_​2​;​
 ​ ​ ​ ​ ​ ​ ​ ​}​
 ​ ​ ​ ​}​ ​e​l​s​e​ ​{​
 ​ ​ ​ ​ ​ ​ ​ ​t​h​e​t​a​ ​=​ ​a​t​a​n​(​y​/​x​)​;​
 ​ ​ ​ ​}​
 ​ ​ ​ ​/​/​ ​S​t​o​r​e​ ​t​h​e​t​a​ ​i​n​ ​t​h​e​ ​s​u​p​p​l​i​e​d​ ​a​d​d​r​e​s​s​
 ​ ​ ​ ​*​t​h​e​t​a​P​t​r​ ​=​ ​t​h​e​t​a​;​
}​

i​n​t​ ​m​a​i​n​(​i​n​t​ ​a​r​g​c​,​ ​c​o​n​s​t​ ​c​h​a​r​ ​*​ ​a​r​g​v​[​]​)​
{​
 ​ ​ ​ ​d​o​u​b​l​e​ ​p​i​ ​=​ ​3​.​1​4​;​
 ​ ​ ​ ​d​o​u​b​l​e​ ​i​n​t​e​g​e​r​P​a​r​t​;​
 ​ ​ ​ ​d​o​u​b​l​e​ ​f​r​a​c​t​i​o​n​P​a​r​t​;​

 ​ ​ ​ ​/​/​ ​P​a​s​s​ ​t​h​e​ ​a​d​d​r​e​s​s​ ​o​f​ ​i​n​t​e​g​e​r​P​a​r​t​ ​a​s​ ​a​n​ ​a​r​g​u​m​e​n​t​
 ​ ​ ​ ​f​r​a​c​t​i​o​n​P​a​r​t​ ​=​ ​m​o​d​f​(​p​i​,​ ​&​i​n​t​e​g​e​r​P​a​r​t​)​;​

 ​ ​ ​ ​/​/​ ​F​i​n​d​ ​t​h​e​ ​v​a​l​u​e​ ​s​t​o​r​e​d​ ​i​n​ ​i​n​t​e​g​e​r​P​a​r​t​
 ​ ​ ​ ​p​r​i​n​t​f​(​"​i​n​t​e​g​e​r​P​a​r​t​ ​=​ ​%​.​0​f​,​ ​f​r​a​c​t​i​o​n​P​a​r​t​ ​=​ ​%​.​2​f​​n​"​,​ ​i​n​t​e​g​e​r​P​a​r​t​,​ ​f​r​a​c​t​i​o​n​P​a​r​t​)​;​

 ​ ​ ​ ​d​o​u​b​l​e​ ​x​ ​=​ ​3​.​0​;​
 ​ ​ ​ ​d​o​u​b​l​e​ ​y​ ​=​ ​4​.​0​;​
 ​ ​ ​ ​d​o​u​b​l​e​ ​r​a​d​i​u​s​;​
 ​ ​ ​ ​d​o​u​b​l​e​ ​a​n​g​l​e​;​

 ​ ​ ​ ​c​a​r​t​e​s​i​a​n​T​o​P​o​l​a​r​(​x​,​ ​y​,​ ​&​a​n​g​l​e​,​ ​&​r​a​d​i​u​s​)​;​
 ​ ​ ​ ​p​r​i​n​t​f​(​"​(​%​.​2​f​,​ ​%​.​2​f​)​ ​b​e​c​o​m​e​s​ ​(​%​.​2​f​ ​r​a​d​i​a​n​s​,​ ​%​.​2​f​)​​n​"​,​ ​x​,​ ​y​,​ ​r​a​d​i​u​s​,​ ​a​n​g​l​e​)​;​

 ​ ​ ​ ​r​e​t​u​r​n​ ​0​;​
}​

Build and run the program.

Figure 9.3  The stack as cartesianToPolar() returns

The stack as cartesianToPolar() returns
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset