CS449, Introduction to Systems Software, Spring 2007 TA: Ricardo Villamarín-Salomón

Lab #4

Exercise 1 Pointers a) (theory) Where are the following pointers (variable ptr) pointing to?

[1] char *ptr;

[2] float *ptr = NULL;

[3] int var = 6; int *ptr; ptr = &var; printf ("%p\n", &var);

b) (common errors)1 Find the error in each of the following program segments. If the error can be corrected, explain how.

[1] int *number; printf("%d\n", *number);

[2] float *realPtr; long *integerPtr; integerPtr = realPtr;

[3] int *x, y; x = y;

[4] char s[] = "this is a character array"; int count; for( ; *s != ‘\0’; s++) printf("%c ", *s);

[5] short *numPtr, result; void *genericPtr = numPtr; result = *genericPtr +7;

1 1-7 By Mohammad Hammoud

-1/8- [6] float x = 19.34; float xPtr = &x; printf( "%f\n", xPtr);

[7] char *s; printf( "%s\n", s);

[8] #define MAX_LEN 20 … char src[MAX_LEN] = "a char array", dst[MAX_LEN] = "another char array", *s = src; int count; for(count=0; *s != '\0'; s++) dst[count++] = *s; printf("%s", dst);

Exercise 2 Pointers, Arrays and pointer arithmetic a) What does the program in Listing 1 do?

Listing 1 #include

#define NUM_ELEMS 7 int main() {

int arr[NUM_ELEMS] = {5, 8, 10, 2, 9, 4, 1}; int *p, *pend;

for (p=arr, pend=(p + NUM_ELEMS); p

return 0; } b) Does the program in Listing 2 do the same as the one in Listing 1? Run it and see if you can explain the difference. What about the program in Listing 3?

-2/8- Listing 2 #include

#define NUM_ELEMS 7 int main() {

short int arr[NUM_ELEMS] = {5, 8, 10, 2, 9, 4, 1}; int *p, *pend;

for (p=arr, pend=(p + NUM_ELEMS); p

return 0; }

Listing 3 #include

#define NUM_ELEMS 7 int main() {

double arr[NUM_ELEMS] = {5.0, 8.0, 10.0, 2.0, 9.0, 4.0, 1.0}; float *p, *pend;

for (p=arr, pend=(p + NUM_ELEMS); p

return 0; }

Exercise 3 Recursive functions and Pointer arithmetic 2

(Palindromes) A palindrome is a string that is spelled the same way forward and backward. Some examples of palindromes are "radar" and "civic".

a. Write a recursive function testPalindrome that returns 1 if the string passed as a constant parameter is a palindrome and 0 otherwise. For this exercise, you can assume that the string passed contains only letters. You may use Listing 4 as a starting point if you want.

b. Write a function testPalindromePtr that behaves in the same way that testPalindrome but instead of receiving an entire string, just receives two pointers, one pointing to the first character and the other to the last character of the part of the string that is still unprocessed (do not use the [ ] operator). Use Listing 5 as a starting point.

2 Modified from exercise 6.31, pg. 265 in the book

-3/8- Listing 4 #include #include int testPalindrome(const char *string, int start, int end) { /* write your code here */

} int main() { printf ("%d\n", testPalindrome("radar", 0, strlen("radar")-1)); printf ("%d\n", testPalindrome("saas", 0, strlen("saas")-1)); printf ("%d\n", testPalindrome("scifi", 0, strlen("scifi")-1)); return 0; }

Listing 5 #include #include int testPalindromePtr(char *start, char *end) { /* write your code here */

} int main() { char *string; int strlength;

string = "civic"; strlength = strlen(string); printf ("%d\n", testPalindromePtr( &string[0], &string[strlength-1] ));

string = "saas"; strlength = strlen(string); printf ("%d\n", testPalindromePtr( &string[0], &string[strlength-1] ));

string = "none"; strlength = strlen(string); printf ("%d\n", testPalindromePtr( &string[0], &string[strlength-1] ));

return 0; }

Exercise 4 Managing Username and Passwords

This exercise will help you practice with the following concepts:

 Insertion and Deletion of elements in an array  Array sorting with Bubble sort and strings  Passing constant arrays to functions

-4/8-  Binary search (optional)

You are working as the system administrator of a company and you are in charge of managing usernames and passwords.

Insertion and Deletion of elements in an array

In order to do your job, you have to create a program that allows you to add and delete usernames and passwords. For this, you have to: a. Use an array of strings for storing the usernames and other array (of the same size) for the passwords. If you are familiar with multi dimensional arrays, you can create a bi- dimensional array that can store the usernames and passwords in one array. b. Use separate functions for inserting, deleting and editing usernames / passwords. These functions receive the arrays by reference (no global arrays please). The insertion function just adds a new username at the end of the array. c. Create a search function that looks sequentially for a specified string in an array and returns the position in the array of that username. If the username is not found, then the function returns -1. d. Before inserting or deleting the password of a user, your function must call the search function described in the previous point.

1. Insertion function: if the search function finds the username, then the insertion function must return an error indicating that the element already exists. If the username does not exist, then the insertion function will insert the username and password passed as parameters at the end of the respective arrays.

