Chapter 4. Arrays

Table of Contents
4.1. Initializing Arrays
4.2. Testing Arrays
4.3. Adding and Removing Elements in Arrays
4.4. Accessing Elements in Arrays
4.5. sizeof
4.6. Iterating Over Arrays
4.7. Getting a Random Item From an Array
4.8. Arrays of Arrays
4.9. Common Errors

  Arrays let me do
  otherwise impossible
  things I like to do

You know what a string is. It's a type of variable that holds a series of characters. It can be used to hold names and descriptions of things.

What if you needed to write a function that returned the names of all the users online? You could do it so that it's all one big string and the users' names are separated by commas.

So, the return for a query_users() function could be something like:


  "joe,harry,tom,pete,fred"

Then if you wanted to write a list of all the users to output you'd have to iterate through that string character by character parsing out the individual names which are separated by commas:


  int i;
  string names = query_users();
  string tempname;

  tempname="";
  for (i=0; i < sizeof(names); i++) {
    if (names[i] == ",") {
      write(tempname + "\n");
      tempname = "";

    } else {
      tempname = tempname + names[i];
    }
  }

  write(tempname + "\n");

That's well and good, except it sucks. It's a terrible way to pass data around. What happens if one of the names has a comma in it like "Fred, Supreme Ruler"? Do you just pick a different delimiter--like maybe "::"? What happens if you needed to store all the names so that you could filter out all the names of characters that are idle? These things become incredibly complex---if not impossible.

It'd be better if the function could return a bunch of separate name strings so then the code calling the function didn't have to separate the names by hand looking for commas. In this case we'd want an array of strings.

With arrays, the above code would be:


  int i;
  string *names = query_users();

  for (i=0; i<sizeof(names); i++) {
    write(names[i] + "\n");
  }

All the comma parsing goes away.

An array is a group of things. You could have an array of ints, an array of strings, an array of objects, or an array of ints, strings, and objects all put together. You can even have an array of arrays (we cover this in another essay).

array: noun. a group of elements forming a complete unit

4.1. Initializing Arrays

You can call functions which return arrays. You can also create your own arrays. LPC uses ({ }) to denote an array. Examples of initializing arrays:

Example 4-1. Initializing arrays


  // creates an array of strings with no elements in it
  string *string_array = ({ });
                                     
  // creates an array of ints with 1 through 5 in it
  int *int_array = ({ 1, 2, 3, 4, 5 });

  // creates an array of strings with names in it
  string *names = ({ "joe", "pete", "tom", "harry" });

  // creates an array of ints and strings
  mixed *strints = ({ "joe", 2, "pete", 4, 5, 6, "harry" });

Let's break down one of those lines into its components:


  string * names = ({ "joe", "pete", "tom", "harry" });
  a        b     c d

  a - the type of the array:       string *
  b - the name of the variable:    names
  c - the operator:                =
  d - the value:                   ({ "joe", "pete", "tom", "harry" })

The type of the array is "string *". The "*" part tells you it's a pointer and the "string" tells you that it's a pointer to strings. Thus the variable "names" points to an array of strings which could be illustrated like this:


               -------     --------     -------     --------- 
  names ----> | "joe" | , | "pete" | , | "tom" | , | "harry" |
               -------     --------     -------     ---------

The names variable points to an array of elements. Each element in this case is a string. Each string holds a name.

You may not need this with arrays, but you will need this with arrays of arrays which we cover in the next essay.

You can use the allocate function to allocate an array. This is optimized if you know what the size of your array is going to be. Then the virtual machine doesn't have to keep resizing the array and copying the contents from the old array to the new array every time you add a new element.

Example 4-2. Initializing arrays with allocate()


  string *names;
  int names_sz;

  names = allocate(10);
  names_sz = sizeof(names);

The variable names now has 10 empty elements. The variable names_sz is equal to 0 because names has 10 empty elements. An empty element is an element of the array that has nothing in it. Think of it as a bucket with no water in it.