February 1, 2019
For today:
1) Read Head First C Chapter 2
2) Finish Homework 01
Today:
1) Hexadecimal
2) Pointers!
3) The virtual address space
For next time:
1) Read Think OS Chapter 2 and do the reading quiz
2) Start Homework 2
3) Prepare for a quiz (here's last year's quiz as practice)
Pointers and the arrangement of memory (stack, heap, globals, constant, code)
Passing a pointer as a parameter.
Getting and printing the address of a variable.
Passing strings as parameters.
The sizeof function (which is not really a function)
Arrays, pointers, string literals.
Pointers and types.
Using scanf and fgets
Bus errors and segmentation faults.
We'll have 7-8 quizzes, roughly every third class session.
They cover all prior material, including the reading due on quiz day.
They are open everything (but beware).
Some programming questions: you can test code on your laptop (but beware).
You can search the Internet for information, but not solutions.
Some short answer questions: for full credit, your response should be clear, concise, true, and responsive. Avoid quotations. Avoid shotgun strategy.
Some numerical answers: for full credit, your response should include units!
Quizzes start at the beginning of class (partly as a way of encouraging promptness) and usually take 30 minutes.
We'll go over them immediately (which creates a moral hazard, but I think the benefits are worth it).
All together, quizzes make up 20-30% of the final grade, so each quiz is relatively small.
There are generally no makeup quizzes. They are, partly, a proxy for attendance.
However, I drop the lowest quiz score. You can miss one with impunity. Missing two or more starts to hurt.
If you have to miss a second quiz, talk to me and we'll do something reasonable.
If you require accommodations, talk to me and we'll figure out the right thing.
Locations in memory are identified by addresses.
In a 32-bit machine, addresses are 32 bits long, so there are 2^32 addresses.
In a 64-bit machine, addresses are 64 bits long, so there are 2^64 addresses.
How should we write addresses:
1) Binary: too long and hard to read
2) Decimal: short, but we lose insight into the power-of-twoness
3) Hexadecimal: best, most common choice
Each hexadecimal digit represents 4 bits, so 32-bit addresses go from 0x0000 0000 to 0xffff ffff
The prefix 0x is often used to indicate hexadecimal numbers.
1) What is 0xb in binary? In decimal?
2) What is 0x111 in decimal?
3) What is 0xbeefface in decimal (you can use online resources for this one).
4) What is 0xface in binary?
5) What is the longest word you can spell with only hexadecimal digits?
A variable is a name that identifies a location in memory.
int x = 0;
declares that x is an integer. The compiler chooses a location for x. Let's suppose it chooses the location 0xbeefface.
1) When x appears on the right side of an assignment, it means "go to 0xbeefface and get the value there.
2) When x appears on the left side of an assignment, it means "store the result at 0xbeefface".
After the program is compiled, the name x doesn't exist anymore. Just 0xbeefface.
A pointer is a variable that contains an address.
int *p;
declares that p is a pointer to an integer. Because we haven't given it a value, it doesn't point to anything.
To give p a value, we need the address of something. One way to get an address is the & operator.
p = &x;
Or
int *p = &x;
If we have an array of integers, we can make a pointer point to one of the elements
int array[10];
int *p = array;
int *q = &array;
int *r = array + 1;
int *s = &array[1];
We can print the value of p
printf("%p\n", p);
But usually we don't care.
Normally we want to dereference p using the * operator.
1) When *p appears on the right side of an assignment, it means "go to where p points and get the value there.
2) When *p appears on the left side of an assignment, it means "store the result where p points".
int y = *p + 1;
*p = y;
One more way to give a value to a pointer is to dynamically allocate space in memory using malloc.
p = malloc(sizeof(int));
The argument of malloc is the amount of space you want, in bytes, which you should almost always compute using sizeof.