So I have this piece of Pascal code:
program P;
var a: array [1..2] of Integer;
var i :Integer;
var k :Integer;
procedure update(x,y,z: Integer);
begin
x := x+1;
y := x*2;
x := y;
k := x;
end
begin
a[1] := 5; a[2] := 10;
k := 3;
for i:=1 to 2 do
begin
update(a[i],a[2],k);
print(a);
print(k)
end
end.
(assume that 'print' prints elements of array separated by spaces, and then prints a new line and also for an integer it just prints it)
And i'm trying to understand how different the output would be if the function call was by value-result or by reference.
obviously, if it was just by-value, it's easy to tell that the procedure wouldn't make any difference to the actual parameter, i.e the output (in by value) should be: 5 10 3 5 10 3.
I think that if it was be value-result it would have been, at least the first iteration: 12 12 12.
at the case of by reference I got confused.
What would it be?
You haven't declared any variable parameters. The variable K will be changed, but that doesn't count in this context and is generally considered bad practice.
PROGRAM ParamTest;
VAR
A, B : Integer;
PROCEDURE TestProc(X : Integer; VAR Y : Integer; CONST Z : Integer);
BEGIN
X := X + Z;
Y := Y + Z;
END;
BEGIN
A := 10;
B := 10;
TestProc(A, B, 5);
WriteLn(A, ' ', B);
END.
X : Call by value
Y : Call by reference
Z : Call by constant
The output of this program should be 10 15.
With declaring Zas constant parameter you promise to the compiler that you don't change that value. The following procedure variant should give an error while compiling.
PROCEDURE TestProc(X : Integer; VAR Y : Integer; CONST Z : Integer);
BEGIN
X := X + Z;
Y := Y + Z;
Z := Z + 1;
END;
Related
i have a problem developing this function, i have this text..
Testing Function
ok
US.Cool
rwgehtrhjyw54 US_Cool
fhknehq is ryhetjuy6u24
gflekhtrhissfhejyw54i
my function :
function TForm5.FindWordInString(sWordToFind, sTheString : String): Integer;
var
i : Integer; x:String;
begin
Result := 0;
for i:= 1 to Length(sTheString) do
begin
x := Copy(sTheString,i,Length(sWordToFind));
if X = sWordToFind then
begin
if X.Length > sWordToFind.Length then
begin
Result := 100;
break;
end else
begin
Result := i;
break;
end;
end;
end;
end;
now, i want X to be US.Cool, but here its always = US, because i want to check the length of sWordToFind and X.
After clarification, this question is about getting length of a word searched by its starting substring within a string. For example when having string like this:
fhknehq is ryhetjuy6u24
When you execute a desired function for the above string with the following substrings, you should get results like:
hknehq → 0 → substring is not at the beginning of a word
fhknehq → 7 → length of the word because substring is at the beginning of a word
yhetjuy6u24 → 0 → substring is not at the beginning of a word
ryhetjuy6u24 → 12 → length of the word because substring is at the beginning of a word
If that is so, I would do this:
function GetFoundWordLength(const Text, Word: string): Integer;
const
Separators: TSysCharSet = [' '];
var
RetPos: PChar;
begin
Result := 0;
{ get the pointer to the char where the Word was found in Text }
RetPos := StrPos(PChar(Text), PChar(Word));
{ if the Word was found in Text, and it was at the beginning of Text, or the preceding
char is a defined word separator, we're at the beginning of the word; so let's count
this word's length by iterating chars till the end of Text or until we reach defined
separator }
if Assigned(RetPos) and ((RetPos = PChar(Text)) or CharInSet((RetPos - 1)^, Separators)) then
while not CharInSet(RetPos^, [#0] + Separators) do
begin
Inc(Result);
Inc(RetPos);
end;
end;
I spend a few times on your idea, so i wrote below codes, but it is not a good way for develop a Start With search. with some research you can find builtin functions, that provide better performance. you can try StrUtils.SearchBuf Function it will provide a full function string search.
anyway this code are working with SPACE separator, I hope it will be useful for you:
function TForm5.FindWordInString(sWordToFind, sTheString : String): Integer;
var
i : Integer; x:String;
flag : Boolean;
begin
Result := 0;
i := 1;
flag := False;
while True do
begin
if i > Length(sTheString) then Break;
if not flag then
x := Copy(sTheString,i,Length(sWordToFind))
else
begin
if sTheString[i] = ' ' then Break;
x := x + sTheString[i];
end;
if (X = sWordToFind) then
begin
flag := True;
if (X.Length >= sWordToFind.Length) and
(sTheString[i + Length(sWordToFind)] = ' ') then
break
else
i := i + Length(sWordToFind) -1;
end;
i := i + 1;
end;
Result := Length(x);
end;
Is there any proper example for explaining call-by-result ? (not pseudocode)
I have learned that ALGOL 68, Ada could use this way,
but I cannot find any clear example of Call-by-Result.
I just made by myself.
pseudocode
begin
integer n;
procedure p(k: integer);
begin
n := n+1;
k := k+4;
print(n);
end;
n := 0;
p(n);
print(n);
end;
Implement using Ada Language
call.adb
with Gnat.Io; use Gnat.Io;
procedure call is
x : Integer;
Procedure NonSense (A: in out integer) is
begin
x := x + 1;
A := A + 4;
Put(x);
end NonSense;
begin
x := 0;
NonSense (x);
Put(" ");
Put(x);
New_Line;
end call;
Since Ada uses call-by-result way, result should be 1 4. (It could be checked by entering this code into online-Ada-compiler "http://www.tutorialspoint.com/compile_ada_online.php")
And, other result applied different passing parameter types should be...
call by value: 1 1
call by reference: 5 5
(compare > call by value-result: 1 4)
I'm writing a procedure to do the calculating. The program asks the user for any number between 1 and 9999 and then calculates whether or not that number is a happy number.
program EindEvaluatieProceduresFuncties2;
uses wincrt, math;
var lucky: boolean;
num: longint;
i, j: integer;
arr: array [1..4] of integer;
sum: integer;
procedure HappyNumber;
begin
repeat
begin
repeat
begin
i:=i+1;
//writeln('i = ',i);
arr[i]:=num mod 10;
//writeln( 'a[i] = ', arr[i] );
num:=num div 10;
//writeln ( 'n = ', num );
end;
until num=0;
//writeln('Digits are : ');
//for j:=i downto 1 do
//writeln('a[j] = ', arr[j],' ', j);
//writeln('Calculating Happy Number');
for j := i downto 1 do
sum := sum + (Sqr(arr[j]));
for j := i downto 1 do
writeln('sum = ',sum);
num := sum;
end;
until sum < 10 ;
end;
begin
lucky := false;
writeln('Please give a positive number below 10000.');
readln(num);
while ( num < 1 ) or ( num > 9999 ) do
begin
writeln('Number must be positive and less than 10000. Try again.');
readln(num);
end;
HappyNumber;
if (lucky = True) then
begin
writeln(num, ' is a happy number.');
end
else
begin
writeln(num, ' is not a happy number.');
end;
writeln('');
writeln('Press < ENTER > to end the program.');
readln;
end.
Within the procedure I have the command i := 0; as seen below:
procedure HappyNumber;
begin
repeat
begin
repeat
begin
i:=0;
i:=i+1;
This is where the problem occurs. If I do this it becomes an infinite loop, however if I place the command outside of the repeat loop then i does not reset to 0 at the beginning of every iteration of the loop, which I need it to.
I should point out that much of the code is there at the moment simply to let me see what is happening and wont be a part of the final code. Wherever I have inserted "//" are those lines.
I am aware that there is perhaps a better way I could be doing this whole program. If anyone has any suggestions for how I can make it easier, I'd also appreciate that very much.
Thank you.
Never heard of happy / unhappy numbers and found it quite interesting to solve this task :-)
There is still a lot to optimize but I think you can use it for studying.
program EindEvaluatieProceduresFuncties2;
uses SysUtils, crt ;
var input: string;
number: integer;
code: integer;
function HapyNumber(num: integer):boolean;
var
erg: integer;
digit: integer;
begin
Result := true;
erg := 0;
if num = 4 then Result := false;
if num = 4 then exit;
if num = 1 then exit;
if num = 0 then exit;
// serialize the number into digits and calculate the next number
while num > 0 do begin
digit := num mod 10;
num := num div 10;
erg := erg + digit * digit;
write(IntToStr(digit) + ' ');
end;
write(IntToStr(num) + ' ');
writeln('=' + IntToStr(erg));
Result := HapyNumber(erg);
end;
begin
repeat
writeln('Please give a positive number below 10000.' + sLineBreak + 'Number must be positive and less than 10000.' + sLineBreak + 'Type x for exit!');
readln(input);
if lowerCase(input) = 'x' then exit;
val(input, number, code);
if code <> 0 then begin
ClrScr;
writeln('Invalid number "' + input + '" !');
end
else if (number > 0) and (number <= 9999) then begin
ClrScr;
writeln('Cheking ' + IntToStr(number) + '..');
if HapyNumber(number) then writeln(number, ' is a happy number.')
else writeln(number, ' is not a happy number.');
writeln('Press enter to continue');
readln;
ClrScr;
end;
until lowerCase(input) = 'x';
end.
The important codepart is
while num > 0 do begin
digit := num mod 10;
num := num div 10;
erg := erg + digit * digit;
write(IntToStr(digit) + ' '); // just output the tmp result
end;
It serialize a number into digits (1973 will be 3 7 9 1)
I used recursion just for fun and it is not really necessary :-)
I have the following program:
begin
integer i;
procedure pass(x, y);
integer x, y;
begin
x := x+1;
y := x+1;
x := y;
i := i+ 1
end
i := 1;
pass(i,i);
print i
end
I can work through the pass-by-value answer, but what would the pass-by-reference and pass-by-value-result traces look like?
is there a way to compare the content of a cell in a grid against the content of a variable.
I need to compare cell 0,1 and if it's value is lower (or higher) than variable x then something happens.
I'm using Lazarus and a StringGrid.
You can try something like this (for integer values, but can easily be modified for another ordinal types). You can follow the commented version of this post as well:
uses
Math;
function CompareValueEx(StringGrid: TStringGrid; const Column, Row: Integer;
const Value: Integer; out Relationship: TValueRelationship): Boolean;
var
Output: Integer;
begin
Result := TryStrToInt(StringGrid.Cells[Column, Row], Output);
if Result then
Relationship := CompareValue(Value, Output);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
I: Integer;
Relationship: TValueRelationship;
begin
I := 111;
StringGrid1.Cells[1, 2] := '112';
if CompareValueEx(StringGrid1, 1, 2, I, Relationship) then
begin
case Relationship of
EqualsValue: ShowMessage('The values are the same');
LessThanValue: ShowMessage('The I value is less than in cell [1;2]');
GreaterThanValue: ShowMessage('The I value is greater than in cell [1;2]');
end;
end
else
ShowMessage('The value in cell [1;2] is not a valid integer value!');
end;