main
functionint main() { return 0; }
main()
is a function, not a method.
main()
is a function.
Here’s a complete C++ program that creates some output:
#include <iostream> using namespace std; int main() { cout << "Hello, world!\n"; return 0; }
Hello, world!
#include <iostream>
to access I/O facilities.
using namespace std;
because you just have to,
for the moment.
Many examples in these slides are just a snippet of code:
cout << "How do you do?" << '\n';
How do you do?
#include <iostream>
.
using namespace std;
.
int main() {
.
return 0;
is, strictly speaking, optional,
but it’s appalling to have a function that returns int
without
a return
statement, so I always include it.
}
to close main
.
main
functionHere’s the other valid definition of main()
:
int main(int argc, char *argv[]) { // Display all arguments, including program name. for (int i=0; i<argc; i++) cout << "argv[" << i << "]: \"" << argv[i] << "\"\n"; return 0; }
argv[0]: "./a.out"
Don’t even ask about void main()
.
It does not exist.
⚠ ☢ ☣ ☠
main()
returns an int
, a success/failure code to the invoker.
int main(int argc, char *argv[])
argc
: number of arguments, including the program name as argv[0]
.
argc
stands for “argument count”.
argv
: array of C-style strings, corresponding to program arguments.
argv
stands for “argument vector”.
argc
is always ≥ 1, except in strange embedded environments.
argv
is always an array of C strings, even if you type
arguments that look like numbers or something else.
% cat ~cs253/Examples/show-args.cc #include <iostream> using namespace std; int main(int argc, char *argv[]) { for (int i=0; i<argc; i++) cout << "argv[" << i << "]: " << argv[i] << '\n'; } % g++ -Wall ~cs253/Examples/show-args.cc -o foobar % ./foobar This class is "CS253: best class ever!" argv[0]: ./foobar argv[1]: This argv[2]: class argv[3]: is argv[4]: CS253: best class ever!
argv[0]
contains the real program name, as executed.
argv[]
an array of char *
?
Surely they should be C++ strings?
argv[]
an array of char *
?
Surely they should be const char *
?
const
when this was all invented.
C++ has a number of built-in types:
void
bool
(not boolean
)
char
(not byte
)
short
/ int
/ long
/ long long
float
/ double
/ long double
size_t
sizeof(long)==4
, but sizeof(long)==8
on
many computers.
short
, int
: 16 bits
long
: 32 bits
long long
: 64 bits
sizeof(char) == 1
sizeof(char)
≤ sizeof(short)
≤ sizeof(int)
≤ sizeof(long)
≤ sizeof(long long)
sizeof(int *)==4
on a 32-bit machine
sizeof(int *)==8
on a 64-bit machine
Qualifiers such as const
, constexpr
, and static
modify
existing types.
const long id = get_id_number(); constexpr double PI = 3.1415926; static const char *program_name;
const
: not allowed to change this
constexpr
: compile-time constant
static
: longer-than-function lifetime, private if a global
Via pointers & arrays, a vast number of derived types exist:
int a[10]; // 10 ints int *b; // A pointer to any number of ints int *c[10]; // An array of 10 pointers-to-ints int (*d)[10]; // A pointer to an array of 10 ints
If you find complex types confusing, build intermediate types
with typedef
:
typedef float cash; // cash is now a synonym for float (note the order) typedef int *intp; // New type intp, a pointer to ints intp e[10]; // An array of 10 such pointers
typedef
With typedef
, you can create an alias for an existing type.
It does not create a new type.
typedef int counter; // typedef old new; counter c = 42; cout << c << '\n';
42
To use typedef
, think of it in two steps:
int counter;
typedef
in front of it: typedef int counter;
using
We’re familiar with using
for using namespace std;
, but it
can also be used to make aliases for types:
using counter = int; // using new = old; counter c = 43; cout << c << '\n';
43
Or, you can just declare variables with auto
:
auto i=4; // an int auto r=3.45; // a double cout << i+r << '\n';
7.45
But you must initialize the variable, so that the compiler knows what type to make it:
auto foo; foo = 'x';
c.cc:1: error: declaration of 'auto foo' has no initializer
if
switch
while
do
… while
for
for
int x = 42; if (x < 100) cout << "This is true\n";
This is true
double pi = 3.14159; if (pi*pi < 10) { cout << "Good--mathematics has not changed\n"; } else cout << "Can’t even trust math any more‽\n";
Good--mathematics has not changed
srand(time(nullptr)); int sides = rand() % 5 + 1; cout << sides << ": "; switch (sides) { case 2: cout << "A line?\n"; break; case 3: cout << "Triangle\n"; break; case 4: cout << "Square\n"; break; case 5: cout << "Pentagon\n"; break; default: cout << "Can’t deal with that!\n"; }
2: A line?
switch
on integral types
(char
, short
, int
, long
, …).
switch
on floating-point types or strings.
break
prevents flow into the next case
.
int i=4; while (i<10) cout << i++ << ' ';
4 5 6 7 8 9
int i=4; do { i += 2; cout << i << ' '; } while (i<15);
6 8 10 12 14 16
for (int i=0; i<5; i++) cout << i;
01234
int a[] = {11,22,33}; for (int v : a) cout << v << ", ";
11, 22, 33,
int b[] = {101, 202, 303, 404}; for (int &n : b) n *= 3; for (const int n : b) cout << n << ", ";
303, 606, 909, 1212,
for (auto q : {12, 34, 56, 78}) cout << q << ", ";
12, 34, 56, 78,
The condition of an if
, switch
, or while
can be a declaration.
const char show[] = "Star Trek"; if (const char *p = strchr(show, 'T')) cout << "Found it at location " << p-show << '\n';
Found it at location 5
false
, 0
, and a null pointer are false,
everything else is true.