CSC 115.005/006 Sonoma State University Spring 2022
Scribbler 2
CSC 115.005/006:
Programming I
Scribbler 2
Instructor: Henry M. Walker

Lecturer, Sonoma State University
Professor Emeritus of Computer Science and Mathematics, Grinnell College


Course Home References Course Details: Syllabus, Schedule, Deadlines, Topic organization MyroC Documentation Project Scope/
Acknowledgments

Notes:

Laboratory Exercise on Functions with Addresses as Parameters

Work Started in Class

Finding the Perimeter and Area of a Rectangle

The lab on program management and functions asked you to write two functions related to circles: one computed the circumference given the radius, and the second computed the area given the radius. Today's reading then developed a program that performed both computations in the same procedure and used address parameters to store the results in the main program.

Following the same approach, program perim-area-1.c computes the perimeter and area of a rectangle, given the lengths of the two sides.

  1. Copy perim-area-1.c to your account. compile and run it, and review how the program works.

    1. Following the approach of the reading on the run-time stack, draw a schematic diagram of main memory after the function perimeter has been called; and draw a second schematic diagram of main memory after the function area has been called.

    2. In C, the address operator (&) allows one to determine the location or address in main memory where a variable is located. Make the following insertions into perim-area-1.c:

      Insert into perimeter just before the return statement:

        printf ("parameter side1:  location: %u, value: %lf\n", 
                (unsigned int) &side1, side1);
        printf ("parameter side2:  location: %u, value: %lf\n", 
                (unsigned int) &side2, side2);
        printf ("local lengthPlusWidth:  location: %u, lengthPlusWidth: %lf\n", 
                (unsigned int) &lengthPlusWidth, lengthPlusWidth);
      

      Insert into area just before the return statement:

        printf ("parameter side1:  location: %u, value: %lf\n", 
                (unsigned int) &side1, side1);
        printf ("parameter side2:  location: %u, value: %lf\n", 
                (unsigned int) &side2, side2);
      

      Insert into main just before the return statement:

        printf ("variable length:  location: %u, value: %lf\n",
                (unsigned int) &length, length);
        printf ("variable width:   location: %u, value: %lf\n",
                (unsigned int) &width, width);
        printf ("variable perim:   location: %u, value: %lf\n",
                (unsigned int) &perim, perim);
        printf ("variable area:    location: %u, value: %lf\n",
                (unsigned int) &ar, ar);
      

      Note: In this code, format %u prints a decimal integer, but ignores any initial minus sign. (We will talk more about signed and unsigned integers later in the course, when we study the representation of different types of data within a computer.)

      Recompile and rerun your program. To interpret the output, suppose that the first printf statement in the perimeter function produced the output:

        parameter side1:  location: 28580, value: 5.00000
      

      This indicates that the parameter side1 corresponds to memory location 28580, and the value 5.0 is stored there. This part of the schematic diagram might look like:


      main

      Use the address information from the inserted print statements to annotate the schematic diagrams from Step 1a with the actual locations or addresses where each parameter and variable was stored.

Program perim-area-1.c computed perimeter and area in two functions, because each function can only return one value. To obtain more than one result from a function, we have to change the nature of the parameters. This is illustrated in perim-area-2.c


Passing Values and Addresses as Parameters

Be sure you have completed the reading on passing values and addresses as parameters before continuing with this lab!

  1. Copy perim-area-2.c, compile and run it, and check that it produces exactly the same output as perim-area.1.c

    To understand how perim-area-2.c works, several print statements have been added to yield program perim-area-2a.c. Compile and run this program.

    When the program was run on one machine, the program generated the following output:

    working with a rectangle of width 7.000000 and length 5.000000
    compute:  addresses, values, and pointer references
                 side1:  address: 640370600, value: 5.000000
                 side2:  address: 640370592, value: 7.000000
       lengthPlusWidth:  address: 640370616, value: 12.000000
       perimeter:        address: 640370584, value: 640370664, *perimiter: 24.000000
       area:             address: 640370576, value: 640370656, *area: 35.000000
    the rectangle's perimeter is 24.000000
    the rectangle's area is 35.000000
    main:  variable addresses and values
       length:  address: 640370680, value: 5.000000
       width:   address: 640370672, value: 7.000000
       perim:   address: 640370664, value: 24.000000
       ar:      address: 640370656, value: 35.000000
    

    This information gives rise to the following schematic for main memory that would have been encountered immediately before the compute procedure finished.


    main

    As we shall discover later in the course, each double requires 8 units (technically called bytes) of memory, so many of the locations given are 8 numbers apart.

    Now run perim-area-2.c, yourself, show the output obtained, and answer the following based on your output.

    1. Explain why the values stored in main memory for side1 and side2 duplicate the numbers stored in main memory for length and width, respectively.

    2. The printf statement involving perimeter in compute indicates

      • the address of perimeter (i.e., &perimeter) is 640370584; that is the variable perimeter is stored at location 640370584
      • the value stored for perimeter is 640370664; note that this is the location of the perim variable in main
      • the value referenced by the location stored in perimeter (i.e., the value stored in perim) is 24.00000.

      Write similar statements about what is printed regarding the parameter area.

