Chapter 0 – C Programming. The C Language  We are programming in C, a subset of C++  C++ was originally compiled into C  No classes, templates, namespaces,

Embed Size (px)

Text of Chapter 0 – C Programming. The C Language  We are programming in C, a subset of C++  C++ was...

CSCI 3431: Operating Systems

CSCI 3431: Operating SystemsChapter 0 C ProgrammingThe C LanguageWe are programming in C, a subset of C++C++ was originally compiled into CNo classes, templates, namespaces, user-defined overloading, streamsHere is a good reference to the language and the basic C libraries:'s FoundationsC is really just a structured version of assembly languageVery minimal library support (see handout)Meant for systems programming originally created as a language to program UnixC was programmed in a week and the manual was written after they determined what the compiler did/acceptedFundamentally linked to the Unix OS and to system programmingCreated by Brian Kernighan and Dennis Ritchie at Bell LabsDeveloped before mice, GUI'sIs a foundational language that spawned C++, Java, C# and many other more recent languagesA reference manual (online or paper) is essential

PhilosophiesC is made to let a programmer do pretty much anything which means that it's easy to really botch something upIt was designed to be as close to assembly language as was comfortable for a programmerThe language is simple which means that complexity is handled by the programmer and programsPuts the emphasis on the programmer to develop good style, structure, and practices

C versus JavaMuch of the two languages is similar (e.g., operators, control structures)Differences mainly occur in the type systemC is much simpler, but in turn, leads to very complex programse.g., complexity is in the programs, not the language as is the case with JavaC's libraries are similarly simple and easy to learn, but most find them hard to use because of their flexibility and the very low level of detailJava protects the programmer while C exposes the programmer, but this is partly due to historical contextThe File ModelAll C I/O is done using files3 special files are provided: stdin, stdout, and stderr These files are automatically opened and closed for you by the compilerstdin = keyboard, stdout = monitor, but both can be redirected as neededstderr also goes to the monitor, but is often redirected to a file to be used as an error logI/O can be done directly using fread() and fwrite()More useful to do formatted I/O using fprintf() and fscanf()File I/OFiles are represented by a file pointer of type FILE *Files must be opened (fopen) Files are opened to support a specific mode of useFiles should be closed (fclose)Files are often buffered so flushing might be necessary to force output (fflush)Buffering is controlled by the programmer (setvbuf) for one of:_IONBFNo buffering (unbuffered)_IOLBFLine buffering_IOFBFFull bufferingThe buffer size is also controllable to achieve optimum performance (usually matched to a disk block)File Mode Values"r"read"w"write"a"append"r+"reading and writing"w+"create then reading and writing (discard previous contents)"a+"open or create and do writing at end

FILE *fp = fopen ("errors.txt","a+");File OutputFormatted: fprintf, printf, sprintf, vprintf ...fputc: write a char to a FILE *fputs: write a char* to a FILE *char* = null terminated stringputc: macro version of fputc that may evaluate its argument more than once (avoid using it)puts: write a char* to stdoutputchar: write a char to stdoutEach function has its own subtletiesYou MUST learn how to use these functions!

Example: Writing a string(not necessarily efficiently or clearly)#include #include #define LENGTH 80

int main(void) { FILE *stream = stdout; int i, ch; char buffer[LENGTH + 1] = "Hello world";

for (i = 0; (i < strlen(buffer)) && ((ch = putc(buffer[i], stream)) != EOF); ++i); } /* end main() */ /******************** Expected output: *************************Hello world */Formatted Outputfprintf(file, format, values);

Various versions of fprintf() exist:printf(...) is the same as fprintf(stdout,...)sprintf(): print to a string (or character buffer)v_printf(): variable number or args (in the format)Other variations exist (see reference material)

Formatted Outputprintf(format, args ...);

Format contains format specifiers, such as %d (integer), %s (string), %c (character)There must be an argument for every specifierFormat can contain output modifiers such as \n to insert a newline

printf(%d is %s than %d\n, i[0], smaller, max);Format Specifiers%flags (0ptional): sign, zero padding, etc.minimum width (optional).precision (optional): maximum charslength modifier (optional): short, longargument type conversion: string, pointer, character, float, integer, etc.

%-2.8s, %hd, %*s

Conversions (used by specifiers)

sstringdsigned integer ffloat (double)csingle characterppointern displays the number of characters printed so farAll these are preceded by a % as part of the format specifierALL the Conversions ...%c The character format specifier.%d The integer format specifier.%i The integer format specifier (same as %d).%f The floating-point format specifier.%e The scientific notation format specifier.%E The scientific notation format specifier.%g Uses %f or %e, whichever result is shorter.%G Uses %f or %E, whichever result is shorter.%o The unsigned octal format specifier.%s The string format specifier.%u The unsigned integer format specifier.%x The unsigned hexadecimal format specifier.%X The unsigned hexadecimal format specifier.%p Displays the corresponding argument that is a pointer.%n Records the number of characters written so far.%% Outputs a percent sign.Examples of Outputprintf ("Hello World\n");

