C++
c string conclude in a null or zero terminator
"fig" contains four characters 'f','i','g', and '\0' the null terminator and 0 (the number) are distinct and have their own ascii codes
some character literals
'y','0',' ','\n','\t','\0' y,0, a space, newline, tab, and the null terminator respectively
*registerpointer is denotes the cashregister object located at registerpointer
(*registerpointer).additem(1.95); parentheses are necessary becasue of the order of operators * and .
Order of operations
++ -- unary(+) unary(-) ! * / % + - < > <= >= == != && ||
there is an operator that corresponds to "follow the pointer and call member function"
-> registerpointer->additem(1.95);
.cpp are source files
.h are header files
// denotes everything until the endline is a comment
/* */ can denote the beginning and end of a comment that spans more than one line
Any nomerc value can serve as a condition for example if (2) ;
0 evaluates to false, any other number evaluets to true C and C+ asignments also have a truth value, if (x=13); the condition is true, x is assigned 13 and because 13 is not 0 the staemtent is true
0<200<100
0 is less than 200 so the first astaeent evalutses to true, which is stored as 1, and 1 is less than 100
double mydouble = (1+2+4)/3 ==
2 changing 3 to 3.0 or first storing the sum as a separate double will give a variable of type double in the division and thus division for double will be used rather than division for integers
The bmp format does not use any kind of data compression unlike GIF,JPEG, and PNG
24bit true color format uses one byte for the blue, green, red pixel respectively
ostringstream strm strm << fixed << setprecision() 10.0/3; strm now contains
3.33333 as a string string output = strm.str()
before the string class became widely available manipulation of character strings was quite common
<cstdlib> has a useful fucntion for converting between a character array of digits, and an integer itn atoi(const char s[]) from alphavetic to integer char[] year = "2020" int y = atoi(year);
sqrt(2) * sqrt(2)
=2.00000000000000044, this is not equal to 2. Often it makes sense to say two floats are equal if they are within some value of eachother. It is common to deem double equal if they are within 10**-14 of eachother, this can be checked with the absolute value function
= assignment
== equality
c++ relation operators inlcude
>= <= == < > !=
Array parameters are always reference parameters
A functions return type cannot be an array if the function computes multiple results the caller can supply an array and store the values there
It is common to come across computer problems for which there is a command that provies a simple solution, but tracking that down takes much time.
Allowing for double the estimate of time can hlep mitigate such frustration and fallout
Object oriented programming is intended to get around the difficulty of maintaining a larger collection of functions
An object has it's own data, and its own functions (called member functions) that can act on that data
{}
Beginning and end of a code block respectively
integers have four bytes b0 + 256b1 + 256^2*b2+256^3+b3 this order in the formula seems backwards to me, since the earlier digits correspond to smaller powers
C++ ints can be larger than VBA ints
a derived class consructor can only initialize obects of the derived class, but the cas calss data memers also need ot be initialize, unless otherwise specified(how) base class data memers are iitialezed with the default constrctor.
Data members are not base clas objects, if not specified an intiial value in teh derived class constructor will hte automatically iniitialize to a default value if they belong to a class with a default constructor, i thin i said this was so in a different flashcard, but i know think i may have misread
Functions must be declared before they are used. A declaration is like a function definition without the block of implementation and instead it has a semicolon after the return type name and parameters
Declarations are aka prototypes. Declaring simplest functions first and functions that use other functions later. <cmath> uses the declaration format. There is drawback to declarations, if ever the programmer wants to change the function name they must change it in two places, the declaration and the definition.
const
Declares a block-scoped, read-only named constant. Cannot be changed.
string word; in_file >> word;
First white spaces are removed from in front of the stream but not added to word. Whitespace includes spaces, tabs, and newlines. The first character that ins't whitespace becomes the first character in the strign word. More characters are added until the stream reaches whtiespace or the end of the file. Whitespace after a word is not removed from the stream
pragma once
Guards against including the same header file more than once in a single cpp file
There is C++ syntax now obsolete but that still exists for backwards compatibility that allows definition of class types and variables simultaneously
If the closing semicolon of a class definition is missing the compiler will parse the code as if this is what was intended, it may end up reporting the error, but only several lines later for some reason. When there are bizarre error messages in line surely correct, the error may actually be a few lines above.
Definite or count controlled loops include for loops
Indefinite or event controlled loops include while loops
\
Initiates an escape sequence. Can be used before characters with special c++ meaning so the character shows up in a quote. E.g. "Hi "there"" is Hi some there and some empty string (which doesn't compile) "Hi \"there\"" is Hi "There"
do { statements } while (condition);
Is also valid
it is typiacl to used fixed and set the precision for output, setw before every output, as well as left or right align for strings and numbers.
Is there a way to permanently setw instead of repeating it before each output
int main()
Main Functions: Programs may have many functions, but will always need a main. Write an "integer" main function.
Use a reference parameter to update a variable in a function call
Modigying a value parameter has no effect on the caller void withdraw(double& balance, double amount) { double& is called a reference to a double or double ref the argument to a reference parameter must always be a variable (what would happen if it wasn't). Expressions constants etc aren't changable as they don't have an address
Array sizes cannot be changed once declared regardless if they are one dimensional or otherwise
Multi dimensional array have multiple subscripts values[] [] [] When array parameters must specify the size of all dimensions except for the row function(double values[] [columns] [slices]
double cube_volume(double side_length){ if (side_length >= 0) { return side_length ** 3 }}
Note not every branch of this function of type double returns a value. In particular if the side_length is negative most compilers flag an error, which if ignored will return a random value.
cout << "Enter values, Q to quit. \n"; while (cin >> values) { statements } cin.clear()
Only ful processed characters are removed from cin, if the porgram is run correctluy cin will still contain the sentinel "Q" string sentinel; cin >> sentinel ;
initializer lists are used to pass various inputs for an object into that objects specific data members. In the previous example the order constructor must call the item constructor. Initializer lists are place before the opening brace of a constructor, these list begin with a colon, and lists for different data members that require them are separated with commas. Each list contains names of data members with their construction arguments
Order(string customername, string itemdescripction, double itemprice) :article(itemdescription, itemprice) { customer= customername} alternatively Order(string customername, string itemdescripction, double itemprice) :article(itemdescription, itemprice) , :customer(customername) {}
sometimes a programmer may find they are using multiple vectors of the same length to store related information, in situations like these the set of information with the same index across each vector is called a slice. the vectors are called parallel vectors
Parallel vectors can become a headache in large programs, and any function that only needs to operate on a given slice must take an argument from each vector which can be tedious to program. The information in each slice could have instead been bundled as a single object, and in place of the parallel objects a single vector of that type
BMP noteworthy positions
Position 2 contains the size of the file in bytes Position 10 contains the location of the start of the image data Position 18 Contains the width of the image in pixels Position 22 Contains the height of the image in pixels Alternatively instead of position i could have said the contents thereof begin at byte number There is probably other information inbetween these and the pixel data
Ways to start a C++ program include
Selecting "run" in the compilation environment, clicking an icon, or typing the name of the program in a command shell. When invoked from the comman line the program can take comman line arguments. For example prog -v inpu.dat. The program "prog" receives two arguments "-v" and "input.dat" It is common to interpret strings strting with a hyphen as options and other strings as file names.
#ifndef CASHREGISTER_H #define CASHREGISTER_H ... #endif
Suppose the cashregister header file, and another header file that itself includes the cashregister header, this code bypasses the second time the compiler sees it. The compiler doesn't check if both of the same named headers conatin the same code, so as a precaution it would return an error
string name = "Will"; name[0] = B; name know reads Bill does name.sub_str(0,1)=B; do the same thing?
The test says [] is more convenient for accessing a string character one at a time, but will sub_str actually work/compile
Semicolon does not go after the if condition, but after the if branch statement
There doesn't need to be an else statement Braces aren't necessary if the if branch contains only one statement
int values[number_of_inputs]; for (i=0; i < number_of_inputs; i++) { cin >> values[i] }
There is a sort function in <algorithm>. To sort an array values[] of x items sort(values, values+x) to sort a vector sort(values.begin(), values.end()); sorted data allow for efficient searches, including binary searches amongst others
C++ allows multiple variables to be declared at once like this int i =0, j = 1;
This doesn't work the same way for pointers double* p, q; creates a pointer to a double "p", but q is not a pointer, but is actually a double
const int COLUMNS = 3; int row_total(int table[][COLUMNS], int row) { int total=0; for (int j=0; j< COLUMNS; j++) { total = total + table[row][j]; return total; }}
This function only works for arrays with 3 columns, a different one would be needed for an array with 4 columns. But why though, it seems like arrays could be defined in such a way to allow that, yet they are not. Array elements are stored one after another, the column size is used to know where each row starts. if the row number is for some reason required pass it as a separate variable int column_total(int table[][COLUMNS], int row, int column) { int total = 0; for (int i=0; i < rows; i++){ total=total + table[i][column]; } return total;}
when a function doesn't modify an array parameter it is considered good style to denote the parameter as const.
This helps make clear to the reader that the element remains unchanged
string intials = first.subsrt(0,1) + "&" + second.substr(0,1);
This is fine, however attempting to concatenate two string literals will return an error
double* firstlast(double a[], int size){ double result[2]; result[0] =a[0]; result[1] = a[size-1]; return result; } error
This returns a pointer to the starting element of the array, passing an array to the caller by reference and then assigning it the desired values works. void firstlast(const double input[],const int size, double result[]){ result[0]=input[0]; result[1]=input[size-1]; }
Vectors are a construct, they can be found in <vector> They are defined like this vector<type> name; or vector<type> name(size); Vectors can be both function arguments and return types
Vectors default to initial size of 0 vector<double> values(); does not define a vector vectors have member functions including .size(), .push_back(value) (appends value), and .pop_back() (removes last value)
recursion
When a function calls itself.
The slicing problem
When upcasting from a derived class to a base class, you lose everything from the derived class that isn't present in the base class.
#include <iostream>
Write the include directive needed to allow use of the various I/O operators such as cout and cin and other stream manipulation
exercise for later make an array that looks like this
[] [][] [][][]
polymorphic collection
a collection of multiple shapes, the previous example of an array of related derived clases is an example of this.
const double p* =&q; defines a constant pointer to be the location of some variable p. the value to which p points cannot be modified, that is *p=0; is illegal (but what about p=o; i.e. can i change the location of the pointer even though i can change the value it stores there?
a constant array parameter variable is equivalent to a constant pointer double sum(const double[] values, int size) is equivalent to double sum(const double* values, int size) do the array brackets go after the type declaration, or after the name of the array variable
constructors only work when an object is first created
a constructor can't be called like other member functions after the object is first created, not even to set that object back to its default values
return type void indicates
a function will not return a value. to end a void function early use a "return" statement without a value to be returned. void type functions can't be used in an expression.
Every file stream has
a get and a put position where the next character is read or written respectively
const int NAME_SIZE = 40; char name[NAME_SIZE]; can hold strings up to length 39 because one spot is required for the terminator
a hacker might try to overwrite memory by supplying more than 39 characers
constructor
a member function of a given class which if existent initializes members of that class to some default value. If there is not a constructor, members of that class can be assumed to have random values upon initialization
Copying a variable is less efficient than using a refernce parameter
a passing a variable as a const ref preserves teh efficinecy of a reference parameter while ensuring the oringial is not changed. void shout(const string& str){ cout << str << "!!!" << endl; } I infer passing by value copies the ref to another location so it can be changed, by ref must give a pointer, and const ref returns an error if the value at that pointer is changed. By reference only needs to pass the location of the data not the data itself. I assume this trick only compiles if the code doesn't attempt to change the data
BMPs are stored as
a sequence of pixel beginning with the bottommost row of the image. The row is "padded" with additional bytes if necessary so that the number of bytes is divisible by 4, the padding bytes can be anything
A stub is
a short piece of code that sits in place of complete implementation, but is sufficient to test another function
endl
a stream manipulator that can be used to advance the cursor to the next line on the computer screen. Equivalent to \n
sentinel
a value that signals termination. Initializing something to a sentinel may cause the code to terminate to soon
Mutators change the value of a class' data members
accessors use the data members, but do not change them, it is typical to mark them as const. Unlike regular function definition the const in the declartion of public functions goes at the end. Is this only the declaration or the definition also?
When an input fails to cin all further input also fails
after a sentinel or triggering a failure state, the failure state must be cleared. I don't know if it needs to be cleared multiple times for multiple failures.
the fail function tells whether input has failed
after reading data it is reasonable to test for success before processing if (!in_file.fail()){ process input }
convention for constants
all caps
new double[n];
allocates an array of size n and returns a pointer to an array of doulbes, i.e. a pointer to the start of an array of doubles. n can be a variable here typically it will be important to capture this pointer in a variable double* x = new double[]; double* y = new double; x[i] will be valid notation, what about y[i]
new type;
allocates memory for a variable of type "type" and returns a pointer to it
if (floor>13) ; { floor-- }
always decrements floor because the if statement ends at the semicolon and is given what I am calling the "empty branch statement". The same goes for else statements
condition ? value1 : value2
an alternate way to write an if statement, the "values" here can themselves be statements such as x-- or y=11, they can also be just a variable to return
for each paramaeter variable aka formal parameter
an argument is supplied aka actual parameter
C++ input output is based on streams
an input stream is a source for data and output stream is a destination for data
it is convention to return 0 if the program ran successfully
and non zero valeus fi an eror is encountered
use get to get the next character of a stream
and unget to put the last one that was read back
Variables created in a loop
are automatially created and removed for each iteration
sqrt (X) and sqrt(x)
are both viable
sqrt(x), pow(x,n) sin, cos, tan, log10, abs
are in <cmath> #include <cmath> to use
the name of the array is a pointer to a location, and the index indicates an element a certain number of positions form the start
array sizes must be known at compile time, either by declaring the size or initializing it with values. the size must be a constant, if a variable is passed some compilers will not process that. suppliying fewer values than the declared size of the array initializes the unspecified values to 0
position=strm.tellg() location=strm.tellp()
assign the the positions of the get and put positions to variables called position and location repectively
*name = 1000;
assigns a value of 1000 to the variable stored at location name the following is legal *name = *name -100
outfile.open("output.txt")
assumes the file is in the same directory as the program, I believe the full path name would be necessary if it wasn't, or some shortcut indicating moving up and down directories maybe
Suppose we wanted to change a datameber belonging to a bse classs, we could create a new data meber in the derived class with the smae ame, and changes its value, but then there would be two of this data member, the new one caled by funtions of the derived class, and th oled wone called by funtions of the base class
at leat thats how i thnk it works
consider the following scenario String name1("Harry"); String name2("Sally"); name1=name2;
at the end of this block the memory location where name2 was will be deleted twice and the memory of name1 not deleted which could lead to a memeory leak
number formatting errors aren't the only reason for stream failure
attempting to read more data after the entire file has been read causes it to enter a failed state whereas cin>> would wait for more input also if the name is invalid or there is no file that matches the name of a file to be opened the stream also enters a failed state
strm.get() strm.put()
between getting and putting the byte or object may be modified, if the starting position from where the data was first gotten is kept track of, then the prrocessed data can be put back to the same location
Attempting to access an array index outside the declared size is a
bounds error. the compiler treats this as if the index was in legal bounds and reads/writes/overwrites the data. What actually happens in a bounds error
When an array is allocated from the heap its szixe may be chosen at run time and doesn't need to be a constant.
but if a size needs to be chosen won't I have to program that in effectively meaning it acaully needs to be chosen before run time at compile time?
7/4 = 1
c++ assumes these are ints and c++ ints are... integers, they don't have a remainder or decimal so it truncates the answer down to the nearest integer. This kind of truncation will also happen when a variable of type double is assigned as the value to a variable of type int Adding +0.5 to the double will have the effect of rounding if it is truncated to fit an integer.
the get position of a stream becomes undefined whenever data is put to the stream. likewise the put position of a stream becomes undefined whenever data is gotten from the stream
call seekg when switching back to reading call seekp when switching back to writing
calling rand() yields an integer between 0 and RAND_MAX typically the largest int value permitted
calling rand() again yileds a different number, rand is found in cstdlib<>, it's starting value is always the sae so we seed it to a random place im its sequence srand(time(0)) seeds rand to the number of seconds away from time 0, time() is found in <ctime>
the heap
can allocate memeory for values and arrays of any type
how does the relationship between .h and .cpp files work, do i not need to include the .cpp file somewhere, does the copiler know if the header is included to look for a .cpp of the same name?
can i include a header in a source file or vice versa and just include the one that contains the other in my final program
double price = 4.35 int cents = 100 * price
cents has a value of 434 thanks to 4.35 being stored as a slightly smaler nubmer because binary has no exact version of 4.35, adding + 0.5 when initializing cents eliminates that
static_cast<type>
changes variable's type without displaying a warning additionally from stackexchange "If the casting is unsafe, then a standard cast will go without a warning, while a static_cast will issue a compilation error."
when a string is read with the >> operator only one word is palce into the string variable
cin >> name >> secondname; Harry Morgan name == Harry secondname == Morgan
Example class definition it contains data members and declarations for public and private functions which will be implemented later
class CashRegister{ public: void clear(); void add_item(double price); double get_total() const; int get_count() const; private: data members }; Can data members be put in the public section if I want them to be? Yes, it is allowed
when consructing an object with data members that are themselves objects those data mebers are intialed by their own dfault construcotrs. if a daa member doesn't have a default construcotr it will be left random or its data members will be ocnstructed by their own default constructors
class Item{ public; Item(string itemdescription, double itemprice); }; class Order{ public: Order(string customername, string itemdescripction, double itemprice); private: item article; string customer; }; note this doesn't place the arguments for oreder into its data members. That's because this is a declaration not a definition
Unlike most instances where braces {} are not followed by a semicolon;
class definitions always end in a semicolon ;
a constructor with no arguments is the default constructor, there may be other constructors that specify given data members. The ocmpiler picks the constructor that matcches the construction argumetns. The following illustrates declarations of two constructors for objects of type myclass
class myclass { public: myclass(); myclass(double somenumber); ...};
constructors never return values but do not need the void type, here is an example
class myclass { public: myclass(); ...}; myclass::myclass(){ datamember1=initialvalue1; datamember2=initialvalue2; } Constructors don't have to initalize all data members of a given class, if they do not, upon declaration those members which have not been given an inital value will be given one by their own default constructor if they have one, if they do not they will be assigned some random value(how is this value assigned, i don't know)
consider an implementation of a string clsss similar to the one in the C++ library. The characters of a string are sored on the heap and each string object contains a pointer to the array holding it s characters
class string { private char* char_array; } if type* are the same as an array where is the size of the char array stored in teh above example? how does the compiler know its size
suppose i left a data member public, how would i assign it? would the foloowing work
class.datamember = value;
There is a certain cost to writing a function instead of placing all the code in one large function.
consider breaking up functions that won't fit on a single screen
consider not modifying parameter instead of int total_cents(int dollars, int cents) { cents=dollars**100+cents return cents }
considernot mixing variables and parameters int total_cents(int dollars, int cents) { result=dollars**100+cents return result }
while (conditon) { statements; }
continues exectuing so long as condiiton is true. braces are only required if there is more than a single staement. Infinite loops are possible and off by one scenarios are common
to_upper(character)
converts a letter to uppercase
a pointer that points to memory that has already been deleted is a
dangling pointer
using namespace std;
declares that the program will be accessing entities whose names are part of the namespace called std
double name[10]; or double values[] = {32,54,68,37,33,44,56,65,24, 40}; this is correct in this situation the ; goes after the }
defines an array of doubles of size ten
overriding a function in a derived class
defining a fucntion in a derived class with the same name as the base class, but giving it a different implementaion
delete name; delete[] name_array;
delete[] arrays;
in C++ a derived clas is formed by specifying what makes it different form a base class
derived clases inherit all member functions from the base class, but they can be modified to better fit the derived class if necesary a derived class also inherits the bases class dta memebrs, additional member funtions and data memebs can be defined if useful
in order to specify anothe construcot use an initializer list, specify the name of hte base class and the constrcutoin arugments in the initializer lis
derivedclass::derivedclass(type name) :baseclass(datamember){} here the base class constructor is called before executing further code
string variable
different from string literal
default format for flaoting point numbers is called general format
displays as many digits as specified by the precision. 6 by default. it switches to scientific notation for small and large numbers
how does the main function work
do all files need one, can they have multiple, how does the compiler react to a main
what's wrong with this code, what happens int* p = new int[10]; int* q = p; q[0] = 5; delete p; delete q;
does this have a different result than the error just above this
type function(type paramater1, type parameter2 ...)
double cube_volume(double side_length) { return side_length**3 }
a++ and a-- mean increment or decrement the variable a and return its old value. The following is yet another way to implement a sum function, it may be confusing or more difficult to understand and maintain
double sum(double* a, int size) { double total=0; while (size-- >0){ total = total + *a++;} return total;} is there a way to combine this trick with for loops like in the other examples and get the lines of code to be even fewer
double sum(double values[], int size) { double total = 0; for (int i = 0; i<size; i ++) { total = total + values[i]; } return total; }
double sum(double* values, int size) { double total = 0; for (int i = 0; i<size; i ++) { total = total + *(values+i);} return total;} double sum(double* values, int size) { double total = 0; double* p = values; for (int i = 0; i<size; i ++) { total = total + *p; p++;} return total;} p++ moves the pointer to the next element, how does it know where the next element is though? does p know that it is the start of an array it is slightly more efficient to increment a pointer than to access an array element therefor this bottom example is commonly used.
Pointers are a data type that store a memory location. * called either the indirection or dereferencing operator denotes a pointer when it immediately follows a type. double* stores the location of a variable of type double. & called the address operator denotes the address of a variable T* denotes a pointer to a variable of type t, &T denotes the location of a variable of type T
double* real_location = &real_number stores the location of the memory address for a variable called real_number in a pointer called real_location
strings default to
empty string #include <string> string concatenation is done with +
;
ends a c++ statement
return 0;
ends the program
Descriptive names help minimize
errors in communication
1.0/3.0 == 0.333333333
evaluates to false, it's clsoe but not exact
cin >> value ;
evaluates to true if the input hass not failed
char is a type and character literals are declared in single quotes
example char igriega = 'y'
The following is legal but I don't know what it does
for (cout << inputs; cin >> x; sum = sum +x;)
derived class objects can be used in place of base class objects
for example an ifstream is a special kind of istream, an ifstream can be the argumetn for the following void process_input(istream& in) istringstream s are also istream, so this function can take them as input arguments as well
when memory is deleted it is perhaps better worded as unreserved, any pointers that ointed there before still point there, they werer not deleted, but accessing them will still change the data to which they point. However, it is possible that because that memory was unreserved the heap at some point reallocated that memory and using the old pointers may overwrite or alter in some unintended way the memory that has now been allocated elsewhere
for this reason many programmers set pointers that pointed to now deleted memory to the Null value, they no longer point anywhere so changing the values to which they point will do nothing pointer = NULL;
to open a binary file for reading or writing
fstream strm; strm.open(filename, ios::in | ios ::out | ios ::binary);
by default vectors are passed to functions by value, pass them by ref to change values
function(vector<double>& values) the efficiency trick also works function(const vector<double>& values) rather than copying the vector visit its positions and use them when not changing them
variables defined inside functions are local variables
global variables are those defined outside of functions <iostream> defines global variables cin and cout variables must be defined before they are used, as the compiler works sequentially/chronologically global variables can cause confusion when different functions are changing the same value, it can also make collaborating more difficult for this same reason. When possible avoiding them often results in lower difficulty. Function parameters provide an alternative way to transfer info from one part of a program to another
noninitialized variables
have whatever value happens to be there
The code of complex programs is often distributed throughout multiple files that are then compiled together
header files contain class definitions and declarations of nonmember functions and definitions of constants, but why not non member funciton definitions
struct employee { string name; StreetAddress* office; }
how does .notation work in this case will it be employee.streetaddress.house_number?
cout << "Enter values, Q to quit. \n";
how does \n work here
there bojects whose type can vary at runtime, this behavior can be achieved with somtheing called vritual funtions
how to use pointers to allow object types to vary at runtime, somehow virtual funtions select thte correct member funtion
it is illegal to define two variables of the same name in the same level of a block
however, there can be overlap in the inside block of nested blocks if a second variable with the same name as the first is defined in the nested block. in this case the variable name will designate the variable defined in the nested block when used in the nested block, and outside the nested block the variable name will refer to the instance defined outside the nested block. The inner variable shadows the outer one.
char ch; in_file.get(ch);
i believe infile now has the next character that was stored in ch get returns the not failed condition allowing the following while (in_file.get(ch));
what was the rationality behind not allwoing derived classes not to be allowed to access base class data members
i think this is the default, derived classes actually have the base class as a data member, so to the compiler it is like they are unrelated in some way
for (int i = 0; i < QUIZZES; i++){ quiz[i]->display(); cout << "Your Answer:"; getline(cin, response); cout << quiz[i]->check_answer(response) << endl;
i think this should work so long as the appropriate funtions are labeled as virtual, i intend to try coding this without labeling the relevant funcitons as virtual and see what happens
string arg= argv[i] in.open(arg.c_str());
if (in.fail()){ cout << "Error"; return 1; }
the fact that the >> operator returns a "not failed" condition can combine input and a validity test
if (in_file >> name >> value) { process input }
example of if statement
if (value > 10) {x+2}; else x=3; should that top semicolon be before or after the }
the if statement can be used in input validation
if (x=6){ cout << "Whoa that's composite" ; return 1; }
Using a switch statement isn't much of a shortcut as compared to using repeated else if s, but it does rpovide at elast one advantage, it makes clears that all the conditions are checking the same value
if a break is not provied the swtich will continue evaluating code until it hits one. I think the switch conditions have to be integers, but I'm not sure
Switches hae a default branch that can be used for
if none of the case clasues amtch
for some reason the string class at this time did not have a function to turn a string into an integer so there is a workaround turning the string into a c string -or character array- first.
if s is a string s.c_str() yields a character pointer to the characters in the string. Because pointers are equivalent to arrays (I think), this has turned the string into a character array aka c string, and we can say atoi(s.c_str()) to give us an integer converting c strings to strings is much easier as the string class allows its variables to be assigned string literals, aka cahracter arrays, aka c strings
filenames contain directory path information such as ~/homework/input.dat in UNIX c:\homework\input.dat in windows
if the filename contains a backslash like in windows the backslash must be used twice because \ is the C++ escape character \\ denotes a single backslash
Evaluation of && and || ends as soon as the truth value has been determined
if the first condition determines the ruth value exectuion stops
cin >> variable;
if the input doesn't match the variable type cin.fail() will be set to true, this can be used in data validation. I dont know what value variable will have
By default numbers are printed with 6 digits
if the width dictated by setw isn't sufficient it is ignored cout << setw(6) << " :" <<< 12; :12
new is a reserved word, when it precedes a data type in signals fro the heap to allocate a new variable of that type
if too many new variables are declared such that the heap runs out of memeory the program crashes i think, for this reason remember to use delete or delet[] to avoid this problem called a memeory leak(s)
Pointers into array support pointer arithmetic
if values[] is an array values +3 is a pointer to values[3] and *(values+3) is a pointer to in general *(values + n) is the same as values[n] array pointer/duality. This is what makes it convenient for the first element of an array to have index 0
suppose a fucntion in a base class calls other member funtions defined in the base class but whcih were overriden in some derived classes.
if we make the used member funtions virtual then when the function they are in gets called they will be the version defined in the class of the explicit parameter
structures agregate items of arbitrary types into a single alue
in C++ structures are defined with the reserved word "struct"
string class
includes string variables and literals
++ --
increment or decrement by 1
for (counter=n; counter<m; counter +=l;)
initialization, condition, and update are the three statements in the parentheses respectively. Typically they are of the indicated format, but can be nonsensical as well, for instance the initialization can be cout << "Term"; I don't know what will happen in this case. The counter of the example is also only defined in this for loop. It's possible to end up in an infinite loop if the condition is counter !=7, n=0, and l =2
to initialize a pointer with no location
initialize its value to NULL Trying to access data through a null pointer is illegal and will cause the program to terminate
<<
insertion operator place string literals in ""
what's to stop a user from inputting a double in the following
int MEnu::get_input() coaonst { int input; do{ diplay(); cin >> input;} while (input<1||input >options.size()); reutn input;}
Does cin only take one piece of data at a time? can i give it a list in parentheses, does does it treat that as one or multiple items, what happens in the following code?
int current_size =0; double input; while (cin>> input){ if (current_size < CAPACITY){ values[current__size] = input; current_size ++; }}
to read a byte form a binary file
int input = strm.get() this gets the next byte not the next bit
c++ is case sensitive
int main() is not the same as int Main()
The main function must be defined in a different way to take command line functions
int main(int argc, char* argv[]) {stuff} argc is the number of argv[] arguments, and argv contains that many strings(up to that many strings?) The first argv is the name of the program to be run "prog" in the above card, thus argv[0] is the name of the program and argc is always >= 1
a helper function to convert the integers in a string to actual integers
int string_to_stream(string s){ istringstream strm; strm.str(s); int n =0; strm >> n; return n; } writing to a stringstream also allows for the opposite, conversion between integers and floating point numbers strings
often functions that act on c strings rely on the terminator to work successfully as an example the strlen function that can be found in <cstring>
int strnlen(const char s[]){ int i =0; while (s[i] !='\0') {i++;} return i; } returns the location where the terminator was found which is the same as the length of the string
the name of an array is a pointer to the starting element of the array
int values[]; int* address = values; assigns the starting location of the array "values" to the pointer variable "address" array names can also be used in other expression cout >> *values; is the same as cout >> values[0];
what is the output of this program (4 i think)
int x; int mystery(int x){ int s = 0; for (int i = 0; i < x; i++) { int x = i + 1; s = s +x } return x; } int main(){ x = 4; int s = mystery(x); cout << s << endl; }
Number types
int, unsigned, short, unsigned short, long long, double, float int - The integer type, with range −2,147,483,648 (Integer.MIN_VALUE) ... 2,147,483,647 (Integer.MAX_VALUE, about 2.14 billion) 4 bytes byte - The type describing a single byte consisting of 8 bits, with range −128 ... 127 - 1 byte short - The short integer type, with range −32,768 ... 32,767 2 bytes long - The long integer type, with about 19 decimal digits 8 bytes double - The double-precision floating-point type, with about 15 decimal digits and a range of about ±10308 8 bytes float - The single-precision floating-point type, with about 7 decimal digits and a range of about ±1038 - 4 bytes char - The character type, representing code units in the Unicode encoding scheme (see Random Fact 2.2) - 2 bytes
baseclassobject1=derivedclassobject1;
is a legal statement in C++, extra data from the derived class will be sliced away, and I believe but am not certain that function from the derived class will not compile for baseclassobject1, however in the case of funtions that were overridden im guessing the version of the fucntion from the base class will now work, and the now baseclass object can use member funtions the derivedclass object couldnt use in the envent that for whatever reason the derived class object inherited privately
implicit parameter
is a reference to the object on which a member funtion has been called. "When a member function is called on an object, the implicit parameter is a reference to that object
it is possible to unget a character this can help when we want to read unitl numeric/non-numeric data, we find the first kind that indicates we have read all we want and then put it back
is it possible to unget multiple characters in a row?
source files contain function implementation
is there a reason code is split the way it is between headers and source files
<cctype> contains certain character funtions more or less what they sound like
isdigit isalpha islower isupper isalnum isspace
how is new double different from just double
isn't memory allocated in both cases does new somehow allow us to do something different at runtime
suppose the string date has a date we'd like to split into day month and year, it comes in Mon, DD, YYYY format
istringstream strm; strm.str("January 24, 1973") the >> operator can then be used to read the month, day, comma, and year string month, comma; int day, year; strm >> month >> day >> comma >> year; this input statement gives day and year as integers, had we taken str apart with substr those values would be strings
look for duplicated code
it can often be condensed, for example in situations where it occurs in both the if and else staemtn. This helps avoid a situration where a rpobamer modifeis one copy of the staemtnes, but nto the other
when we refer to a class we are refering to the name functions and data members defined int it, these do not include data members or member funcitons of a base class it may be derived form even though it has access to pulbic member funciotns of the base class, and pulic data mebers of the base class even though there are seldom pulic data members.
it does not however have acces to private member ucniton of a base class, and perhaps more iportantly private data members of a base class. While a derived class does inherit the private data members of a base class, it can not directly modify them like te base class can becasue those data mebers wer not actually defined in the base class, it must instead use public mutator functions of the base class to do so
It takes time to compile a file, recompiling code that didn't change uses extra resources, when multiple files are involved
it would also be difficult for multiple programmers to alter the same file simultaneously
when writing an array parameter don't include the size in the [] function(type array[])
let points be an array of size ten, the following is legal and computes the sum of the first five terms in points sum(points, 5)
the pointer type must match the variable type
let x be a pointer of type integer and y a variable of type double the following is illegal *x = y; I don't know how it would work if the types were reversed, would it fail or have some kind of truncation
cout << fixed << setprecision(n);
manipulator that sets the number of decimals places shown to n. applies to all subsequent values #include <iomanip>
variable names
must begin with a letter or underscore, the rest can be these characters and also numbers. Case sensitive, and can't be the same as any reserved words
can't simply assign one array to another
must use a loop to copy each position one at a time that is a[number] = b[number] is a kind of error, I wonder if it does work though, that or a[]=b[], or a=b. would those set a to the same memory location as b
use the ClassName:: prefix when defining member funtions
myclass::dothingtoobject(type name){} multiple classes or funtions may have the same "name" so long as the ClassName:: portion are different, the class:: name portion for any of them is only use d in the defintion, not the call to the function
standard header file is enclosed in <>
nonstandard header files are enclosed in ""
COmparing strings
numbers before uppercase letters before lowercase letters, otherwise the ordering is like in a dictionary
istringstream reads characters from a string
ostringstream writes charaters to a stream these have the same interface as the other stream classes including << and >> to read and write numbers contained in strings. for this reason these classes are known as adapters, they adapt strings to the stream interface these classes are found in <sstream>
stream manipulators help control how output is formated. manipulators are sent with the << operator
outfile << setfill('0') << setw(2) << hours <<":" << setw(2) << minutes <<setfill(' ');
Encapsulation
providing a public interface while hiding the implementation details
when adding an element to the middle of an vector
pushback the last element then traverse the vecor from the back towards the desired index pushing back each element along the way
UML class diagrams can be used to express that objects of one class contain objects of another class
qualitatively speaking we might say the quizzes "aggregate" questions UML shows this as a line with a diamond on the aggregating end coming out of the aggregated end
Sequential access must go through all preceding items
random access allows reading or writing to begin at any random location
string.substr(start, length)
returns length characters in string beginning with the starth character if length is not specified it returns from start to the end of the string
string.length()
returns the length of the string, the first string position is 0, and tis doens't affect the length from returning what would normally be called length
How might I code the following without the fucntionality of "new" int* count[10]; for (int i = 0; i < 10; i++) { count[i]= new int[i+1]; }
review example chapter 7 code
sentinels < numbers.txt
sentinels.cpp was the name of the program file sentinels < numbers.txt > output.txt will place the output into output.txt this was all performed from the command line
the .str function
sets the stringstream to a string to be used
setw(n)
sets width of the output to at least n characters. right justified. applies only to the next value
Examples of stream manipulators
setw sets the field with, only applies to the next item setfill changes the fill character, the default is a space left left alignment right right alignment, the default fixed see above setprecision left and right are permanent i think
Capacity is the number of values an array can hold
size is the number that are filled
header files should include all header files necessary for defining the class
so if a class uses string it should include the <string> header as well when including a header from the standard library using namespace std; what is namespace std; ?
thus far in my experience when talking about a position in a file it hasn't ever referred to bits
sometimes when cycling through objects in an array incrementing an index goes to the next object even if it is larger than a byte, here, in BMP each position is a byte
Consider different coding strategies
storing a total and a running count of how many elements contributed vs storing all the prices
string month = "March"; int day = 5; int year = 1999; ostringstream strm; strm << month << " " << day << "," << year; string output = strm.str()
string int_to_string(int number){ ostringstream strm << number; //is this a valid assignment otherwise replace line with the next two ostringstream strm; strm << number; return strm.str() }
somteims each line of a file is an individual record in can be useful in these situations to use the getline function and then parse the line for the desired infromation
string line; getline(infile, line); gets the next line from infile (without the upcoming newline character) and places it into line
a sequence of characters enclosed in double quotes is a string literal, it is an array of characters and includes a character at the end to designate termination called the zero terminator
string literals such as "pumpkin' are not actually string but instead an array of characters (I believe this functionality comes from the character class and is inherited from C into C++) the string class however knows how to interact with string literals
strm.seekg(position); moves the get position for the stream strm to position "position"
strm.seekp(position) moves the put position of the stream strm to position "position"
consts are protected from change by checking if the function about to act on them is a const
suppose a conscientious programmer declares their function as a const because it changes nothing, like in an accessor, and it calls some function that while it changes nothing, is not itself labeled as a const, the new function will not compile. If some programmers on a team are conscientious about const it is important that all be for this reason
Compile time error
syntax error detected by the compiler
delete the memory of the Stirng object on the left hand side of the assinment and allocate a new memory block to the left hand side object and fill it wirh a copy of the string on the righ hand side
teh destructor assignment operatior and copy constructor are often called the big3 operations of memory management in C++
class derivedtype : public type{ public: newmemberfunction(); private: newdatamember; }; classes have a semicolon after the closing brace
the : symbol after derivedtype denotes inheritance, public is not necessary, but without it the derivedtype will inherit privately from the type class, only the memberfuntions from the derivedtype can call member funtion from type, derivedtype objects cannot have type member funtions called on them elsewhere
the get function reads whitespace characters
the >> does not and is useful when whitespace is not desired infile >> ch; ch is set to the next non-white space character
when collecting objects of different classes you want the approptiea t member fucntion to be applied. FOr reasons of efficient this sii not the default in C++, by default quiz[i].display(); always calls Question::display() whether or not the object at that particular index belongs to a derived class of question.
the compiler must be alerted when a function call needs to call an overridden funtion of a derived class that has been passed into a pointer array of a base class the reserved word "virtual" serves this purpose
Inheritance isa realtionship between a base class, and a derived calss
the derived lcas sinherits beahvior from the base lcass
Common funtion comments include
the funtions purpose, aruments, and return /* does stuff @param @return /* this style is common in java
the constructor allocates and initialized the array String::String)const char initial_chars[]){ char_array = new char[strlen(initial_chars)+1]; strcpy(char_array, initial_chars);} the destructor is what will deallocate this memory
the name of the destructor is ~classname ~String in this example, a class can only have one destructor and it has no arguments String::~String(){ delete[] char_Array;}
function caller
the piece of code that calls a function
double cube_volume(double side_length) { double volume = side_length **3 return volume } int main() { double volume = cube_volume(2); cout << volume << endl; return 0; }
the scope of the volume variables does not overlap
cout
the standard output stream object in C++; used with the insertion operator to display information on the computer screen
reading or writing modifies a stream variable, they keep track of the number of characters read or written
therefore stream parameter variables should always be reference parameters this kind of makes sense ot me in the case of reading but not so much for the case of writing
C++ allows for the creation of new classes of objects
these have a public interface though which the programmer using the class can interact with the class, and also private functions and data members accessible in the class implementation for use in the code of the public interface
when a program ends all opened streams are automatically closed
they can be manually closed with .close()
numbers and poiners are not classes and therefore have no constructors
they will have random values if values are not specified wehn they are first declared
There is no universal convention for the width of a tab character
this can lead to issues ruing programs written in a different editor. Some editors automativaky convert to tab characters to spaces, using spaces instead of tabs can help avoid this
Some programmers set the result of a function by passing passing a parameter by reference
this function won't be able to set that parameter as the result as an assignment expression
to a compiler the following are equivalent double sum(double* a) double sum(double a[])
this is an exampole of syntactic sugar denotes notarion that is easy to read that glosses over the complexity of the impolementation. here it gives teh illisuion that an entire array is passed when in reality the function only receives a starting address values[1] is syntactic sugar for *(values + 1), note this is not 1 greater than the location of "values" but however many bytes in the data type greater &values[3] is legal
some programmers build inheritance hierarchies where each object ahs a tag (data member i assume) that indicates its type, they then do a bunch of if else statemnets to pick the write code
this is more tediuos than virtual funcitons and the book points this out for some reason
the fixed format prints all numbers with an equal number of digits after the decimal point
this will override scientific notation defaults to 6 digits post decimal i think
What does the following mean
to build the complet proram you need to compile both the registertest2.cpp and cashregister.cpp soruce files. with a gnu compiler for example this is done with the following command g++ -o registertest registertest2.cpp cashregister.cpp what does it mean i have to compile them both to form the complete program doesn't one include the other because it needs it, i thought the compiler could make that work, and if they don't need eachother what does the book mean by the complete program
to open a file for writign use an ofstream
to open a file for reading and writing use an fstream istream for reading all these object types can be found in <fstream>
to open a file it must be a string literal
to pass the contents of a string variable to be opened it must first be turned into a c string, the c_str function will accomplish this fstream infile; string filename; infile.open(filename.c_str);
to read form a file stream it must first be opened
to read data from a file readme.dat located in the same directory as my program does in_file.open("readme.dat"); work what kind of object does in_file need to be
Instead of storing a value in a variable it is often possible
to return a more complicated expression
Question* quiz[2]; quiz[0] = new question; quiz[0] -> set_text("who was the inventor of C+"); quiz[0]->set_answer("Bjarne Stroustrup"); ChoiceQuestion* cq_pointer = new ChoiceQuestion; cq_pointer->set_text("In which country was the inventor of C++ born"); cq_pointer->add_choice("Australia",false); ... quiz[1] = cq_pointer;
to set up an array of pointers difine it to hold pointers and allocate all objects with the new reserved word, and use the -> operator what's the point of new in quiz[0] = new question isn't it already assumed to be a question pointer, what happens if i omit this line
use the >> operator to send strings and numbers to a stream
to write a single chaarcter to a stream use outfile.put(ch)
-10 && 10 >= 0
true
o<humidity<50
true the first staement is either ture or false and equals 1 or 0 respectivley, both are less than 50
allocating a new of something can also take arguments new type(arg); typically we will want to store this location in a pointer
type* mypointer = new type(arg); could I say new type* mypointer = new type(arg) so I could delete the memeory later if i wanted
A variable is defined
until the end of the block where it was defined. This is its scope
struct StreetAddress { int house_number; string street_name; }; note the semicolon at the end
use .notation to access a single memeber of the structure, members are the things on the left, the peices of data which comprise the structure, the two named parts house_number and street_name in this case. For example StreetAddress myhouse; myhouse.street_name();
arrays of objects are subject to this slicing problem, it can be gotten around by
using an array of pointers
The compiler ignores indentation and matches an else to the preceding (unmatched I think) if
using braces helps make clear what is matched to what
overloading
using the same name for multiple functions, this works so long as their parameter variables are different. This works in general not just for constructors. double calculate(int number) double calculate(double number) calculate(x); the compiler checks x variable type and matches it to the appropriate calucalte funtion in genereal overloading is avoidable by using unique names, but not with constructors, they must have the same names
compiler compiles statements in order
variable must be declared before used
How to declare a variable
variable_type variable_name; can but doesn't need to be initialized when declared. type name = value;
vectors can be assigned to eachother
vector<double> vectora; vector<double> vectorb; vectora = vectorb
in a member fucntion "this" is a pointer to the implicit parameter that can be used in the defintion of a member fucniton
void CashRegister:: add_item(double price){ this->item_count++; this->total_price= this->total_price + price; } aside form being convenient some programmers think this helps make clear that item_count for example is a data meber and not a variabel how were we altering data members before, is "this->" even necessary here i dont hitnk it is. i think this is the answere to the preference question i just asked
void append_inputs(double inputs[], int capacity, int size) { while (size<capacity) { cin>>inputs[size]; size++; } Is this the same as
void append input(double inputs[], int capacity, int size){ double input while (cin >> input) { if (size < capacity){ inputs[size]=input; size++;}}}
suppose we wish to pass a derived class into a fucntion in place of a base class, we can write the function to take baseclass& that is take the baseclass object by reference, and because taking something by reference is actually a pointer the slicing problem is aoided and virtual functions work corectly
void fucntion(const baseclass& name)
error messages are fatal
warnings are advisory and the program will sitll run. perhaps not as intedned
suppose we wish to make a caesar cipher called caesar and that encrypts by default and decrypts when indicated we might call caesar (-d) input.txt encryted.txt
we might use the folowing helper funtion void encrypt(char& ch, int cyphersize){ ch=ch+cyphersize; } void encrypt(ifstream& in, ofstream& out, int cyphersize){ char ch; while (in.get(ch)){ out.put(ch+cyphersize); } }
when initializing an array its size "must be known"
when a given function takes an array as a parameter the dimension of its row need not be defined but the rest of its dimensions do.
void CashRegister:: add_item(double price){ item_count++; total_price=total_price+price; }
when a member function's definition calls another member function do not use .notation like would occur outside the class defintion, just call the function, the compiler assumes the called function is acting on the implicit parameter void CashRegister::add_items(int quantity, double price){ for (int i=1; i<= quantity; i++) { add_item(price);}} can add multiple instacnes of the same item and uses the previously defined function
Memory exhaustion will cause the program to crash
when a program exits, al allocaed memory is reutned to te operating sstem
double values[10]; suppose values stores location 1000 the second element will begin at location 1008 because doubles take 8 bytes and the whole array will take up memory location 1000 through 1079
when passing an array to a function only the starting address is passed
StreetAddress* address_pointer = new StreetAddress; *address_pointer.house_number =1600; the second line is a syntax error because the dot operator takes precedence over the * operator the compiler sees this as*(address_pointer.house_number)=1600; or set the value of whatever is stored at the location of the memory address denoted by the house_number of address_pointer to 1600 which likely deosn't work as the house number is an int not a memory address
which is different from (*address_pointer).house_number =1600; set the house number member of the structure located at address pointer to 1600
the following loop can be useful in a file where each line is its own record
while (getline(infile, line)){ process line } getline also returns the not failed condition
A loop and a half is hen the test for termination is in the middle of the loop
while (true) { cin >> value; if (cin.fail)) {break;} more statmentes } as opposed to while (go) { cin >> value; if (cin.fail)) { more = false; } else }
by convention class names are
written in camel case
can a base class member fucniton be used to define is override or another funtion in a deived class
yes BaseClass::BaseClassFunction(args);
3=6/2
yields an error 3 cannot be assigned the value 6
"10" > 5
yields an error, comparing a strig to an itneger yileds an eror
&& the and operator is true if both the staements around it are true
|| the or operator is true if a t least one of the 2 statemnets around it is true