Phantasmal MUD Lib for DGD

Phantasmal Site > DGD > DGD Reference Manual (legacy) > Arrays

3.7 Arrays

An array is a list of values, either all of the same type or of multiple types. An array makes it easy to reference values by their number — for instance, it's easy to say "give me the fourth value in the array". However, an array is slow when you add values or remove them.

Let's write a function to count digits in a string. Go ahead and change myobj.c (or make a new file) to the following:

mixed count_digits(string str) {
  int   *num_count;
  int    ctr;
  object user;

  num_count = allocate_int(10);

  for(ctr = 0; ctr < strlen(str); ctr++) {
    if((str[ctr] <= '9') &&
       (str[ctr] >= '0')) {
      num_count[str[ctr] - '0']++;
    }
  }

  user = this_user();
  user->message("Count: [");
  for(ctr = 0; ctr < 10; ctr++) {
    user->message(num_count[ctr] + " ");
  }
  user->message("]\n");
}

To call this file, first compile it. So you'll type compile /usr/admin/myobj.c. If you're not using myobj.c as the filename, substitute the one you're using. You should get a result like $34 = </usr/admin/myobj>. Now, using the history variable you get back (we'll pretend it's $34 here), type $34->count_digits("0123456789"), or the equivalent with your own history variable number. You should see a result like the following:

Count: [1 1 1 1 1 1 1 1 1 1 ]
$36 = nil

Since the function doesn't explicitly return anything, the history variable result is nil. But since the function calls user->message to send output to the user (that's you!), the list of number counts is printed out. Try calling the function a few more times with arguments different from "0123456789". It will count the number of occurrences of each digit in your input.

If you look at the line in the code starting with mixed count_digits, you'll notice that it's different from the code in the last section. It uses a different function name, count_digits instead of exec. That's why you typed "count_digits" when calling the function. You'll also notice that instead of having object user, mixed argv... in parentheses, it has string str. That section tells what the function needs to do its thing. For the "return 7" function, you called it with this_user(), a user object, in parentheses. For count_digits, you gave a string which it then counted numbers in.

There are two new types of variable declaration in the code to count_digits. There is a variable type called object, like mixed or int. A variable of type object will hold a compiled DGD object, such as a connection object, or the object that myobj.c compiles into. In count_digits, it holds a user object like the one you passed to the function in the last section.

You'll notice that the variable declaration for num_count starts with int, but that there's an asterisk in front of the variable name. The asterisk means that num_count isn't an integer, but rather an array of integers.

Defining num_count doesn't give it a value. Arrays, like strings, are assigned nil by default, and have to be initialized to something. One way to assign reasonable values to an array of integers is the allocate_int function, which returns an array of zeroes. The array is as long as the number in parentheses is big. For the example above, that means it returns an array of ten zeroes.

There are a couple of other new things in the code above. We'll tackle them one at a time. The first is ++, called the increment operator. It adds one to whatever variable you use it on. So if a was a variable, then a++ means "add one to a".

Another is the zero in single quotes. Remember that LPC characters are represented as ASCII-encoded integers. A character in single quotes will evaluate the that character's integer. Try typing code 'A' and you should get a result of 65, just like in the section on handling strings. The 'if' statement checks to make sure that the character is a number between 0 and 9. That way letter, spaces and punctuation will be ignored.

The final new feature of the code is the square brackets, called the array dereference operator. The idea is that for an array, like a string, you can take a single element from it. So if an array called arr contains a zero followed by four nines, then the value of arr[0] is zero, and the value of arr[1], arr[2] and arr[3] would each be nine. If you tried to check arr[4], you'd get an error because there are only four elements and you tried to ask about the fifth one.

In num_count[str[ctr] - '0']++;, the square brackets are used twice, one inside the other. The first is to dereference a character of the string, just like before. Then '0' is subtracted from that character. The numbers 0 through 9, when ASCII encoded, become 48 through 57. Since the numbers are in order, starting with zero, you can subtract ASCII zero (which equals the number 48) from an ASCII digit such as the ones you typed in, and get a number 0 through 9 for which digit it was. That's why we subtract the character zero from that character of the string.

The second dereference, the one outside, is an array dereference, not a string dereference, but they work the same way if you think of a string as being like an array of ASCII-encoded characters. Since subtracting the character '0' leaves a number between 0 and 9, we can then use that character as the offset within the array. Since the array has ten elements, they're numbered 0 through 9.

To write an array value in LPC, you surround the entries with parentheses and curly braces and separate the entries with commas. So the array mentioned above would be written ({ 0, 9, 9, 9, 9 }) in LPC. Instead of the allocate_int call, you could have written num_count = ({ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }); The curly braces have to be inside the parentheses, they can't be outside them.

Arrays can also be added to each other like strings. Adding them will make a new array which is all the elements of the first array followed by all the elements of the second array. So code ({ 1, 2, 3 }) + ({ 7, 8, 9 }) will print a result like $40 = ({ 1, 2, 3, 7, 8, 9 }).

<— Prev
Making and Using LPC Files
Up
A Quick LPC Tutorial
Next —>
Mappings