Pointers CMSC 104 Spring 2014, Section 02, Lecture 22 Jason Tang Topics • Pointers • Pointer Arithmetic • String Pointers Indirect Variables (Review) • What if the value of a variable X happens to be the address of another variable Y? • If one does not change value of X, but instead changes the memory that X is indirectly referencing, then Y will change! • Recall that every variable refers to a unique memory address Pointer Where have I heard this before? • Special type of variable whose value is the address of some other piece of memory • If pointing to nothing at all, it has the value NULL • NULL is not the nul character (‘\0’) • Use & operator to get the address of a variable • Use * operator to “dereference” a pointer • Dereferencing NULL will cause program to die Example of a Pointer #include <stdio.h> int main(void) { char s[] = "Hello, there!"; char *t = &s[0]; printf("%s\n", t); return 0; } Example of a Pointer #include <stdio.h> int main(void) { char s[] = "Hello, there!"; char *t = &s[0]; t “points” to the printf("%s\n", t); first element of s return 0; } This works because %s format specifier (and every other built-in string routine) accepts either a char array or a char pointer Why Use Pointers? • Create “aliases” of other variables • Effectively what an indirect variable really is in C • Manipulate array contents • Use dynamic memory (next week’s lecture) Pointer Example 2 #include <stdio.h> void f(int *jim, int *bob); int main(void) { int x = 5; printf("x was %d\n", x); f(&x, &x); printf("x is now %d\n", x); return 0; } void f(int *jim, int *bob) { *jim = *jim + 10; *bob = *bob * 3; } Pointer Example 2 void f(int *jim, int *bob) { *jim = *jim + 10; *bob = *bob * 3; } x jim bob Indirectly Modifying array Contents #include <stdio.h> int main(void) { char s[] = "Hello, there!"; char *t = &s[0]; t = t + 4; *t = ' '; t = t + 3; *t = ' '; printf("%s\n", s); return 0; } Pointer Arithmetic ... t = t + 4; *t = ' '; t = t + 3; *t = ' '; ... s[] H *t e l l o ... *(t + 4) = ' '; *(t + 7) = ' '; ... , *(t + 4) t *(t + 7) h e r e ! \0 Crashing Programs #include <stdio.h> int main(void) { char s[] = "Hello, there!"; char *t = NULL; /* *t = 'A'; <-- line A */ /* printf("%s\n", t); <-- line B */ return 0; } 1. Compile and run this program as is. 2. Then uncomment line A, recompile, and run. 3. Then comment line A, uncomment line B, and run. Crashing Programs #include <stdio.h> int main(void) { char s[] = "Hello, there!"; char *t = NULL; /* *t = 'A'; <-- line A */ /* printf("%s\n", t); <-- line B */ return 0; } • Dereferencing NULL or otherwise manipulating a NULL pointer cause a “segmentation fault” • Program will almost always crash and burn Strings and Pointers • Many built-in string functions return pointers to some subset of an existing string: • strchr() • strstr(), strfry(), etc. strchr() • Returns pointer to first occurrence of target character within a string, or NULL if that character not found • NULL is not the \0 character H e l l o strchr(s, ‘l’) , t h e r strchr(s, ‘h’) e ! \0 NULL strchr(s, ‘x’) strchr() example #include <stdio.h> #include <string.h> int main(void) { char buf[80], *s = buf; fgets(buf, 80, stdin); int count = 0; while (s != NULL) { s = strchr(s, ' '); if (s != NULL) { count = count + 1; s = s + 1; } } printf("Number of spaces in input = %d\n", count); return 0; }