130 likes | 137 Views
Learn about C functions, variable arguments using var.args, and compare them to Java's printf method and variable arguments
E N D
C is readable... :-) • What does this function do? void what(char *s, char *t) { while (*s++ = *t++) ; } • How about this function? int why(char *s, char *t) { while(*s && *s == *t) s++, t++; return *s == *t; }
printf( ) ... super polymorphism? • printf( ) is a function, written in C.The definition must include a list of its parameters.So, how can we write... printf("hi there"); // 1 parameter printf("n=%d", 4); // 2 parameters, one int printf("x=%f", 0.5); // 2 parameters, one float printf("%s %d %f","hi",n,x); // 4 parameters! printf("%s%s%d%d%f","2","3",4,5,6.0); // 6 !! • printf( ) accepts an infinite variety of argument lists.How???
Variable Parameters • C allows variable number of parameters using "var args", also called "stdarg". #include <stdarg.h> int sum(int num, ...) /* "..." indicates var args */ { va_list ap; int d, sum = 0; /* second value (num) is the name of the param before start of variable parameters */ va_start(ap, num); /* initialize */ for(int k=0; k < num; k++) { /* read next arg. Expect an "int" */ d = va_arg(ap, int); sum += d; } va_end(ap); /* end va_arg processing */ return sum; }
The Problem with C's var args: • C variable parameters are not type-safe. The compiler does not check that actual arguments are of the correct type. • If you use the wrong data, you get a run-time error: dynamic semantic or logic error, your choice :-) /* using sum from the previous slide */ int sum1, sum2, sum3; /* this is correct! */ sum1 = sum(4, 3, 12, 88, -45); // add 4 integers /* wrong number of arguments! */ sum2 = sum(4, 3, 12, 88); // crash! /* wrong data type of arguments! */ sum3 = sum(4, 3, 1.2, 88, "help"); // crash!
Java printf( )... super polymorphism? • The Java Format class has a format( ) method; PrintStream (System.out) has a printf( ) method.Both of these methods accept a String argument followed by any number of other arguments! • Is this more super polymorphism? System.out.printf("hi there %s", you.toString() ); System.out.printf("%s is %s", "now", new Date()); // works with primitive types, too! int a = 5, b = 12; System.out.printf("%d + %d = %d", a, b, a+b); printf("x=%f", 0.5); // 2 parameters, one float
Java also has variable arguments • Java 5.0 adopts syntax similar to C, but more strict: printf(String format, Object ... arg ); defines arg as an array of Object. /** Define a method that can sum any number * of integer arguments. */ public static int sum(int num, int ... x) { int total = 0; if ( x.length < num ) num = x.length; for( int k=0; k<num; k++ ) total += x[k]; return total; } • the variable length argument must be the last param. • all arguments must be the same or compatible type.
Java variable argument is safer • The compiler will check that all arguments match the parameter data type. • Since the formal parameter is an array, the method can verify the number of actual arguments. /* using sum from the previous slide */ int sum1, sum2, sum3; /* this is correct! */ sum1 = sum(4, 3, 12, 88, -45); /* wrong number of arguments! */ sum2 = sum(4, 3, 12, 88); // no problem /* wrong data type of arguments! */ sum3 = sum(4, 3, 1.2, 88, "help"); // Compile-time error
Safe string input (1) • gets( ) reads a string from the input into a character array: char s[255]; gets(s); // not safe if ( *s != NULL ) mysub(s); // not safe • gets( ) is considered UNSAFE. Why?
Safe string input (2) • fgets( ) is a safer alternative to gets( ): • usage: fgets(char *s, int sizeof_s, FILE *stream ) char s[255]; fgets(s, sizeof(s)-1, stdin); if ( *s != NULL ) mysub(s); // OK
Classify the errors in this code 1: #include <stdio.h> 2: int gcd(int u#, double v); 3: { if ( v = 0 ) return 0; 4: else return gcd(v, u# % v); 5: } 6: main() 7: { int x, y; 8: printf("Input two integers: "); 9: scanf("%d%d", x, y); 10: printf("The gcd is %d\n", GCD(x,y) ); 11: return; 12: }
Errors Line 2, 4: "u#" is a lexical error (not legal identifier) Line 2: "double v" is a static semantic error. Will be reported on line 4 when % is used. Line 2: ";" can be a semantic or syntax error: the statement is a legal function prototype so you could call it semantic; but the following code block is not legal in this case, so you could call it syntax if viewed with the following code. Line 3: "=" is a logic error. It will result in a dynamic (run-time) semantic error (division by zero). Not detected by compiler! Line 6: syntax error. No return type for main(). ** Line 9: forgot "&" -- syntax or semantic error? Line 10: static semantic error; caught by the linker, not the compiler. Line 11: missing return value is a semantic error. The semantics of main() is that it returns an int. ** ** Many compilers will permit this, even though it violates standard.
C Prototype /*function prototype */ int sum(int count, int array[ ] ) ; int average(int n, int x[]) { /* compute average of x[] */ return sum(n, x)/n; } int sum(int n, int x[]) { int i, s = 0; for(i=0; i<n; i++) s += x[i]; return s; }