160 likes | 250 Views
CS113 Introduction to C. Instructor: Ioannis A. Vetsikas E-mail: vetsikas@cs.cornell.edu Lecture 3 : August 30 webpage: http://www.cs.cornell.edu/Courses/cs113/2000FA/cs113.htm. Logical Operators (additions). Unary negation operator ! Ex: if (!var) same as if (var == 0)
E N D
CS113Introduction to C Instructor: Ioannis A. VetsikasE-mail: vetsikas@cs.cornell.edu Lecture 3 : August 30 webpage: http://www.cs.cornell.edu/Courses/cs113/2000FA/cs113.htm
Logical Operators (additions) • Unary negation operator ! • Ex: if (!var) same as if (var == 0) • What is if (!!var) equivalent to? • Lazy evaluation (logical AND/OR): • if ((x!=0) && (1/x>1)) … • If x equals 0 then the whole boolean expression is false and thus (1/x>1) does not get evaluated (good since otherwise it would give a divide by zero type error) • The evaluation order for && and || is guaranteed to be from left to right
Logical Operators (examples) • a==1 && b!=2 || !c • !(a==1 || b>=3) && c • a>b == b>c
A little bit about Functions • Should perform a well-defined task • Why? Adds no functionality. • Breaking tasks into smaller ones make them easier to think about • Hiding details tends to make code less complicated, rendering it more readable • Easier to debug the code as well • Code can be re-used, not just within one program but in others. • Recursion easier to do • more on that later…
More on functions • Syntax: • [return type] <name> ([type param_name]*) • e.g. int factorial(int n) • e.g. void execute_loop(char c, float f) • Call as: • i=factorial(3); • execute_loop(townInitial, distance); • Can also declare them • int factorial(int n); or int factorial(int); • Return (w/ or w/o value): return [expr];
Example: A simple function #include <stdio.h> int max( int a, int b ); void main() { int i = 8, j = 17; printf( “Maximum of %d and %d is %d\n”, i, j, max(i, j)); } int max( int a, int b ) { if( a > b ) return a; else return b; }
Example 2 (Call by value) #include <stdio.h> void printDouble( int x ) { printf(“Double of %d”, x); x *= 2; printf(“is %d\n”, x); } void main() { int i = 13; printDouble(i); printf(“i=%d\n”, i); } • What does it print? • A parameter of the function can be a constant, expression, variable etc. (anything that has a value!) • Only the value is passed (not variable!)
One-Dimensional Arrays • Often, programs use homogeneous data. As an example, if we want to manipulate some grades, we might declare • int grade0, grade1, grade2; • If we have a large number of grades, it becomes cumbersome to represent/manipulate the data using unique identifiers. • Arrays allow us to refer to a large number of the same data type using a single name. For instance, • int grade[3];
One-Dimensional Arrays (continued) • Makes available the use of integer variables grade[0], grade[1], grade[2] in a program. • Declaration syntax: Type array_name[number_of_elements] • WARNING: arrays are zero-indexed (numbering always starts at 0). • Now, to access elements of this array, we can write grade[expr], where expr is an integral expression. • Example: for( i = 0; i < 3; i++ ) sum += grade[i];
Pointers • A variable in a program is stored in a certain number of bytes at a particular memory location, or address, in the machine. • Pointers allow us to manipulate these addresses explicitly. • Two unary operators: (“inverses”) • & operator – “address of”. Can be applied to any variable. “Adds a star to type”. • * operator – “information at”. Can be applied only to pointers. “Removes a star from type” • Pointer when declared points to an invalid location usually; so you must make it point to a valid one.
Pointers (continued) int a = 1, b = 2, *p; void *void_p; char *char_p; p = &a; b = *p; • An assignment like char_p = &a; is illegal, as the types do not match. • void * is a generic pointer type; can make assignments such as void_p = char_p; or void_p = &b; • void * is also the type of pointer returned by memory allocation functions (more later…)
Constructs not to be pointed at • Do not point at constants: • int *ptr; • *ptr = 3; /* OK */ • ptr = &3; /* illegal */ • Do not point at arrays; an array name is a constant. • int a[77]; • void *ptr; • ptr = a; /* OK */ • ptr = &a; /* illegal */ • Do not point at expressions that are not variables. • int k = 1, *ptr; • *ptr = k + 99; /* OK */ • ptr = &(k + 99); /* illegal */ • Do not point at register variables (not presented yet!) • register int k=1; int *ptr; • ptr = &k;
“Call by reference” (not really) • Pointers allow us to perform something similar to call-by-reference (we are passing pointers/references by value) • “call-by-reference” allows a function to make changes to a variable that persist void set_int_to_3( int *p ) { *p = 3; } void swap( int *p, int *q ) { int temp; temp = *p; *p = *q; *q = temp; }
Arrays and Pointers • Assume int i, a[10], *p; • The type of a is “int *”. • a is equivalent to &a[0] • a + i is equivalent to &a[i] • Correspondingly, • a[i] is equivalent to *(a + i) • In fact, • p[i] is equivalent to *(p + i) for( p = a; p < &a[10]; p++ ) sum += *p; for( i = 0; i < 10; i++ ) sum += *(a + i); p = a; for( i = 0; i < 10; i++ ) sum += p[i];
Example: Arrays as Function Arguments(Array passed by reference, so changes to array persist) int change_and_sum( int a[], int size ) { int i, sum = 0; a[0] = 100; for( i = 0; i < size; i++ ) sum += a[i]; return sum; } void main() { int a[5] = {0, 1, 2, 3, 4}; printf( “sum of a: %d\n”, change_and_sum( a, 5 )); printf( “value of a[0]: %d\n”, a[0] ); }
Arrays and Pointers (a difference) • An array is in essence a pointer • However: int i, a[10], *p; p=a; /* equiv. to p=&a[0]; */ p++; /* valid */ a++; /* error! */ • The name of an array is not a variable, so the only operator you can apply to it is [] • E.g. a[i+3]