This was a nice advanced chapter. I remembered as well as learned many things.
Some basic stuff:
When a signed number is bit shifted right, the sign bit is propogated.
typedef declares synonyms. For eg:
typedef struct Student Student;
says that Student is a synonym for struct Student.
We can have nested pointers, such as pointers to pointers and pointers to pointers to pointers… uptil 12 levels. However 2 levels is what is practically used.
When sizeof is applied to a pointer to an array, the value it returns is the size of the array. An interesting idiom to find out the number of elements in an array is:
int num_ele = sizeof a/sizeof a;
Void pointers are generic pointers. They are used when we do not know what type of pointer to accept or send. In C any pointer type can be assigned to void and the other way round.
Pointers can be constant, which means that the pointer cannot point to another location, and the pointer’s referent can also be constant, which means that the value held in the location pointed by the pointer cannot be changed. Here is how we use them.
int* const i; Here i is a constant pointer. The value of the referent can be changed, but i cannot be changed.
const int* i; Here the referent is constant. The value of the pointer can be changed but the value of what it is pointing to cannot be changed.
When doing pointer arithmatic, when we add to or subtract from a pointer, the pointer is incremented or decremented by the number of elements and not the number of bytes. For eg:
a is a pointer to the begining of the array of integers. a++, a will not point to the next address, but to the next int in the array. So if an int is 4 bytes on your machine, a will be incremented by 4 bytes.
Similarly subtracting 2 pointers yeilds the number of elements between them. It follows that we cannot do arithmatic with pointers of different types.
We can also have pointers to functions. Here is how we can get a pointer to printf.
int (*fp) (const char*,…) = printf;
This means that fp is a pointer to a function called printf which takes a const char* and an unknown number of parameters after that.
Incomplete types are used when we do not have the information in advance or we want to hide it from clients.
They are used with arrays and structures. For eg:
extern int a; Struct Employee;
- What happens when a signed number is bit shifted left? Is the sign bit maintained, or is it shifted out?
- What happens when we have pointers of two different types and we cast them into void pointers to do arithmatic with them?
- When a variable is declared extern, does the compiler try to verify it?