import discussion in §1.2.1
main function
#include <iostream> int main() std::cout << "Hello world" << std::endl; }
#include <iostream> using namespace std; int main() cout << "Hello world" << endl; }
…
void displayHello(); // declaration — function header only
int main() {
displayHello();
}
void displayHello() { // definition — has body
cout << "Hello world1" <<;
}
int, doublea,
bool, char, etc
' as literal separator ... 123'45'6789.
bool as integer type
cin >> x >> y;
while (x = y) { // Note this is an assignment, not an equality test
// do something with x and y
cin >> x >> y;
}
y assigned to x) is converted to boolean: 0 → false; everything else → true
0 is read into y, regardless of whether x and y are equal
char - usually 8 bit
w_char and other character types fill in the Unicode gap
const modifier can only be assigned to once
constexpr must be a compile-time value
autoauto
auto i = 17; // int — Doh
Rational r; … auto n = r.getNum(); // don't have to go look up the return type of 'getNum'
std::vector<SomeLongClassName> vect; // an iterator for the above class has type std::vector<SomeLongClassName>::iterator for (auto iter = vect.begin(); iter != vect.end(); iter++) …
auto was already a keyword in C
auto was an anachronistic way of declaring a local variable (which automatically
goes in and out of scope lifetime upon entry/exit of the function)
{} in which declared.
{}) of declaration
const: value may not be changed. May be a runtime value (used mainly in parameter specification for references that should not be modified, and values that should not be modified)
constexpr: value must calculable by compiler. (used for 'real' constants, and performance).
#include <iostream>
using namespace std;
int main() {
int i = 17;
int *ip = &i; // ip is a pointer to integer; & is 'address-of' operator
cout << "ip: " << " " << ip << " *ip: " << *ip << endl;
(*ip)++; // increments what the pointer points at
cout << "ip: " << " " << ip << " *ip: " << *ip << endl;
ip++; // increment pointer
cout << "ip: " << " " << ip << " *ip: " << *ip << endl;
return 0;
}
the above produces the output:
ip: 0x16d392d98 *ip: 17 ip: 0x16d392d98 *ip: 18 ip: 0x16d392d9c *ip: 0
Employee e; // e is of type Employee (class type)
Employee *ep = &e;
…
cout << ep; // "
cout << *ep; // "
…
//ep.getEmpId(); // illegal … ep is not an class object, it's a pointer
(*ep).getEmpId(); // dereference ep to get the class object, then use member selection (.) operator
//*ep.getEmpId(); // also illegal … postfix operators have precedence, so this is *(ep.getEmpId())
ep->getEmpId(); // intuitive, convenient notation for member selection through a pointer
void swap(int *ip1, int *ip2) {
int templ = *ip1;
*ip1 = *ip2;
*ip2 = temp;
}
…
swap(&x, &y); // x and y are declared as int
*, &) associated with
pointers and indirection; this will NOT be the case with true call-by-reference (using references)
void *nullptr0 is a good choice for a null pointer
nullptr, NULL was defined as a macro for 0
#define NULL 0
nullptr is an abstraction of 0 / NULL
nullptr, rather than one for each pointer type
int a[10]; // note bracket location const int MAX_SIZE = 100; Employee a[MAX_SIZE];
int a[10] = {…}
for (int i = 0; i < 9; i++) {
cout << a[i];
}
int a[10] = {…}
int *ip = &a[0];
for (int i = 0; i < 9; i++) {
cout << *ip;
ip++;
}
length field
int i = 17; int &ir = i; // MUST be initialized in this context; rarely used in this manner … ir++; // increments i
// This is the primary use for reference void f(int &x, int &y); // true call-by-reference … f(a, b);
void swap(int &ir1, int &ir2) {
int temp = ir1;
ir1 = ir2;
ir2 = temp;
}
…
swap(x, y); // x and y are declared as int