Ada Programming/Variables
Variables are references that stand in for a value that is contained at a certain memory address.
Variables are said to have a value and may have a data type. If a variable has a type, then only values of this type may be assigned to it. Variables do not always have a type.
A value can have many values of many different types: integers (7), ratios (1/2), (approximations of) reals (10.234), complex numbers (4+2i), characters ('a'), strings ("hello"), and much more.
Different languages use different names for their types and may not include any of the above.
Assignment statements
[edit source]An assignment statement is used to set a variable to a new value.
Assignment statements are written as name := value
.
X := 10;
The example set the variable X to the integer value of 10. The assignment statement overwrites the contents of the variable and the previous value is lost.
In some languages, before a variable can be used, it will have to be declared, where the declaration specifies the type.
Ada is the same. The declaration is as follows:
declare
X : Integer := 10;begin
Do_Something (X);end
;
Uses
[edit source]Variables store everything in your program. The purpose of any useful program is to modify variables.
Without variables, we would not be able to create programs that go much beyond the classic "Hello World!" example. Variables in Ada must be declared. They cannot just magically appear in a program without first having been declared. A variable declaration looks like this:
Variable_Name : Variable_Type [:=Optional Value]
If a variable is assigned a value when declared, it is said to be initialized. It is possible to declare more than one variable of the same type
in one go by comma-separating the variable names:
Variable_A, Variable_B : Variable_Type [:=Optional Value]
As you can see, the assignment of a value to a variable is optional. All the compiler needs to know, is what kind of data (the type
) you intend the variable to hold. It doesn't care if there's actual data in the variable or not. When you declare a variable, you're basically just asking for a specific amount of memory to be set aside. The actual amount of memory depends, of course, on the declared type
. An Integer
might take up 4 bytes of memory, and a String (1 .. 10)
might take up 10 bytes of memory. The variable name is nothing more than a symbolic name, associated with whatever value that is placed in the memory reserved to the variable.
If we were to assign a value to a variable during its declaration, it would look like this:
Variable_Name : Variable_Type := Variable_Value
Let's try it with some real Ada variables. As seen above, a variable in Ada **must** be declared as pointing to a specific type
of data:
A_String_Variable : String (1 .. 10);
Here we declare the variable A_String_Variable
as a String
type, the length of which is 10 characters, (1 .. 10)
. Lets see how it looks if we assign a value to A_String_Variable
during its declaration:
A_String_Variable : String (1 .. 10) := "abcdefghij";
Here we've first declared and then initialized the A_String_Variable
variable.
In the case of the String
type, the length can be omitted and we can instead simply write:
A_String_Variable : String := "abcdefghij";
Here the assignment of "abcdefghij"
implicitly declares A_String_Variable
to be of length (1 .. 10)
, because that is the length of the assigned string.
Variables can be declared as any type
, be it String
, Integer
, records
, array
or homegrown types. Lets try and declare a variety of variables:
An_Array : array (1 .. 3) of Integer := (1, 2, 3);
A_Positive : Positive := 10;
type Colors is (Red, Blue, Green);
Color : Colors := Red;
type Person is record
Name : String (1 .. 12);
Age : Natural;
end record;
A_Person : Person;
B_Person : Person := (Name => "Thomas Løcke", Age => 37);
Notice the homegrown Colors
type. First we declare the new type, and then we declare the Color
variable the of that type. This is one of the biggest strengths of Ada: The ability to declare your own types and subtypes. More can be found on this subject in the Type System article.
Now, let's try and use the above declared variables in an actual program:
with Ada.Text_IO;
procedure VarCon is
package IO renames Ada.Text_IO;
A_String : String (1 .. 8) := "A_String";
B_String : String := "B_String";
An_Array : array (1 .. 3) of Integer := (1, 2, 3);
A_Integer : Integer := 10;
type Colors is (Red, Blue, Green);
package IOENUM is new Ada.Text_IO.Enumeration_IO (Colors);
Color : Colors := Red;
type Person is record
Name : String (1 .. 12);
Age : Natural;
end record;
A_Person : Person;
begin
IO.Put_Line (Item => A_String);
IO.Put_Line (Item => B_String);
A_String := "String_A";
B_String := "String_B";
IO.Put_Line (Item => A_String);
IO.Put_Line (Item => B_String);
for i in An_Array'Range loop
IO.Put (Item => i'Img & ":" & An_Array (i)'Img);
IO.New_Line;
end loop;
An_Array := (1 => 10, 2 => 20, 3 => 30);
for i in An_Array'Range loop
IO.Put (Item => i'Img & ":" & An_Array (i)'Img);
IO.New_Line;
end loop;
IO.Put_Line (Item => A_Integer'Img);
IOENUM.Put (Item => Color);
IO.New_Line;
A_Person := (Name => "Thomas Løcke",
Age => 37);
IO.Put_Line (Item => A_Person.Name);
end VarCon;
When executed, the above program should output the following:
A_String B_String String_A String_B 1: 1 2: 2 3: 3 1: 10 2: 20 3: 30 10 RED Thomas Løcke
Here we can actually see why variables are called variables: Their values vary.
Notice how we are able to change the data contained in, for example, the A_String
variable. When we declare it, we assign the value A_String
(the variable is said to be initialized), but a little later we assign another value to A_String
: String_A
. That right there is the core concept of variables that every beginning programmer must understand: Variables vary. A variable name is just a reference to a place in memory where a a specified type
of data resides. The exact data can, and probably will, change a lot during the run of a program, but the variable name and the type
remains the same.
If a variable doesn't change during program execution, then we have a better option: A constant. These are the stiff upper lip siblings of variables.
Scope
[edit | edit source]Finally, let's take a short look at variable scope in regard to blocks. When and where are they visible? This is perhaps best understood by a simple program:
with Ada.Text_IO;
procedure Scope is
package IO renames Ada.Text_IO;
Name : String := "Thomas Løcke";
begin
IO.Put_Line (Item => "1:" & Name);
declare
Name : String := "Dwight S. Miller";
begin
IO.Put_Line (Item => "2:" & Name);
end;
IO.Put_Line (Item => "3:" & Name);
declare
begin
IO.Put_Line (Item => "4:" & Name);
end;
end Scope;
The output we get from the above looks like this:
1:Thomas Løcke 2:Dwight S. Miller 3:Thomas Løcke 4:Thomas Løcke
Note how Name
is declared as a local variable in the first block. The declaration in the first block does not in any way interfere with the "global" Name
variable. If no Name
variable is declared for a block, the "global" Name
variable is used, as can be seen in the final block, where Thomas Løcke
is printed, even though no such assignment has been done in the block.
So variable scope in regard to blocks is very straightforward: Blocks inherit variables from their parent(s) and these can then be overridden locally in the block by declaring the variable anew.