Join 149,571 C++ Programmers for FREE! Get instant access to thousands of C++ experts, tutorials, code snippets, and more! There are 1,655 people online right now. Registration is fast and FREE... Join Now!
Are you sitting down? This might make your head hurt a little..
You probably know that char* is a data type for an object or variable whose purpose is to store a memory address for your program. (The data type is pointer-to-char, as indicated by the asterisk).
So, when you try the operation char* c = 'c'; you're creating a pointer variable, and trying to copy in a value whose type is completely different (and fundamentally incompatible) to a pointer.
So.. why did the first one work? a string isn't a pointer either! well..
A string in C and C++ is represented by an array of characters. C and C++ treat arrays a little differently to ordinary variables, because arrays are designed to hold multiple "things" all in a continuous sequence in memory. like a string, which is a series of multiple characters, all lined up next to each other in memory.
Since arrays are not individual objects, C and C++ will not allow them to be copied using the assignment operator (the = operator). You probably noticed that if you have 2 array variables, you can't copy one to the other with assignment. So the assignment operator needs to do something else.
What the assignment operator does behind the scenes when it encounters an array, is that it yields a value which corresponds to the address of the first element of that array. It yields an address - which means the data type of the value it retrieves is a pointer type. Specifically, the type is 'pointer to' the element type of the array.
The element type of a string in 'C' is char, so, using the = operator against a string causes an address-of char to be yielded, which may be stored by char* variables. For this reason it is perfectly valid to then do something like this
CODE
char* s = "hello, world"
What's happening "behind the scenes" is that a constant (non-modifiable) array is created in memory, with the contents { 'h', 'e', 'l', 'l', 'o', ' ,' 'w', 'o', 'r', 'l', 'd', '\0' } . - Which is an array of char.
Then the = comes along, and sees the array. It does the only thing that it can do, which is yield the address of the first character, and plonk that address value into the variable s.
The reason why 'C' was designed this way is so that the task of direct manipulation of bytes in memory is made possible. Although, right now, you don't care about low-level memory manipulation, so, you just have to remember that 'C' gets a little finicky with arrays and strings, and that operations involving arrays often involve memory addresses or pointers
However it is extremely important to remember that, despite the close relationship between array operations and pointer operations, an array is not a pointer. A pointer is merely the mechanism by which arrays can be manipulated, and passed around your program. (though pointers have other uses too)
I hope this sheds some light for you.
This post has been edited by Bench: 30 Nov, 2007 - 04:43 PM
// [1] char *pStr = "Hello"; // Note. This is deprecated for (const char *pStr = 'hello';) though behavior is compiler dependent
// [2] char *pchar = 'c';
The reason that the [1] works is because the compiler is performing an implicit converstion to a (const) char *. The compiler then assigns the address of the first character to your char* pointer.
The reason why [2] doesn't work is because a pointer needs to point to a memory address not a value.
just a note about bench's post (very good, though by his own admission a little hard to read).
if you have:
CODE
char *ptrToChar = {'c'};
this will work... this works because the compiler sees this as an array with one element. Note that this is not the same as:
CODE
char *ptrToChar = "c";
In this version the array has two characters, it is the array {'c', '\0'}. (strings in C are null (zero) terminated arrays... the last character of a string is always marked with a 0x00 character -- C++ has a string object that is more complex).
When you define a string using double quotes, or an array using brackets the compiler knows to tell the linker that this data is special and should be loaded into a special data area when the program loads. This is partly why string (and arrays) defined in the code this way are considered to be of type const char * rather than the char * that you would have thought.
ummm... I am in the airport at the moment and can't really look something up, but I believe that there is a difference between:
CODE
char str1[100] = "This is a test"; char *str2 = "This is a test";
in the first version the program should create space on the stack for the array and then copy over string (initializing the array) and the second creates a pointer to a static string in memory. BUT... some little alarm is going off in my head about that..
Are you sitting down? This might make your head hurt a little..
You probably know that char* is a data type for an object or variable whose purpose is to store a memory address for your program. (The data type is pointer-to-char, as indicated by the asterisk).
So, when you try the operation char* c = 'c'; you're creating a pointer variable, and trying to copy in a value whose type is completely different (and fundamentally incompatible) to a pointer.
So.. why did the first one work? a string isn't a pointer either! well..
A string in C and C++ is represented by an array of characters. C and C++ treat arrays a little differently to ordinary variables, because arrays are designed to hold multiple "things" all in a continuous sequence in memory. like a string, which is a series of multiple characters, all lined up next to each other in memory.
Since arrays are not individual objects, C and C++ will not allow them to be copied using the assignment operator (the = operator). You probably noticed that if you have 2 array variables, you can't copy one to the other with assignment. So the assignment operator needs to do something else.
What the assignment operator does behind the scenes when it encounters an array, is that it yields a value which corresponds to the address of the first element of that array. It yields an address - which means the data type of the value it retrieves is a pointer type. Specifically, the type is 'pointer to' the element type of the array.
The element type of a string in 'C' is char, so, using the = operator against a string causes an address-of char to be yielded, which may be stored by char* variables. For this reason it is perfectly valid to then do something like this
CODE
char* s = "hello, world"
What's happening "behind the scenes" is that a constant (non-modifiable) array is created in memory, with the contents { 'h', 'e', 'l', 'l', 'o', ' ,' 'w', 'o', 'r', 'l', 'd', '\0' } . - Which is an array of char.
Then the = comes along, and sees the array. It does the only thing that it can do, which is yield the address of the first character, and plonk that address value into the variable s.
The reason why 'C' was designed this way is so that the task of direct manipulation of bytes in memory is made possible. Although, right now, you don't care about low-level memory manipulation, so, you just have to remember that 'C' gets a little finicky with arrays and strings, and that operations involving arrays often involve memory addresses or pointers
However it is extremely important to remember that, despite the close relationship between array operations and pointer operations, an array is not a pointer. A pointer is merely the mechanism by which arrays can be manipulated, and passed around your program. (though pointers have other uses too)
I hope this sheds some light for you.
Thank Bench for your long descriptive explanation although I'm still confused.
just a note about bench's post (very good, though by his own admission a little hard to read).
if you have:
CODE
char *ptrToChar = {'c'};
this will work... this works because the compiler sees this as an array with one element. Note that this is not the same as:
CODE
char *ptrToChar = "c";
In this version the array has two characters, it is the array {'c', '\0'}. (strings in C are null (zero) terminated arrays... the last character of a string is always marked with a 0x00 character -- C++ has a string object that is more complex).
When you define a string using double quotes, or an array using brackets the compiler knows to tell the linker that this data is special and should be loaded into a special data area when the program loads. This is partly why string (and arrays) defined in the code this way are considered to be of type const char * rather than the char * that you would have thought.
ummm... I am in the airport at the moment and can't really look something up, but I believe that there is a difference between:
CODE
char str1[100] = "This is a test"; char *str2 = "This is a test";
in the first version the program should create space on the stack for the array and then copy over string (initializing the array) and the second creates a pointer to a static string in memory. BUT... some little alarm is going off in my head about that..
CODE
char str1[100] = "this is test"; char *str2 = "this is a test";
from memory side, it should be different I think, since the first one it's declared more memory while the second one isn't. But if from programming, it shouldn't be much different since array and pointer are almost alike. Then again, I can be wrong.
Thank Bench for your long descriptive explanation although I'm still confused.
What are you still confused about? or, perhaps, which bits aren't you confused about?
so I can't do this:
CODE
char *ptrChar; char ptrChar = 'c';
first it's because 'c' is not the same type as ptrChar and second 'c' is considered as a constant(am I right) that has single block of memory so because of that, it doesn't work?
This post has been edited by skyHigh: 1 Dec, 2007 - 07:02 PM
first it's because 'c' is not the same type as ptrChar and second 'c' is considered as a constant(am I right) that has single block of memory so because of that, it doesn't work?
Yes the character 'c' is a constant, but doesn't have any memory whatsoever. its 'just' a data value, which only exists within the code of your program, Since it doesn't exist in memory, then asking it for its memory address would be meaningless.
The actual reason the compiler complained, however, is that it thought you were trying to treat the character 'c' as a memory address value.
Reason for editing - fixed some typo's
This post has been edited by Bench: 2 Dec, 2007 - 04:14 AM
first it's because 'c' is not the same type as ptrChar and second 'c' is considered as a constant(am I right) that has single block of memory so because of that, it doesn't work?
Yes the character 'c' is a constant, but doesn't have any memory whatsoever. its 'just' a data value, which only exists within the code of your program, Since it doesn't exist in memory, then asking it for its memory address would be meaningless.
The actual reason the compiler complained, however, is that it thought you were trying to treat the character 'c' as a memory address value.
Reason for editing - fixed some typo's
Thank you bench for keep following up to my questions. Very appreciate. Now I understand although hahaha won't able to explain to others like you did.