Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

larswik

macrumors 68000
Original poster
Sep 8, 2006
1,552
11
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 check before: 0
The Values read: C10101020
the check after: 1

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
 
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
 
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.
 
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
 
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.
 
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

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.
 
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
 
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
 
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

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
 
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 ?
 
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
 
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 ?

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.
 
I see thank you. I will convert that boolean to a 1.

Thanks!

-Lars
 
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?
 
Last edited:
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?

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.
 
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
 
Or something to that effect...
Code:
ALLINRANGE:=(INRANGE(A) AND INRANGE(B)) AND (INRANGE (C) AND INRANGE (D))
might actually be cleaner.

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.
 
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
I almost beat ya to it. I just couldn't decide what to name the suggested arguments. :p
 
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
 
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
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.