410 likes | 558 Views
CPS 393 Introduction to Unix and C. START OF WEEK 7 (C1). How C Relates to other Languages. Widespread usage. Well-known sites using C: YouTube, LiveJournal, Wikipedia/Wikimedia, Amazon.com, Wikia, SourceForge, Metacafe, Facebook, Digg, TwitterFotolog, The Pirate Bay and Netlog.
E N D
CPS 393Introduction to Unix and C START OF WEEK 7 (C1) Course material created by D. Woit
How C Relates to other Languages • Widespread usage. • Well-known sites using C: • YouTube, LiveJournal, Wikipedia/Wikimedia, Amazon.com, Wikia, SourceForge, Metacafe, Facebook, Digg, TwitterFotolog, The Pirate Bay and Netlog. • [wikipedia/Memcached Dec09]. GoogleApps [pz Dec08] • Google Android OS (modified Linux) written largely in C. [wikipedia Jan11] Course material created by D. Woit
Low Level vs High Level Languages • high <--------------------------------------------->low • Lisp Java Ada C Assembler • Python Pascal Machine • Scala Fortran Language • Ruby C++ • C is lowest level *portable* language • OO vs Procedural Languages • OOP: main building block is *objects/message-passes* • Procedural: main building block is *variables/functions* • step-by-step process involving explicit storage of data into variables to solve problem Course material created by D. Woit
Structure of C Pgms--simplified • Pgm comments • Includes • Constant definitions • Function Prototypes • Global variable definitions • Functions (main and others) Course material created by D. Woit
Example program structure sample1.c /*source: sample1.c Author: Dr. Woit Purpose: to show how printf works Input: None Output: a line stating the lucky number */ #include <stdio.h> #include <stdlib.h> #define LUCKY 723 int main(void) { printf("The lucky number is %d\n",LUCKY); exit(0) ; } 9/17/2014 Course material created by D. Woit 5
Explanations and comments #include <stdio.h> needed for printf's definition preprocessor replaces with file contents *then* compiles #include <stdlib.h> for exit's definition. if we use return(0) built-in difference is that exit quits whole program (even if called in a function), whereas return passes control back to caller Differences in invocation: <lib.h> -looks in standard path, likely /usr/include (whereis stdio.h) "lib.h" -looks in current dir #define LUCKY 723 -preprocessor replaces *all* LUCKY with 723 *before* compile easy global changes, readability, fast execution 9/17/2014 Course material created by D. Woit 6
int main(void) -necessary. Execution begins here -body enclosed in { } printf(format-string, arguments); ^ ^ | to replace formats in format-string regular chars (letters, digits) control chars \n -newline \t -tab \a -bell formats %d -decimal integer %c -character %s -string %f -floating point %lf -double (long floating point) e.g., printf("my \a %s has %f fleas\n","dog",12.45); To run pgm: gcc filename.c ./a.out or: gcc -o filename filename.c ./filename Note: if current dir in path, just need a.out or filename Explanations and comments
HMWK Fix the following program so that it does what the comments say it will. Note that errors can be BEFORE the line it complains about. /*Purpose: to calculate the area of a rectangle with given length and width Input: none Output: length, width, and area of rectangle */ #include <stdio.h>; #define LENGTH 36 #define WIDTH 92 int main(void); printf("Length: %d, Width: %c, Area: %d\n", LENGTH,WIDTH,LENGTH*WIDTH); return 0; } 9/17/2014 Course material created by D. Woit 8
Variable types C: paradigm declare variable before use C is not strongly typed (can combine vars of diff types) TYPE USUAL SIZE RANGE (signed) char 1 byte -128...127 short int 2 bytes -32,768...32,767 or, int 4 bytes -2,147,483,648...2,147,483,647 float 4 bytes -3.4E-38 ... 3.4E+38 double 8 bytes -1.7E-308 ... 1.7E+308 9/17/2014 Course material created by D. Woit 9
Example for var. sizes /*source: typeSize.c Program to print number of bytes of C types */ #include <stdio.h> #include <stdlib.h> int main (void) { printf("char is %d bytes\n", sizeof(char)); printf("int is %d bytes\n", sizeof(int)); printf("float is %d bytes\n", sizeof(float)); printf("double is %d bytes\n", sizeof(double)); return 0; } 9/17/2014 Course material created by D. Woit 10
Modifiers Can be signed, unsigned, short, long short applies to integer only long applies to integer or double signed, unsigned apply to char or integer only unsigned char range 0...255 unsigned short int 0...65,535 As a variable, you can say: double xx = 3.9876; As a constant, you say: #define xx 3.9876 (taken as double unless suffix) #define xx 3.9876L is taken as long double L is double (if has decimal point) or long int (if no decimal) U is unsigned. So #define x 44UL makes it unsigned long int 9/17/2014 Course material created by D. Woit 11
Modifiers /*program comments go here*/ /*Source: sample2.c*/ #include <stdio.h> int main(void) { char initial1, initial2; /*first initial, last initial*/ int age; /*an age */ printf("Input first and last initial and your age (sep. space):"); scanf("%c %c %d", &initial1, &initial2, &age); printf("\nHello %c%c. Your age is %d\n",initial1,initial2,age); return 0; } Does? scanf: reads input from keyboard & stores in variables and has same formats as printf 9/17/2014 Course material created by D. Woit 12
Assignment in C age=3; initial1='D'; <<Arithmetic Operations>> + - * / % var=age*2+1; 4%2 is 0 4%3 is 1 <<Increment/Decrement using prefix and postfix>> i=i+1; i++ or ++i -used then inc; inc then used i=i-1; i-- or --i -used then decr.; decr. then used 9/17/2014 Course material created by D. Woit 13
example /*Purpose: to sum numbers from i to i+3 */ /*Source: sample3.c*/ #include <stdio.h> int main(void) { int i; /*starting number */ int sum; /*sum of i to i+3 */ printf("Enter starting number: "); scanf("%d",&i); sum=0; sum=sum + i++; sum=sum + i++; sum=sum + i++; sum=sum + i; printf("Sum from %d to %d is: %d\n", i-3,i,sum); return 0 ; } 9/17/2014 Course material created by D. Woit 14
i=1; j=i++; printf("%d %d",i,j); 2 1 i=1; j=++i; printf("%d %d",i,j); 2 2 int a,b=0,c=0; a=++b + c--; printf("%d %d %d",a,b,c); 1 1 -1 In sample3a.c /*Purpose: to convert human age to dog age*/ /*Input: a human age */ /*Output: corresponding dog age */ /*Source: sample4.c */ #include <stdio.h> int main(void) { int age; /*the human age*/ /*read in the human age */ printf("Enter your age: "); scanf("%d", &age); /*compute and print dog age */ printf("You are just like a %f year old dog.\n",age/7.0); return 0 ; } Example, prefix and postfix 9/17/2014 Course material created by D. Woit 15
Type casts are explicit type conversions Note: type conversion char < int < float < double float f = 2.8; printf("%d", (int)f); int i = 4; double result; result= i*(double)8; //if result needs to be double or result= (double) (i*8); //if result needs to be double Note: be careful where the (double) goes. e.g., dresult1= i/(double)8; dresult2= (double) (i/8); /* i/8 is 0 */ puts .5 in dresult1 but 0 in dresult2. why? See sample3b.c 9/17/2014 Course material created by D. Woit 16
HMWK re-write the program above that sums the numbers from i to (i+3) using only 1 scanf and 2 printf calls, and no assignment statements. 9/17/2014 Course material created by D. Woit 17
Functions Functions need two steps: 1. *declare* a function before use in file (fn prototype) 2. *define* a fn somewhere in pgm (maybe different file) Example for functions: /*Purpose: to compute square of an integer*/ /*Input: an integer to square */ /*Output: the square of the input integer */ /*Source: sample5.c*/ #include <stdio.h> 9/17/2014 Course material created by D. Woit 18
Sample5.c cont. int square(int a); /*prototype of function square*/ int main(void) { int num, sq; /*number to square, and its square*/ printf("Enter number: "); scanf("%d", &num); /*scanf("%d\n", &num);*/ sq = square(num); printf("The square of %d is %d\n",num,sq); return 0 ; } int square(int a) { return (a*a); } NOTE: return ENDS function. Will be the LAST EXECUTED STATEMENT It is as if "square(num)" is REPLACED by what function square returns. If we put square definition where prototype is, no need for prototype 9/17/2014 Course material created by D. Woit 19
functions Many functions are supplied with C to use them – you need to include the .h file (definitions) #include <stdio.h> #include <math.h> /*Source: sample6.c on some machines need to to compile with -lm flag: gcc -lm sample6.c */ int main(void) { double answer; answer = sin(0.2); printf("%lf",answer); return 0 ; } man math.h (for all functions, macros, etc) man sin (for a specific function) 9/17/2014 Course material created by D. Woit 20
Type Casts in Function Calls example int i; double result; result = sqrt(i); The int i is converted to double before it is passed to sqrt (sqrt is in math.h and requires a double argument.) However, be careful! printf("Sqrt of 1/2 is %lf\n",sqrt(1/2)); printf("Sqrt of 1/(double)2 is %lf\n",sqrt(1/(double)2)); prints on moons: Sqrt of 1/2 is 0.000000 Sqrt of 1/(double)2 is 0.707107 Why? (integer division) see example sample6c.c 9/17/2014 Course material created by D. Woit 21
Implicit Function Declarations Ansi C says we should use function prototypes (or define the function before its use). If we don't do this, gcc creates an implicit declaration for the function which is often not what we expected. Why? Because: implicit declarations *always* use type "int" for the function return type and for all argument types. 9/17/2014 Course material created by D. Woit 22
Eg: problem occurs when we forget function prototype /* source sample6a.c */ #include <stdio.h> #include <math.h> /* missing line: double p(double y, double z) */ int main(void) { int y=2; printf(" %lf\n",p(4,y)); return 0 ; } double p(double y, double z) { return (pow(y,z)); // pow(x,y) returns x^y } On some linux/unix versions, it will compile, (with or without a warning message) but produce an unexpected result (not 16) on metis, get errors: sample6a.c:9: error: conflicting types for 'p' sample6a.c:6: error: previous implicit declaration of 'p' was here Corrected program gcc -lm –o sample6b sample6b.c 9/17/2014 Course material created by D. Woit 23
Functions may return nothing They can be used used for their "side-effects" /*Source: sample7.c*/ #include <stdio.h> void out (char c); void bell(void); int main(void) { out('A'); bell(); return 0 ; } void out(char c) { printf("%c\n",c); } void bell(void) { printf("\a"); } 9/17/2014 Course material created by D. Woit 24
Exiting functions 1. return statements (or exit statement if main function) . Type of returned value should be same as type of function 2. falling off the end (e.g., functions out and bell above). In sample8.c variable "result" must be float because function "square" has type float. 9/17/2014 Course material created by D. Woit 25
#include <stdio.h> float square(float n); int main(void) { float num; /*number to square*/ float sqr; /*number squared */ printf("Enter a number to square: "); scanf("%f",&num); sqr=square(num); printf("%f squared is %f\n",num,sqr); return 0 ; } float square(float n) { float result; result=n*n; return(result); /*return(n*n) OK too */ } Parameters passed by *value* a *copy* of value of parameter is passed to function function can modify value and use it but does not affect the value outside of fn /*Source: sample8.c*//*differs from sample5.c in that type of square is float (and input is float) */ 9/17/2014 Course material created by D. Woit 26
/*Source: sample9.c*/ #include <stdio.h> void f(int i); int main(void) { int i=0; printf("%d\n",i); f(i); printf("%d\n",i); return 0 ; } void f(int i) { printf("%d\n",i); i=1; printf("%d\n",i); } Output? 0 – main program 0 – function #1 1 – function #2 0 – main program Scope of variables 9/17/2014 Course material created by D. Woit 27
Scope of variables 1. local variable declared in a function referenced within that function exist only while function is executing However if we want variable which maintains its value from one call of function to another we should declare it as static example: static int i; 2. globalvariable if we want global variable , we must explicitly declare it as global. This is done by declaration *outside* any function Global variable can be referenced/modified by any function A local definition of variable overrides a global definition in the case local and global variables have the same name. Global and static variables are initialized to 0 by compiler 9/17/2014 Course material created by D. Woit 28
/*Source: sample10.c*/ #include <stdio.h> void f(void); int i,k;/*global*/ int main(void) { int j=0; i=10;k=10; /*global*/ f(); printf("%d %d",i,k); return 0 ; } void f(void) { int i=20; k=5; printf("%d",j); /*error j not def.*/ } Corrected program is in sample10a.c Pros. and cons of global variables Advantage: share data among functions. Disadvantage: use memory throughout entire pgm may be used when unnecessary (fn less general) side-effects (accidental modification by some fn) Example for scope of variables 9/17/2014 Course material created by D. Woit 29
HMWK A function called "pow" is available in math.h. Read about it in man page and use it to write a program to do the following: /*Purpose: to compute the maximum sized unsigned integer that could be stored in a given number of bits Input: an integer, b, representing a number of bits Output: a line stating the maximum unsigned decimal integer that could be represented with b bits Example: Input: 4 Output: Max unsigned decimal int that could be represented with 4 bits is 15 */ Hint: (2 to the power 4) - 1 is 15 Write a function called "me" which takes no arguments and has no return value, but has the side-effect of printing out your name and address. Test it by calling it in a program. 9/17/2014 Course material created by D. Woit 30
Function code may be supplied and/or compiled in another file from main. /*Source: prog.c */ #include "myfuncs.h" int main(void) { outchar('A'); outchar('B'); outchar(G); return 0 ; } /*Source: myfuncs.h */ #define G 'v' void outchar(char c); /*Source: myfuncs.c */ #include <stdio.h> #include "myfuncs.h" void outchar(char c) { printf("%c , %c\n",c,G); } Separate Files/Compilation 9/17/2014 Course material created by D. Woit 31
Separate Files/Compilation Compile all source files: gcc prog.c myfuncs.c or gcc –o prog prog.c myfuncs.c Can compile 1 or more into object code first. gcc -c myfuncs.c gcc -c prog.c gcc prog.o myfuncs.o or gcc prog.c myfuncs.o or gcc prog.o myfuncs.c Note: myfuncs.h is incorporated into the above compiles. How? (through the header line in myfuncs.c ) 9/17/2014 Course material created by D. Woit 32
Makefile There is good documentation online. If it is still there: http://www.gnu.org/software/make/manual/html_node/index.html (just need the overview and intro.) Note it uses cc but you would use gcc Using a Makefile: make prog where file Makefile in this dir is: ---------------------------------------- prog: prog.o myfuncs.o <TAB> gcc -o prog prog.o myfuncs.o prog.o: prog.c myfuncs.h <TAB>gcc -c prog.c myfuncs.o: myfuncs.c myfuncs.h <TAB> gcc -c myfuncs.c ---------------------------------------- Option gcc –c creates object file without linking. 9/17/2014 Course material created by D. Woit 33
makefile Or, could do just: make myfuncs.o if wanted. A makefile consists of targets, dependencies, and rules target ( before the : ) dependencies ( after the : ) rules (after a TAB under a target: dependency line You can say make x where x is any target in the makefile named Makefile. make looks at the dependencies for x. If they are files and they don't exist, or have been updated since the last time the target was created, then the rule is executed. However, before the rule is executed, it checks for each dependency, d, as a target. If it does not find d, it implicitly does all "make d" first before "make x" 9/17/2014 Course material created by D. Woit 34
Makefile cont. If no *.o files existed, make prog would do all 3 lines in the Makefile (gcc -c prog.c, gcc -c myfuncs.c, gcc -o prog prog.o myfuncs.o) If we type make with no argument, it does the first target in the list (prog in our case) If a target, t, has no dependencies, its rule is always run when you do "make t" To use a file other than Makefile (e.g., mf): make -f mf prog make -f mf etc 9/17/2014 Course material created by D. Woit 35
Makefile cont. If make is not in your path, do "whereis make" to find out where it is, and add that dir to your path. Or run it directly: /usr/bin/make prog.o Makefiles also have "default/implicit rules". One such rule is that it knows that to make file x.o it must do gcc -c x.c. So you can leave out rules with exact form: prog.o: prog.c Note that in our case we cannot omit prog.o: prog.c myfuncs.h gcc -c prog.c because it is not a "default" rule (prog.o has more dependencies than just prog.c) Note that myfuncs.c depends on myfuncs.h *not* for the prototype, but for the #define directive. 9/17/2014 Course material created by D. Woit 36
Reading and Writing Characters getchar(); reads in one char putchar(); prints out one char /*Source: sample11.c*/ #include <stdio.h> int main(void) { char c; printf(“Enter a character : "); c=getchar(); /*read in 1 char*/ printf("you entered a %c\n",c); printf("In case you missed that, it was a: "); putchar(c); putchar('\n'); printf("char %c has ASCII code %d\n",c,c); //see below return 0 ; } 9/17/2014 Course material created by D. Woit 37
Reading and Writing Characters Chars are represented by their ASCII codes int 0-255 A is 65 n is 110 c=getchar(); if (c <= 'Z' && c >= 'A') printf("%c is upper case",c); c='B'; printf("char %c has ASCII code %d",c,c); WARNING: getchar returns the actual ENTER-key character too! Why? getchar() has buffered input as if reads do not happen until enter pressed e.g., see sample11A.c 9/17/2014 Course material created by D. Woit 38
*sample11A.c*/ • /* If enter: • ABC • Then c4 is the enter key (carriage-return) • */ • #include <stdio.h> • int main(void) { • char c1, c2, c3, c4; • /*read in 3 chars*/ • c1=getchar(); • c2=getchar(); • c3=getchar(); • putchar(c1); putchar(c2); putchar(c3); • c4=getchar(); • putchar(c4); • return 0; • }