2. Deletion function: If the search function does not find the username, then the deletion function must indicate so, but if the username is found, the function deletes the username and password from the array. e. Create a function that allows the system administrator to sort the list of usernames and passwords. Use the bubble sort algorithm adapted to sort strings. f. Create a function that prints the complete list of usernames and passwords.

Binary search and alphabetical ordered arrays g. Adding an element at the end of the array makes adding elements a very fast operation, but it slows down the process of looking for a specific element in the array.

1. Modify your insertion function so that it always inserts elements in alphabetical order. In this way you will avoid sorting the array when the administrator selects that option. For doing this, you need to create a search

-5/8- function that returns an approximate position were the element should be inserted in relation to the other elements (if it does not exist)

2. Doing a sequential search is very slow if the list of usernames grows too large. In order to improve the search, you can use binary search to locate a specific element in the list. Since the insertion function in the previous point stores the elements in sorted order, you do not have to sort the array first, before attempting to use binary search if you implement the previous point.

3. Can you implement binary search without inserting elements in sorted order? You will have to sort the array first using bubble sort (or other sorting algorithm you may want).

You can take a look at the skeleton program below to see an example of a test program for your functions.

Listing 6 #include #include

/* Max username or password length */ #define MAX_LEN 10 #define MAX_ELEMS 50 typedef char login_str[MAX_LEN];

/******** * Create your functions here ********/ int main() { login_str usernames[MAX_ELEMS]; login_str passwords[MAX_ELEMS]; int N=0; int result;

seq_insert("john", "wayne", usernames, passwords, &N); result = seq_insert("john", "wayne", usernames, passwords, &N); printf("%d\n", result); seq_insert("mary", "hadalamb", usernames, passwords, &N); seq_insert("james", "bond", usernames, passwords, &N); seq_insert("Wilma", "Fred", usernames, passwords, &N);

result = seq_insert("mary", "hadalamb", usernames, passwords, &N); printf("%d\n", result);

print_arrays(usernames, passwords, N);

/* Uncomment these lines if you implement binary search printf("\'%d\'\n", binarySearch("mary", usernames, 0, N-1)); printf("\'%d\'\n", binarySearch("nancy", usernames, 0, N-1)); */ bubble_sort( usernames, passwords, &N ); print_arrays(usernames, passwords, N);

-6/8- /* Uncomment these lines if you implement binary search printf("\'%d\'\n", binarySearch("mary", usernames, 0, N-1)); printf("\'%d\'\n", binarySearch("nancy", usernames, 0, N-1)); */

seq_delete("mary", usernames, passwords, &N); seq_delete("Wilma", usernames, passwords, &N);

result = seq_delete("fred", usernames, passwords, &N); printf("%d\n", result);

result = seq_delete("Wilma", usernames, passwords, &N); printf("%d\n", result);

seq_delete("john", usernames, passwords, &N); seq_delete("james", usernames, passwords, &N);

print_arrays(usernames, passwords, N);

sorted_insert("Wilma", "Fred", usernames, passwords, &N); sorted_insert("john", "wayne", usernames, passwords, &N); result = sorted_insert("john", "wayne", usernames, passwords, &N); printf("%d\n", result); print_arrays(usernames, passwords, N); sorted_insert("mary", "hadalamb", usernames, passwords, &N); print_arrays(usernames, passwords, N); sorted_insert("james", "bond", usernames, passwords, &N); print_arrays(usernames, passwords, N); result = sorted_insert("mary", "hadalamb", usernames, passwords, &N); printf("%d\n", result); print_arrays(usernames, passwords, N);

/* Uncomment these lines if you implement binary search printf("\'%d\'\n", binarySearch("john", usernames, 0, N-1)); printf("\'%d\'\n", binarySearch("Wilma", usernames, 0, N-1)); printf("\'%d\'\n", binarySearch("nancy", usernames, 0, N-1)); */

return 0; }

-7/8- You need to know the following to solve the exercise:

In C, strings cannot be compared using >, == or <. You have to use: int strcmp(const char *s1, const char *s2); /*Returns a positive integer if string s1 is lexically greater than string s2; zero if the two strings are identical; and a negative integer if string s1 is lexically less than string s2. It's case sensitive*/ int strcasecmp(const char *s1, const char *s2); /*Does a case-insensitive string comparison between the strings referenced by the pointers s1 and s2. Note: strcasecmp is UNIX specific, it does not belong to the C standard*/

Examples: strcmp("cscience", "cscience"); /* returns 0 */ strcmp("john", "mary"); /* returns a negative integer */ strcmp("wilma", "james"); /* returns a positive integer */ strcmp("Wilma", "james"); /* returns a negative integer since 'W' < 'j'*/ strcasecmp("Wilma", "james"); /* returns a positive integer: case insensitive*/ strcasecmp("cscience", "cscience"); /* returns 0 */ strcasecmp("john", "mary"); /* returns a negative integer */

For strings in C, the assignment operator = cannot be used to copy the contents of one string to another. You have to use this function: char *strcpy(char *s1, const char *s2);

For example: char str1[20] = "james", str2[20]; strcpy(str2, str1); /* str2 ends up with the value "james" */

To get the length of a string you must use this function: size_t strlen(const char *s);

For example: int j = strlen("mary"); /* j ends up with the value 4*/

All the functions above are available if you include in your program

#include

-8/8-