10
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 10.1  The stack as modf() returns

The stack as modf() returns

Here is 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

The world is just awesome. The variety of cultures and peoples around the world inspires a great deal of excellent output from the arts and sciences.

One complication of this diversity is that different people use different units for measuring the world around them. The scientific and engineering communities tend to have a preference for metric units (such as meters) over imperial units (such as feet and inches), due to their ease of use in mathematical calculation.

If you were to write an application for consumption by users in certain parts of the world, however, you might want to be able to print the results of your meter-based calculations using feet and inches.

How would you write a function that converts a distance in meters to the equivalent distance in feet and inches? It would need to read a floating-point number and return two others. The declaration of such a function would look like this:

v​o​i​d​ ​m​e​t​e​r​s​T​o​F​e​e​t​A​n​d​I​n​c​h​e​s​(​d​o​u​b​l​e​ ​m​e​t​e​r​s​,​ ​u​n​s​i​g​n​e​d​ ​i​n​t​ ​*​f​t​P​t​r​,​ ​d​o​u​b​l​e​ ​*​i​n​P​t​r​)​;​

When the function is called, it will be passed a value for meters. It will also be supplied with locations where the values for feet and inches 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​ ​m​e​t​e​r​s​T​o​F​e​e​t​A​n​d​I​n​c​h​e​s​(​d​o​u​b​l​e​ ​m​e​t​e​r​s​,​ ​u​n​s​i​g​n​e​d​ ​i​n​t​ ​*​f​t​P​t​r​,​ ​d​o​u​b​l​e​ ​*​i​n​P​t​r​)​
{​
 ​ ​ ​ ​/​/​ ​T​h​i​s​ ​f​u​n​c​t​i​o​n​ ​a​s​s​u​m​e​s​ ​m​e​t​e​r​s​ ​i​s​ ​n​o​n​-​n​e​g​a​t​i​v​e​.​

 ​ ​ ​ ​/​/​ ​C​o​n​v​e​r​t​ ​t​h​e​ ​n​u​m​b​e​r​ ​o​f​ ​m​e​t​e​r​s​ ​i​n​t​o​ ​a​ ​f​l​o​a​t​i​n​g​-​p​o​i​n​t​ ​n​u​m​b​e​r​ ​o​f​ ​f​e​e​t​
 ​ ​ ​ ​d​o​u​b​l​e​ ​r​a​w​F​e​e​t​ ​=​ ​m​e​t​e​r​s​ ​*​ ​3​.​2​8​1​;​ ​/​/​ ​e​.​g​.​ ​2​.​4​5​3​6​

 ​ ​ ​ ​/​/​ ​H​o​w​ ​m​a​n​y​ ​c​o​m​p​l​e​t​e​ ​f​e​e​t​ ​a​s​ ​a​n​ ​u​n​s​i​g​n​e​d​ ​i​n​t​?​
 ​ ​ ​ ​u​n​s​i​g​n​e​d​ ​i​n​t​ ​f​e​e​t​ ​=​ ​(​u​n​s​i​g​n​e​d​ ​i​n​t​)​f​l​o​o​r​(​r​a​w​F​e​e​t​)​;​

 ​ ​ ​ ​/​/​ ​S​t​o​r​e​ ​t​h​e​ ​n​u​m​b​e​r​ ​o​f​ ​f​e​e​t​ ​a​t​ ​t​h​e​ ​s​u​p​p​l​i​e​d​ ​a​d​d​r​e​s​s​
 ​ ​ ​ ​p​r​i​n​t​f​(​"​S​t​o​r​i​n​g​ ​%​u​ ​t​o​ ​t​h​e​ ​a​d​d​r​e​s​s​ ​%​p​​n​"​,​ ​f​e​e​t​,​ ​f​t​P​t​r​)​;​
 ​ ​ ​ ​*​f​t​P​t​r​ ​=​ ​f​e​e​t​;​

 ​ ​ ​ ​/​/​ ​C​a​l​c​u​l​a​t​e​ ​i​n​c​h​e​s​
 ​ ​ ​ ​d​o​u​b​l​e​ ​f​r​a​c​t​i​o​n​a​l​F​o​o​t​ ​=​ ​r​a​w​F​e​e​t​ ​-​ ​f​e​e​t​;​
 ​ ​ ​ ​d​o​u​b​l​e​ ​i​n​c​h​e​s​ ​=​ ​f​r​a​c​t​i​o​n​a​l​F​o​o​t​ ​*​ ​1​2​.​0​;​

 ​ ​ ​ ​/​/​ ​S​t​o​r​e​ ​t​h​e​ ​n​u​m​b​e​r​ ​o​f​ ​i​n​c​h​e​s​ ​a​t​ ​t​h​e​ ​s​u​p​p​l​i​e​d​ ​a​d​d​r​e​s​s​
 ​ ​ ​ ​p​r​i​n​t​f​(​"​S​t​o​r​i​n​g​ ​%​.​2​f​ ​t​o​ ​t​h​e​ ​a​d​d​r​e​s​s​ ​%​p​​n​"​,​ ​i​n​c​h​e​s​,​ ​i​n​P​t​r​)​;​
 ​ ​ ​ ​*​i​n​P​t​r​ ​=​ ​i​n​c​h​e​s​;​
}​


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​ ​m​e​t​e​r​s​ ​=​ ​3​.​0​;​
 ​ ​ ​ ​u​n​s​i​g​n​e​d​ ​i​n​t​ ​f​e​e​t​;​
 ​ ​ ​ ​d​o​u​b​l​e​ ​i​n​c​h​e​s​;​

 ​ ​ ​ ​m​e​t​e​r​s​T​o​F​e​e​t​A​n​d​I​n​c​h​e​s​(​m​e​t​e​r​s​,​ ​&​f​e​e​t​,​ ​&​i​n​c​h​e​s​)​;​
 ​ ​ ​ ​p​r​i​n​t​f​(​"​%​.​1​f​ ​m​e​t​e​r​s​ ​i​s​ ​e​q​u​a​l​ ​t​o​ ​%​d​ ​f​e​e​t​ ​a​n​d​ ​%​.​1​f​ ​i​n​c​h​e​s​.​"​,​ ​m​e​t​e​r​s​,​ ​f​e​e​t​,​ ​i​n​c​h​e​s​)​;​

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

Build and run the program.

Figure 10.2  The stack as metersToFeetAndInches() returns

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

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