-1

I'm working through some code for a class I'm taking, and since I'm not familiar with C++ I am confused by subscripting pointers.

My assumptions:

& prefixed to a variable name, gives you a pointer to the memory address of that value and is roughly inverse to * prefixed to a variable name, which in turn gives you the value that resides at a particular memory address.

Pointers are subscriptable, so that ptr[0] == ptr and ptr[n] == ptr + (n * data_bytes), where data_bytes depends on the particular type of the pointer (eg. 4 bytes wide for 32-bit ints).

The Problem:

When I want to subscript the memory address, I have to put it in a variable first, and I don't understand why I can't just subscript the variable directly.

Minimal Code Example:

#include <iostream>

using namespace std;

int main() {

    int val = 1;
    int *val_ptr = &val;

    cout << &val << endl;

    // works
    cout << val_ptr[0] << endl;

    // does not work
    // cout << &val[0] << endl;

    return 0;
}

Addendum

I am aware of some related questions, but they didn't really help me understand this specific issue.

I looked at:

and while this is almost certainly a duplicate (I will hardly be the first person that's confused by pointers), or maybe even has an answer that I overlooked in the linked questions, I'd appreciate any help!

Fynn
  • 303
  • 1
  • 11
  • 4
    Operator precedence. `[]` is considered before `&`. Do `(&val)[0]` instead. – Ted Klein Bergman May 05 '22 at 15:31
  • You forgot to ask the question. "I don't understand" and "it does not work" are not questions. Do you want to understand it or make it working? – 273K May 05 '22 at 15:34
  • When I want to subscript the memory address, I have to put it in a variable first, and I don't understand why I can't just subscript the variable directly. – Fynn May 05 '22 at 15:35
  • It's in there, but I agree, that it doesn't stand out enough. Would you think putting this at the start would improve readability/understandability? – Fynn May 05 '22 at 15:36
  • @TedKleinBergman thank you! That makes total sense. If you want to publish this as an answer I will accept immediately – Fynn May 05 '22 at 15:38
  • @273K just adding the ping. Also saying "I don't understand why ..." clearly implies a question, but if you want to be pedantic about it, I can change the wording =) – Fynn May 05 '22 at 15:40
  • 1
    `ptr[0] == ptr and ptr[n] == ptr + (n * data_bytes)` are both incorrect. We don't say that an address and the value at that address are `==` equal. For a pointer `p` and integer `i`, by definition `p[i] == *(p + i) == *(i + p) == i[p]`. Note that `int(p + i) == int(p) + i * sizeof(*p)`, that is, the multiplication by element size applies during pointer arithmetic. So `ptr + (n * bytes_per_element)` is wrong, it would multiply by element size twice. – Ben Voigt May 05 '22 at 16:15
  • @BenVoigt thanks for the clarification and pointing out, that I missed the asterisks! So you are saying that adding the 'offset' manually doesn't make sense, because C++ does it automatically? Therefore, I should change my assumption to `ptr[n] == *ptr + n` for it to be correct, right? (adding the asterisk and getting rid of the manual offsetting) Also thanks for suggesting the more idiomatic `sizeof` – Fynn May 05 '22 at 16:53
  • 1
    `ptr[n] == *(ptr + n)`, that's actually the definition of the `[]` operator (array subscripting). The parentheses are needed, due to operator precedence (which is what your question turned out to be about), if you write just `*ptr + n` that would be the same as `ptr[0] + n` not `ptr[0 + n]` – Ben Voigt May 05 '22 at 17:14

1 Answers1

1

As per Ted Klein Bergmann's comment, there was a problem with operator precedence.

[] is considered before &. Do (&val)[0] instead.

So a working example would be

#include <iostream>

using namespace std;

int main() {

    int val = 1;

    // does work now
    cout << (&val)[0] << endl;

    return 0;
}
Fynn
  • 303
  • 1
  • 11