Chapter 11 Introduction to Programming in C Copyright © The McGraw-Hill Companies, Inc. Permission required for reproduction or display. Compilation vs. Interpretation Different ways of translating high-level language Interpretation • • • • • interpreter = program that executes program statements generally one line/command at a time limited processing easy to debug, make changes, view intermediate results languages: BASIC, LISP, Perl, Java, Matlab, C-shell Compilation • translates statements into machine language does not execute, but creates executable program • performs optimization over multiple statements • change requires recompilation can be harder to debug, since executed code may be different • languages: C, C++, Fortran, Pascal 11-2 Copyright © The McGraw-Hill Companies, Inc. Permission required for reproduction or display. Compilation vs. Interpretation Consider the following algorithm: • • • • • Get W X = W Y = X Z = Y Print from the keyboard. + W + X + Y Z to screen. If interpreting, how many arithmetic operations occur? If compiling, we can analyze the entire program and possibly reduce the number of operations. Can we simplify the above algorithm to use a single arithmetic operation? 11-3 Copyright © The McGraw-Hill Companies, Inc. Permission required for reproduction or display. C Source and Header Files Compiling a C Program Entire mechanism is usually called the “compiler” Preprocessor (No Java equivalent) • macro substitution • conditional compilation • “source-level” transformations output is still C Linker • combine object files (including libraries) into executable image Compiler Source Code Analysis Symbol Table Target Code Synthesis Compiler • generates object file machine instructions C Preprocessor Library Object Files Linker Executable Image 11-4 Copyright © The McGraw-Hill Companies, Inc. Permission required for reproduction or display. Multi-Pass Compiler Source Code Analysis (Java does this) • “front end” • parses programs to identify its pieces variables, expressions, statements, functions, etc. • depends on language (not on target machine) Code Generation (JVM or JIT does this) • • • • “back end” generates machine code from analyzed source may optimize machine code to make it run more efficiently very dependent on target machine Symbol Table • map between symbolic names and items • like assembler, but more kinds of information 11-5 Copyright © The McGraw-Hill Companies, Inc. Permission required for reproduction or display. Compiling and Linking Various compilers available • cc, gcc • includes preprocessor, compiler, and linker Lots and lots of options! • level of optimization, debugging • preprocessor, linker options • intermediate files -object (.o), assembler (.s), preprocessor (.i), etc • • • • gcc –S file.c // to spit out the assembly file (.s) gcc –c file.c // spits out the object file (.o) gcc file.c // produces a.out gcc –o myprogram file.c // “-o” allows you to name output 11-6 Copyright © The McGraw-Hill Companies, Inc. Permission required for reproduction or display. Major differences between C and Java Preprocessor allows for efficient naming of constants No String or boolean types Keyboard input and monitor output static, public, and private are slightly different Memory allocation – must deallocate memory explicitly No objects in C – though we can group data together. How references / pointers are used Most other differences are minor. 11-7 Equivalent to Preprocessor “import” A Simple C Program directive Copyright © The McGraw-Hill Companies, Inc. Permission required for reproduction or display. #include <stdio.h> #define STOP 0 Equivalent to String[] args “static public” /* No Function: main */ /* Description: counts down from user input to STOP */ int main(int argc, char *argv[]) Declarations { are the same /* variable declarations */ int counter; /* an integer to hold count values */ int startPoint; /* starting point for countdown Printing*/a /* prompt user for input */ screen printf("Enter a positive number: "); scanf("%d", &startPoint); /* read into startPoint */ /* count down and print count */ for (counter=startPoint; counter >= STOP; counter--) printf("%d\n", counter); Reading from } Printing an the keyboard 11-8 integer Copyright © The McGraw-Hill Companies, Inc. Permission required for reproduction or display. Preprocessor Directives #include <stdio.h> #include <stdlib.h> • These are the most common library files in C • To make your functions visible to other code, place prototype into a .h file no restrictions -- could be any C source code #define STOP 0 • Before compiling, preprocessor replaces all instances of the string "STOP" with the string "0" • Called a macro • Used for values that won't change during execution, but might change if the program is reused. (Must recompile.) • Lots and lots of other uses – we might learn some later 11-9 Copyright © The McGraw-Hill Companies, Inc. Permission required for reproduction or display. Comments Begins with /* and ends with */ Can span multiple lines Cannot have a comment within a comment Comments are not recognized within a string • example: "my/*don't print this*/string" would be printed as: my/*don't print this*/string // - style commenting is C++. Some C compilers accept it. As before, use comments to help reader, not to confuse or to restate the obvious 11-10 Copyright © The McGraw-Hill Companies, Inc. Permission required for reproduction or display. main Function Every C program must have a function called main(). argc contains the number of arguments argv is an array of char pointers (array of strings), just like in Java main(int argc, char *argv[]) { /* code goes here */ } 11-11 Copyright © The McGraw-Hill Companies, Inc. Permission required for reproduction or display. Variable Declarations – Just like Java int counter, startPoint; Predefined types in C: int integer (at least 16 bits) – short, long double floating point (at least 32 bits) char character (at least 8 bits) Sizes are influenced by register sizes of computer. Declaring arrays in C: int myArray[5]; Declaring references (pointers) in C: int *myArray; Dereferencing a pointer: myArray[0] = 5; *myArray = 5; Note: In Java, references are tied to the type. No references to primitive types, only references to objects. 11-12 Copyright © The McGraw-Hill Companies, Inc. Permission required for reproduction or display. Literals Integer 123 /* decimal */ -123 0x123 /* hexadecimal */ Floating point 6.023 6.023e23 5E12 /* 6.023 x 1023 */ /* 5.0 x 1012 */ Character 'c' '\n' /* newline */ '\xA' /* ASCII 10 (0xA) */ 11-13 Copyright © The McGraw-Hill Companies, Inc. Permission required for reproduction or display. Bitwise Operators – the same as Java Symbol ~ << >> & ^ | Operation bitwise NOT left shift right shift bitwise AND bitwise XOR bitwise OR Usage ~x x << y x >> y x & y x ^ y x | y Precedence Assoc 4 r-to-l 8 l-to-r 8 l-to-r 11 l-to-r 12 l-to-r 13 l-to-r Operate on variables bit-by-bit. • Like LC-3 AND and NOT instructions. Shift operations are logical (not arithmetic). Operate on values -- neither operand is changed. 11-14 Copyright © The McGraw-Hill Companies, Inc. Permission required for reproduction or display. Logical Operators – Same syntax as Java Different semantics since C has no boolean values Symbol Operation Usage Precedence ! logical NOT !x 4 && logical AND x && y 14 || logical OR x || y 15 Assoc r-to-l l-to-r l-to-r Treats entire variable (or value) as TRUE (non-zero) or FALSE (zero). Result is 1 (TRUE) or 0 (FALSE). 11-15 Copyright © The McGraw-Hill Companies, Inc. Permission required for reproduction or display. Input and Output Variety of I/O functions in C Standard Library. Must include <stdio.h> to use them. printf("%d\n", counter); • String contains characters to print and formatting directions for variables. • This call says to print the variable counter as a decimal integer, followed by a linefeed (\n). scanf("%d", &startPoint); • String contains formatting directions for looking at input. • This call says to read a decimal integer and assign it to the variable startPoint. (Don't worry about the & yet.) 11-16 Copyright © The McGraw-Hill Companies, Inc. Permission required for reproduction or display. More About Output Can print arbitrary expressions, not just variables printf("%d\n", startPoint - counter); Print multiple expressions with a single statement printf("%d %d\n", counter, startPoint - counter); Different formatting options: %d decimal integer %x hexadecimal integer %c ASCII character %f floating-point number %s string (char *) 11-17 Copyright © The McGraw-Hill Companies, Inc. Permission required for reproduction or display. Examples This code: printf("%d printf("43 printf("43 printf("43 is a plus plus plus prime 59 in 59 in 59 as number.\n", 43); decimal is %d.\n", 43+59); hex is %x.\n", 43+59); a character is %c.\n", 43+59); produces this output: 43 43 43 43 is a plus plus plus prime 59 in 59 in 59 as number. decimal is 102. hex is 66. a character is f. 11-18 Copyright © The McGraw-Hill Companies, Inc. Permission required for reproduction or display. Examples of Input Many of the same formatting characters are available for user input. scanf("%c", &nextChar); • reads a single character and stores it in nextChar scanf("%f", &radius); • reads a floating point number and stores it in radius scanf("%d %d", &length, &width); • reads two decimal integers (separated by whitespace), stores the first one in length and the second in width Must use ampersand (&) for variables being modified. This is the symbol for “address of” because it needs to know where to place the input. 11-19 Copyright © The McGraw-Hill Companies, Inc. Permission required for reproduction or display. public – everyone can see it static – always exists Scope in Java – For those who know Java private – only MyClass code sees it class MyClass { static – always exists public static int globalItem; private static int onlyISeeGlobal; Only exists during function call Only accessible within function call int myFunction() { int localItem; Only exists while in if statement if (true) Hides earlier variable { int localItem; // hides early variable } // if true } // end of myFunction } // end of MyClass 11-20 Copyright © The McGraw-Hill Companies, Inc. Permission required for reproduction or display. Scope: Global and Local Where is the variable accessible? Global: accessed anywhere in program Local: only accessible in a particular region Compiler infers scope from where variable is declared • programmer doesn't have to explicitly state Variable is local to the block in which it is declared • block defined by open and closed braces { } • can access variable declared in any "containing" block Global variable is declared outside all blocks 11-21 Copyright © The McGraw-Hill Companies, Inc. Permission required for reproduction or display. Example #include <stdio.h> int itsGlobal = 0; main() { int itsLocal = 1; /* local to main */ printf("Global %d Local %d\n", itsGlobal, itsLocal); { int itsLocal = 2; /* local to this block */ itsGlobal = 4; /* change global variable */ printf("Global %d Local %d\n", itsGlobal, itsLocal); } printf("Global %d Local %d\n", itsGlobal, itsLocal); } Output Global 0 Local 1 Global 4 Local 2 Global 4 Local 1 11-22 Copyright © The McGraw-Hill Companies, Inc. Permission required for reproduction or display. Example #include <stdio.h> int itsGlobal = 0; main() { int itsLocal = 1; /* local to main */ printf("Global %d Local %d\n", itsGlobal, itsLocal); { itsLocal = 2; /* local to this block */ itsGlobal = 4; /* change global variable */ printf("Global %d Local %d\n", itsGlobal, itsLocal); } printf("Global %d Local %d\n", itsGlobal, itsLocal); } Output Global 0 Local 1 Global 4 Local 2 Global 4 Local 2 11-23 Copyright © The McGraw-Hill Companies, Inc. Permission required for reproduction or display. Scope Example 2 #include <stdio.h> int nextCount(); // function prototype so compiler knows it exists main() { int itsStatic = 5; printf(“Counter: %d %d\n", nextCount(), itsStatic++); printf(“Counter: %d,%d\n", nextCount(), itsStatic++); printf(“Counter: %d\n", nextCount()); printf(“Counter: %d\n", nextCount()); } int nextCount() { static int itsStatic = 0; return ++itsStatic; } only visible in this function static – always exists Output Counter: Counter: Counter: Counter: 1, 5 2, 6 3 4 11-24 Copyright © The McGraw-Hill Companies, Inc. Permission required for reproduction or display. Scope Example 2 #include <stdio.h> int nextCount(); // function prototype so compiler knows it exists main() { int itsStatic = 5; printf(“Counter: %d %d\n", nextCount(), itsStatic++); printf(“Counter: %d,%d\n", nextCount(), itsStatic++); printf(“Counter: %d\n", nextCount()); printf(“Counter: %d\n", nextCount()); } int nextCount() { static int itsStatic = 0; return itsStatic++; } only visible in this function static – always exists Output Counter: Counter: Counter: Counter: 0, 5 1, 6 2 3 11-25 Copyright © The McGraw-Hill Companies, Inc. Permission required for reproduction or display. Making variables visible to other programs Must be a global variable where allocated declared extern in other file extern int otherGlobal; Common practice: Place “extern int otherGlobal” in code.h file Place “int otherGlobal” in code.c file Anyone who wants to use otherGlobal includes code.h: #include “code.h” Note: There can only be one instance of “int otherGlobal” declared globally throughout all files. All global variables must have distinct names. 11-26 Copyright © The McGraw-Hill Companies, Inc. Permission required for reproduction or display. Local Variable Storage Local variables are stored in an activation record, also known as a stack frame. Symbol table “offset” gives the distance from the base of the frame. • R5 is the frame pointer – holds address of the base of the current frame. • A new frame is pushed on the run-time stack each time a block is entered. • Because stack grows downward, R5 base is the highest address of the frame, and variable offsets are <= 0. seconds minutes hours time rate amount 11-27 Copyright © The McGraw-Hill Companies, Inc. Permission required for reproduction or display. Allocating Space for Variables Global data section 0x0000 • All global variables stored here (actually all static variables) • R4 points to beginning Run-time stack • • • • Used for local variables R6 points to top of stack R5 points to top frame on stack New frame for each block (goes away when block exited) Offset = distance from beginning of storage area 0xFFFF • Global: LDR R1, R4, #4 • Local: LDR R2, R5, #-3 instructions global data run-time stack PC R4 R6 R5 11-28 Copyright © The McGraw-Hill Companies, Inc. Permission required for reproduction or display. Variables and Memory Locations In our examples, a variable is always stored in memory. When assigning to a variable, must store to memory location. A real compiler would perform code optimizations that try to keep variables allocated in registers. Why? 11-29 Copyright © The McGraw-Hill Companies, Inc. Permission required for reproduction or display. Example: Compiling to LC-3 #include <stdio.h> int inGlobal; main() { int inLocal; /* local to main */ int outLocalA; int outLocalB; /* initialize */ inLocal = 5; inGlobal = 3; /* perform calculations */ outLocalA = inLocal++ & ~inGlobal; outLocalB = (inLocal + inGlobal) - (inLocal - inGlobal); /* print results */ printf("The results are: outLocalA = %d, outLocalB = %d\n", outLocalA, outLocalB); } 11-30 Copyright © The McGraw-Hill Companies, Inc. Permission required for reproduction or display. Example: Symbol Table Name Type Offset Scope inGlobal int 0 global inLocal int 0 main outLocalA int -1 main outLocalB int -2 main 11-31 Copyright © The McGraw-Hill Companies, Inc. Permission required for reproduction or display. Example: Code Generation ; main ; initialize variables AND R0, R0, #0 ADD R0, R0, #5 ; inLocal = 5 STR R0, R5, #0 ; (offset = 0) AND R0, R0, #0 ADD R0, R0, #3 STR R0, R4, #0 ; inGlobal = 3 ; (offset = 0) 11-32 Copyright © The McGraw-Hill Companies, Inc. Permission required for reproduction or display. Example (continued) ; first statement: ; outLocalA = inLocal++ LDR R0, R5, #0 ; ADD R1, R0, #1 ; STR R1, R5, #0 ; LDR NOT AND STR R1, R1, R2, R2, R4, #0 R1 R0, R1 R5, #-1 ; ; ; ; ; & ~inGlobal; get inLocal increment store get inGlobal ~inGlobal inLocal & ~inGlobal store in outLocalA (offset = -1) 11-33 Copyright © The McGraw-Hill Companies, Inc. Permission required for reproduction or display. Example (continued) ; next statement: ; outLocalB = (inLocal + inGlobal) ; - (inLocal - inGlobal); LDR R0, R5, #0 ; inLocal LDR R1, R4, #0 ; inGlobal ADD R0, R0, R1 ; R0 is sum LDR R2, R5, #0 ; inLocal LDR R3, R5, #0 ; inGlobal NOT R3, R3 ADD R3, R3, #1 ADD R2, R2, R3 ; R2 is difference NOT R2, R2 ; negate ADD R2, R2, #1 ADD R0, R0, R2 ; R0 = R0 - R2 STR R0, R5, #-2 ; outLocalB (offset = -2) 11-34