C A Short Course for REU Students Summer 2008 Instructor: Ben Ransford http://www.cs.umass.edu/~ransford/ ransford@cs.umass.edu 1
Outline Last time: basic syntax, compilation This time: pointers, libraries, I/O,... Goal: soundness, not completeness http://www.cs.umass.edu/~ransford/reuc/ 2
Pointers There s nothing to fear. int i = 12345; int* location_of_i = &i; 3
Pointers: You already know them. 1: public class Hello { 2: private int value; 3: public void setvalue (int val) { this.value = val; } 4: public int getvalue () { return this.value; } 5: Hello (int val) { this.setvalue(val); } 6: } 1: public class foo { 2: public static void main(string[] args) { 3: Hello a = new Hello(5); 4: Hello b = a; 5: b.setvalue(10); 6: 7: System.out.println(a.getValue()); 8: System.out.println(b.getValue()); 9: System.exit(0); 10: } 11: } 4
Pointers: You already know them. 1: public class Hello { 2: private int value; 3: public void setvalue (int val) { this.value = val; } 4: public int getvalue () { return this.value; } 5: Hello (int val) { this.setvalue(val); } 6: } 1: public class foo { 2: public static void main(string[] args) { 3: Hello a = new Hello(5); 4: Hello b = a; 5: b.setvalue(10); 6: 7: System.out.println(a.getValue()); 8: System.out.println(b.getValue()); 9: System.exit(0); 10: } 11: } 4
Pointers in C: syntax int i = 12345; 5
Pointers in C: syntax int i = 12345; This code allocates enough space on the stack for one integer. 5
Pointers in C: syntax int i = 12345; This code allocates enough space on the stack for one integer. foo 999 i 12345 sizeof(int) [4 bytes]...... 5
int i = 12345; On the stack, in memory: 0x0000 foo 999 0x0004 i 12345 0x0008...... Memory locations (addresses) 6
int i = 12345; On the stack, in memory: 0x0000 foo 999 0x0004 i 12345 0x0008...... Memory locations (addresses) We say: &i == 0x0004 6
Pointers are types int i; int* pointer_to_i; pointer_to_i will hold the memory address of an int. 7
Pointers are types int i; int* pointer_to_i; pointer_to_i will hold the memory address of an int. Like this: pointer_to_i = &i; 7
Pointers are references int i; int* addr = &i; Referencing: addr stores a reference to i. Dereferencing: *addr is the thing whose address is in addr (namely i) i = 5; *addr = 5; 8
Pointers are references int i; int* addr = &i; Referencing: addr stores a reference to i. Dereferencing: *addr is the thing whose address is in addr (namely i) i = 5; *addr = 5; Equivalent! 8
Example 1: #include <stdio.h> 2: 3: int main (int argc, char** argv) { 4: int i = 12345; 5: int* location_of_i = &i; 6: 7: printf("%d\n", i); 8: printf("%d\n", *location_of_i); 9: 10: return 0; 11: } 9
Example 1: #include <stdio.h> 2: 3: int main (int argc, char** argv) { 4: int i = 12345; 5: int* location_of_i = &i; 6: 7: printf("%d\n", i); 8: printf("%d\n", *location_of_i); 9: 10: return 0; 11: } 9
Pointers: why we care Hint: argument passing. 10
Pointers: why we care Hint: argument passing. Call-by-value semantics: function gets a copy of whatever information you pass it. No side effects. Call-by-reference semantics: function gets a reference to the real object you want it to manipulate. 10
Argument passing example 1: #include <stdio.h> 2: 3: void triple (int* i) { 4: *i = *i * 3; 5: } 6: 7: int main (int argc, char** argv) { 8: int x = 11111; 9: printf("%d\n", x); 10: triple(&x); 11: printf("%d\n", x); 12: } 11
Argument passing example 1: #include <stdio.h> 2: 3: void triple (int* i) { 4: *i = *i * 3; 5: } 6: 7: int main (int argc, char** argv) { 8: int x = 11111; 9: printf("%d\n", x); 10: triple(&x); 11: printf("%d\n", x); 12: } 11
Example: time Goal: print 1:30 12
String is char* There is no built-in string type. Use char*. 1: #include <stdio.h> 2: #include <stdlib.h> 3: #include <string.h> 4: 5: int main (int argc, char** argv) { 6: char* foo = "This is foo."; 7: char* bar = (char*) malloc(100); 8: char* foobar; 9: bar[0] = B ; 10: bar[1] = A ; 11: bar[2] = R ; 12: bar[3] = \0 ; // string functions work on null-terminated strings 13: 14: printf("%s\n%d\n", foo, strlen(foo)); 15: printf("%s\n%d\n", bar, strlen(bar)); 16: 17: foobar = (char*) malloc(strlen(foo) + strlen(bar) + 1); 18: strcat(foobar, foo); 19: strcat(foobar, bar); 20: printf("%s\n%d\n", foobar, strlen(foobar)); 21: } 13
String is char* There is no built-in string type. Use char*. 1: #include <stdio.h> 2: #include <stdlib.h> 3: #include <string.h> 4: 5: int main (int argc, char** argv) { 6: char* foo = "This is foo."; 7: char* bar = (char*) malloc(100); 8: char* foobar; 9: bar[0] = B ; 10: bar[1] = A ; 11: bar[2] = R ; 12: bar[3] = \0 ; // string functions work on null-terminated strings 13: 14: printf("%s\n%d\n", foo, strlen(foo)); 15: printf("%s\n%d\n", bar, strlen(bar)); 16: 17: foobar = (char*) malloc(strlen(foo) + strlen(bar) + 1); 18: strcat(foobar, foo); 19: strcat(foobar, bar); 20: printf("%s\n%d\n", foobar, strlen(foobar)); 21: } 13
Arrays are pointers char c[5]; c[0] = A ; c[2] = C ; Is equivalent to *c = A ; *(c+2) = C ; 14
Pointer math Avoid this when possible. Error-prone. int arr[3]; *arr = 12345; arr++; *arr = 45678; arr^ arr^??? 12345?? 12345?? arr^ 12345 45678? arr^ 15
Libraries A library is precompiled code you can use. Libraries come with headers (.h files) so you know what s in them. Most nontrivial software uses libraries. E.g.: every Windows program uses Windows header files and libraries. 16
Library example Hello world for Windows: 1: #include <windows.h> // Windows header file 2: 3: int WINAPI WinMain (HINSTANCE hinst, HINSTANCE hprevinstance, 4: LPSTR lpcmdline, int ncmdshow) { 5: MessageBox (NULL, "Hello world!", "Title Bar Text", MB_OK); 6: return 0; 7: } 8: Header file (windows.h) + library (some DLL). 17
Linking To use a library, you link your program to it. Static linking (compile time): incorporate libraries code into your executable. Dynamic linking At compile time, store a placeholder OS must find appropriate library at runtime 18
Linking strategies compared Statically linked executables are: Larger Self-contained (independent of environment) Dynamically linked executables: Are smaller Promote code reuse (shared libraries) 19
Library example X11 is a UNIX graphics system. To write an X11 program, you use libx11. 1: #include <X11/Xlib.h> 2: #include <stdio.h> 3: 4: int main (int argc, char** argv) { 5: Display* d; 6: d = XOpenDisplay(":0.0"); 7: printf("hello!\n"); 8: XCloseDisplay(d); 9: } 20
File I/O Write to a file: 1: #include <stdio.h> 2: 3: int main (int argc, char** argv) { 4: if (argc!= 2) { 5: fprintf(stderr, "Usage: %s file\n", argv[0]); 6: return 1; 7: } 8: 9: FILE* f = fopen(argv[1], "w"); 10: fprintf(f, "Hello, I am %s\n", argv[1]); 11: fclose(f); 12: } 21
File I/O Write to a file: 1: #include <stdio.h> 2: 3: int main (int argc, char** argv) { 4: if (argc!= 2) { 5: fprintf(stderr, "Usage: %s file\n", argv[0]); 6: return 1; 7: } 8: 9: FILE* f = fopen(argv[1], "w"); 10: fprintf(f, "Hello, I am %s\n", argv[1]); 11: fclose(f); 12: } 21
File I/O Read from a file (and print its contents): 1: #include <stdio.h> 2: 3: int main (int argc, char** argv) { 4: if (argc!= 2) { 5: fprintf(stderr, "Usage: %s file\n", argv[0]); 6: return 1; 7: } 8: 9: FILE* f = fopen(argv[1], "r"); 10: char c; 11: while ((c = fgetc(f))!= EOF) { 12: putchar(c); 13: } 14: fclose(f); 15: } 22
File I/O Read from a file (and print its contents): 1: #include <stdio.h> 2: 3: int main (int argc, char** argv) { 4: if (argc!= 2) { 5: fprintf(stderr, "Usage: %s file\n", argv[0]); 6: return 1; 7: } 8: 9: FILE* f = fopen(argv[1], "r"); 10: char c; 11: while ((c = fgetc(f))!= EOF) { 12: putchar(c); 13: } 14: fclose(f); 15: } 22
That s it. C is small C is everywhere You know some C now 23
What to do now Practice writing some C programs! Read some C source code -- wherever you can find it. Find and read K&R. 24