The purpose of this quiz is to give you a chance to focus your knowledge of pointers in C++.
In order to understand pointers, remember to read their declarations ____.
Show examples of the four (4) different kinds of pointer const-ness. Briefly explain how each differs from the others.
i) type * nothing is const; both ends of the pointer can be changed ii) const type * target is const; only the destination of the type const * pointer can be redirected; the value there cannot be changed iii) type * const destination is fixed/const; the value there can be changed at will, but we cannot redirect the pointer iv) const type * const everything is const; can't move the pointer and type const * const can't change the value pointed to
The ____ operator is used to dereferrence a pointer (follow it to the value at its end). The ____ operator, on the other hand, is used to 'take' the address of an object (for either storing in a pointer or comparing to a pointer value).
One must show care with declaration of multiple pointers as the * (star, asterisk) used during declaration doesn't 'distribute' through the declaration. (That is, 'type *p1, p2;' would declare p1 to be a pointer but p2 would be a simple variable.) This symbol isn't an operator, btw, but simple syntax.
To alleviate such easy to make logic errors, we can utilize the idea of a typedef to make the * stick to the data type.
TRUE ✗ | FALSE ✓ | If a pointer to a constant points to the same memory location
as a pointer to a normal value, neither pointer can be used to
change the location's contents. (i.e.
type x; const type * p1 = &x; type * p2 = &x; // *p1 = value; // illegal since p1 points to a constant // since p1 points to a constant, p2 won't be able to change x either *p2 = value; // won't work?) | ||
---|---|---|---|---|
TRUE ✗ | FALSE ✓ | If one pointer points to another pointer which in turn points
to a data value, you would need only one dereference operator to reach the data from the first
pointer. (i.e.
p1 p2 x +---+ +---+ +---+ | | | | | | | ------------------>| ------------------>| 4 | | | | | | | +---+ +---+ +---+) | ||
TRUE ✓ | FALSE ✗ | Pointers were used to effect reference arguments in C. | ||
TRUE ✗ | FALSE ✓ | If a function is going to change the destination/address
pointed to by a pointer argument, it need not have a reference to
the pointer argument. (i.e.
... f(type * p...) // don't need a reference to p?? { p = ...; // f wants to point p somewhere new for its caller }) |
When using pointer arithmetic, all increments, decrements, and differences are measured in elements (not in bytes as many newbie programmers tend to believe). So, when we have a pointer to long (a long typically takes up 4 bytes of memory), a ++ of the pointer will move its target 4 (four) bytes from its original address.
Show code to find the length of a C-string using no counter or index variables. (And don't call the strlen function! Do it yourself...)
const char * p = cstr; while (*p != '\0') { ++p; } // length is p - cstr
Write a loop which can uppercase every third character in a C-string. Use no index variables.
char * p = cstr; while (*p != '\0') { *p = static_cast<char>(toupper(*p)); ++p; if (*p != '\0') { ++p; if (*p != '\0') { ++p; } } }
To call a method of a class object to which we have a pointer, we should use the -> (arrow) operator.
That is:
Class_type * p, object; p = &object; (*p).method(); // call method via p -- nasty precedence rules! // that was horrible, how else do we call a method of 'object' from p?
Given the following code, show what is printed in each code snippet.
float array[10] = { 4, 8, 16, 32, 64, 128, 256, 512, 1024 }; float *p;
p = array; cout << *p << endl;
4
p = &(array[4]); cout << *p << endl;
64
p = array+5; cout << *p << endl;
128
p = array+5; cout << p[-1] << endl;
64
p = array+10; cout << p[-1] << endl;
0
p = array; p += 12; p -= 4; cout << *p << endl;
1024
p = array+10; cout << p-array << endl;
10
p = array; cout << *(p++) << ' ' << *p << endl;
Either: 4 4 Or: 4 8 depending on the compiler's sequencing choices.
p = array; cout << *(p++) << ' '; cout << *p << endl;
4 8