Write your own function

  1. Write a program that reads the width, length, and height of a box and computes the volume and surface area of the box. In this program,

    • the reading of user input from the terminal should be done in the main program.
    • results of the computation should be printed in the main program.
    • computation of volume and surface should be done in a separate compute_rect procedure.
    • the program may have no global variables, so the program will need to use parameters with addresses for volume and surface area within the compute_rect procedure.

Practice with parameters and the run-time stack

  1. Copy program amp-example.c to your account.

    1. Write a few sentences explaining what the program does.
    2. Draw a schematic diagram of main memory for just before valIncrease finishes.
    3. Draw another schematic diagram of main memory for just before refIncrease finishes.
  2. Consider the program practice-param-1.c.

    1. Copy this program to your account.
    2. Compile and run this program. Show the output printed, and explain each value obtained.
    3. Using your output as a base, draw a schematic memory diagram, showing variables and their values just before the pr procedure finishes.
    4. Edit out the address operation & in the call pr (x, &y), and make the corresponding changes in the pr procedure itself (e.g., remove the * as needed). Recompile and run. Again, explain why the resulting output occurs.

Homework

  1. Consider the program practice-param-2.c.

    1. Copy this program to your account.
    2. Compile and run this program, show the program's output, and explain each value obtained.
    3. Using your program's output as a base, draw a schematic memory diagram, showing variables and their values just before the pr procedure finishes.
    4. Add the declaration int w = 100; as the first statement in the main procedure (before the declaration int x = 3;). Recompile and rerun your program. Does the output change? Explain. Does the result depend upon the value assigned to w? Why or why not?
    5. Add the declaration int z = 25; immediately after the declaration of y in main. Recompile and rerun. Again, does the output change? Why or why not?
    6. Within the printf statements for pr, change each a to *a and each b to *b. Recompile, rerun your program, and explain the resulting output.
    7. Replace the line *a = *b; by the statement a = b;. Again, recompile and rerun, and explain the resulting output.
    8. Replace the same line (now a = b;) by the statement *a = b;. Try to predict what will be printed. Then recompile, rerun the program, and explain what happens.
    9. Change *a = b; back to *a = *b;, and change the subsequent assignment *b = 6; to *a = 6;. Again, predict, recompile, rerun, and explain.
  2. Consider the program practice-param-3.c.

    1. Copy this program to your account.
    2. Compile and run this program, show the output obtained, and explain each value printed.
    3. Using the program's output as a base, draw a schematic memory diagram, showing variables and their values just before the prA procedure finishes.
    4. Within the printf statements, change each *s to s and each *b to b. Recompile, rerun, and explain, as before.
    5. Within prA, change each *s to s. Recompile, rerun, and explain.
    6. Within prA, change each r to *r. Recompile, ... .


Steps 1, 2, 4:
  • created 20 July 2011 by Erik Opavsky
  • revised 29 July 2011 by Erik Opavsky and Dilan Ustek
  • revised 12 October 2011 by Erik Opavsky
  • revised 31 October 2011 by Henry M. Walker
  • revised (step 6 reworded) 22 July 2012 by Henry M. Walker
Steps 5-7:
  • created 22 July 2012 by Henry M. Walker
  • revised 22 July 2012 by Henry M. Walker
composite editing 22 July 2012 by Henry M. Walker
minor editing, typo fixed 13 October 2013 by Henry M. Walker
introductory material expanded 30-31 January 2014 by Henry M. Walker
readings added 19 September 2014 by Henry M. Walker
wording refined for passing values and addresses as parameters 21 September 2014 by Henry M. Walker
addition of Step 3, editing, and reformatting 15-16 August 2016 by Henry M. Waker
Valid HTML 4.01! Valid CSS!
For more information, please contact Henry M. Walker at walker@cs.grinnell.edu.