Ada Programming/Variables

This computer programming article is available in pseudocode and Ada.

Variables are references that stand in for a value that is contained at a certain memory address.

Ada. Time-tested, safe and secure.
Ada. Time-tested, safe and secure.

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

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

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

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.

See also

edit

Ada Reference Manual

edit