i'm new to C and i've got a question about char pointers and what it will print . take a look :
int main()
{
char *p1="ABCD";
p1="EFG";
printf ("%s",p1);
return 0;
}
it will print EFG
and now :
int main()
{
char *p1="ABCD";
//p1="EFG";
printf ("%s",p1);
return 0;
}
and it will give you ABCD
The point that I don't get is what exactly *p1
is ?
Is it a number of an address that contains a char
value ?
Is it a char
?
what is in *p1
right now ? Why is it const
?
A pointer may be a special memory location that's capable of holding the address of another memory cell. So a personality pointer may be a pointer that will point to any location holding character only. Character array is employed to store characters in Contiguous Memory Location.
When casting character pointer to integer pointer, integer pointer holds some weird value, no where reasonably related to char or char ascii code. But while printing casted variable with '%c', it prints correct char value. Printing with '%d' gives some unknown numbers.
char* is how you declare a pointer to a char variable. It's useful when you want a string with unknown length.
From the C Standard:
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf
EXAMPLE 8 The declaration
char s[] = "abc", t[3] = "abc";
defines ‘‘plain’’ char array objects s and t whose elements are initialized with character string literals.
This declaration is identical to
char s[] = { 'a', 'b', 'c', '\0' },
t[] = { 'a', 'b', 'c' };
The contents of the arrays are modifiable. On the other hand, the declaration
char *p = "abc";
defines p with type ‘‘pointer to char’’ and initializes it to point to an object
with type ‘‘array of char’’ with length 4 whose elements are initialized with a
character string literal. If an attempt is made to use p to modify the contents
of the array, the behavior is undefined.
In other words:
1) char *p1;
declares a variable (p1) that is a pointer. The pointer, p1 can be changed.
2) char *p1 = "ABCD";
declares p1 (same as "1") and also initializes the data it points to (initializes it to the read-only, 5-lelement character array "ABCD\0").
So you can change the address "p1" points to (you can make it point to "EFG", assign it to NULL, etc. etc). But you CANNOT safely change the data itself. You'll probably get an "access violation" if you try to overwrite "ABCD". The exact behavior is "undefined" - ANYTHING can happen.
3) char p2[] = "ABCD";
declares a variable (p2) that is an array. It allocates 5 characters, and initializes the data to "ABCD\0".
The array is read-write (you can change the data in the array), but the variable "p2" cannot be changed (you cannot change p2 to point to a different address - because it's not a pointer).
4) So what's the "difference" between a char *pointer and a char array[]? Here is a good discussion:
http://c-faq.com/aryptr/aryptrequiv.html
int main()
{
char *p1="ABCD";
p1="EFG";
printf ("%s",p1);
return 0;
}
This is missing the required #include <stdio.>
. Without it, your compiler might let you get away with calling printf
, but it's not guaranteed to work. And a minor point: int main()
should be int main(void)
.
There's actually quite a lot going on in this program, and some of it is rather subtle.
char *p1 = "ABCD";
"ABCD"
is a string literal. It specifies an anonymous array object of type char[5]
(4 for the characters you specified plus 1 for the '\0'
null character that marks the end of the string). That object has static storage duration, which means that it exists during the entire execution of your program (unlike a local variable, for example, which ceases to exist when it goes out of scope (that's a slight oversimplification)).
An array expression is, in most contexts, implicitly converted to a pointer to its first element. So p1
is initialized to point to the character 'A'
, the first character of that anonymous array object.
p1
should be defined as const char *p1 = ...
. It's not actually required, but it will help the compiler catch any attempt to modify the array object. (The object is not const
, but modifying it has undefined behavior.)
p1 = "EFG";
Now the value stored in p1
is clobbered and replaced by a new pointer value, this time pointing to the 'E'
of the string literal "EFG"
. (So there was no point in initializing it, but that's ok.)
printf("%s", p1);
Here we pass the value of p1
(a pointer value) to the printf
function.
At this point, the value of *p1
is 'E'
, and is of type char
. But printf
is able to print the entire string "EFG"
. It uses pointer arithmetic to do so. Somewhere in the implementation of printf
, there's a loop that takes the pointer value that was passed in, dereferences it to obtain the character value to be printed, and then increments the pointer so it points to the next character of the string ('F'
). This loop continues until it reaches the '\0'
null character that marks the end of the string; that null character is not printed.
Since arrays are in a sense "second-class citizens" in C, most operations on array objects are done this way, using pointers to the array elements to traverse the array. (You can also use indexing notation arr[i]
, which does essentially the same thing.) printf
doesn't have direct access to the array object itself; it relies on the pointer (to its first element) to determine where the array is in memory, and on the '\0'
terminator to determine where the string ends.
The second program is the same, except that p1
is not reassigned, so the string "ABCD"
is printed.
The relationship between arrays and pointers in C can be confusing. Section 6 of the comp.lang.c FAQ does a very good job of explaining it.
I don't get is what exactly
*p1
is ?
Is it a number of an address that contains a char value ? Is it a char ?
If you are talking about *p1
in the declaration
char *p1 = "ABCD";
then *
indicates that p1
is a pointer to char
(in fact const char
in this case). p1
just points to the first character of the string literal ABCD
.
If you are asking about *p1
as in
printf("%c", *p1);
then *
here is an indirection operator and *p1
means the value of the character p1
points to which is A
. *p1
is equivalent to p1[0]
.
The statement
p1 = "DEF";
let p1
point to first character of the string literal DEF
.
Why is it
const
?
String literals are stored in read-only section of memory.
char *p1 = "ABCD";
is equivalent to
char const *p1 = "ABCD";
This means that you can't modify a string literal.
*p1 = 'a'; // WRONG. Invokes undefined behavior.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With