# -*- mode: org -*-

#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="../../css/style.css" />
#+LATEX_HEADER: \hypersetup{colorlinks=true,linkcolor=blue}
#+LATEX_HEADER: \usepackage[left=2cm,top=2cm,right=2cm,bottom=2cm,bindingoffset=0.5cm]{geometry}

#+ATTR_HTML: :class subheader
*C++ basics*

- Starter C++ program:
  #+BEGIN_SRC cpp :class cpp
    // WITHOUT ARGUMENTS     // WITH ARGUMENTS
    int main()               int main( int argCount, char* args[] )
    {                        {
      return 0;                return 0;
    }                        }
  #+END_SRC

- Declare a variable: =DATATYPE VARIABLENAME;=
  #+BEGIN_SRC cpp :class cpp
  int myNumber;      string myString;      float myFloat;
  #+END_SRC

- Declare a variable and initialize it: =DATATYPE VAR = VALUE;=
  #+BEGIN_SRC cpp :class cpp
  int myNumber = 10;   string myString = "Hello!";    float myFloat = 9.99;
  char myChar = 'a';   bool myBool = true;
  #+END_SRC

- Declare a named constant: =const DATATYPE NAME = VALUE;=
  #+BEGIN_SRC cpp :class cpp
  const int NUMBER = 10;      const string STATE = "Missouri";
  #+END_SRC

- Assign a value to a variable that has already been declared: =VAR = VALUE;=
  #+BEGIN_SRC cpp :class cpp
  myNumber = 100;             myString = "Goodbye";
  #+END_SRC

- Copy a value from one variable to another: =RECEIVER = COPYME;=
  #+BEGIN_SRC cpp :class cpp
  vipStudent = student3;
  #+END_SRC

- Output text to the console: =cout << ITEM << ITEM << endl;=
  - You can mix variables (=VAR=) and string literals (="HI"=), as long as the stream operator =<<= is between each item.

- Get input from the keyboard and store it in a variable: =cin >> VAR;=

- Get a full line of text and store in a string: =getline( cin, VAR );=
  - Only works with *string variables*.
  - Note that if you have a =cin >>= statement immediately before the getline statement, your input will get skipped.
    In this case you need to add a =cin.ignore()= statement:
  #+BEGIN_SRC cpp :class cpp
    cin >> myNumber;
    cin.ignore();
    getline( cin, myString );
  #+END_SRC

--------------------------------------------------------------------------------

#+ATTR_HTML: :class subheader
*Branching*

- If statements:
  #+BEGIN_SRC cpp :class cpp

    // IF STATEMENT                   // IF/ELSE STATEMENT
    if ( a == 1 )                     if ( a == 1 )
    {                                 {
      // Executes when a == 1           // Executes when a == 1
    }                                 }
                                      else
                                      {
                                        // Executes when a != 1
                                      }



    // IF/ELSE IF STATEMENT           // IF/ELSE IF/ELSE STATEMENT
    if ( a == 1 )                     if ( a == 1 )
    {                                 {
        // Executes when a == 1         // Executes when a == 1
    }                                 }
    else if ( a == 2 )                else if ( a == 2 )
    {                                 {
        // Executes when a != 1         // Executes when a != 1
        // and a == 2                   // and a == 2
    }                                 }
                                      else
                                      {
                                        // Executes when a != 1
                                        // and a != 2
                                      }
  #+END_SRC
  - *If:* If the condition evaluates to true, then execute the code within the if statement. Otherwise, skip that code completely.
  - *If/else:* If the condition from if statement results to false, then the code in the else case is executed instead. No condition is written with the else case.
  - *If/else if statement:* Checks each condition in order. If one is true, then subsequent =else if= statements are ignored.
  - *If/else if/else statement:* Similar to above, but if all =if= and =else if= statements are false, then =else= is executed.

--------------------------------------------------------------------------------

#+ATTR_HTML: :class subheader
*Switch statements*

- Switch statement: =switch( VARIABLE ) { case VALUE: break; }=
  - The switch variable can be int, char, but not string.
  #+BEGIN_SRC cpp :class cpp
  switch( myNumber )
  {
    case 1:  cout << "It's one!" << endl; break;
    case 2:  cout << "It's two!" << endl; break;
    default: cout << "I don't know what it is!" << endl;
  }
  #+END_SRC

--------------------------------------------------------------------------------

#+ATTR_HTML: :class subheader
*Looping*

- Conditional loops:
  #+BEGIN_SRC cpp :class cpp
    // WHILE LOOP                   // DO...WHILE LOOP
    while ( a < b )                 do
    {                               {
      cout << a << endl;              cout << "Enter a number: ";
      a++;                            cin >> input;
    }                               } while ( input < 0 || input > max );
  #+END_SRC
  - Looping with While Loops: =while ( CONDITION ) { }=
    - Runs 0 or more times, depending on whether the CONDITION is true.
  - Looping with Do...While Loops: =do { } while ( CONDITION );=
    - Runs /at least once/ and then continues looping if the condition is true.

