SIPB's IAP Programming in C
Total Page:16
File Type:pdf, Size:1020Kb
SIPB’s IAP Programming in C C was developed at AT&T Bell Labs between 1971 and 1973, by Dennis Ritchie. It was derived from an experimental language called B, which itself was a stripped-down version of BCPL. All of these are derivatives of the ALGOL family of languages, dating from the 1950s. This work was done on a PDP-11, a machine with a 16 bit address bus. While a PDP-11 should be able to address up to 64K of memory, these machines only had 24K. The C compiler was written in C, and was able to compile itself on these machines, running under the nascent Unix operating system. #include <stdio.h> main() The classic { printf("hello, world\n"); } /* * %% - a percent sign * %s - a string * %d - 32-bit integer, base 10 * %lld - 64-bit integer, base 10 * %x - 32-bit integer, base 16 * %llx - 64-bit integer, base 16 * %f, %e, %g - double precision * floating point number */ /* * the following should produce: A word on printf() * * printf() test: * string: 'string test' * number: 22 * float: 18.19 */ printf("printf() test:\n" " string: '%s'\n" " number: %d\n" " float: %g\n", "string test", 22, 18.19); Language Structure char i_8; There are five different /* -128 to 127 */ kinds of integer: unsigned char ui_8; /* 0 to 255 */ - char short i_16; - short /* -32768 to 32767 */ unsigned short ui_16; - int /* 0 to 65536 */ int i_32; - long /* -2147483648 to 2147483647 */ unsigned int ui_32; - long long /* 0 to 4294967295U */ long i_arch; unsigned ui_arch; Each of these can be /* architecture either: * dependent */ long long i64; - signed (the default) /* -9223372036854775808LL to * 9223372036854775807LL */ - unsigned unsigned long long ui64; /* 0 to 18446744073709551615ULL */ There are at least four float f_32; /* single precision: * +/- 1.1x10^-38 to 3.4x10^38, different kinds of * roughly 7 digits precision */ floating point value: double f_64; /* double precision: * +/- 2.2x10^-308 to 1.7x10^308 - float * roughly 16 digits precision */ long double f_80; - double /* extended precision: * +/- 1.1x10^-4932 to 1.1x10^4932, - long double * roughly 19 digits precision */ __float128 f_128; /* quadruple precision: * +/- 1.2x10^-4932 to 1.2x10^4932, - __float128 * roughly 34 digits precision */ Additionally, C char zero = '0'; understands strings char *one_as_string = "One"; char *stuff = "I think I see " and characters: "Bob Marley " "in my cornflakes!\n"; There are a number of /* * \a Bell (alert) backslash escapes * \b Backspace * \f Formfeed available, to encode * \n New line * \r Carriage return commonly used but * \t Horizontal tab * \v Vertical tab unprintable (or * \' Single quotation mark * \" Double quotation mark reserved) characters in * \\ Backslash * \? Literal question mark strings: */ /* * 000 NUL '\0' * 001 SOH (start of heading) * 002 STX (start of text) * 003 ETX (end of text) * 004 EOT (end of transmission) * 005 ENQ (enquiry) * 006 ACK (acknowledge) * 007 BEL '\a' (bell) * 010 BS '\b' (backspace) * 011 HT '\t' (horizontal tab) * 012 LF '\n' (new line) * 013 VT '\v' (vertical tab) * 014 FF '\f' (form feed) Backslash escapes can * 015 CR '\r' (carriage ret) * 016 SO (shift out) * 017 SI (shift in) * 020 DLE (data link escape) also be composed with * 021 DC1 (device control 1) * 022 DC2 (device control 2) * 023 DC3 (device control 3) * 024 DC4 (device control 4) octal values, to specify * 025 NAK (negative ack.) * 025 NAK (negative ack.) * 026 SYN (synchronous idle) ASCII coded * 027 ETB (end of trans. blk) * 030 CAN (cancel) * 031 EM (end of medium) * 032 SUB (substitute) characters in a general * 033 ESC (escape) * 034 FS (file separator) * 035 GS (group separator) * 036 RS (record separator) fashion: \NNN * 037 US (unit separator) * * * 40 50 60 70 100 110 120 130 140 150 160 170 * -------------------------------------------- * 0: ( 0 8 @ H P X ` h p x * 1: ! ) 1 9 A I Q Y a i q y * 2: " * 2 : B J R Z b j r z * 3: # + 3 ; C K S [ c k s { * 4: $ , 4 < D L T \ d l t | * 5: % - 5 = E M U ] e m u } * 6: & . 6 > F N V ^ f n v ~ * 7: ' / 7 ? G O W _ g o w DEL */ int ten_integers[10]; Arrays double five_doubles[5]; unsigned long long guess[22]; struct NameOfStructure { int integer_field; double floating_point_field; unsigned short an_array[15]; Structs }; struct AnotherStructure { int a; char b; struct NameOfStructure nos; }; struct NameOfStructure { int one_bit:1; Bitfields int two_bits:2; int many_bits:22; }; union NameOfUnion { int integer_field; Unions double floating_point_field; unsigned short an_array[15]; }; enum NameGoesHere { Gives, Each, Enums An, Integer, Value }; typedef unsigned long long my_uint64_t; struct Example { Typedefs my_uint64_t a; my_uint64_t b; }; typedef struct Example Example_t; struct One { int a; int b; double c; char *string; }; struct Two { These composite data char *name; char *desc; types can be init- struct One data; ialized, too, which is }; struct Two values[] = { handy for working with "slug", "squooshy, gross", 1, 2, large sets of constant, 3.0, "four", "bat", "blood thirsty", { 7, 14, complex data 21.0, "rump roast" }, /* ... etc ... */ { "chicken", "walking gizzard", { 9, 7, 5, "boombox" }}, NULL, NULL, 0, 0, 0, NULL }; /* start by declaring: * - the return type * - the function name * - the types and names of the * function parameters */ int sum_of_squares(int a, The building block of int b) { computation in C is the /* first come variable * declarations */ function; all int c; computation must /* then statements; each * statement should end with occur inside one * a semicolon */ c = (a * a) + (b * b); /* return a value, if we said * we would */ return c; } int sum_of_squares(int a, int b) { int c; c = (a * a) + (b * b); return c; } int pythagorean_p(int a, int b, Functions can call int c) { other functions int v1,v2; /* a function call looks * like this */ v1 = sum_of_squares(a,b); v2 = c * c; if(v1 == v2) return(1); else return(0); } The top level function is main(); that gets called when your program runs int sum_of_squares(int a, int b) { int c; /* notice we don't even use argc and * argv; not a big deal! */ c = (a * a) + (b * b); int main(int argc, return c; char *argv[]) } { if(pythagorean_p(3,4,5)) int pythagorean_p(int a, printf("3:4:5 is a " int b, "pythagorean triple\n"); int c) else { printf("3:4:5 is NOT " int v1,v2; "a pythagorean triple\n"); v1 = sum_of_squares(a,b); return(0); } v2 = c * c; if(v1 == v2) return(1); else return(0); } /* func1() will return nothing, A C function can which is called 'void' in c. */ void func1(int a) return nothing. { printf("a = %d\n",a); } /* func2() will return a Or a function can * single integer value */ int func2(int a) return a single value. { return(a ^ (a << 2)); } /* func3() will return multiple * integers values, by way of a * struct. we'll learn other * approaches later! */ /* this holds our results: */ struct Func3Results { Or, a function can int v1; int v2; wrap multiple values }; into one return result. struct Func3Results func3(int a) { struct Func3Restults back; back.v1 = a * 2; back.v2 = a * 4; return(back); } #include <stdio.h> #include <stdarg.h> /* sum_integers() accepts first a * count of integers to sum, then * those integers themselves. it C functions can accept * returns their integer sum. */ int sum_integers(int count, variable numbers of ...) { parameters. These are int i,sum; va_list list; called variadic va_start(list,count); for(i=0,sum=0;i<count;i++) functions, and they are sum += va_arg(list,int); declared with the ’...’ va_end(list); return(sum); token. } int main(int argc, char *argv[]) { printf("sum = %d\n", sum(4, 1,2,3,4)); } /* * arithmetic operators: * +, - * : add, subtract Types can be operated * *, /, % * : multiply, divide, mod with: * ++a, --a * : increment/decrement and * : evaluate as new value * a++, a-- - Arithmetic * : increment/decrement and * : evaluate as old value operators * * bitwise operators: * &, |, ^, ! - Bitwise operators * : and, or, xor, not * >>, << * : bitshift right, left * */ /* * boolean operators: * >, >= * : greater than, greater than * : or equal to And also with: * <, <= * : less than, less than or * : equal to - Boolean operators * ==, != * : equal, not equal * &&, ||, ^^ * : and, or, xor - Assignment * * assignment operators: operators * = * : assignment * +=, -=, *=, /= * : add, sub, mul, div, * : and then assign */ /* * Do first Order of operations is * * 1 () Grouping * 2 ! ~ - ++x --x Unary ops as commonly used in * 3 * / % Mul, div, mod * 4 + - Add, sub mathematics, though * 5 << >> Bit shifts * 6 < <= > >= Comparisons interactions between * 7 == != Equality tests * 8 & Bitwise and e.g. subtract and * 9 ^ Bitwise xor * 10 | Bitwise or bitwise xor may not be * 11 && Logical and * 12 || Logical or * 13 = += -= *= /= Assignments intuitive. * * Do last */ if(a > b) { /* only case */ } Flow control is if(a > b) { achieved with: /* first case */ } else { - if contructs /* alternative case */ } - if/else contructs if(a > b) { /* first case */ - if/else if/else } else if(b > c) { /* second case */ contructs } else { /* default case */ } for(i=0;i<count;i++) { Some looping contructs /* do something with i here */ are available: } while(predicate()) { - for /* do something here */ - while } - do ... while do { /* get stuff done here */ } while(predicate()); for(i=0;i<count;i++) { if(weird_case(i)) Looping action can be continue; regulated with: /* do much important work here */ } - break do { - continue if(bored_p()) break; } while(predicate()); for(y=0;y<height;y++) { goto is wrongly feared! for(x=0;x<width;x++) { if(super_badness_p(x,y)) It is great for getting goto eject;