Let's suppose we are in this case (I'm using Maple)
add:=function()
e1:=0;
e2:=1;
for j in [1..2]do
ej:=ej+1
od;
return e1,e2;
end;
This program gives me a global variable error. I understand why that happens -- because ej is not defined as local -- but if you define it then the program just doesn't do anything. ) I don't know how to solve it. My objective (in a bigger program) is to call e1,e2 in a for loop.
Maybe I didn't express myself correctly simplifying my problem, there is my Program, it is made with program GAP but it works similar to Maple:
G12Decode:=function(c)
localx,G,C,sG,sH,a,u,b1,e1,b2,e2,b3,e3,b4,e4,b5,e5,b6,e6,h1,h2,i,j;
x:=Codeword(c,GF(3));
G:=[[1,0,0,0,0,0,0,1,1,1,1,1],[0,1,0,0,0,0,1,0,1,2,2,1],
[0,0,1,0,0,0,1,1,0,1,2,2],[0,0,0,1,0,0,1,2,1,0,1,2],
[0,0,0,0,1,0,1,2,2,1,0,1],[0,0,0,0,0,1,1,1,2,2,1,0]];
C:=GeneratorMatCode(G,GF(3));
sG:=x*TransposedMat(GeneratorMat(C));
sH:=x*TransposedMat(CheckMat(C));
a:=[0,0,0,0,0,0];
b1:=Codeword([0,1,1,1,1,1],GF(3));
e1:=Codeword([1,0,0,0,0,0],GF(3));
b2:=Codeword([1,0,1,2,2,1],GF(3));
e2:=Codeword([0,1,0,0,0,0],GF(3));
b3:=Codeword([1,1,0,1,2,2],GF(3));
e3:=Codeword([0,0,1,0,0,0],GF(3));
b4:=Codeword([1,2,1,0,1,2],GF(3));
e4:=Codeword([0,0,0,1,0,0],GF(3));
b5:=Codeword([1,2,2,1,0,1],GF(3));
e5:=Codeword([0,0,0,0,1,0],GF(3));
b6:=Codeword([1,1,2,2,1,0],GF(3));
e6:=Codeword([0,0,0,0,0,1],GF(3));
if Weight(sH)<=2 then
sH:=ShallowCopy(VectorCodeword(sH));
Append(a,sH);
a:=Codeword(a,GF(3));
u:=x-a;
return u;
elif Weight(sG)<=2 then
sG:=ShallowCopy(VectorCodeword(sG));
Append(sG,a);
sG:=Codeword(sG,GF(3));
u:=x-sG;
return u;
else
for i in [1..6] do
for j in [1..6] do
if sG-bi=ej or sG-bi=2*ej then
h1:=sG-bi;
h2:=ei;
h1:=ShallowCopy(VectorCodeword(h1));
h2:=ShallowCopy(VectorCodeword(h2));
Append(h1,h2);
h1:=Codeword(h1,GF(3));
u:=x-h1;
return u;
elif sG-2*bi=ej or sG-2*bi=2*ej then
h1:=sG-2*bi;
h2:=ei;
h1:=ShallowCopy(VectorCodeword(h1));
h2:=ShallowCopy(VectorCodeword(h2));
Append(h1,h2);
h1:=Codeword(h1,GF(3));
u:=x-h1;
return u;
fi;
od;
od;
fi;
end;
The program dont send me an error but i know it don't work because of the ej,bi and ei. I want to do what it says after the last "else" but i don't know how to solve it to make it work.
Your syntax is invalid. It is proc, not function.
And add is already a Maple command, so it's a protected name and cannot be assigned to. You have to use another name.
And your syntax for the do-loop is likely not what you want. You probably want for j from 1 to 2 do .
And you really should initialize ej with a value before doing the recursive assignment ej:=ej+1 .
And you might as well declare the procedure's local variables.
Personally, I favour using end do instead of od , and end proc instead of just end , in modern Maple. It makes it easier to tell what's being terminated.
For example,
restart;
my_add:=proc()
local e1,e2,ej,j;
e1:=0;
e2:=1;
ej:=0;
for j from 1 to 5 do
ej:=ej+1
end do;
return ej,e1,e2;
end proc:
my_add();
5, 0, 1
There is a Maple Programming Guide, which you can read online or inside Maple's own Help system. It has a nice introduction to writing procedures. And there is a more detailed Help page for the proc command.
I've got a question related to the way the for loop works in Pascal:
Program example;
var i:integer;
Begin
i:=7;
for i:=1 to i do write(i);
End.
This piece of code outputs: 1234567.
I think that the compiler makes a secondary copy of the variable i, and then uses that one in the for loop.
Note that this is REQUIRED to work in Pascal according to the ISO7185 standard. The "end value" should be copied before the loop counter is modified.
https://github.com/Leporacanthicus/lacsap/blob/master/test/Basic/iso7185pat.pas#L761
In the for loop in Pascal we have variable called loop counter which controls the iterations of the loop, and this variable changes in each iteration of the loop, so it's that i which is declared here: i:=1 in your code.
The second is the variable declared above the loop which is called also i but it's a variable which is the final value for the loop.
Consider this:
Program example;
var i:integer;
var addr:^word;
Begin
i:=10;
for i:=1 to i do addr:=#i;
addr^ := addr^+1; { I add 1 to the last loop counter }
writeln(i); { This is final variable, I don't add anything to the final variable of the loop }
writeln(addr^); { This is value of the last loop counter index }
{ Both variables give us the same result }
{ Proposal: In my opinion, your guess about the copy is correct }
End.
As in comment in the code - in my opinion, pascal creates a copy of this variable.
Hope it will help!
If yes please let me know by voting up.
Regards!
The point here is the Pascal compiler will set the parameters for the for once, at the first execution. Then it sets a start point i:=1 and and end point 7 before doing anything with the control value, then starts the loop.
But I should point that this is bad practice in programming. Unless you are just making an academical or speculative question, I see no reason to "save" a variable name doing something like this.
It is interesting to notice too that this abuse of the control variable name may cause unpredictable results if this is done inside the loop.
As they use to say in those programs who show dangerous adventures, don't try to do this at home!
I developed the following sorting algorithm but there are some run time errors that I cant figure out. The program terminates when it comes to the part of filling the array. I'm still a beginner in ada so I couldn't figure out where the problem is...
With Ada.Text_IO;
With Ada.Integer_Text_IO;
Use Ada.Integer_Text_IO;
Use Ada.Text_IO;
Procedure sort is
n,i,x : Integer;
-- Max_Heapify Function...
Procedure Max_Heapify ( i, n : integer) is
j, Temp : Integer;
begin
Temp:=Int_Acc(i);
j:=2*i;
if Temp>Int_Acc(j) then
elsif Temp<=Int_Acc(j) then
Int_Acc(j/2):=Int_Acc(j);
j:=2*j;
end if;
end loop;
Int_Acc(j/2):=Temp;
end Max_Heapify;
begin
Get(n);
for i in MyArr'range loop
Put_Line("Enter Element " & Integer'Image(i));
Get(MyArr(i));
end loop;
end;
end sort;
Thanks in advance :)
Your Problem is that you are insisting on writing Ada code using c - Style programming paradigms.
Firstly:
The declarations:
Type Arr is array(1..20) of Integer;
Type int_access is access Arr;
MyArr : int_access;
Where you use Int_Acc : in out int_access as parameters to procedures are useless in Ada. You are trying to pass a pointer to an array in (which you are doing!), but you should just pass your Type Arr as in out - The Ada compiler knows to do this as a pointer!
Secondly:
I cannot see where you actually allocate any memory to MyArr. This is a possible source of your runtime error. (when you write to or index an array that does not exist, i would expect to have a problem!)
Thirdly:
You seem to be mixing fixed length arrays with variable length input. If N > 20, you will have a problem.
Fourthly:
Insulting the language is not the best way of getting help from those who like it.
NWS has nailed it : there is a pointer, but no array there.
But it's clear that you have learned C, which leaves you with a lot to learn about other languages including Ada. There really are better ways of doing many things, that aren't taught to C programmers because C doesn't allow them.
Allocating variable sized arrays without pointers, malloc and free for example...
Type Arr is array(positive range <>) of Integer; -- of any size
begin
Put_Line("Enter Number Of Elements Of Array");
Get(n);
declare -- now we know the size
My_Arr : Arr(1 .. n);
begin -- My_Arr is in scope until the end of this block
...
end;
end sort;
Using the type system better...
Bad programming :
for i in 1 .. n loop
Get(MyArr(i));
end loop;
HeapSort(MyArr,n);
for i in 1 .. n loop
Put_Line(Integer'Image(MyArr(i)));
end loop;
This is bad because it violates the DRY principle : loop bounds repeated, and something that hopefully represents the array size passed around as a separate parameter... a maintenance nightmare if you decide to rename n to something meaningful for example.
better programming : Use the type system. Recognise that merely declaring an array has declared a new subtype of integer, representing the index of the array. You can access it as My_Arr'range, and the high bound as My_Arr'last.
for i in My_Arr'range loop
Get(MyArr(i));
end loop;
HeapSort(MyArr);
for i in My_Arr'range loop
Put_Line(Integer'Image(MyArr(i)));
end loop;
And accidents such as redefining n after the array declaration can no longer generate buffer overflows.
NOTE: Heapsort now gets its range from the array. (Max_Heapify may still need a separate parameter to operate on subsets of the array)
Arguably best - if it makes the intent clearer - name the index datatype explicitly and use it...
declare -- now we know the size
subtype My_Range is positive range 1 .. n;
My_Arr : Arr(My_Range);
begin -- My_Arr is in scope until the end of this block
for i in My_Range loop ...
And lastly, which do you prefer; a Storage_Error exception immediately the bug occurs (writing to memory you forgot to allocate) or something odd happening much later because something scribbled across another variable?
EDIT
Having cleared up the major issues two more subtle ones remain...
If I compile the modified program (in Gnat 4.8) I get several warnings : one of them is important and tells you exactly what the problem is...
Most of the warnings stem from the fact that
for i in My_Arr'range loop
declares its own loop variable i which hides any existing in-scope declaration. So you can tidy up the code by removing the unnecessary declarations.
What remains is:
sort.adb:51:28: warning: loop range may be null
sort.adb:51:28: warning: bounds may be wrong way round
The for loop bounds are empty ranges, reversed...
1 .. 3 declares a subtype with 3 values
reverse 1 .. 3 declares the same subtype and iterates backwards over it.
But 3 .. 1 declares an EMPTY subtype (containing NO valid values) so iterating over it - either way round - does precisely nothing.
Hopefully that is the missing part of the puzzle. I'm not clear why one faulty loop gets this warning while the other (at line 38) doesn't...
if j<n **and then** Int_Acc(j+1)>Int_Acc(j) then
j:=j+1;
I think you want just 'and' instead of 'and then,' although I haven't looked at Ada code in years.
Did that compile?
I'm having a problem when I use these 2 FOR to initialize a two dimensional vector/array:
I have these types defined:
type
Range9 = 0..8;
Digit = '0'..'9';
Board = array [Range9,Range9] of Digit;
and then the part of the code where there are problems with the FOR's is the following:
var
i : Range9;
j : Range9;
table : Board;
BEGIN
for i:=0 to 8 do begin
for j:=0 to 8 do begin
table[i,j] := '0'
end
end;
END.
Now the problem is that, when I debug this portion of code, for some reason, my i variable is modified when it's not supposed to.
For example, I have a watch on i and j and if I put a breakpoint in the line table[i,j] := 0
I see with the watches these values:
i j
0 0
256 1
512 2
768 3
1024 4
1280 5
1536 6
1792 7
2048 8
2049 8
1 0
257 1
513 2
769 3
and so on...
So, when the program enters in the second for (the one that increases the j) my i increases in intervals of 256... I really don't know why is this happening.
And another thing I discovered is that, the problem solves if I change the TYPE of the i variable.
If in the VAR section I put i : integer instead of i : Range9, i doesn't get modified when isn't supposed to.
I would really appreciate if someone explains me why is happening this.
I've found the answer to my own question... well, I didn't exactly found the answer, I've asked this same question in the forum board of the programming course I'm attending and one of the professors gave me this link:
(it's in spanish btw)
http://www.fing.edu.uy/inco/cursos/prog1/pm/field.php/FAQ/Laboratorio#toc17
A quick translation:
This happens with variables defined as subranges. The reason isn't sure; but without doubt is an implementation error of the debugger. There is a 'trick' that can work to solve this (although not always), to be able to see the correct values on the debugger:
Suppose that you have the following variable in your program:
var anything: 1 .. 10;
Add in your program a integer variable which won't be used in any part of the program:
var anything: 1..10;
aux: integer; { only for the debugger }
Then when you define the debugger watch, instead of adding the anything variable, you should add the following expression:
aux:= anything
The aux variable can be used to view different variables, so you only need to declare one aux variable.
In some cases, the previous may not work. Another solution is to change the type of all the variables defined with subranges to integer, char, string, etc (depending the case) only for debug and the change it back again.
end of the translation.
Hope this will be useful for someone else facing the same error.
BTW, this happens with the debugger of free pascal IDE 2.2.2 , maybe in another IDE/compiler/debugger of pascal it doesn't happen.
I haven't done Pascal in a while, so I might be a bit rusty. The only thing I can think of that is creating your problem is that you created a character range that was interpreted as a byte array, which was then converted to a Digits and then multiplied, which gave you those weird values. But, I could be wrong. I am unfamiliar with FreePascal.
Type
Range9 = 0..8
Board = Array[Range9,Range9] of Integer;
var
A : Board;
I,J : Integer;
begin
For I:=0 to 8 do
For J:=0 to 8 do
A[I,J]:=I*J;
end.
Reference: ftp://ftp.freepascal.org/pub/fpc/docs-pdf/ref.pdf
This snippet not only causes a runtime error, it makes FPC close if I run it using the debugger.
procedure sortplayersbyscore(var vAux:tplayers);
procedure swap(var a:trplayers;var b:trplayers);
var
rAux:trplayers;
begin
rAux:=a;
a:=b;
b:=rAux;
end;
var
i,j:integer;
sorted:boolean;
begin
vAux:=playersarray;
i:=1;
sorted:=false;
while (i <= MAXPLAYERS -1) and not sorted do
begin
j:=1;
sorted:=true;
while (j <= MAXPLAYERS -i) do
begin
if (vAux[j].score < vAux[j+1].score) then
begin
swap(vAux[j],vAux[j+1]);
sorted:=false;
end;
inc(j);
end;
inc(i);
end;
end;
The code itself is part of a really big source file, I can post the whole thing but the responsible for the error is just that bunch of lines. The debugger terminates at line:
swap(vAux[j],vAux[j+1]);
tplayers is just a type defined as an array of records that contain score (an integer) among a bunch of other variables. trplayers is the type of the aforementioned records. I'm at a total loss; FPC (while not under debugging mode) spits an out-of-range error but under my watches I see that the variables I'm trying to read exist. Any help is really appreciated!
rAux:trplayers; have you typed a wrong symbol or the type here really contains "r" in its name?
It looks valid (other than typos) ... so let's try something simple.
What's the value of "j" when you abort?
If the debugger won't tell you, try adding:
writeln ('j = ', j);
just before the "swap" call.
As Yochai's question implied, your array needs to be dimensioned at least from
1 (or lower) to MAXPLAYERS (or larger). (I.e.: 0..MAXPLAYERS-1 would not work,
but 1..MAXPLAYERS should.)