What is the difference between (pointer + n) and pointer[n]?

97 Views Asked by At

In this code, I don't understand why the input character value is being put into (ptr + i) but then we print out ptr[i]. I know they are different because I am printing out the values in the first for loop, but I don't understand what the difference between them is and why we are using one to accept input with scanf and a different one to output.

#include<stdio.h>
#include<stdlib.h>
int main ()
{
    int n, i;
    char *ptr;
    printf ("Enter number of characters to store: ");
    scanf ("%d", &n);

    ptr = (char *) malloc (n * sizeof (char));
    printf("POINTER %p\n", ptr);
    for (i = 0; i < n; i++)
    {
        printf ("Enter ptr[%d] (%p) (%p): ", i, ptr[i], ptr + i);
        /* notice the space preceding %c is
            necessary to read all whitespace in the input buffer
        */
        scanf (" %c", ptr + i);
    }

    printf ("\nPrinting elements of 1-D array: \n\n");
    for (i = 0; i < n; i++)
    {
        printf ("%c ", ptr[i]);
    }

    //signal to operating system program ran fine
    return 0;
}

In addition, I know doing ptr + i = ptr + (i * numberofbytes) based on the number of bytes of the data type of pointer, so it makes sense that we would store each new input into a memory address with that number of bytes that we used malloc for. But then why do we print out ptr[i] instead of ptr + i?

Hope this is described specifically enough, let me know if it isn't.

Thank you!

3

There are 3 best solutions below

0
Vlad from Moscow On

Due to the pointer arithmetic the expression ptr + i has the type char * and points to the i-th elemenet of the array. The function scanf expects a pointer to an object to which the entered data will be stored.

The expression ptr[i] that is the same as *( ptr + i ) yields the object pointed to by the expression ptr + i.

From the C Standard (6.5.2.1 Array subscripting)

2 A postfix expression followed by an expression in square brackets [] is a subscripted designation of an element of an array object. The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2))). Because of the conversion rules that apply to the binary + operator, if E1 is an array object (equivalently, a pointer to the initial element of an array object) and E2 is an integer, E1[E2] designates the E2-th element of E1 (counting from zero).

So the expression ptr + i points to the i-th object. And the expression *( ptr + i ) that is the same as ptr[i] yields the object itself pointed to by the expression ptr + i.

0
ikegami On

ptr[i] is equivalent to *(ptr + i), by definition.

This means that

&ptr[i] is equivalent to &*( ptr + i ) and thus to ptr + i.

As such, the difference is that the code passes the value of ptr[i] to printf, but the address of ptr[i] to scanf.

We need to pass a pointer to scanf because having the value of ptr[i] does not allow it to write to ptr[i]. Only passing the address of ptr[i] does that. But printf simply needs the value to format and print. It doesn't care from where the value came.

// Passes a pointer to `ptr[i]` to `scanf`.
// `scanf` will write at the address pointed by this pointer.
scanf( " %c", ptr + i );

// Same
scanf( " %c", &ptr[i] );

// Passes the value of `ptr[i]`.
// `printf` will print a formatting of that value.
printf( "%c ", ptr[i] );
0
Geetesh Paidi On

The value at the address of (ptr+i) or simply (ptr+i) is the same as ptr[i]. You have mentioned that you know ptr+i denotes the memory location as (ino.of bytes of the pointer's data type). I think it is notable to mention that an array is also a pointer pointing towards the Zeroth index of array. Another main thing is that although both as a pointer and array they are the same, you cannot reinitialise an array once it is initialised as int array[size] , but you can always reinitialise an array if it was initialised as array: *int array

Thus I would say both are same and you should use them according to your problem and convenience. I hope this helped.