P.Lecture 2.21.08 - Announcements Assignment 3 D Due next Tuesday by midnight t T d b id i ht Assignment 4 Out next Tuesday Out next Tuesday I'm

Info iconThis preview shows page 1. Sign up to view the full content.

View Full Document Right Arrow Icon
This is the end of the preview. Sign up to access the rest of the document.

Unformatted text preview: Announcements Assignment 3 D Due next Tuesday by midnight t T d b id i ht Assignment 4 Out next Tuesday Out next Tuesday I'm out of town all next week Professor Krasner will be in next week to continue lectures Professor Krasner will be in next week to continue lectures Topics for today Pointers Strings Why do we need pointers? Power of direct manipulation of memory locations is crucial in many embedded and locations is crucial in many embedded and systems software applications Its faster to pass only a reference (pointer) Its faster to pass only a reference (pointer) instead of a whole array or structure to a function Pointers are required to do file IO (next week) Others reasons later Pointer Concepts The pointer type supports indirect addressing The pointer type supports indirect addressing A pointer variable holds a memory address rather than a value What's the difference? Basic unary operations are: & the "address of" operator (We've already seen this. Where?) * the indirection operator or "contents at" an address Pointer variables have to be declared along with the type of data that they point to data that they point to E.g, (p is not an integer, but capable of pointing to an int) int *p; /* a pointer variable p must point to an int */ Mixed type pointer manipulations are not allowed int *p; double q; double *q; p = q; /* not allowed */ Before it's assigned a value, a pointer points to nothing in particular The Address Operator p A pointer can be given a value by assigning it the address of a variable To determine the address of a variable, use the address operator (&) int i, *p; p = &i; /* now p points t i */ &i /* i t to i */ The Indirection Operator p To determine what a pointer points to, use the indirection operator (*) int i, *p; ... p = &i; printf("%d\n", *p); If p points to i, then *p is just another name for i Pointer Implementation Memory p A pointer variable(e.g. p) contains the memory address t i th dd of another variable or location as its value 25 x int p = 0; / set p to NULL / int *p = 0; /*set p to NULL*/ int x; p = &x; /* p is given the address of x */ x 25; x = 25; / or *p = 25; */ /* or p 25; / printf("Value is %d \n", (*p) ); Pointer Assignment g One pointer may be assigned another, provided both have the same type h h int i, *p, *q; p = &i; q = p; After the assignment, both p and q point to I Don't confuse pointer assignment with assignment using Don t confuse pointer assignment with assignment using indirection: int i, j, *p, *q; p = &i; q = &j; i = 1; /* p is pointing to 1 (i), q is pointing to some undefined value (j) */ *q = *p; /* p and q now both point to 1, though different memory locations */ * * /* d b th i t t 1 th h diff t l ti */ What does this do? int number ; int *p1, *p2; p1 = & number ; number = 23; number = 23; p2 = & number ; printf (" *p1 = %d *p2 = %d ", *p1, *p2); Pointers as Arguments g For a function to be able to modify a variable, it must be given a pointer to the variable: be given a pointer to the variable: void swap(int *a, int *b) { int temp; temp = *a; *a = *b; *b = temp; b temp; } ... int x, y; int x y; swap(&x, &y); The arguments of scanf must be pointers to places to The arguments of scanf must be pointers to places to store the input Using const to Protect Arguments g g The const specifier provides a way to protect arguments from change: void f(const int *p) { int j; i j *p = 0; /* illegal */ p = &j; / legal / p = &j; /* legal */ } Pointers as Return Values Functions may return pointer values: i l int *max(int *a, int *b) { if (*a > *b) { ( ){ return a; } else { else { return b; } } ... p p = max(&x, &y); ( , y); Never return a pointer to a local variable l l i bl int *f(void) { int i; ; ... return &i; } The variable i will not exist once f returns, so exist once f returns so the pointer will be invalid Pointers and Arrays y A pointer variable may point to an element of an array an array int a[10], *p; p = &a[0]; p = &a[0]; *p = 5; / p points to the beginning of a / /* p points to the beginning of a */ /* stores 5 into a[0] */ With scanf: With scanf: scanf("%d", &a[i]); Pointer Arithmetic Only addition subtraction and comparison operations are Only addition, subtraction and comparison operations are allowed for pointer variables Remember, a pointer is just a memory location, which is just a number int *p =0, *q =0; int *p 0 *q 0; int x[4] = {25, 37, 77, 99}; p = &x[0]; /* OR just p = x; when x is an array */ q = p; q++; if (p < q) printf ("p points to a lower address\n"); printf ("value is %d", *(q + 2)); /* what value is output? */ A pointer can be used to index through a list/array of elements / char str[ ] = "Test"; char *p ; int i; int i; for( p = &str[0], i=0; *p != '\0'; p++, i++) printf(" The character at position %d is %c\n ", i, *p); When two pointers are subtracted the result is the distance (in array When two pointers are subtracted, the result is the distance (in array elements) between the pointers Only meaningful if the pointers point into the same array Array Names and Pointers y The name of an array can be used as a pointer to the first element in an array fi l i int a[10]; *a = 0 a = 0 / stores 0 in a[0] / /* stores 0 in a[0] */ The second element can be accessed through a+1 *(a+1) = 1 /* stores 1 in a[1] */ ( ) / [ ] / In general, a+i is another way to write &a[i] g g p Moving through a loop: char str[ ] = "Test"; char *p ; int i; for( p = str, i=0; *p != '\0'; p++, i++) printf(" The character at position %d is %c\n ", i, *p); Array Arguments Revisited When an array is used as an argument to a function, the function is given a pointer to the array's first element. int a[N]; [ ] store_zeroes(a, N); This is why a function can modify the elements of an y y array parameter (but not OTHER parameters) void store_zeroes(int a, int n) { int i; int i; for (i = 0; i < n; i++) a[i] = 0; } T To protect an array argument from change, use const t t tf h t int find_largest(const int a, int n); An array parameter can be declared as a pointer instead: An array parameter can be declared as a pointer instead: void store_zeroes(int *a, int n); int find_largest(const int *a, int n); Multiple Indirection Variables q A pointer variable contains the memory address of another pointer variable as its value p double **q; double p; double *p; double x = 25.7; p = &x; q = &p; & printf ("%le" ,**q); 25.7 x What's a String? g Basically, a sequence (array) of characters. What do we do with Strings? Input and output them Make a bigger String out of little ones Make a bigger String out of little ones Break big Strings into smaller ones Do comparisons (like in chars) Extremely useful in any application that manipulates text (e.g. translators, word processors, language puzzles, etc.) String Literals String literals are enclosed in double quotes; e.g.: "Put a disk in drive A, then press any key to continue\n" Put a disk in drive A, then press any key to continue\n A string literal may be extended over more than one line by writing \ immediately followed by the end of the line: y g\ y y printf("Put a disk in drive A, then \ press any key to continue\n"); A string literal may be divided into two or more shorter strings; the compiler will join these together into one string: printf("Put a disk in drive A, then " "press any key to continue\n"); " k t ti \ ") How String Literals Are Stored The string literal "abc" is represented by the three characters a, b, and c, followed by a null character (\0): a b c \0 Lik Like any array, a string literal is represented by a pointer t th t i lit l i t db i t to the first character in the string A string literal of length 1 is different from a character constant g g A string literal of length 1 (e.g., "a") is represented by a pointer A character constant (e.g., `a') is represented by an integer value Don't use a character constant when a string literal is required ' h h l l d (or viceversa): printf("\n"); //is legal, because printf expects a string as its first parameter printf('\n'); // \ //is not legal. String Variables A string variable is just a one dimensional array of characters: A string variable is just a onedimensional array of characters: #define STR_LEN 80 char str [STR_LEN+1]; The array should be one character longer than the string it will hold, to leave space for the null character at the end. Leave room for the null character when using stringhandling Leave room for the null character when using string handling functions in the C library. A string variable can be initialized: char date1[8] = "June 14"; A string initializer need not completely fill the array: char date2[9] = "June 14"; char date2[9] "June 14"; The leftover array elements are filled with null characters: If the length of the array is omitted, the compiler will compute it: char date3[ ] = "June 14 "; /* date3 is 9 characters long */ Reading and Writing Strings To read or write a string, use scanf or printf with the %s conversion specification: scanf( %s str); scanf("%s", str); printf( %s , str); printf("%s" str); scanf skips white space, then reads characters into str until it encounters a whitespace character This is a problem if you want more than 1 word No ampersand is needed when using scanf to read into a string variable variable Since a string variable is an array, the name of the variable is already a pointer (to the beginning of the array) Af A faster alternative: Use gets and puts f l i U d functions: i gets(str); gets reads characters into str until it encounters a newline character. puts(str); puts prints str, followed by a newline character. Reading and Writing Strings (cont.) scanf and gets automatically put a null at the end of the input string g printf and puts assume that the output string ends with a null Both scanf and gets assume that the string variable is large enough to contain the input string (including the null at the end) Failing to make the variable long enough will have unpredictable results Failing to make the variable long enough will have unpredictable results To make scanf safer, use the conversion specification %ns, where n specifies the maximum number of characters to be read. d Use fgets instead of gets for greater safety Allows you to specify max length of string to read Allows you to specify max length of string to read Accessing the Characters Because of the close relationship between arrays and pointers, the elements of a string can be accessed by normal array subscripting or pointer reference l b i ti i t f Here is a function that counts the number of spaces in a given string: a given string: int count_spaces(const char s[ ]) { int count, i; count = 0; for (i = 0; s[i] != '\0'; i++) { if (s[i] if (s[i] = = ' ') count++; ) count++; } return count; } Accessing the Characters (cont.) g ( ) The Code from before: int count_spaces(const char s[ ]) { int count, i; count = 0; for (i = 0; s[i] != '\0'; i++) { for (i 0 s[i] ! '\0' i++) { if (s[i] = = ' ') count++; } return count; return count; } Pointer version: int count_spaces(const char *s) { i t t ( t h * ){ int count; count = 0; for (; s != \0 ; s++) { for (; *s != `\0'; s++) { if (*s == ` `) { count++; } } return count; } Using the C String Library C provides some builtin support for strings Since strings are treated as arrays, they are restricted in the same ways as arrays--in particular, strings cannot be copied or compared by array i ti l ti tb i d db name. Why? Attempts to copy or compare two strings using C's builtin operators will fail: char str1[10], str2[10]; str1 = str2; /* illegal */ t 1 t 2 /* ill l */ if (str1 == str2) ... /* will produce the wrong result */ The C library provides a set of functions for performing The C library provides a set of functions for performing operations on strings. These functions reside in <string.h>. The strcpy Function strcpy copies one string into another: char str1[10], str2[10]; char str1[10] str2[10]; strcpy(str1, "abcd"); /* str1 now contains "abcd" */ strcpy(str2, str1); /* str2 now contains "abcd" */ strcpy(str2 str1); /* str2 now contains "abcd" */ strcpy calls can be chained: strcpy(str2, strcpy(str1, "abcde")); ( ( " b ")) /* both str1 and str2 now contain "abcde" */ strcpy has no way to check that the second string will fit into the first one The strcat Function strcat appends the contents of one string to the end of another ("concatenates"): char str[10] = "abc"; strcat(str, "def"); /* str now contains "abcdef" */ strcat has no way to check that the first string y g can accommodate the added characters. The strcmp Function strcmp compares two strings: if (strcmp(str1, str2) < 0) ... strcmp returns a value less than, equal to, or greater than 0, depending on whether str1 is less than, equal to, or greater than str2 greater than str2 strcmp considers str1 to be less than str2 if The first i characters of str1 and str2 match, but the (i+1)st The first i characters of str1 and str2 match, but the (i+1)st character of str1 is less than the (i+1)st character of str2 (for example, "abc" is less than "acc", and "abc" is less than "bcd"), or than "bcd") or All characters of str1 match str2, but str1 is shorter than ( p , ) str2 (for example, "abc" is less than "abcd") The strlen Function strlen returns the length of a string: int i; char str[10]; i = strlen("abc"); /* i is now 3 */ i = strlen(""); /* i is now 0 */ i t l ("") /* i i 0 */ strcpy(str, "abc "); i = strlen(str); / i is now 4 / i = strlen(str); /* i is now 4 */ When given an array of characters as its argument, strlen does not measure the argument strlen does not measure the declared length of the array; instead, it returns the length of the string stored inside the array. the length of the string stored inside the array Escape Characters in Strings T To get certain characters to show up in a string or be part of a i h h i i b f string (for output or other reasons) we must use a special combination of characters Done just like when using printf (" . . . \n") The \ is a control character. \' \" \\ \n \t \r \f \ \b tab carriage return form feed backspace p single quote double quote back slash character back slash character newline, also called line feed Except for the first three, these are non printable output control character sequences Other Useful String Functions Found in <stdlib.h> Converting strings to numbersgiven a string argument, they return the numeric equivalent strtod string to double strtol string to int string to int strtoul string to long int For example char numberString [ ] = "2345"; double x = strtod (numberString); These replace older functions: atof, atoi, atol p , , Converting numbers to strings; use sprintf () sprintf (string, conversionspec, value); sprintf (s, "%d", i); /* stores the converted value of i into s */ String scanf ( ) sscanf( ) can be used to convert a string into its known elements known elements Example: read a line (fgets) & extract a number int value; int value; / variable for the input value / /* variable for the input value */ char line[80]; /* temp variable for input line */ g ( ( ) ) fgets( line, sizeof(line), stdin); sscanf( line, "%d", &value ); You must make sure that the variable formats and types agree String Functions Summary g y all the standard array algorithms for: searching, adding, removing, sorting the char [ ] can be used ddi i i h h b d various input and output functions strcpy strcat strcmp strlen number to/from string conversion functions String Examples Make a computer password out of the first letters of a person's first, middle and last names, appended with the person's age Reverse the contents of a string Create a Password Program int main ( ) { int main ( ) { char [ ] firstName = "harold"; char [ ] middleName = "joseph"; char [ ] lastName = hacker ; char [ ] lastName "hacker"; char [6] password = ""; int age = 19; /* assume this is the age of the user */ char [3] stringAge = ""; /* to hold age as a string */ h [3] t i A "" /* t h ld t i */ /* extract&concatonate the first letter of first, middle,last names*/ strcat (password, firstName [0]); strcat (password, middleName [0]); ( d iddl N [0]) strcat (password, lastName [0]); /* convert & append age to the initials to create a password */ sprintf (stringAge, "%d", age); /*convert age to a string */ / / strcat (password, stringAge); printf ("Your password is %s ", password); return 0; } String Reverser /* create a copy of a string in reverse order */ int i =0; char ch; char [80] phrase; /* the initial string*/ char [80] reversed; /* the reversed string*/ gets (phrase); i = strlen (phrase); reversed = ""; while (i >= 0) { ch = phrase [i]; strcat (reversed, ch); i = i 1; } reversed [strlen (phrase)] = `\0'; printf ("the reversed string is %s\n", reversed); ...
View Full Document

This note was uploaded on 03/22/2008 for the course EE 312 taught by Professor Shafer during the Spring '08 term at University of Texas at Austin.

Ask a homework question - tutors are online