Printing a char pointer ... what's going on?

I'm new to C and I have 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 he will give you ABCD

What I am not getting is what exactly *p1

? Is this the number of addresses containing the value char

? Is it char

?
what's in *p1

right now? Why is this const

?

+3


source to share


8 answers


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) which is a pointer. Pointer, p1 can be changed.

2) char *p1 = "ABCD";

declares p1 (same as "1") and also initializes the data it points to (initializes it only for a read-only character array 5 ABC \ 0).



Thus, you can change the address of "p1" (you can point it to "EFG", assign it to NULL, etc., etc.). But you CANNOT safely modify the data itself. You will probably get an "access violation" if you try to overwrite "ABCD". The exact behavior is "undefined" - something might happen.

3) char p2[] = "ABCD";

declares a variable (p2) which is an array. It allocates 5 characters and initializes the data "ABCD \ 0".

An array is read-write (you can change the data in the array), but the variable "p2" cannot be changed (you cannot change p2 to a different address - because it is not a pointer).

4) So what's the "difference" between a char * pointer and a char [] array? Here's a good discussion:

http://c-faq.com/aryptr/aryptrequiv.html

+2


source


p1

is a pointer char

that contains the base address or the start address or the address of the first element of a string assigned to it by an operator =

.

In your first code, you assigned base address "ABCD" to it and then base address "EFG" [which overwrites the previous value] and finally prints it. Thus, the last value ["EFG"] is printed.



In the second case, you assign the base address "ABCD" and print it. So he prints ABCD

. It may be worth mentioning, the format specifier %s

in printf()

awaiting the start address of the string with zero termination, which is here indicated p1

.

As per the part, the const

value of the string pointed p1

to is constant in this case, since string literals are usually stored in read-only memory locations. Values โ€‹โ€‹that change values โ€‹โ€‹are p[1] = 's'

not allowed. However, the pointer is p1

not const

, so it can be reassigned to a new value p1="EFG";

by right.

+1


source


p1

is a char pointer that contains the address where the compiler puts "ABCD" into memory. The address has the first character in the array.

When you have char *p1 = "ABCD";

, you simply assign the value to the address contained in p1

. When you reassign p1 = "EFG";

, you reassign the pointer to store the new address (where "EFG" is located)

printf ("%s",p1);

prints the contents of memory at position p1

.

+1


source


Initially, p1 is declared as a char pointer and points to "ABCD" (base address "ABCD").

Later the pointer points to "EFG" (contains the base address "EFG")

+----+      +---+
|ABCD|      |EFG|
+----+      +---+
 1000        2000

char *p1="ABCD";
         +----+
before   |1000|
         +----+
          p1
p1="EFG";
After    +----+
         |2000|
         +----+
          p1

      

+1


source


int main()
{
    char *p1="ABCD";
    p1="EFG";
    printf ("%s",p1);
    return 0;
}

      

Required is missing #include <stdio.>

. Without it, your compiler might let you get away with the call printf

, but that doesn't guarantee it will work. And a minor point: there int main()

should be int main(void)

.

There is quite a lot going on in this program, and some of it is quite subtle.

char *p1 = "ABCD";

      

"ABCD"

- string literal. It defines an anonymous array object of type char[5]

(4 for the characters you specified plus 1 for the '\0'

null character , which marks the end of the string). This object has a static storage duration, which means that it exists throughout the entire execution of your program (as opposed to a local variable, for example, which ceases to exist when it goes out of scope (which is a slight simplification)).

In most contexts, an array expression is implicitly converted to a pointer to its first element. So, p1

initialized to point to a character 'A'

, the first character of this anonymous array object.

p1

should be defined as const char *p1 = ...

. This is not required, but it will help the compiler catch any attempt to modify the array object. (The object is not const

, but changing it has undefined behavior.)

p1 = "EFG";

      

Now the value stored in p1

is flushed and replaced with the new pointer value, this time pointing to a 'E'

string literal "EFG"

. (So โ€‹โ€‹there was no point in initializing it, but that's okay.)

printf("%s", p1);

      

Here we are passing a value p1

(pointer value) to a function printf

.

At this point, the value *p1

is equal 'E'

and has a type char

. But it printf

can print the whole line "EFG"

. This is done using pointer arithmetic. Somewhere in the implementation printf

there is a loop that takes the pointer value that was passed in, looks for it to get the printable character value, and then increments the pointer to point to the next character in the string ( 'F'

). This loop continues until it reaches the '\0'

null character , which marks the end of the line; that the null character is not printed.

Since arrays are in some sense "second-class citizens" in C, most operations on array objects are done this way, using pointers to array elements to traverse the array. (You can also use indexing notation arr[i]

, which does much the same thing.) printf

Doesn't have direct access to the array object itself; it relies on a pointer (on its first element) to determine where the array is in memory and on a terminator '\0'

to determine where the string ends.

The second program is the same, except it is p1

not reassigned, so a line is printed "ABCD"

.

The relationship between arrays and pointers in C can be confusing. Section 6 of comp.lang.c often asks the question . It is very helpful to explain this.

+1


source


I donโ€™t understand what exactly *p1

? Is this the number of addresses containing the char value? Is it char?

If you are talking about *p1

in an ad

char *p1 = "ABCD";    

      

that *

indicates what p1

is a pointer to char

(actually const char

in this case). p1

simply points to the first character of a string literal ABCD

.

If you ask about *p1

how in

printf("%c", *p1); 

      

then *

here is the indirection operator, and *p1

means the value of the symbol p1

that is A

. *p1

is equivalent p1[0]

.
Statement

 p1 = "DEF";  

      

let p1

points to the first character of a string literal DEF

.

Why is this const

?

String literals are stored in a read-only section of memory.

char *p1 = "ABCD";  

      

equivalent to

char const *p1 = "ABCD";

      

This means that you cannot change the string literal.

*p1 = 'a'; // WRONG. Invokes undefined behavior.  

      

+1


source


What I don't get is what exactly * p1 is! is it the address number that contains the char value? is it char? what is in * p1 right now?

Type *p1

- char

. Its meaning is symbol 'A'

.

why is he const

?

String literals such as "ABCD"

are placed in permanent storage. Changing them with p

is the reason for undefined behavior. Therefore, *p1

read-only, i.e. A const

.

0


source


What I don't get is what exactly * p1 is! is it the address number that contains the char value? is it char? what is in * p1 right now?

The value *p1

is equal p1[0]

, that is, the char

values 'E'

in your first program and the values 'A'

in your second program.

why is it const?

It's not const

in C (it's in C ++), but string literals are listed as unmodifiable in C, which means trying to change *p1

causes undefined behavior.

0


source







All Articles