0

Quick summary: In our activity, we were supposed to declare 3 variables (x, y, and z) and 4 pointer variables (p1, p2, p3, and p4). Two of those pointer variables (p3 and p4) should point to the same variable (z).

in this article: https://www.geeksforgeeks.org/pointers-in-c-and-c-set-1-introduction-arithmetic-and-array/

it said:

// C program to demonstrate use of * for pointers in C 
#include <stdio.h> 

int main() 
{ 
    // A normal integer variable 
    int Var = 10; 

    // A pointer variable that holds the address of var. 
    int *ptr = &Var; 

    // This line prints value at address stored in ptr. 
    // Value stored is value of variable "var" 
    printf("Value of Var = %d\n", *ptr); 

    // The output of this line may be different in different 
    // runs even on same machine. 
    printf("Address of Var = %p\n", ptr); 

So I did my code:

int main () {

    int x = 10;
        int *p1= &x;

    float y = 12.5;
        float *p2 = &y;

Now is for the p3 and p4 pointer variables. I found this thread: Can two pointer variables point to the same memory Address?

which said in the answer: "Yes, two-pointer variables can point to the same object: Pointers are variables whose value is the address of a C object, or the null pointer. multiple pointers can point to the same object:"

char *p, *q;
p = q = "a";

and did that as well:

int main () {

    int x = 10;
        int *p1= &x;

    float y = 12.5;
        float *p2 = &y;

    char z = 'G';
        char *p3, *p4;
        p3 = p4 = &z;

My confusion now is when printing p3 and p4:

int main () {

    int x = 10;
        int *p1= &x;

    float y = 12.5;
        float *p2 = &y;

    char z = 'G';
        char *p3, *p4;
        p3 = p4 = &z;

    printf("%d  %.2f %s %s", *p1, *p2, p3, p4);

Why in the line printf("%d %.2f %s %s", *p1, *p2, p3, p4); it only print p3 and p4 only if they don't have the asterisk??

JU-SethY
  • 31
  • 1
  • 6
  • 2
    `p3` and `p4` are pointers to a **single-character literal** not a character at the beginning of a *nul-terminated* string. Use `"%c"` to output them and derefernce `*p3, *p4` in `printf("%d %.2f %c %c", *p1, *p2, *p3, *p4);` A few links that provide basic discussions of pointers may help. [Difference between char *pp and (char*) p?](https://stackoverflow.com/a/60519053/3422102) and [Pointer to pointer of structs indexing out of bounds(?)...](https://stackoverflow.com/a/60639540/3422102) – David C. Rankin May 21 '20 at 07:14
  • David’s comment should be an answer. – Carl Norum May 21 '20 at 07:16
  • `p3` is not a string: it points to a single char, not to a sequence of chars `'\0'` terminated. – pmg May 21 '20 at 07:16
  • @DavidC.Rankin Oh I see, so that's why... thanks! – JU-SethY May 21 '20 at 07:24
  • Yep, you can also just use `putchar(*p3)` or `putchar(*p4)` to output the single characters separately without relying on the `printf` *format-string* and the `"%c"` *conversion-specifiers*. (`"%s"` expects a pointer to the first character in a *nul-terminated* string as the argument, `"%c"` expects an actual characters as the argument) Take a look at the links above -- they are for different problems, but the discussions in the answers provide pointer basics. Good luck with your coding! – David C. Rankin May 21 '20 at 07:30
  • @DavidC.Rankin Thank you so much! – JU-SethY May 21 '20 at 07:32

3 Answers3

3

Why the problem with p3 and p4? ... Well, they don't point to what you are using them as...

p3 and p4 are pointers to a single-character literal not a character at the beginning of a nul-terminated string. Use "%c" to output them and derefernce *p3, *p4 in printf("%d %.2f %c %c", *p1, *p2, *p3, *p4);

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
0

"Why in the line printf("%d %.2f %s %s", *p1, *p2, p3, p4); it only print p3 and p4 only if they don't have the asterisk??"

First of all, The %s conversion specifier, as opposed to %c, expects an argument of type char *, not char.

If you would use *p3 and/or *p4 there would be a type mismatch - char vs. char*.


Your main issue:

p3 and p4 point to z which is just a single char object, not an array which contains a string. To use %s with a pointer to a single character, which is not the null character, invokes undefined behavior.

If you want to print the character hold in z by the pointers p3 and p4, use the %c format specifier to print a single character and precede each pointer argument by the asterisk operator * to dereference the pointers:

printf("%d %.2f %c %c", *p1, *p2, *p3, *p4);
-1

It's totally irrelevant if you assign one or more pointers to the same variable, don't let it confuse you. You can just as well remove p4 from your code and it would work the same (print p3 without the asterisk.

When you declare char* it is considered a char array. So, when you are printing p1 and p2, which are int and float respectively (numeric types), you need to dereference your pointer, and when printing an array, there is no need to dereference. For further reading I would recommend going here.

Rorschach
  • 734
  • 2
  • 7
  • 22
  • Pointers aren’t arrays. – Carl Norum May 21 '20 at 07:15
  • @CarlNorum Edited it as soon as I posted it, it was a stupid formulation of a sentence. – Rorschach May 21 '20 at 07:16
  • That was what our activity said: "Activity 11: Declare 3 variables x, y, and z as integer, float, and character with initial values 10, 12.5, and ‘G’ respectively. Also, declare 4 pointer variables p1, p2, p3, and p4 so that p1 points to x, p2 points to y, p3, and p4 point to z. " – JU-SethY May 21 '20 at 07:22
  • @SethJustinValenciano I didn't mean you should remove `p4`, I meant that the fact that you have two pointers both pointing to `z` doesn't influence the fact that you need/don't need asterisk. – Rorschach May 21 '20 at 07:25