Skip to content

Instantly share code, notes, and snippets.

@jdliss
Last active June 30, 2016 17:42
Show Gist options
  • Save jdliss/c40bfa5fcf281ad1aa42a2024d1e22dc to your computer and use it in GitHub Desktop.
Save jdliss/c40bfa5fcf281ad1aa42a2024d1e22dc to your computer and use it in GitHub Desktop.

Q: What is C/C++ used for? A: Everything

Ruby vs C/C++

Ruby is interpreted, whereas C++ is compiled.

An interpreted language works like this:

  • The high level language code is processed and translated into a low level language then gets executed.

  • It does this on the fly, as the code is run, one line at a time.

    LINE 1 (Translate->Run)

    LINE 2 (Translate->Run)

    LINE 3 (Translate->Run)

A compiled language works like this:

  • the whole program is translated into machine code
  • the machine code is executed

Interpreted languages:

  • little time spent analyzing the code initially.
  • but this means overall program execution is much slower as all the analysis is done on the fly

Compiled languages:

  • large initial analysis
  • the resulting machine code executes very fast

C and C++

C++ was built on top of C, and is meant to be Object Oriented C, as C is not.

Created by Bjarne Stroustrup

It was originally called "C with Classes", but was shortened to "C++", named after the ++ operator, which increments a number by 1. So it's basically named "D" since C + 1 is D.

"I don't care about any of this... Let's write some code!"

Setup

  • If you have a mac you're all good.

  • File extension is .cpp for implementations, .h is for header files which contain class and function declarations

  • Write some code in a .cpp file and compile it using the terminal: g++ file.cpp

    • If you want to use the latest version of the C++ compiler instead of the 1998 GNU version, use g++ -std=c++14 file.cpp. Make an alias for that in your bash profile for ease of use. It's not necessary for what we'll be doing though.

Syntax

  • Lines end with ;

  • Functions longer than 1 line require curly braces surrounding the body of the function.

Header files and namespacing

  • #include <standard_library_file> This is like using Ruby's require method.

  • #include "file.h" This is like using Ruby's require_relative for a header file you created within the project.

  • Header files are included at the top of your files. Beware of circular inclusions. If you include a file that has #include <vector> in it, you don't need to #include <vector> in any of the files above it.

  • In order to use any of the "standard" methods or classes, you need to either namespace them like std::cout;, or declare using namespace std; at the top of the file. Then you are free to use any of the methods in the standard library without specifying a namespace. A third option is to declare using std::cout; at the top and then use cout without specifying a namespace each time.

Variables

  • Variables are camel case starting with the second word. example: int myAge = 21;

  • Variables must always be declared with a data type.

  • Variables may not change data type

Functions

  • Function names are camel case starting with the second word. example: setAllValues();

  • Functions with no input still must use empty parentheses when called

  • Like variables, they must be declared with a specific return type. If there is a return type, it should always return something of that type. If you do not return anything when there is a return type, you run into the realm of undefined behavior

  • Functions that return nothing have a return type of void

  • Must be declared with a specific input type, or no input. In C, no input would be specified as a void input type. But this is not necessary in C++. You may see this from time to time from people who wrote in C first, or who write in both languages.

  • C++ uses explicit returns only, so if you want to return anything from a function you must use return

  • A function that does not return anything has a return type of void.

Classes

  • Class names are camel case starting at the first word. example: class CarWheel

  • Constructors are like the initialize method. They dictate what happens on instantiation of the class.

  • Destructors dictate what happens on the on "destruction" of the object. There is no need to override the default destructor unless you have specific garbage collecting you want to do.

  • You can declare a prototype of a function inside a class and implement it outside of the class using namespacing. I think this is pretty standard in C++. Even if it's not, you will see it a lot.

  • Static functions and variables are like self methods in ruby. They are accessible through the class without having to instantiate an object first.

  • There is an object pointer (like self in ruby) called this.

I/O

  • cout << "some text" << endl; prints "some text" to the terminal with an endline character.

  • You can combine text and variables/calculations strung together with the << operator. cout << "Five + two = " << 5 + 2 << endl; will print five + two = 7

  • cin >> variable; gets a single word of user input and stores it in the variable.

  • getline(cin, variable); grabs a whole line of use input and stores it in a variable.

  • File I/O is a little more complicated. It makes use of streams. Streams are abstract contstructs which use buffers to send and receive unknown sizes of information as they come or go. Explore fstream if you're curious.

Conditionals

  • if, else if, else. Brackets used when the body of the conditional is longer than one line

  • switch statements:

    int num = 2;
    switch(num) {
    case 1:
      cout << "value was 1" << endl;
      break;
    case 2:
      cout << "value was 2" << endl;
      break;
    default:
      cout << "value was neither 1 or 2" << endl;
    }

Arrays and vectors

  • Arrays must be declared with a type and a length, or if no length, and initial list.. int numArray[5] = { 1, 2, 3, 4, 5 }; or int numArray[] = { 1, 2, 3, 4, 5 };

  • If you give a length you don't have to provide a list of values on initialization.

int numArray[5];
numArray[0] = 1;
numArray[1] = 2;
numArray[2] = 3;
numArray[3] = 4;
numArray[4] = 5;
  • Array sizes are locked at runtime, so dynamically adding things to arrays is not a great idea. There is no boundary checking in C++, so you can run off the edge of the array quite easily and without warning. This results in undefined behavior and is impossible to predict. Don't do go into the realm of undefined behavior. Ever.

  • Vectors are great. They are basically arrays that can do their own dynamic memory allocation at runtime, and as such, do not need to be specified with a size (you can if you want, though). You can use the vector.push_back(variable) method to append a new variable to the vector, even if the vector is full.

  • Vector declaration syntax is like this: vector<int> name;

Pointers

  • There are two types of memory. The stack and the heap. The stack is allocated and used before runtime, and the heap is used during runtime. The stack effectively becomes "locked" in place during runtime, (that's why you can't add more space to arrays. You're stuck with the size you initialize them with) and any memory allocations you make are also locked in place. The heap is memory that remains unlocked at runtime, but the only way to access it is through pointers. If you want to add dynamically create an array based on user input you have to use a pointer and allocate memory from the heap because array sizes must be a constant, not a variable.

  • Pointers contain memory addresses, and are how you access heap memory.

  • Pointers contain a hex number that is an address in memory. (This is one of the reasons C++ is considered a "dangerous" language by some people; You have direct read/write access to memory.) You can dereference a pointer to get the value that it's pointing to using the * operator.

  • Pointers are one of the reason that you can make very efficient programs. Imagine you have a method that takes and array and does some things to it. That can be very inefficient if you pass in an array that contains a million items. However, using pointers it becomes lightning quick. You can create a pointer that points to the first spot in the array, and pass that in. That means instead of passing around a giant array, you're passing around a small hex number. And since array's are contiguous in memory, we can use something called pointer arithmetic to traverse the array. Pointer arithmetic is basically just using the ++ operator to add one to the pointer (which is just a hex number), to move to the next index in the array, until we reach the end.

Execution

  • Everything starts in the main function. There must always be a main. You can get around using it, but it must be there, and acts as the starting point of the application from which you make all your calls.

  • Similarly, projects are usually tied together with a runner file called main.cpp.

  • To compile, run g++ file_name.cpp. The program will be compiled, an an executable file (default is a.out I think) will be created. To execute the program run ./a.out

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment