3  Course Introduction and the Development Environment

4 Course Introduction and the Development Environment

Week 1, Session 1. CSS 342.

4.1 Warmup

There is no warmup for the first lecture. The warmup ritual starts in Chapter 2. Take the first ten minutes to look around — make sure your laptop has a working C++ compiler, you can clone a repository from GitHub, and you can run a program from the command line. That is the actual goal of this lecture.

If you want a problem to gnaw on while we do logistics, here is the canonical first one. It is short, easy, and surprisingly useful for getting your environment working: solve Two Sum (LeetCode #1) on paper. Do not type it yet. We will type it together in Chapter 2.

4.2 Learning objectives

By the end of this chapter you will be able to:

  1. Set up and navigate a modern C++ IDE on your own machine.
  2. Compile and run a C++ program from the command line using g++ or clang++.
  3. Explain the role of .h versus .cpp files and why the separation exists.
  4. Clone a GitHub repository, make a commit, and push the change.
  5. Write a simple C++ program using fundamental data types and a loop.

4.3 The five things you will type a thousand times

g++ -Wall -Wextra -std=c++17 main.cpp -o main
./main
git add .
git commit -m "..."
git push

If you only remember one thing from week 1, remember those five commands. They are the entire dev cycle. Everything else in this chapter is decoration.

4.4 Hello, World

// main.cpp
#include <iostream>
using namespace std;

int main() {
  cout << "Hello, World" << endl;
  return 0;
}

Compile it:

g++ -Wall -std=c++17 main.cpp -o hello
./hello

Output:

Hello, World

I write using namespace std; in everything in this book. It is bad practice in headers. It is fine in main.cpp files of a teaching textbook. You will be told by some people on the internet that this is The Worst. Those people are usually correct in production code and wrong in classroom code. We will revisit this in Chapter 5.

4.5 What -Wall actually does

-Wall enables most useful compiler warnings. -Wextra enables more. There is no -Wall -Wsane -Wdefault flag because the C++ committee enjoys watching you suffer. Use both:

g++ -Wall -Wextra -std=c++17 main.cpp -o main

If the compiler complains, fix it before running. Warnings become bugs faster than you would think.

4.6 Header files and implementation files

A C++ class lives in two files. One declares what it is, the other says what it does.

greeter.h — the declaration. Goes in the header file. Other files include this.

// greeter.h
#ifndef GREETER_H
#define GREETER_H

#include <string>

class Greeter {
public:
  Greeter(const std::string& name);
  void sayHello() const;

private:
  std::string name_;
};

#endif

greeter.cpp — the definition. Goes in the implementation file. Compiled separately.

// greeter.cpp
#include "greeter.h"
#include <iostream>

Greeter::Greeter(const std::string& name) : name_(name) {}

void Greeter::sayHello() const {
  std::cout << "Hello, " << name_ << "!\n";
}

main.cpp — the user.

// main.cpp
#include "greeter.h"

int main() {
  Greeter g("World");
  g.sayHello();
  return 0;
}

Compile both translation units together:

g++ -Wall -std=c++17 main.cpp greeter.cpp -o hello
./hello

Why bother with the split? Two reasons. First, when greeter.cpp changes you do not have to recompile main.cpp. For one file you do not care. For a hundred files you care a lot. Second, the .h file is the public interface — it is the contract between the writer and the user. The .cpp file is the implementation. Other people read your .h to learn how to use your class. They do not read your .cpp unless they have to. Write your headers like documentation, because that is what they are.

4.6.1 The include guard

Those three lines #ifndef GREETER_H / #define GREETER_H / #endif are an include guard. They prevent the same header from being parsed twice in one compilation unit, which would cause a “redefinition” error. There is also #pragma once which does the same thing in one line and is supported by every modern compiler:

#pragma once

I use #pragma once in my own code. The textbook uses #ifndef guards. They both work. Pick one and be consistent.

4.7 Git and GitHub

Almost everything you submit this quarter goes through GitHub. The minimum sequence:

# One-time setup: clone the starter repo
git clone https://github.com/pisan342/css342-starter.git
cd css342-starter

# Every time you change something
git add main.cpp
git commit -m "wrote hello world"
git push

A few things students get wrong:

  • Forgetting to git add the file before committing. Commit will succeed but with nothing in it.
  • Committing without a useful message. "updated" and "fix" are not useful. "fix off-by-one in middleNode" is useful.
  • Pushing to the wrong branch. If git push says “everything up-to-date” but the grader cannot see your code, you pushed to a branch nobody is looking at.

4.8 Fundamental types — quick review

You should already know these. I am writing them down so you have one consolidated cheat sheet.

Type Size (typical) What it holds
int 32 bits Integer up to ±2 billion
long long 64 bits Integer up to ±9 quintillion
double 64 bits Floating point, ~15 decimal digits
char 8 bits Single ASCII character
bool 8 bits true or false
std::string varies Sequence of char, dynamically sized

When in doubt, use int. When you suspect overflow, use long long. Avoid unsigned types in 342 unless you have a reason — they cause subtle bugs when subtracted.

4.9 A loop

#include <iostream>
using namespace std;

int main() {
  for (int i = 1; i <= 10; ++i) {
    cout << i << " ";
  }
  cout << endl;
  return 0;
}

Three things to notice. First, ++i not i++. They produce the same result in a for loop but ++i is the habit you want. Second, the loop runs from 1 to 10 inclusive. The number of iterations is hi - lo + 1. Third, endl flushes the stream and "\n" does not. For an interactive program this does not matter. For a program that prints a million lines it makes a 10x difference. I use endl in lectures because I want the output to appear immediately when I am debugging. You will figure out your own preference.

4.10 Try it

Write a program that reads ten integers from cin and prints the largest one. Compile with -Wall -Wextra. The compiler should give you zero warnings. If it does, you wrote it wrong. Here are two hints in white text on white background: read into a vector first, then loop; OR keep a running max as you read.

Solution sketch (one possible version):

#include <iostream>
using namespace std;

int main() {
  int n;
  int biggest;
  cin >> biggest;
  for (int i = 1; i < 10; ++i) {
    cin >> n;
    if (n > biggest) biggest = n;
  }
  cout << biggest << endl;
  return 0;
}

Notice that I read the first value into biggest directly, then loop the remaining nine. That avoids initializing biggest = INT_MIN, which is a clever idea that students sometimes get wrong by writing INT_MAX instead.

4.11 Self-check

1. Which command compiles main.cpp and greeter.cpp together with all warnings, C++17, into an executable named hello?
b is the right command. -Wall -Wextra turns on warnings, -std=c++17 selects the language version, and listing both .cpp files compiles them together. c is wrong because gcc is the C compiler. d is wrong because you never list .h files on the command line — they are included by #include.
2. Why split a class across a .h and a .cpp file?
c. The split is by convention, not requirement — you can write a whole program in one file. But for any non-trivial project, separating declarations from definitions is what lets the compiler skip recompiling unchanged units.

4.12 Challenges

These are warmup-tier. Solve them in the LeetCode online editor or in your local environment. Both work.

  1. Hello World — n/a, just write one in C++ on your machine.
  2. Running Sum of 1d Array (#1480) — vector traversal, one accumulator.
  3. Build Array from Permutation (#1920) — array indexing with nums[nums[i]].

4.13 Where this fits

This chapter is the floor. Every chapter after this assumes you can compile a program and push it to GitHub. If any of that is fuzzy, fix it now — by week 3 the assignments require a Makefile, a class split across files, and an automated test runner.

You are here Coming up
Hello World, IDE setup, command-line compile, git basics Chapter 2: std::vector and the warmup ritual begins