Pascal Function

Discussion in 'Mac Programming' started by larswik, Mar 31, 2011.

  1. larswik macrumors 68000

    Joined:
    Sep 8, 2006
    #1
    I am working on Functions for my class and I am testing to make sure the input values are valid. As a test I am reading in the first line of data which is 'C 10 10 10 20'. I set the variable 'Check' to 0; then if I send those values through a function and if the values of those 4 numbers are higher or lower it should change the value of Check from 0 to 1.

    The end result should be 0 before and after the function but it is returning 1.

    Code:
    program chap9(infile, outfile);
    
    var
    	ch : char;
    	check,A,B,C,D : integer;
    	infile, outfile : text;
    	
    FUNCTION INRANGE(A,B,C,D:integer):integer;
    
    	begin
    		if ((A < 10) OR (A > 20))
    			then INRANGE := 1;
    		if ((B < 10) OR (B > 20))
    			then INRANGE := 1;
    		if ((C < 10) OR (C > 20))
    			then INRANGE := 1;
    		if ((D < 10) OR (D > 20))
    			then INRANGE := 1;
    	end;
    begin
    reset(infile);
    rewrite(outfile);
    check := 0;
    
    WHILE NOT EOLN(infile) do
    	begin
    		writeln(outfile,'the check before: ',check); (* displays what check is*)
    		READ(infile, ch, A,B,C,D);
    		writeln(outfile,'The Values read: ',ch , A , B , C , D);
    		check := INRANGE(A,B,C,D);
    		writeln(outfile, 'the check after: ', check);
    	end;
    	readln(infile);
    end.
    
    result from the file out
    The values are bunched together for now since I have not put a separator between them so instead of C 10 10 10 20 it is C10101020.

    Thanks,

    -Lars
     
  2. larswik thread starter macrumors 68000

    Joined:
    Sep 8, 2006
    #2
    Never Mind, I figured it out after I wrote all of this. I guess it helped me write my question here.

    It seems that the function had to return something. But after my last IF statement in that function I added
    Code:
    ELSE
     INRANGE := 0;
    
    Now it correctly returned 0 as the value. I still wonder why it returned a 1 if none of the IF statements evaluated as TRUE?

    Thanks,

    -Lars
     
  3. ramases macrumors member

    Joined:
    Jan 14, 2008
    #3
    What was the initial value of INRANGE?

    Call me old fashioned, I never like to use a variable/function unless I know I have initialised it first at some point.
     
  4. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #4
    So it looks like right now unless I am mis-remembering Pascal syntax, that if any of the numbers are inrange, then inrange returns 1. I think that inrange should only return 1 if ALL of the values are in range. This would mean either a larger if with all of the conditions AND'd together, or adding AND inrange = 1 to the last three conditions.

    -Lee
     
  5. knightlie macrumors 6502a

    Joined:
    Feb 18, 2008
    #5
    It depends on your compiler, but Pascal doesn't usually initialise local variables, so you may well have had a random value of 1 on there when the function started. Always initialise variables, just in case.
     
  6. Sydde macrumors 68020

    Sydde

    Joined:
    Aug 17, 2009
    #6
    The problem with that is if your second IF detects and out-of-range condition and sets the return value to 1, your ELSE might still set the return value to 0 if the last parameter is in range.

    Things like return values and internal variables live in a turbulent, active region where stuff changes constantly before and after your function. These temporary variables start out their brief existence filled with leftover values from whatever was last using the space assigned to them. You can never rely on the value of a variable unless you have already set it yourself.

    Hence, the very first line should set the zero return value for your function to work reliably.
     
  7. balamw Moderator

    balamw

    Staff Member

    Joined:
    Aug 16, 2005
    Location:
    New England
    #7
    A more typical construct to do what you want is to set the default return value first and override it if necessary. So, you should try putting the
    Code:
    INRANGE := 0;
    before any of the if statements rather than as an else after the fact.

    EDIT: This sat open in my browser for hours. Sydde already mentioned it, but I figured I'd post it anyhow.

    B
     
  8. larswik thread starter macrumors 68000

    Joined:
    Sep 8, 2006
    #8
    Thanks, I will try to initialize INRANGE with in the function as a local variable. I have a question. This function:

    FUNCTION INRANGE(A,B,C,D:integer):integer;

    First it's declared a function. Next the function name is INRANGE which takes 4 parameters of type INTEGER and then returns the value that will be type INTEGER. It looks like INRANGE is a variable since it returns the value. But it is not declared as a variable under the Vars so I don't see how I can initialize it? I seems like it is a pathway from my call to the function, here is the call again

    check := INRANGE(A,B,C,D);

    It is passing the value through INRANGE and stored in the variable check?

    Do I understand that right?

    -Lars
     
  9. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #9
    INRANGE is the name of the function, and the line assigning its result to check you are calling it properly. Inside of the INRANGE function the name INRANGE is a variable that stores the value that will be returned from the function when it completes. The first line of INRANGE should be:
    INRANGE := 0;

    -Lee
     
  10. larswik thread starter macrumors 68000

    Joined:
    Sep 8, 2006
    #10
    I get it. Even though I don't declare it it creates it's self as a temporary local variable that destroys it's self upon exiting the function.

    I would almost think INRANGE would be a global variable, not local. When I learned C (still learning) I would pass in the address of a variable as a parameter so the result of that function would be assigned to the variable that is outside the scope of that function.

    When the call to that function is made from Main, control is transferred to the function, data is processed and then control is returned back to Main where INRANGE is assigned to the variable CHECK in my code. But when control is returned to main that should destroy the local variable INRANGE from that function. So back in Main there should be nothing to assign to Check and should get a Syntax or runtime error ?
     
  11. balamw Moderator

    balamw

    Staff Member

    Joined:
    Aug 16, 2005
    Location:
    New England
    #11
    I just noticed that you actually have your pseudo boolean int bass-ackwards. I would do it this way:

    Code:
    FUNCTION INRANGE(A,B,C,D:integer):integer;
    
    	begin
    		INRANGE :=1;
    		if ((A < 10) OR (A > 20))
    			then INRANGE := 0;
    		if ((B < 10) OR (B > 20))
    			then INRANGE := 0;
    		if ((C < 10) OR (C > 20))
    			then INRANGE := 0;
    		if ((D < 10) OR (D > 20))
    			then INRANGE := 0;
    	end;
    
    By default if all values are in range the function will return 1 (a.k.a. "TRUE"), if any are out of range it will return 0 (a.k.a. "FALSE"). (Or, call your original function NOTINRANGE or OUTRANGE).

    B
     
  12. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #12
    Pascal and C have radically different syntax and semantics for functions. It's a major stumbling block if you're only familiar with one.

    First, Pascal has the separate keyword PROCEDURE. C only has functions. Second, C has an explicit 'return' keyword, and it can be used at any point in a function (early return, return from within loops, etc.). Pascal doesn't have 'return'. Third, Pascal has VAR parameters, C doesn't (but C++ does). If you want to modify an arg in C, you have to pass a pointer to a variable, and explicitly dereference it. Those are the top 3 major differences, but certainly not all.

    All the C-like languages are similar in these areas: C++, Java, even JavaScript.
     
  13. larswik thread starter macrumors 68000

    Joined:
    Sep 8, 2006
    #13
    I see thank you. I will convert that boolean to a 1.

    Thanks!

    -Lars
     
  14. Bill McEnaney, Mar 31, 2011
    Last edited: Mar 31, 2011

    Bill McEnaney macrumors 6502

    Joined:
    Apr 29, 2010
    #14
    Since there's some duplicate code in the INRANGE function, would it be good to rewrite that function and then call each time you want to test two pairs of integers?
     
  15. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #15
    Or write it in terms of a function with one arg. Check that one arg for in-range. Call function for each value A, B, C, D. Combine 4 results using AND operator.
     
  16. Bill McEnaney macrumors 6502

    Joined:
    Apr 29, 2010
    #16
    That's better than my idea.
     
  17. balamw Moderator

    balamw

    Staff Member

    Joined:
    Aug 16, 2005
    Location:
    New England
    #17
    Doesn't Pascal have a true Boolean type? (Though I don't know if this has been covered yet in larswik's course, so it may not be appropriate for the homework project.)

    Code:
    FUNCTION INRANGE(A:integer):boolean;
    	begin
    		INRANGE := TRUE;
    		if ((A < 10) OR (A > 20))
    			then INRANGE := FALSE;
    	end;
    
    FUNCTION ALLINRANGE(A,B,C,D:integer):boolean;
            begin
                    ALLINRANGE:=TRUE;
                    ALLINRANGE:=ALLINRANGE AND INRANGE(A); 
                    ALLINRANGE:=ALLINRANGE AND INRANGE(B); 
                    ALLINRANGE:=ALLINRANGE AND INRANGE(C); 
                    ALLINRANGE:=ALLINRANGE AND INRANGE(D); 
            end
    
    Or something to that effect...
    Code:
    ALLINRANGE:=(INRANGE(A) AND INRANGE(B)) AND (INRANGE (C) AND INRANGE (D))
    might actually be cleaner.

    NOTE: If you are returning an integer, you might as well make it return a flag that would allow you to tell which values are out of range or at least how many. Powers of 2 are handy here.

    B
     
  18. Bill McEnaney macrumors 6502

    Joined:
    Apr 29, 2010
    #18
    Code:
    FUNCTION INRANGE(A:integer):boolean;
       begin
          INRANGE :=  ((A < 10) OR (A > 20))
       end;
    Why not change the INRANGE function, too? You might even replace 10 and 20 with two more arguments to generalize the function.
     
  19. balamw Moderator

    balamw

    Staff Member

    Joined:
    Aug 16, 2005
    Location:
    New England
    #19
    I ultimately would have gone there. :p

    Although what I was going to suggest was to generalize the INRANGE so that the limits would be passed as arguments. i.e. INRANGE(A,10,20);

    B
     
  20. Bill McEnaney macrumors 6502

    Joined:
    Apr 29, 2010
    #20
    I almost beat ya to it. I just couldn't decide what to name the suggested arguments. :p
     
  21. balamw Moderator

    balamw

    Staff Member

    Joined:
    Aug 16, 2005
    Location:
    New England
    #21
    min/max? Lo/hi?

    B
     
  22. larswik thread starter macrumors 68000

    Joined:
    Sep 8, 2006
    #22
    Ok, now I have some more to think about how I want to do INRANGE. The Math part I need to get down.

    1. Sum of cubes = (A*A*A)+(B*B*B)+(C*C*C)+(D*D*D)
    2. Square of Cubes = (A*A)+(B*B)+(C*C)+(D*D)
    3. Average of Squares = ?. I know I need to add something up and guessing then I divided by the number of squares.

    Would it be this -> (A*A)+(B*B)+(C*C)+(D*D) / 4

    -Lars
     
  23. balamw Moderator

    balamw

    Staff Member

    Joined:
    Aug 16, 2005
    Location:
    New England
    #23
    That's sum of squares.

    B
     
  24. larswik thread starter macrumors 68000

    Joined:
    Sep 8, 2006
    #24
    Ahhh, sorry, I meant 'Sun of the Squares'.

    He wants 1. Sum of squares 2. Sum of cubes and 3. Average of the squares.

    I know the first 2 but number 3 I am not sure of. I did an internet search but could not find the answer. The Instructor explained all 3 in class but I only wrote down 2 of them. I took bad notes.

    Can you help me with the math or direct me to a page that has the math?

    Thanks!

    -Lars
     
  25. balamw Moderator

    balamw

    Staff Member

    Joined:
    Aug 16, 2005
    Location:
    New England
    #25
    The average of the squares is the sum of the squares divided by the number of squares. (Hint: reuse code or check your operator precedence for #3).

    B
     

Share This Page