-
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
- 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.
- 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).
- 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:
- If you only want the value of a string, you can use either an array or a pointer declaration.
- If you want to write to the string, use an array, but the name of the string is constant.
- If you want to treat the name of the string as a variable, use a pointer declaration.
-
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.)
-
- 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
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).
-
The following diagram shows two different views of the array:
- see diagram above
- address of A[3] is 0x80000C
- 0x800006 is the address of byte #2 in the element at address 0x800004, so the value is 0x00
- 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
-
int strlen(char *str) {
int len = 0;
int i;
for (i=0; str[i]!='\0'; i++) {
len++;
}
return len;
}
|
int strlen(char *str) {
int len = 0;
char *cp;
for (cp=str; *cp!='\0'; cp++) {
len++;
}
return len;
}
|