0

So while studying for my exams I was trying to do a practice problem for pointers.

In the following code I'm trying to display the number of elements before the first occurrence of 0.

There is only one part that i didn't understand please see the 6th last line.

#include <iostream>

using namespace std;

int main()
{
    int A[10];
    for (int i = 0; i < 10; i++){
        cout << "Please enter number " << i + 1 << " in the array: ";
        cin >> A[i];
    }
    int *Aptr = A;
    while(*Aptr !=0){
        cout << *Aptr << "";
        Aptr++;
    }
    cout << "\nThere are " << (Aptr - A)  //Here is what i don't understand.
    << " numbers before the first occurrence of 0." << endl;

    system("pause");
    return 0;
}

So why exactly is (Aptr - A) giving me the number of elements instead of a memory location, and why is this even doable since Aptr is a pointer and A is an array?

Can someone explain to me in detail?

4
  • 1
    An array and a pointer are not so different as they might seem. Commented Dec 16, 2016 at 5:50
  • 1
    also A is pointer that points to A[0] Commented Dec 16, 2016 at 5:54
  • See C++ pointer arithmetic. Commented Dec 16, 2016 at 5:56
  • 1
    What if the user entered 10 non-zero integers? Commented Dec 16, 2016 at 6:06

2 Answers 2

4

When used in an expression, like Aptr - A, the name of an array A will be implicitly converted to a pointer (equal to &A[0]).

Then the compiler is faced with subtracting two pointers of the same type (both of type int * in your case). That is specified as giving a value of type std::ptrdiff_t, which is, in turn "a signed integral type able to represent the result of subtracting two pointers".

Pointer arithmetic, when subtracting two pointers of type int (i.e. two int *s) gives the number of ints between the two pointers (assuming they are in the same object, which is true in this case, since Aptr points at an element of the array A).

Practically, if Aptr is equal to &A[i], the subtraction Aptr - &A[0] gives a std::ptrdiff_t equal to i.

Note: there is another problem in your code, as since the first (for) loop reads 10 values, while the second while loop keeps incrementing Aptr until it points at an int with value 0. If the user enters any zero values, the second loop will stop when it finds the first (even if the user enters non-zero elements after that). If the user enters no values equal to 0, then the while loop has undefined behaviour, since Aptr will keep walking through memory past the end of A until it happens to find memory that compares (as an int) equal to 0.

Sign up to request clarification or add additional context in comments.

Comments

1

First of all, name of array A is associated to address of (pointer at) the first item in the array.

So why exactly is (Aptr - A) giving me the number of elements?

Because according to rules address arithmetic subtraction operation (also +, and similar) is performed based on the data type.

I mean, that compiler operating with int* makes ++, --, addition, subtraction an integer, etc. adds addresses needed for shifting to next/previous item.

If you really want to see how many bytes are located between addresses, just convert addresses to int before making subtraction:

 cout << endl << "Address difference is " << int(Aptr) - int(A) << endl;

You can try that with different data types as follows:

#include <iostream>
#include <iomanip>
using namespace std;

int main()
{
    int A[5];
    short B[5];
    unsigned char C[5];
    cout << "Array (data type) | Syze of array | Size of item | Item distanse | Bytes distance" << endl;
    cout << "A (int)           :" << setw(10) 
                            << sizeof(A) << setw(15)
                            << sizeof(A[0]) << setw(15) 
                            << &A[4] - A << setw(15) 
                            << int(&A[4]) - int(A) << endl;
    cout << "B (short)         :" << setw(10) 
                            << sizeof(B) << setw(15)
                            << sizeof(B[0]) << setw(15) 
                            << &B[4] - B << setw(15) 
                            << int(&B[4]) - int(B) << endl;
    cout << "C (un.char)       :" << setw(10)
                            << sizeof(C) << setw(15)
                            << sizeof(C[0]) << setw(15)
                            << &C[4] - C << setw(15)
                            << int(&C[4]) - int(C) << endl;

    system("pause");
    return 0;
}

UPDATE

To be better prepared for your exam, consider the following example with pointers:

#include <iostream>
using namespace std;

int main()
{
    int A[5] = {0}; // all items now are 0
    int * P = A + 2; // the same as P = &A[2];
    *P = 33; // writing to item A[2];
    cout << A[2] << endl; // just to check in usual way
    cout << *(A + 2) << endl; // using A as a pointer
    cout << *(2 + A) << endl; // almost the same to previous
    cout << 2[A] << endl; // quite strange, but it works
    cout << 0[P] << endl; // and this is the same
    return 0;
}

You must understand that 0[P] means for compiler *(0 + P), as well as 2[A] means - *(2 + A), but you should not write in your program in such style (exceptions are only cases when you want to confuse a reader).

And one more important thing - difference between array and pointer - are shown in the following example:

    int A[] = {1, 2, 3, 4, 5};
    int *P = A;
    cout << "A = " << A << endl;
    cout << "P = " << P << endl;
    cout << "size of A = " << sizeof(A) << endl;
    cout << "size of P = " << sizeof(P) << endl;

even if the addresses (vaules A and P) are equal, compiler works with array (A) in a different way than with pointer: sizeof(A) means memory allocated for whole array (5 items of sizeof(int) each), but sizeof(P) means memory allocated for data type int * (pointer to int). So, sizeof(P) depends only on compiler and OS platform (e.g. pointer can be 32-bit or 64-bit), but sizeof(A) depends on size of item (int may be not 32 bits) and NUMBER OF ITEMS in the array.

And you can "go to the next item" with pointer:

  P++;
  cout << *P << endl;

but you are not able to do:

  A++;

because A is not variable of pointer type (it is just similar in sense of "address of the first item"), and compiler will say you something like:

error : '++' needs l-value

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.