C_&_C++.txt CCC & CCC + + By: Simon Cheng C & && C +++++ +++++ Date: 200208-200406 CCC && & CCC + + GET - 493 WRITTEN NOTES, ENCM339 LAB NOTES ************************************************************************** Table of Contents ************************************************************************** 12345678101234567820123456783012345678401234567850123456786012345678701234 1. C (I) features not covered in ENCM339 (II) DMA *. Malloc *. Free (III) I/O -> see stdio.h -> File I/O (IV) stdio.h *. File I/O *. Printf *. Scanf (V) General Notes 2. C++ (I) Need to Learn (II) NOTES *. keywords *. alternative representation of operators *. precedence of operators (III) DMA *. syntax (IV) Classes i) The Big 3 *. Assignment Operator *. Copy Construtor - explicit keyword *. Destructor *. Examples (3) ii) Operator overloading (list and notes) iii) Friend functions iv) Templates -> see 2.IV Templates v) Casts *. Castaway const *. Down casting vi) Static members - also see static in 2.IV.v polymorphism vii) Inheritance *. Public/private/protected *. Overshadowing *. Using directive *. Multiple inheritance *. Virtual inheritance/abstract base class *. Static members in inheritance *. Polymorphism - dynamic binding viii)Polymorphism - also see 2.IV.vi inheritance, 2.V templates ix) Typeinfo, typeid, typeid.name() (V) Templates *. Class *. Functions *. Structures *. Typedef *. Non-generic arguments *. Special cases *. Function call resolution *. Templates in templates (VI) Standard Libraries - list and STL *. Standard C++ *. Old libraries 3. C/C++ (I) type conversion . . . 4. Notes on the Unix/Linux OS NOTE: for C/C++ related Unix/Linux terminal commands, please consult other files (eg. gcc -E file.cpp to look at translation unit). ************************************************************************** C ************************************************************************** - features not covered in ENCM339: pointerr--to-pointer and array-of-pointer types rules about global variables pointer-to-function types need to learn using key library functions for I/O & memory mgmt === (II) DMA =============== ============================ - some declarations in header file : typedef [some integer type] size_t; void *malloc (size_t nbytes); void free (void *p); - type casting is not necessary - a C comppiiler will set up implicit conversions; but are good style - reminding you free store contains blocks of "typeless" bytes ==--==- Malloc =--==-- - arg nbytes >0 - return value is either a pointer to an UUNNINITIALIZED block of nbytes BYTES in the free stor or a null pointer to indicate no block of that size can be allocated (latter case in C++ will result in a crash) - eg. p=(int*) malloc (n_elements * sizeoff(int)); if (p==NULL) { // print error message - program out of memory exit (1); } ==--= Free =--== - arg must either be a pointer to the BEGIINNNING of a free store block allocated with malloc, or a null pointer (=> no effect) - eg. free ((void*)p); ============================ ::::: (IV) stdio.h ::::: ============================ - also see common features of stdio.h in CC//C++ ==--==--= File I/O =--==--== - doesn't include stdin/out ones (eg. scannf, getchar, printf, putchar...) (- read ENCM339 notes for even finer details such as WHY fopen fails) - EOF is a #define in for some nneegative int - pointers to FILE variables are used as ""hhandles" for opening files - fopen (const char* filename, const char** mode); - "mode" can be but NOT LIMITED TO: r, w, a (text append), rb, wb, ab - returns FILE* if succeeds, NULL if fails - eg. FILE *fp; if((fp = fopen(argv[1], "rb")) == NULL) { // do something } - fclose (FILE* fp); // returns 0 if succeeeeds, EOF if error - if any operation to the file fails, an error will be indicated on the attempt to close the file - eg. if (fclose(fp) == EOF) <- called fclose()!! fprintf (stderr, "Error closing file!\n"); SUMMARY CHART: READ DETAILS BELOW!!! |Operation| Text | Binary | |========================================================================| | |fprintf(FILE*, char*, *var);|fwrite((void*), int, int, FILE*);| | Writing | fputc | | | | fputs(char*, FILE*); | | |------------------------------------------------------------------------| | | fscanf(FILE*, char*, *var);| | | Input | fgets(char*, int, FILE*); |fread((void*), int, int, FILE*); | | | fgetc(FILE*); | | --- Writing --- - fprintf(FILE* fp, char* out, *var,...); - may replace FILE* fp with "stdin", "stdout", or "stderr" eg ./a.out > output.txt <-stdout go to file, stderr still go to screen - *var is optional - fputc <- "put char" - fputs(char* out, FILE* fp); - automatically puts '\n' after out <=> always hits Enter for you - may replace FILE *fp with "stdin","stdout", or "stderr", see fprintf() - fwrite((void*)*start_addy, int size_of_11__chunk,int #_of_chunks,FILE*fp); - eg. int count; fwrite ((void*) &count, sizeof(int), 1, fp); fwrite ((void*) array, sizeof(int), count, fp); --- Input --- - fscanf(FILE* fp, char* in, *var...); <- uuse int nscan = ~ or while(~==#) - success: nscan==1,2,...; fail: nscan==0 || EOF, var,... unchanged - use %ns conversion to limit input size (see example below); Algorithm: - read & discard whitespace chars (' ', '\t', or '\n') until non-whitespace or EOF - read & copy non-whitespace chars into fp until n chars read, whitespace char encountered, or EOF (- terminate string with '\0') (- return 1 if at least one non-whitespace char read, EOF if fail) - example: char buffer[11]; FILE* fp; while (fscanf(fp, "%10s", buffer) == 1) // do something - fgets(char* dest, int copy_num_plus_1, FFIILE* fp); - automatically puts '\0' to terminate the string in the array - returns char* dest if success, NULL if fail - int copy_num_plus_1 can be array (string) size - may replace FILE *fp with "stdin","stdout", or "stderr", see fprintf() - Algorithm: - read until '\n' is read AND COPIED into array, or size-1 (hence the name I chose "copy_num_plus_1") read & copied (non being '\n'), or EOF returned on attempt to read char (due to EOF or some sort of error), in this case, EOF is not copied into array - NOTE THE DIFFERENCE BETWEEN '\n' and '\0'! - good for reading input 1 line at a time as it prevents buffer overflow - fgetc(FILE* fp); - returns char, or EOF on fail - may replace FILE* fp with "stdin","stdout", or "stderr", see fprintf() - technique: eg. INT c = fgetc(fp); - fread((void*)*dest_addy, int size_od_1_iittem, int #_of_items, FILE *fp); - dest_addy is the addres of beginning of destination in memory - returns number of items read ==--==- Printf =--==-- - starts printing from where the pointer ppooints (for strings) - (void)? printf(const char*, ~var_list) eg 1. printf("%-14d%d:%02d%2d\n", id[3], time, num, score) <- fill empty spaces with '-', regular printing, %02d is like %2d, but puts a zero where %2d would be a space | int | double | char |string|unsigned| ======================================================================== | %d | %f | %c | %s | %u | | %@Nd - @ is | %.Nf - # of decimal places | | | | | 1 char: what| %.Pg -total # digits excl dec pt| | | | | to fill w/, | %M.Nf - M is total field width | | | | | N is width | incl dec. pt, N is # of dec pl.| | | | - can also use puts (const char*) - different from fputs in that puts() doesn't put '\n' at the end ==--== Scanf =--==- - int scanf(const char* str, ~var_ptr_listt)) eg 1. nscan = scanf("%d:%d:%d", &hours, &min, &sec); <- POINTERS!! if (nscan ~= 3) {... eg 2. nscan = scanf ("%d", actual count); if (nscan != 1 || *actual_count>MAX_COUNT) exit(EXIT_FAILURE); //1 eg 3. nscan = sscanf(string, "%s %s %s", arg1, arg2, arg3); // put strings separated by spaces into variables | int | double | char | =========================== | %d | %lf | | === (V) General Notes ====== ============================ - *(void **) 0x8c = (void*) & the_isr; /// mem addr 0x8c is pointer to // function; '&' optional, but makes it implicit - no Boolean in C, use char or int, or preeferably unsigned char - must use "enum_var;" (in C++, can simplyy type "_var;") (see C/C++) ************************************************************************** C++ ************************************************************************** - need to learn: exception handling (tyr, throw, catch) namespace how to read and write to the same file /\ (II) NOTES \/ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ - g++ 2.7.2 does not have namespace - MS Visual C++ 4.0 does not support expliicit, does not have bool type - references CANNOT be reattached - a character literal can be preceded by ''L', as in L'a'. This is a wide-char literal and has type wchar_t. This type supports language character sets, such as Chinese & Japanese, in which some of the char varlues cannot be represented within a single char ==--==--= keywords =--==--== asm do inline short typeid auto double int signed typename bool dynamic_cast long sizeof union break else mutable static unsigned case enum namespace static_cast using catch explicit new struct virtual char extern operator switch void class false private template volatile const float protected this wchar_t const_cast for public throw while continue friend register true default goto reinterpret_cast try delete if return typedef Also identifiers containing "__" are reserved for use by C++ implementations and standard libraries and should not be used in progs ==--==--==--==--==--==--==-- alternative representations for operatorss and punctuation reserved =--==--==--==--==--==--==--= && &= & | ^ (complement) ~ (not) != || |= ^ (xor) ^= (xor_eq) ==--==--==--==--==--==-- precedence of operators =--==--==--==--==--==--= ______________________________________________________ | :: scope resolution operator | |------------------------------------------------------| | . dot operator | | -> member selection | | [] array indexing | | () function call | | ++ postfix increment operator (placed after the var) | | -- " decrement " ( " " " " ) | |------------------------------------------------------| | ++ prefix increment operator (placed before the var) | | -- " decrement " ( " " " " ) | | ! not | | - unary minus | | + unary plus | | * dereference | | & address of | | new, delete, delete[] | | sizeof | |------------------------------------------------------| | * multiply | | / divide | | % remainder (modulo) | |------------------------------------------------------| | + addition | | - subtraction | |------------------------------------------------------| | << insertion operator (output) | | >> extraction operator (input) | |------------------------------------------------------| | <, <=, >, >= | |------------------------------------------------------| | ==, != | |------------------------------------------------------| | && | |------------------------------------------------------| | || | |------------------------------------------------------| | = assignment | | += add and assign, -= | | *= | | /=, %= modulo and assign | |______________________________________________________| === (III) DMA ============== ============================ - like malloc but, ctor or a loop of ctorss are called to initialize all class objects allocated - like free but dtors are called before thhee block of bytes gets deallocated (assuming the class has a destructor) - (see Classes for more notes) ==--==- Syntax =--==-- - new ~type - generates a pointer to that vvariable (eg. int *p = new int;) new ~type(default_value); new ~Class(a, b); // calls ~Class::~Class(a,b) new ~type [size] - generates a pointer to element 0 delete ~ptr - pointer must be addy of a single variable allocated w/ new delete [] ~ptr - it is safe to delete a null pointer - syystem will not crash === (IV) Classes ============ ============================ - (see Templates for more details on classs template syntax) - law of Big 3 (from C++ FAQs by Cline & LLoonrow): dtor, copy ctor, assmt operator: if need one, probably need the other two - private member functions, which also havvee the "this" pointer, exist to help public member functions - always have "this" pointer! ==--==--==--==--==-- Assignment Operator =--==--==--==--==--= - goals in writing an AO: 1) indep data (sshhouldn't share DM) (eg. x=y) 2) resources (eg. DM) no longer needed should be recycled 3) self-assignment is harmless 4) chained assignment should work - ClassName& ClassName::operator= (const CCllassName& rhs) { if (this != &rhs) { // code to assign } return *this; } ==--==--==--==--= Copy Constructor =--==--==--==--== - unless a class has a copy constructor anndd assignment operator, copying objects is like copying struct variables => data is copied memberwise (ie,pointers to free store will point to the same variable, not different copies of the same data etc.) - copy constructor: ClassName::ClassName(cconst ClassName& source) {...} - cases where copy constructor is called: StringTwo a("foo"); StringTwo b(a); <- StringTwo c=a; <- call-initialization, not assignment - also used with dynamically allocated objjects: ClassName *p1 = new ClassName; // no args -- call default ctor ClassName *p2 = new ClassName(201); // ctor with int arg ClassName *p3 = new ClassName(*p2); // copy ctor - when allocate an array of objects, are ffoorced to accept the default ctor for initialization of all objects (unless use some advanced, hard-to-use C++ features), element 0 is initialized first, then element 1, and so on - copy ctors are also called to set up argguuments upon call to function and return values --- explicit keyword --- ==--==--==- Destructor =--==--==-- - dtor - ClassName::~ClassName() {...} - destructors should NEVER be called manuaallly - static member functions do not have a thhis pointer - elements of an array of allocated objecttss are destroyed in reverse order of construction - MUST have code to deallocate free store mmemory variables used by class!! ==--==--= Examples =--==--== - eg. 1 ClassName::ClassName() <- default ctor; call by ClassName c; not c()!! : mbr_name1(0), mbr_name2(1982) <- initializes to zero & 1982, only { // more code constructors can have this syntax } and is more efficient int ClassName::count() const { return countM; ŻŻŻŻ?<- remember non-member functions cannot } access private member variables! void ClassName::increment() <- since is member, no need for arg declaraj { countM++; // <=> (this -> countM)++; } - eg. 2 void Foo:foo(int x=0, int y=0) {} // can have default values - eg. 3 void Foo::bar(const Foo& x) { quuxM = x.quuxM + 2; <- access own (this pointer), use '.' for others } ==--==--==--==--==--==--==--==--==-- Operator Overloading (classes only) =--==--==--==--==--==--==--==--==--= As long as you have one of the arguments being a user-defined type, anything works! Also do not return reference to local var (eg. operator+ as compared to operator+=) since it'll get destroyed after fcn ends Overloadable operators (listed in brackets is the type each must return): + (Type) - (Type) * (Type) / (Type) % (Type) ^ (Type) & (Type/*) | (Type) ~ (Type) ! bool , = (Type&) < bool > bool <= bool >= bool ++ (Type&) -- (Type&) <<(ostream&) >>(istream&)== bool != bool && bool || bool += (Type&) -= (Type&) /= (Type&) %= (Type&) ^= (Type&) &= (Type&) |= (Type&) *= (Type&) <<= (Type&) >>= (Type&) [] (Type&) () -> ->* new new[] delete delete[] Examples (some IMPORTANT!): operator bool() // NO return type required, also no argument operator int() // same as above, this one is a cast bool operator< (int) C operator+(A a, B b); // doesn't have to be C C::operator+() Type? operator-() // unary operator, eg. x = -y; Type& operator++(int) // post-fix; requires int dummy argument Type& operator++() // prefix Non-overloadable operators: :: .* . ?: Notes: - for operators that return Type&, return stmt is "return *this;" - use friend keyword for operator<< and operator>> - operator+ etc. cannot return a reference since it must create a new object which will be temporary (cannot return a reference to a temporary object) - operator arguments must contain at least one user-defined type ==--==--==-- Inheritance =--==--==--= - eg. 1 class B: public A { B (): A() { cox = NULL; } // can call base calss ctor like this === Templates ========== ============================ ==--== Class -==--= - (see Typedef subsection below for templaatte class type defintions) template // can also use "typename " Class ClassName { T mbr_func(T value); int mbr_func2(const ClassName &arg); // can be specific, ie T mbr_func3(ClassName &arg); // or not specific } template // <- this is needed for EVERY member function defn T ClassName ::mbr_func(T value) { // return_type, class_name, , ::, func_name, args } ClassName obj_name; // create actual obj, replace type w/ appr type ==--==--== Functions =--==--==- template // T is the commonly used letter for generic type // function prototype/defintions // eg. "void quicksort(T* array, int left, int right) { // func code }" ==--==--==- Structures -==--==--== - class template in struct can only declarree type, not size?? eg. (in struct defn) sclArray str; ==--==-- Typedef =--==--= typedef ClassName ClassInt; //<- can be done iff type arg is specific ClassInt int1, int2; // (ie, int NOT T) === Standard Libraries ===== ============================ Note: old C libraries are incorporated and used by adding 'c' at the beginning of the library name and removing ".h" at the end Note2: To use any iterator, must #include . Also see IMPORTANT note about erase(iterator) in below. Note3: after listing libraries with #include directives, need to also include the using directive "using namespace std;" or else will need to use "std::" every time before the library-provided functions Note on iterators: if iterator i was used in remove(i) or erase(i), i would point to the next item in the STL container (ie i++ if no removal) i) search algorithms adjacent_find(), binary_search(), count(), count_if(), equal_range(), find(), find_end(), find_first_of(), find_if(), lower_bound(), upper_bound(), serach(), search_n() ii) sorting & general ordering algorithms inplace_merge(), merge(), nth_element(), partial_sort(), partial_sort_copy(), partition(), random_shuffle(), reverse(), reverse_copy(), sort(), stable_sort(), stable_partition() iii) deletion and substitution algorithms copy(), copy_backwards(), iter_swap(), remove(), remove_copy(), remove_if(), remove_copy_if(), replace(), replace_copy(), replace_if(), replace_copy_if(), swap(), swap_range(), unique(), unique_copy() iv) permutation algorithms next_permutation(), prev_permutation() v) numeric algorithms // also need to include adjacent_difference(), accumulate(), inner_product(), partial_sum() vi) generation & mutation algorithms fill(), fill_n(), for_each(), generate(), generate_n(), transform() vii) relational algorithms equal(), includes(), lexicographical_compare(), max(), max_element(), min(), min_element(), mismatch() viii) set algorithms set_union(), set_intersection(), set_difference(), set_symmetric_difference() ix) heap algorithms make_heap(), pop_heap(), push_heap(), sort_heap() note if you use eg. list_a.erase(iterator it). it CANNOT be used anymore!! So strategy is to set a temp_it = it; temp_it--; list_a.erase(it); it = temp; it++; (especially in for loops) If this procedure not followed, it would just point to NULL after erase(). // size_t size(), bool empty(), void clear(), remove(const T&), // erase(iterator), insert(iterator, const T&), push_back(const T&), // push_front(const T&), pop_back(), pop_front(), T& front(), T& back() // *** Note insert push others back while inserting // encapsulates & a set of nonmember functions such as toupper(), tolower(), etc. // contains object const first (key_type), data (data_type) // *** test if key exists *** // map ::iterator i; // map obj; // i = obj.find(key); // if (i != obj.end()) { // got it } // *** iteration *** // for (map ::iterator it=obj.begin(); it!=obj.end(); it++) // cout << it->first << it->second << it->empty() << endl; // must be used in conjunction with // includes istringstream (derived from istream, reads from a string), ostringstream (der. from ostream, writes into a string), stringstream (der. from iostream, both reads from and writes into a string) Eg. string f() { ostringstream out_msg; out_message << "error: " << variable << ": " << __FILE__ return out_msg.str(); } // push_tack(const T&), pop_back(), size_t size(), insert(iterator, T&), // erase(iterator), clear(), T& front() --- Standard C++ ----- #include int main() { std::cout << "hello world\n"; // if don't have "using namespace std" return 0; } ::::: fstream.h ::::: - stream parameters must be call-by-refereennce (in a function call)!! - if(infile.good()) // stream opened succeessfully without any problem if(infile.eof()) if(infile.bad()) // a hardware or a system error occurred if(infile.fail()) // input in stream does not contain the expected type - ios::in - input mode ios::out - output mode ios::ate - opens file and seeks to the end of file ios::app - opens file in append mode ios::binary - opens file in binary mode eg. ifstream in_file; in_file.open("output.dat", ios::binary | ios::out); // notice use '|' - ifstream in_stream; in_stream.open("infile.dat"); // or ifstream in_stream("input.dat", ios::in); ios::nocreate); // not = if (in_stream.fail()) // print error message int a, b; // now can take input from file using extraction operator >> while (in_stream >> next) sum += next; #if 0 the above is the best way to check if there are more input/#s to read, but the following also works: while (!in_stream.eof()) in_stream >> temp; sum += temp; #endif in_stream.close(); - binary file I/O: in_file.read((char*)&nuum, sizeof(int)); // reads an int out_file.write((char*)&num, sizeof(int)); // writes int - ofstream out_stream; out_stream.open("outfile.dat"); // or ofstream out_file("output.dat",ios::app); ios::ate); (both append) if (out_stream.fail()) // exit program #if 0 the following is a better way to quit if file stream fails: assert(!out_stram.fail()); // see assert.h to see more details #endif out_stream << a << b << endl; out_stream.close(); - ofstreams can set flags and manipulatorss exactly like iomanip.h (but all functions are in fstream.h) - eg. out_stream.setf(ios::showpoint); out_strea.precision(3); - stream_var.bad(); // returns true if thee stream stream_var is corrupted - ifstream.get(char); // reads 1 char fromm input stream and puts into char // does not skip over whitespace. - ifstream.getline(char*, max_characters ++11); // one line of input from the stream is read and the resulting string is // placed in string. If the line is more than max_characters long, only // the first max_characters chars are read. The declared size of the // string should be max_characters +1 or longer - ifstream.peek(char*); // reads 1 char from the input stream and returns that char. But the // char read is not removed from the input stream; the next read will be // the same char - ofstream.put(char*); // writes char* to tthe output stream - ifstream.putback(char*); // places char* in the input stream so that that value is the next input // value read from the stream. The file connected to the stream is NOT // changed ==--== Notes =--==- - input delivered to program via streams - streams are example of objects - declare and connect stream to file - type for input and output file stream vaarriables - ifstream, ofstream (these are classes) - a file has two names - external file nammee, stream name - if program ends normally, program will ccllose file connections for you even if object.close() is not in source code. However, if program ends abnormally due to an error, file will not be closed and may be left in a corrupted state. ::::: iomanip.h ::::: ==--== Flags =--==- - these must be called before any changes wwill be in effect. - eg. cout.setf(ios::showpoint); OR cout <<<< setiosflags(ios::showpoint); | Flag | Meaning | Default | ======================================================================== | |If this flag is set, floating point #s are | | | ios::fixed |not written in e-notation. (Setting this flag| not set | | |automatically unsets flag ios::scientific.) | | |--------------|---------------------------------------------|---------| | |If this flag is set, floating point #s are | | / |written in e-notation. (Setting this flag | | |ios::scientific|automatically unsets the flag ios::fixed.) | not set | \ |If neither ios::fixed nor ios::scientific is | | | |set, then the system decides how to output | | | |each number. | | ------------------------------------------------------------------------ | |If this flag is set, a decimal pt & trailing | | | |zeros are always shown for floating-pt #s. If| | |ios::showpoint|it is not set, a number with all zeros after | not set | | |the decimal pt might be output w/out the dec | | | |point and following zeros. | | ------------------------------------------------------------------------ | ios::showpos |If this flag is set, a '+' sign is output | not set | | |before positive integer values. | | ------------------------------------------------------------------------ | |If this flag is set & some field-width value | | | |is given with a call to the member function | | | |width, then the next item output'll be at the| | | ios::right |right end of the space specified by width. In| set | | |other words, any extra blanks are placed be4 | | | |the item output. (Setting this flag auto-lly | | | |unsets the flag ios::left.) | | |--------------|---------------------------------------------|---------| | |If this flag is set & some field-width value | | | |is given with a call to the member function | | | |width, then the next item output will be at | | | ios::left |the left end of the space specified by width.| not set | | |In other words, any extra blanks are placed | | | |after the item output. (Setting this flag | | | |automatically unsets the flag ios::right.) | | ------------------------------------------------------------------------ - any flag that is set may be unset. eg. ccoout.unsetf(ios::showpos); ==--==--==--= Manipulators =--==--==--== | Manipulator | Member function | Meaning | ===================================================================== | setw | width |total # of spaces, output rounded| | | | and (by default) right-aligned | --------------------------------------------------------------------- | setprecision | precision | set number of decimal places | --------------------------------------------------------------------- - cout << setprecision(int); - same as cout.precision(int); // NO "set"!! - cout << setw(int); - same as cout.setw(int); - eg. double z = 12.345678; cout << "z=: << setprecision(2) << setw(7) << z << endl; output: z= 12.35 - a manipulator is a function that is callleed in a nontraditional way. In turn, the manipulator function calls a member unction. Manipulators are placed after << - like traditional functions, manipulatorss may or may not have arguments - can be chained together &/or chained toggeetherwith flags if set using << (eg. cout << setiosflags(ios::scientific) << setprecision(2) << setw(5) << z << endl;) ::::: iostream.h ::::: - if don't know what function does, see dooccumentation in fstream.h - stream_var.bad(); // stream_var being ciinn or cout - cerr // <=> fprintf(stderr, "")?? I thinnkk cerr is in iostream.h // got from Norman's scl.cpp - cin.eof(); - stream_var.fail(); eg. int k; cin >> k; if (cin.fail() || k<0) // do something - cin.get(char); // remember does NOT skipp over whitespace - cin.getline(char*, int max_characters +11)); - cin.peek(char*); // can char* be void?? - cout.put(char*); - cin.putback(char*); - cout.precision(int),width(int),setf(flagg)),unsetf(flag) // these should be in iomanip.h only or now things have changed or what? - getline(cin, string); // need to find ouutt conditions for error and // string input (ie, does it stop at end of str?) ************************************************************************** C/C++ ************************************************************************** /\ NOTES \/ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ ==--==- Syntax =--==-- - long <=> long int; short <=> short int - octal: 022, hex: 0x12, long: 18L - static keyword: limits the scope of a gllobal var to the current source file; for var in a function, remembers the value even after function is finished (ie, value of var is maintained when function is called later) - extern keyword declares a var or fcn & sspecifies that it has external linkage (its name is visible from files other than the one in which it's defined). When modifying a var, extern specifies that the var has static duration (it is allocated when the program begins and deallocated when the program ends). The var or fcn may be defined in another src file, or later in the same file. Declarations of vars and fcns at file scope are external by default. - volatile keyword: variable updated by soome agent outside the running program, hence suppressing optimization - 0 is the only int that is also a pointerr <=> NULL. Any type, except enum, can be coverted to (int*) NULL (eg. 0L) - p->member <=> (*p).member - int a=2, b; b = a++; // a=3, b=2 b = ++a; // a=4, b=4 - double ans = 5/3.; fabs(3.0); - const int FALSE = 0; const int TRUE = !(FALSE); - if !() break; <- terminates exec of smallest enclosing iteration/switch stmt else if () continue; <- go check iteration cond immed (used for while/do-while loops) - if (a!=b!=c && c!=a) - int main(int argc, char **argv) // int mmain(int argc, char* argv[]) { if (argc !=3) fputs("Error: Incorrect # of args in command.", stderr); if (strcmp(argv[1]==argv[2])) fprintf(stderr, "Error: %s cannot be both input and output file.\n", argv[1]); // ... } - switch (i) { case 0: case 7: // do something break; case 'b': // do something else break; default: // do another thing <- DO NOT NOT NEED "break;"!! } - const char *x[] = {"ABC", "DEF", "GHI"};; // array of 3 ptrs pointing to const char **z = x+1; // 3 strings in static storage, // z points to x[2] not "DEF"!! - const char *apc[3]; <- apc is an array ooff 3 pointers-to-const-char - int grid [2] [8]; - ?: operator: z = (a>b) ? a : b; // z = max(a,b); - unions - void function (T arg) { (void) arg; // tells the compiler not to generate an "unused argument" } // warning. Should not be used in complete programs - for(;;); // infinite loop ==--== Notes =--==- - activation records <=> stack frames - 3 types: automatic (stacks/AR) static (occurs in static storage, containing global variables, static local variables (declared with static keyword), static member variables of classes (C++ only) (declared with static keyword), string constants dynamic (occurs in free store) - if p==NULL, cannot use p->next - global variables, constants - 4 fundamental rules fo recursion 1) Base cases 2) Always make progress 3) when designing a recursive function, assume that recursive calls work * satisfying the first two rules guarantees that infinite recursion will not occur (doesn't mean it'll produce correct results though) - ref-to-const types: cannot modify refereent - short circuit evaluation - sizeof(pe->b)/sizeof(int) - temporary variables set up in arguementss (eg. foo (x, y+3);) - void* - pointer to any kind of data - sometimes, eg. deallocating linked listss,, it's easier to write code with while loops rather than for loops - bitwise operators in C & C++: ____________________________________________ | ~, ~= bitwise complement | | ^, ^= bitwise exclusive or | | &, &= bitwise and | | |, &= bitwise or | | <<, <<=, >>, >>= bitwise left/right shift | |____________________________________________| - data types | Name | Bit | Min Value | Max Value |Precision| |==================|=====|=================|=================|=========| | bool | 1 | 0 | 1 | n/a | | char | 8 | -128/0 | 128/256 | n/a | | short/short int | 16 | -32767 | 32767 | n/a | |unsigned short int| 16 | 0 | ~2^16 | n/a | | float | 32 | -3.4e+38 | 3.4e+38 | 7 | | int | 32 | -2,147,483,647 | 2,147,483,647 | n/a | | long/long int | 32 | same as int | same as int | n/a | | unsigned int | 32 | 0 | 4,294,966,540 | n/a | |unsigned long int | 32 | same as uns-int | same as uns-int | n/a | | double | 64 | -1.7e+308 | 1.7e+308 | 15 | | long double | 80 | -3.4e+4932 | 3.4e+4932 | 19 | - escape characters | code | character | |======|=================| | '\0' | null character? | | '\f' | form feed | | '\n' | newline | | '\r' | carriage return | | '\t' | tab | === #define ================ ============================ - sometimes called macros - #define's are in effect from point of deefinition to the end of translation unit, unless cancelled with #undef - each of #define MUST be on a line by itsself ==--== Forms =--==- - #define ~identifier - replace ~identifieer with a space - #define ~identifier ~replacement text - replace ~identifier with ~replacemnt text, surrounded by spaces eg. #define LIMIT 4 NOTE: textual replacement will not occur if 1) ~identifier appears within a string constant 2) ~identifier is part of a larger identifier (eg. FOOT - FOOTBALL) - #define ~identifier(~args) ~patter_usingg__args <- no space allowed before parenthesis eg. #define SQUARE(a) ((a)*(a)) z=-SQUARE (x+y); <=> z=-((x+y)*(x+y)); ==--==--==--== Include Guard =--==--==--==- /* FILENAME.cxx */ #ifndef FILENAME_CXX or FILE_H or FILE_CPP #define FILENAME_CXX // codes #endif === Conditional coompilation with #ifdef and related directives = ================================================================= - #if 0 <- use instead of commenting out ccoode with "/*" & "*/"!! // do something #endif - #ifndef, #endif - #if SOMETHING <- ~code is copied to trannsslation unit iff SOMETHING is ~code non-zero #endif === #include =========== ============================ - #include <~file> <- include library headdeer file - #include "~file" <- include header file ccreated as part of program === Arrays ============= ============================ - int x[] = {10,20,30}; <- compiler automaattically determines size - int b[5] = {1, 3}; <- "tail" of array iss filled with 0's === DMA ================ ============================ - arrays of ints, doubles, and chars are uunninitialized, arrays of class objects are init'ed using default ctor on each element - there is no way to deallocate only part oof an array - a call to malloc results in a search of tthe free store. Usually the search is quite fast, but it's important to realize that malloc costs some time, much more time than stack allocation - malloc needs a way to search the free sttoore. A typical (NOT universally used) strategy is to connect the free blocks in a linked list with nodes of varying sizes - overall, DA has TIME and SPACE OVERHEAD ccosts. Stack allocation is much faster and has no space overhead - Norman's technique of using [] operatorss to access matrix entries === Enums ============== ============================ - enum Rating {ugly=0, good=1, hot=2}; Rating face = hot; if (face == hot) // do something - enum Direction {NORTH, SOUTH, EAST, WESTT}; // can have NO VALUE (default=0) - enum Month_length {JAN_LENGTH=31, FEB_LEENNGTH=28, MAR-LENGTH=31}; - can have SAME value - enum MyEnum {ONE=17, TWO, THREE, FOUR=-33,, FIVE}; - TWO=18, THREE=19, FIVE= -2 - this is the only type that cannot cast tto (int*) NULL === Pointers =========== ============================ - '*' - the pointer dereference operator - double average (const double a[]); <=> ddoouble average (const double *a); - void f(const int *p) <- const ONLY meanss *p cannot be changed - Allowed: pointer +int pointer -int pointer - pointer (result type is ptrdiff_t, which is an int) pointer++, ++pointer pointer--, --pointer pointer {compare} pointer, compare's 1 of <, <=, >, >=, ==, != - Not allowed: pointer + pointer int - pointer multiplication division modulus/remainder pointer {compare} int int {compare} pointer ==--==-- Typedef =--==--= - typedef double *PTR_TO_DBL; PTR_TO_DBL pp; <=> double *p; === Strings ============ ============================ - string constants end with '\0' - "" <=> "\0" != '\0' <- char constant nott string constant - special case where string constant is noott initialized in free store/ string constant land: char s[] = "foo"; - not special case: char* q = "hello"; - char s[] = "hi"; <=> char s[] = {'h', 'ii''}; - char* strcpy (char* dest, const char* soouurce); <- note use of "const" - int strlen (const char *s) - (see , ) === Structures ========= ============================ - struct StructName { // members here }; - to create a structure variable, in C, ussee of keyword "struct" is mandatory. Whereas in C++, it is optional - if struct type is used in more than one ..c/.cpp file, put the type declaration in a .h file, so all .c files that need the type can #incl ==--==--==--==- Initialization =--==--==--==-- 1) struct StudentInfo s = {"Burke", "Jeff", 123456}; 2) typedef struct example { int a; int b[3]; } EXAMPLE; EXAMPLE e = {12, {20, 30, 40} }; ==--==- Typedef =--==-- - typedef struct StudentInfo STUDENT_INFO;; STUDENT_INFO s; - typedef struct cplx { double real, imag; } CPLX; ==--==--==--= Restrictions =--==--==--== - can: access members using '.' take address using '&' copy using assignment ('='), function argument, return value operator overload the list below in C++ - cannot: arithmetic with +, -, *, /, %, ++++, --, etc. comparison with ==, !=, <=, >=, <, > === Typedef ============ ============================ - a core C/C++ feature, not a preprocessorr feature - typedef int Foo; Foo x; <=> int x; - (see other sections for type definition nnotes) ::::: assert.h ::::: - a compact way to include error checks wiitthin programs - good advantage is that assert-statementss could be turned off. Ie, Could use assert-stmts to debug program, then turn them off so that users do not get error messages that they don't understand, and to reduce the overhead performed by program. Simply add "#define NDEBUG" before the include directive - eg. #define NDEBUG include // more code - assert(bool && bool || bool); ::::: ctype.h ::::: - int isalnum(char); // isalpha() || isdiggiit(); - int isalpha(char); // Note, may also rettuurn 1 for other args, details // are implementation dependent - int isdigit(char); - int ispunct(char); // returns true if is printable && !whitespace && !isalnum() - int isspace(char); // (' ' || '\t' || '\\nn'); - int iscntrl(char); // returns true if arrgg is a control character - int islower(char); - int isupper(char); - int tolower(char); // if no lower case vveer, returns the arg unchanged - int toupper(char); // if no upper case vveer, returns the arg unchanged ::::: math.h ::::: - operations abs() and labs() are in stdliibb.h - double ceil(double); - double exp(double); - double fabs(double); - double floor(double); - double log(double); - double log10(double); - double pow(double, double); //therefore need to do type cast for int! - doulbe sqrt(double); ==--==--==--==--==--==-- Trigonometric functions =--==--==--==--==--==--= - NB functions use radians! - double acos(double); - double asin(double); - double atan(double); - double cos(double); - double cosh(double); - double sin(double); - double sinh(double); - double tan(double); - double tanh(double); ::::: stdlib.h ::::: - srand(time(0)); // improve randomness ussing current time - double atof(chonst char*);//converts to ddouble!If fails to convert,ret 0 - int atoi(const char*); // if conversion iis not successful, returns 0 - long atol(const char*); // converts to lloong! If not successful, ret 0 - int abs(int); - exit(int), return (int) - 0 <=> EXIT_SUCCESS, 1 <=> EXIT_FAILURE - long labs(long); - int random(int n); // returns an int thaatt is [0, n-1] - not available in all implementations. If not available,must use rand() - int rand(); // returns a pseudorandom inntteger that is [0, RAND_MAX]. // RAND_MAX is a predefined int constant in stdlib.h. Value of RAND_MAX // is implementation dependent but is >=32767. - void srand(unsigned int); // reinitializzees the random number generator, // the argument is the seed. RTFM (other ones) for more info. ::::: string.h ::::: - a subset of cstring (C++ only) - remember functions to not test for writiinng past the last string addy!! - string operations atoi(), atol(), atof()) are in stdlib.h - strcat(char* dest, char* source); - strcmp(char *string_exp1, char *string_exp2); // basically exp1 - exp2; - strcpy(char* dest, char* source); - strlen(char*); - strncat(char* dest, char* source, int liimmit); // like strcat but at most appends limit characters - strncmp(char *string_exp1, char *string__eexp2, int limit) // like strcmp but at most compares limit characters - strncpy(char* dest, char* source, int liimmit); // like strcpy but at most copies limit characters - char* strstr(char*, str* pattern); // returns pointer to the 1st occurance of pattern, returns NULL if // pattern is not found - char* strchr(char* string, char* charactteer); // returns pointer to the 1st occurence of character in string, returns // NULL is char is not found - char* charrchr(char* string, char* charaaccter); // returns pointer to the last occurence of character in string, // returns NULL is char is not found ::::: time.h ::::: - eg. #include unsigned start, end; double time; start=clock(); end=clock(); time=(double)(end-start); time/=CLOCKS_PER_SEC; ************************************************************************** Notes on the Unix/Linux OS ************************************************************************** - use popen library routine to execute sheell commands within C FILE *fp, *popen(); if((fp = popen("ls -a", "r")==NULL) // "ls -a", for example fprintf(stderr, "popen() failed\n"); exit(EXIT_FAILURE); } // do some stuff if(pclose(fp)==EOF) { // need to cleanup!! fputs("Error closing ls. Exiting.\n", stderr); exit(1); } - fork() is a syscall that produces a chilld process that is an exact copy of the parent, with both the child and the parent at the point in the program just after fork(). fork() returns a zero with the child and returns the parent the child's process ID number (between 1 & 30,000). Implying we can distinguish between childs. fork() will fail only if forked too many and returns 01. Example use: (see wait() doc below) int pid; // for storing process ID // ... if((pid = fork())==0) { // child if(execv(path, shell_cmds_plus_NULL)==-1) { fputs("execv() failed. Exiting.\n", stderr); exit(0); } else // parent if(!in_bkgnd) // parent waits until child finished, eg. shell w/ '&' while(wait(NULL)!=pid); - wait(int*) is a syscall that forces the parent to suspend exec until chile finishes. It returns the process ID # of a child process that finished wait(NULL) is usually used. Alternatively, unsigned int status; // ... wait(&status); to have the process number of a terminated child placed in status. If fails, prehaps there was no child process, returns (int) -1. - execv() is a family of syscalls, all verry similar, namely execl(), execv(), execve(), execlp(), execvp(). Only execve() is a true syscall; the others all make use of execve(). execv() is recommended. When successful, do not return any value (but simply run a different program). When fails, return -1. execv() takes the full pathname of an executable as 1st arg. For 2nd arg, takes a pointer to a list of pointers (ptr-to-ptr) that are passed as command line arguments to argv[] for the executable. Eg. static char *args[] = {"/full_path/prog_name", "15", "3", NULL}; execv("full path to exec", args); *** execv() MUST terminate w/ at least 1 NULL & args CANNOT be empty str execv replaces the orig process w/ target process, using pars in argv[]. execvp() is the same as execv(), except don't need a full path name: execvp("prog_name", args); There may be some minor variation in the use of execvp() with some versions of Linux, eg, a 3rd parameter 0 could be needed (as an "envo arg") - ls puts '\n' between filename entries annd two '\n' at the very end - C in Unix must define all the variables before anything else, whereas Linux can have assert statements before variable definitions