I was reading the following text from Stanford's Programming Paradigms class, and I noticed that 开发者_开发知识库when the author uses the string class, the constructor does a function call that looks like this:
string::string(const char* str) {
initializeFrom(str, str + strlen(str));
}
If the initializeFrom function takes two char* arguments, how come the second argument can pass a (char* + int) to a char* and have it work out properly? How does the type system interpret this statement?
Thanks in advance.
That is called pointer arithmetic. A char* + int results in a char* that is int characters higher in memory.
Binary additive operators +
and -
can be used when one argument is a pointer to any complete type (say, T* p
) and the other argument is an integer (say, i
). They implement so called pointer arithmetic.
The compiler assumes that the pointer is pointing to an element of some array (say, T array[N]
). The operation produces a pointer to another element of the array, which is i
elements away from the original element. It is possible to "move" the pointer in either direction, i.e. towards the beginning of the array or towards the end of the array. For example, if p
points to array[3]
, then p + 4
will point to array[7]
.
The operation is only valid when the result points to an existing element of the array or one past the last element of the array, i.e. given the array T array[N]
, it is possible to create pointers to elements from array[0]
to the imaginary element array[N]
. Any attempts to cross these bounds using pointer arithmetic result in undefined behavior.
The type T
has to be complete, meaning that pointer arithmetic cannot be used with void *
pointers, for one example, even though some compilers allow this as an extension (treating void *
pointers as equivalent to char *
pointers).
In addition to the binary additive operators, pointer arithmetic also includes prefix and postfix unary ++
and --
operators (applied to pointers) as well as compound assignment operators +=
and -=
(with pointers on their left-hand side and integers on the right-hand side).
In your case, str + strlen(str)
expression will produce a pointer of char *
type that points to the terminating \0
character in the string str
.
Remember that a pointer is just a variable that holds a memory address. So you can add values to a memory address. A memory address is a number.
When you add 1 to a pointer of a certain type, it will actually add 1 * sizeof(type). When you add any value N, it will actually add N * sizeof(type).
Consider the following example:
int x[5] = {0,1,2,3,4};
int *p = &(x[0]);//point to the first element
p = p + 1;//p now points to the second element.
how come the second argument can pass a (char* + int)
It is still passing a char *
pointing to strlen(str)
past the initially pointed location.
The first argument points to the start of the char array and the second points the NULL char at the end of the char array.
const char *str = "abc";
char *start = str; // start now points to the first char.
char *end = str + strlen(str); // end now points to the null char at the end.
You can confirm this by printing:
printf("%c %d",*start,*end); // will output: a 0
I think this may be over-answered.
In:
initializeFrom(str, str + strlen(str));
str
is a pointer to the start of the string.
(str + strlen(str))
is a pointer to the end of the string.
Keep in mind that str
(a character pointer) is just an integer ((int)
, (long)
, (long long)
depending on architecture) that identifies a location in memory.
精彩评论