Assignment 3 Question 1: The inventors of the C language have created a language that requires very little typing. One-character symbols are used a lot, and abbreviations are part of the syntax. Here is an example of an abbreviation in correct code: void function( char* buf ) { ... } void otherfunction( ) { char buffer[200]; ... function( buffer ); /* <- abbreviation */ ... } What is this actually? Solution: It means { char buffer[200]; function( &buffer[0] ); /* <- abbreviation */ } The array's name is the same thing as a pointer to its first element. This means also that void function( char* buf ) { ... /* first version */ } and void function( char buf[] ) { ... /* second version */ } are _nearly_ equivalent. The difference is that you can never change buf in the second version. For example, the use "free(buf)" or "buf = buf + 1" in the second version is not allowed. Question 2: You have the following code: void function( int a, int* b, char c, char* d, char e[] ) { a = 2; *b = 3; b = &a; c = 'x'; *d = 'y'; d = &c; e[2] = 'z'; } int main( ) { int k,l; int* m; char n,o; char* p; char q[5]; k = 100; l = 101; m = &l; n = 'n'; o = 'o'; p = &o; q[0] = 'h'; q[1] = 'e'; q[2] = 'r'; q[3] = 'e'; q[4] = '\0'; function( k,m,n,p,q ); printf( "k=%d l=%d *m=%d\n", k, l, *m ); printf( "n=%c o=%c *p=%c\n", n, o, *p ); printf( "q=%s\n", q ); } What is printed onto the screen? Why? Solution: This is printed: k=100 l=3 *m=3 n=n o=y *p=y q=heze When function is called, it receives _copies_ of the values k, m, n, and p, and a pointer to the array q. (1) Because a and b are copies, k and n remain unchanged. (2) For m and p, on the other hand, function does at first not try to change m and p themselves, but the places that they point to. They point to the actual variables l and o, not to copies. So, l and o are changed. (3) After that, function changes b and d, which are only copies of m and p, so m and p are not changed. (4) The name of an array is always a pointer to the array. So, when function is called with the paramter q, e becomes also a pointer to the array q. That means that it can also change the contents of the array. And that's what it does. Question 3: You have the following code: void funA( char buf[10] ) { int i; for( i=0; i<10; i++ ) { buf[i] = 'a' + i; } } void funB( char* buf ) { int i; for( i=0; i<10; i++ ) { buf[i] = 'b' + i; } } void funC( char* buf ) { int i; for( i=0; i<10; i++ ) { *buf = 'c' + i; buf = buf + 1; } } int main( ) { char buf[11]; memset( buf, 0, 11 ); funA( buf ); printf( "%s\n", buf ); funB( buf ); printf( "%s\n", buf ); funC( buf ); printf( "%s\n", buf ); } What is the output? Why? Solution: The output is: abcdefghij bcdefghijk cdefghijkl First of all, the character 'a' is identical to the number 97, and the rest of the alphabet follows, 'b' is 98, and so on. This means that you can say that 'c' == 'a' + 2. Second, funA and funB are semantically identical because we have already said that array names are only pointer to their first element anyway. So clearly, char buf[10] and char* buf are essentially the same thing. funC shows that you can do something more with pointers. You can change them. This is called pointer arithmetics. You can even use them the following way: void funD( char* buf ) { int i; for( i=0; i<10; i++ ) { *(buf+i) = 'c' + i; } } The C book by its inventors Kernighan and Ritchie clarifies why this works. They say that &buf[3] is only a transformation of buf+3 and buf[3] is a transformation of *(buf+3) So, "*(buf+3)" is the original version, and buf[3] has been introduced into the C language to make it _easier_ for us to understand what is going on. Question 4: You have the following variable: char* apple = " a\n" " ppl\n" " eappl\n" " eapple\n" " apple\n" " appl\n" " eappleappleappleappl\n" " eappleappleappleappleapple\n" " appleappleappleappleappleapple\n" " appleappleappleappleappleappleappl\n" " eappleappleappleappleappleappleapple\n" "appleappleappleappleappleappleappleapp\n" "leappleappleappleappleappleappleapplea\n" "ppleappleappleappleappleappleappleappl\n" "eappleappleappleappleappleappleappleap\n" "pleappleappleappleappleappleappleapple\n" "appleappleappleappleappleappleappleapp\n" "leappleappleappleappwormpleappleapplea\n" " ppleappleappleappleappleappleappleap\n" " pleappleappleappleappleappleapplea\n" " ppleappleappleappleappleappleapp\n" " leappleappleappleappleappleap\n" " pleappleappleappleappleapp\n" " leappleappleappleapple\n" " appleappleappleapp\n"; (Yes, this string can be copied and pasted into your program, although it is longer than one line) How long is the string? How many bytes would you have to allocate with malloc if you wanted to make a copy? Solution: 822 823 Question 5: Try to find the "worm" in the apple in several ways: - Using no C functions at all, basic language operations such as if/else, for, while, do, and so on - Make your search function a bit simpler by using one the C function strchr() - Make your search a lot easier by using the C function strstr() Cut the worm out of the apple by overwriting it with space characters " ". Remember that you must #include to use strchr() and strstr(). Solution: These are rather short answers that make use of the knowledge that the worm is in the apple, and that there is no other w in it. They are legal answers, but more sophisticated answers would be appreciated. int main() { int i = 0; while( apple[i] != 'w' ) i++; for( j=0; j<4; j++ ) apple[i+j] = ' '; } int main() { int i = 0; char* c = strchr(apple,'w'); for( j=0; j<4; j++ ) c[j] = ' '; } int main() { int i = 0; char* c = strstr(apple,"worm"); for( j=0; j<4; j++ ) c[j] = ' '; } Question 6: How deep in the apple is the worm? (What is the index of the character 'w' of the word "worm"). Use the strstr() function to find the answer! Solution: 565 The easiest way to figure this out is to: #include ... int x; ... x = strstr(apple,"worm") - apple;