char buf[256];sprintf(buf,"%8d\t%8d", a, b);

fprintf(stderr, "%s: fatal: %s not found", argv[0], argv[1]);

FILE *log = fopen("log.txt","w+");fprintf(log,"%s: %s\n", time, msg);

Command Line Arguments#include intmain (int argc, char**argv) { int i; for (i = 0; i < argc; i++) { printf("Argument %d: %s\n", i, argv[i]); } return (i);} /* end main () */

%>./a.out h o testArgument 0: a.exeArgument 1: -hArgument 2: -oArgument 3: testC InputFormatted input is done using various versions of fscanffscanf(stdin,...) same as scanf(...)scanf() is hard to use at first!Also have:fgetc(), getc(), getchar(), fgets(), gets(), and ungetc()Each function has its own little quirksYou must learn to use the printf() and scanf() families of functions!Learning to read the documentation while you practice using them is crucialC InputTo match fprintf() for output there is fscanf(file,fmt,args) for input. E.g.,fscanf(stdin, %s %d, name, &grade);Format specifiers are pretty similar, but do have a few differencesArgs MUST be addresses (pointers)name is a char*grade is an int so we use its addressscanf() Conversions

/* Example: Tami Meredith, 2011 */#include

#define debug 0#define COUNT 10#define SUCCESS 0

int main (int argc, char** argv) { int i, data[COUNT], max = 0;

for (i = 0; i < COUNT; i++) { scanf("%d", &data[i]);#if debug printf("%d: Read %d\n", i, data[i]);#endif if (data[i] > data[max]) { max = i; } } printf("Max = %d\n", data[max]); return(SUCCESS);} /* end main () */

C Operators1.Parentheses( ) [ ]L to R1.Structure Access . ->R to L2.Unary! ~ ++ -- + - * & (type) sizeofL to R3.Mult., Div., Modulus* / %L to R4.Add, Subtract+ -L to R5.Shift>L to R6.Comparison< >=L to R7.Equality== != L to R8.Bitwise And&L to R9.Bitwise Exor^L to R10.Bitwise Or|L to R11.Logical And&&L to R12.Logical Or||L to R13: Conditional?=L to R14.Assignment= += -= *= /= %= &= ~= |= =R to L15. Comma,L to RControl StructuresPretty much the same as Javaf(), returnif () ... , if () ... else ...switch () { case _: ... default: ... }for (;;) ..., while () ..., do { ... } while ();break, continuef(), returnlabel:, goto Example: Switchswitch (c) { default: printf("This is just a mess \n"); case '\n': case '\t': printf("c is whitespace\n"); break; case '_': printf("c is an underscore"); break; default : printf("c is unspecified\n");}

You can have more than one default. Cases can come in any order. If no break exists, execution "falls through" into the next case.

Quirks and Tricksfor(i = 1, j=2; x < 10; a++, b++) { }for (;;) { /* infinite loop */ }#define loop for(;;)continue jumps to test of a loopbreak exits innermost loop or switch a = (x < y) ? x : y;printf("sex: %smale\n", (sex='f') ? "fe" : "");while ((c = getchar()) != EOF) { }x++; ++x; x += 1; x = x + 1;But x[i++] is not the same as x[++i]x = x * 2; x *= 2; x (b))?(a):(b))

Macro Quirks#undef will undefine a macroe.g.: #undef COUNTMacros can be redefined if desiredToken concatenation is allowed in macro bodiese.g., #define cat(x,y) x ## ycat(var,123) produces var123#arg as a use causes stringificatione.g., #define string(x) #xstring(hi\n) produces "hi\n"

Preprocessor#define COUNT 10#define MAX(x,y) (((x)>(y))?(x):(y))#undef COUNT#include #include "myjunk.h"#ifdef CONST ccode #endif -- also ifndef#if defined(CONST) ccode #endif #if (1) ccode #endif#elif, #elseMakefilesmakefiles automatically build your program in Unix environments

lab1: lab1.cgcc o lab1 lab1.c

Format of entries in makefilefile: dependenciescommand

To use type: makeWill use the first entry as the target by default

Good CodeSimple, clearReadable, understandableMaintainableEfficient, but only sacrifice readability and maintainability if the efficiency is criticalUniform with regard to coding standardComments are "value added"Neither under nor over commentedCoding Thoughts 1Write it once only; if you duplicate code then refactor! (#bugs = LOC)No magic numbers; use symbolic constantsCheck for errors!Clarity before efficiency unless neededTrust the compiler to optimise for youMake things explicit; casts not conversionsAim for type con