Week 4 Tutorial — Sample Solutions

  1. char p[] = "robert" is a declaration of an array of characters, which looks like:
     p:
     +----+----+----+----+----+----+------+
     | r  |  o |  b |  e |  r |  t | '\0' |
     +----+----+----+----+----+----+------+
      p[0] p[1] p[2] p[3] p[4] p[5] p[6]
    
    p is not a variable: it contains the location of the array, and is constant.

    char *q = "robert" is a pointer declaration (to an anonymous string):
     q:
     +---+         +---+---+---+---+---+---+------+
     |   |-------->| r | o | b | e | r | t | '\0' |
     +---+         +---+---+---+---+---+---+------+
     Pointer        Anonymous array
    
    q is a variable: it contains the location of the first element of the string

    1. The output is:
      robert
      robert
      r
      r
      r
      r
      o
      s
      
      Basically you can use pointers or array references interchangeably to read the elements in a string.

    2. Writing to strings requires care:
      • p[0] = 'R' This will have the desired effect. You can basically do anything to the elements of an array.
      • *q = 'R' This will generate an error at run-time because a string declared in this way is stored in the same area of memory as code is stored, and hence cannot be modified (i.e. written to).

    3. Changing the name of a string also requires care:
      • p = q
        This will generate an error at compile-time because the name of an array is linked to an area of memory and hence the name cannot be treated as an ordinary variable.
      • q = p
        This is okay. The pointer q will now point to the same string as p does. Note however that the string that q pointed to is lost. (It becomes data that cannot be referenced by the program, commonly called garbage.)

    In summary:

  2. junk
    a0junk
    b1
    

    Notice the array s has been declared too short, so there is no room for the '\0' terminator. The print statement will keep on outputting bytes that follow s in memory until a '\0' is found. The order of storing data in the stack is the reverse of the declaration order so the 'next' declaration is r, and as r does contain a '\0' terminator, the result is that string r is appended to string s. (The short declaration of s is of course a bug.)

    1. In days2[2], there isn't room for the '\0' terminator in "wednesday". The second declaration should be char days2[][10].
      • days1 stores the strings in variable-length format (with '\0' terminators of course), hence will require 7+8+10 bytes
      • days2 stores the strings in fixed-length format: that is 10+10+10 bytes
      • c = days1[0][0]; // legal
      • c = days2[0][0]; // legal
      • days1[0][0] = 'M'; // run-time seg fault because you're writing to an anonymous string declaration
      • days2[0][0] = 'M'; // legal
      • days1[0] = "MONDAY"; // legal
      • days2[0] = "MONDAY"; // compile-time "incompatible types" because it's an array declaration

  3. For the CSE workstations the sizes are:

    Data structure Min. Max. sizeof() element sizeof() structure
    char str[50]; 0 49 1 50*1 = 50
    int counts[100]; 0 99 4 100*4 = 400
    double temps[31]; 0 30 8 31*8 = 248
    int m[20][50]; 0 19 4 20*50*4 = 4000
    char *names[20]; 0 19 4 20*4 = 80
    char *argv[]; 0 undef 4 undef

    The variable *argv[] is a pointer to an array that is defined at run-time, so at compile time the structure is undefined. The values above assume particular computer hardware: different systems may have different sizes for an int and double (say).

  4. The following diagram shows two different views of the array:


    1. see diagram above
    2. address of A[3] is 0x80000C
    3. 0x800006 is the address of byte #2 in the element at address 0x800004, so the value is 0x00
    4. 0x800008 is the address of A[2] (i.e. &A[2] == 0x800008); you ought to recognise 65536 as being 216 and so its value is the one shown in blue in the diagram
    1. int strlen(char *str) {
         int len = 0;
         int i;
         for (i=0; str[i]!='\0'; i++) {
            len++;
         }
         return len;
      }
      

    2. int strlen(char *str) {
         int len = 0;
         char *cp;
         for (cp=str; *cp!='\0'; cp++) {
            len++;
         }
         return len;
      }