- For loops:
  #+BEGIN_SRC cpp :class cpp
    // TRADITIONAL FOR LOOP                // RANGE-BASED FOR LOOP
    for ( int i = 0; i < 10; i++ )         vector<int> myVec = { 1, 2, 3, 4 };
    {                                      for ( int element : myVec )
      cout << i << endl;                   {
    }                                        cout << element << endl;
                                           }

  #+END_SRC

  - Traditional for loops: =for ( INIT; CONDITION; UPDATE ) { }=
    - Iterate some amount of times through the loop based on your counter variable and range.
  - Range-based for loops: =for ( INIT : RANGE ) { }=
    - Iterates over all elements in a collection. Only moves forward, doesn't give access to index

--------------------------------------------------------------------------------

#+ATTR_HTML: :class subheader
*Arrays*

- Declare a traditional C-style array: =DATA_TYPE ARRAY_NAME[SIZE];=
  - When declaring a vanilla array, you need to set its size. You can either hard-code the size with a number or use a named constant.

- Declare an STL array object: =array<DATA_TYPE, SIZE> ARRAY_NAME;=
  - Remember that you will need =#include <array>= at the top of your file to use the array object.
  - Use the array documentation (https://cplusplus.com/reference/array/array/) for info on its functions.

- Declare an STL vector object: =vector<DATA_TYPE> VECTOR_NAME;=
  - Use the vector documentation (https://cplusplus.com/reference/vector/) for info on its functions.

- Initialize array/vector with an initializer list:
  #+BEGIN_SRC cpp :class cpp
  vector<string> cats3 = { "Kabe", "Luna", "Pixel", "Korra" };
  #+END_SRC

- Iterate over an array/vector:
  #+BEGIN_SRC cpp :class cpp
  // STL Array and STL Vector:
  for ( size_t i = 0; i < bankBalances.size(); i++ )
  {
    cout << "index: " << i << ", value: " << students[i] << endl;
  }
  #+END_SRC
  - =size_t= is another name for an =unsigned int=, which allows values of 0 and above - no negatives.

--------------------------------------------------------------------------------

#+ATTR_HTML: :class subheader
*File input and output*

- Reading and writing with ifstream and ofstream:
  #+BEGIN_SRC cpp :class cpp
    // WRITE OUT TO A TEXT FILE        // READ IN FROM A TEXT FILE
    ofstream output;                   ifstream input;
    output.open( "file.txt" );         input.open( "file.txt" );
                                       if ( input.fail() )
    // Write to text file              {
    output << "Hello, world!";           cout << "ERROR!" << endl;
                                       }
                                       string buffer;

                                       // read a word
                                       input >> buffer;

                                       // read a line
                                       getline( input, buffer );

  #+END_SRC
- Create an output file and write with =ofstream= (output file stream)
- Create an input file and read with =ifstream= (input file stream)
  - =INFILE >> VAR;= to read one word at a time
  - =getline( INFILE, VAR );= to read one line at a time
- Make sure to have =#include <fstream>= in any files using =ifstream= or =ofstream=!



- Prevent file duplication with *File Guards*: When creating .h/.hpp files, it is important to include these lines to prevent file duplication, which happens if you #include this file in more than one place.
  #+BEGIN_SRC cpp :class cpp
  #ifndef _FILENAME_H // LABEL SHOULD BE UNIQUE FOR EACH .h FILE!
  #define _FILENAME_H

  // Code goes here

  #endif
  #+END_SRC

- Function declaration: A function declaration contains the function header and no body. It declares that the function exists and will be defined elseware.
  #+BEGIN_SRC cpp :class cpp
    // NO output return          // int output return
    // NO input parameters       // two int input parameters
    void DisplayMenu();          int Sum(int a, int b);
  #+END_SRC

- Function definition: A function definition defines how the function operates. It includes the function header and a function body, which has commands in it.
  #+BEGIN_SRC cpp :class cpp
  void DisplayMenu()                      int Sum(int a, int b)
  {                                       {
    cout << "1. Deposit" << endl;           return a + b;
    cout << "2. Withdraw" << endl;        }
    cout << "3. Quit" << endl;
  }
  #+END_SRC

- Calling a function: Calling a function requires invoking the function's name and passing in any arguments.
  #+BEGIN_SRC cpp :class cpp
  DisplayMenu();

  int result = Sum( 1, 2 ); // Passing in literal values

  int num1 = 2;
  int num2 = 5;
  int result = Sum( num1, num2 ); // Passing in variable values
  #+END_SRC

--------------------------------------------------------------------------------

#+ATTR_HTML: :class subheader
*Classes*

- Declaring a class: Remember that classes must end with =;= on their closing curly brace!
  #+BEGIN_SRC cpp :class cpp
    // EXAMPLE              // STUDENT CLASS
    class CLASSNAME         class Student
    {                       {
        public:             public:
                              // Constructor functions
                              Student();
        protected:            Student( string new_name, float new_gpa );

                              // Member functions
        private:              void Setup( string new_name, float new_gpa );
                              void Display();
    };
                            private:
                              // Member variables
                              string name;
                              float gpa;
                            };
#+END_SRC

- Defining a class member function (method): =RETURNTYPE CLASSNAME::FUNCTIONNAME( PARAMETERS )=
  - A class' member functions must be *declared* within the class declaration. Then, you *define* the member function within a .cpp file.
  #+BEGIN_SRC cpp :class cpp
  // Function definition
  void Student::Setup( string name, float gpa )
  {
    m_name = name;
    m_gpa = gpa;
  }
  #+END_SRC

# -------------------------------------------------------------------------------------------------- # --------------------------------------------------------------------------------------------------

# - Getter and Setter patterns: It is best practice to make member variables *private* to protect the integrity of the data. Private members cannot be accessed outside of the function, so instead you'll have to create interfacing functions to access (get) and mutate (set) data.

- Getter function, aka Accessor:
  - Doesn't take in any inputs (parameters)
  - Returns the value of the member variable (return type should match the member variable)
  - Getter functions can be good for formatting data before returning it

#+BEGIN_SRC cpp :class cpp
  // Basic getter function     // Example of formatting before returning data
  float Student::GetGPA()      string Person::GetFullName()
  {                            {
    return m_gpa;                return m_lastname + ", " + m_firstname;
  }                            }
#+END_SRC

- Setter function, aka Mutator:
  - Takes in an input value for a new value for the member variable - parameter should have the same data type as the member variable
  - Doesn't return any data - void return type
  - Setter functions should include any needed error checking and reject invalid data

#+BEGIN_SRC cpp :class cpp
  // Basic setter function                // Example of data validity check
  void Student::SetGPA( float newGpa )    void Student::SetGPA( float newGpa )
  {                                       {
    m_gpa = newGpa;                         if ( newGpa < 0 || newGpa > 4 )
  }                                         {
                                              cout << "Error! Invalid GPA!" << endl;
                                              return; // Return without saving data
                                            }
                                            else
                                            {
                                              m_gpa = newGpa;
                                            }
                                          }
#+END_SRC

--------------------------------------------------------------------------------

#+ATTR_HTML: :class subheader
*Pointers*

- Declare a pointer: =DATATYPE* PTRNAME = nullptr;=
- Assign an address to a pointer: =PTRNAME = &VARIABLE;=
  - Pointer variables store addresses as their value. To get the address of a variable, prefix the variable name with the address-of operator =&=.
- Dereference a pointer: =*PTRNAME=
- Dereference an object pointer and access a member variable: =PTRNAME->MEMBER=

#+BEGIN_SRC cpp :class cpp
  // DECLARING POINTERS
  int * ptrInt = nullptr;
  string * ptrString = nullptr;


  // SETTING POINTERS TO ADDRESSES
  string name = "Bob";      // Normal variable
  string * ptrName = &name; // Pointer


  // DEREFERENCING POINTERS
  cout << *ptrName; // Display contents that pointer is pointing to
  cin >> *ptrName; // Overwrite contents that pointer is pointing to


  // POINTERS TO OBJECTS
  Student* newStudent = new Student;
  newStudent->name = "Hikaru";
  cout << "Student name: " << newStudent->name << endl;

  // CHECKING IF POINTER IS SAFE
  if ( ptrName != nullptr )
  {
    // Pointer is safe to use...
  }
#+END_SRC


- Allocate memory for a single variable: =DATATYPE* PTRNAME = NEW DATATYPE;=
- Deallocate memory of a single variable: =DELETE PTRNAME;=
- Allocate memory for an array: =DATATYPE* PTRNAME = new DATATYPE[ SIZE ];=
- Deallocate memory of an array: =DELETE [] PTRNAME;=


#+BEGIN_SRC cpp :class cpp
    // ALLOCATE MEMORY                        // DEALLOCATE MEMORY
    // FOR A SINGLE VARIABLE                  // FOR A SINGLE VARIABLE
    int * num = new int;                      delete num;
    Node* newNode = new Node;                 delete newNode;


    // ALLOCATE SPACE FOR AN ARRAY            // DEALLOCATE SPACE FOR AN ARRAY
    int * numList = new int[100];             delete [] numList;
    Node* nodeList = new Node[10];            delete [] nodeList;
#+END_SRC
