CompileArtisan

Learning C++

Table of Contents

1. Boilerplate

  • To compile: g++ filename.cpp
  • To run: ./a.out

1.1. Streams

#include <iostream>   // Like "import" — brings in the standard I/O library

int main() {          
    std::cout << "Hello, World!"; 
    std::cout << "should come on same line" << std::endl;  
    std::cout << "should come on new line" << ", because of 'std::endl'" << 5 << false; 
    return 0;        
}
Hello, World!should come on same line
should come on new line, because of 'std::endl'50
  • A stream is an abstraction of a sequence of bytes, that represents the flow of that data from one place to another.
  • Streams are useful because the lack of it would mean you’d have to load all of the data completely into memory. In case of streams, you can transfer data in small and manageable chunks. When such a small and manageable chunk of memory is stored, we say they’re stored in a buffer.
  • << is actually the bitwise left shift operator, but it’s been overloaded. Here’s what it does with the operands:
    • The operand on the left is a std:ostream& object reference (a stream object)
    • The operand on the right is any data that should be written to the stream.
    • \(operand\) << \(operand\), as an operator is overwritten like this:

      operator<<(std::cout, "Hello");
      

      And it returns the current stream object

      std::ostream& operator<<(std::ostream& stream, const std::string& data) {
          // ... internal code that writes data into the stream ...
          return stream;   // and it returns the stream containing the data
      }
      
    • This is why you’re able to chain these commands:

      std::cout << "A" << "B" << "C";
      

      It evaluates from left to right. std::cout << "A" runs and this returns a stream object, then the next one return a stream object, and so on.

  • std::cout is a stream object and cout stands for character output (the terminal/screen).

1.2. Namespaces

  • A namespace is container for names (variables, functions, objects) to avoid conflicts.

    #include <iostream>
    
    namespace myStuff {
      int count = 5;
    }
    namespace yourStuff {
      int count = 10;
    }
    
    int main() {
      std::cout << myStuff::count << std::endl;
      std::cout << yourStuff::count << std::endl;
      return 0;
    }
    
      5
      10
    
  • The namespaces here are myStuff, yourStuff (and std too!).
  • myStuff::count means asks the compiler to use count from myStuff. If you want the compiler to always look inside myStuff whenever count is referenced, you can make the program use the namespace myStuff.

    #include <iostream>
    
    namespace myStuff {
      int count = 5;
    }
    
    int main() {
      using namespace myStuff;
      std::cout << count;  
      return 0;
    }
    
    
      5
    
  • This means you can also make it use the namespace std too:

    #include <iostream>
    
    namespace myStuff {
      int count = 5;
    }
    
    int main() {
      using namespace myStuff;
      using namespace std;
      cout << count;  
      return 0;
    }
    
    
      5
    

1.3. Input

#include <iostream>
#include <string>
using namespace std;

int main() {
  cout << "enter your name: ";
  string name;
  cin >> name;
  cout << endl << name << endl;
  return 0;
}
enter your name: 

  • cin is short for console input, and it reads data from the input buffer.
  • cin >> name stops at the first white space.
  • To stop at a newline character, you use getline(cin, name) (where name is a string variable).
    • One thing to note is that if you use cin first, and then you use getline, the input isn’t read because the \n from the previous input gets consumed.
    • The fix for this is to clear that one character by using cin.ignore():

      cin.ignore();
      getline(cin, name);
      
  • You can also chain inputs:

    #include <iostream>
    #include <string>
    using namespace std;
    
    int main(){
      int x, y;
      cin >> x >> y; // takes two inputs, one after the other
      cout << x << " " << y;
      return 0;
    }
    
    
      1332849520 32767
    

1.4. Headers

  • In competitive programming, people often use this GCC specific header:

    #include <bits/stdc++.h>
    

    This includes every standard library header at once (vectors, math, strings, etc.), and is used in competitive programming for speed of writing, and not in production code.

2. Pointers

2.1. Basics

#include <iostream>
using namespace std;

int main(){
  int x = 10;
  int* p = &x;
  
  cout << p << endl;
  cout << *p << endl;
  return 0;
}

0x7fff0905a81c
10

2.2. Arrays

#include <iostream>
using namespace std;

int main(){
  int arr[] = {10, 20, 30}; // arr is nothing but a pointer
  for(int i=0 ; i<size(arr) ; i++)
    cout << *(arr+i) << endl;
  return 0;
}

10
20
30

2.3. Pass by reference

  • When you pass a variable to a function, you can pass by value or pass by reference.
  • Pass by value (the function gets a copy of the variable, and any action you do doesn’t affected the original variable) happens all the time, until you pass a reference to the variable (if you do this, the original variable is modified).

    #include <iostream>
    using namespace std;
    
    void incrementor(int* x){ // function takes a pointer
      (*x)++;                 // pointer is dereferenced and used
    }
    
    int main(){
      int a = 4;
      incrementor(&a); // you're passing the address of 'a'
      cout << a;
      return 0;
    }
    
    
    
    
      5
    

    A pointer is a variable that stores a memory address. In C++, a reference is a variable that