简体   繁体   中英

Difference between pointer[0] and *pointer in C?

So I have the following array fib_sequence in C passed to a function as *fib_sequence[] .

My function segfaults when I access an element by doing:

*fib_sequence[i]

However it works when I do:

fib_sequence[0][i]

Am I going insane or are these not equivalent?

For reference here is the entire function, it failed when assigned to index 1 only .

Segfault function

void fib(int *fib_sequence[], int count) {
    *fib_sequence = malloc(sizeof(int[count]));

    for (int i = 0; i < count; i++) {
        if (i == 0) {
            *fib_sequence[i] = 0;

        } else if (i == 1) {
            *fib_sequence[i] = 1;

        } else if (i >= 2) {
            *fib_sequence[i] = *fib_sequence[i-2] + *fib_sequence[i-1];
        }
    }
}

Working Function

void fib(int *fib_sequence[], int count) {
    *fib_sequence = malloc(sizeof(int[count]));

    for (int i = 0; i < count; i++) {
        if (i == 0) {
            fib_sequence[0][i] = 0;

        } else if (i == 1) {
            fib_sequence[0][i] = 1;

        } else if (i >= 2) {
            fib_sequence[0][i] = fib_sequence[0][i-2] + fib_sequence[0][i-1];
        }
    }
}

They are not equivalent, because postfix operators have a higher precedence than unary. This means that *fib_sequence[i] actually means *(fib_sequence[i]) . Then by the equivalence of *(E) and (E)[0] that you understand correctly, that expression means (fib_sequence[i])[0] , from which we can drop the unnecessary parentheses to get fib_sequence[i][0] .

Remember postfix versus unary/prefix: *E , ++E , &E and others are all unary operators. E(...) , E[] , E->memb , E.memb are postfix.

All unary and postfix can be clumped together as one. When postfix is combined with postfix, it's clear: they go in one direction, from the root expression on the left, toward the right: E[i]->foo.memb(arg)[blah] . The precedence is all the same and the associativity can obviously only be left to right.

When unaries are combined, same thing in the opposite direction: sizeof (T) &*++E . The precedence is all the same, and the associativity is right-to-left. All of these are higher than the various binary operators.

If we put these two together, we hardly have to think:

sizeof (T) &*++E[i]->foo.memb(arg)[blah]

Once we scan past the unary operators to find the E , the precedence situation is simply this:

sizeof (T) &*++ ( E[i]->foo.memb(arg)[blah] )
                ^---------------------------^

the postfix cruft all has higher precedence than the unary cruft.

Postfixes have the highest precedence, followed by unaries, then everything else.

You want to be aware that unary * and [] has different "precedence", and your expression

*foo[1]

is actually parsed as

*(foo[1])

You need to parenthesize your "preference" so it functions correctly:

(*foo)[1]

On a side note: In some cases *p is not equivalent to p[0] , though it's always equivalent to *(p + 0) (note the pointer arithmetic here).

Therefore, you may find p[0] refuses to compile when p is a function pointer, because it cannot participate in pointer arithmetics. For data pointers, *p and p[0] doesn't really make any difference, however.

*pointer and pointer[0] are exactly the same in C. But that means that *fib_sequence[i] is the same as fib_sequence[i][0] , which is NOT the same as fib_sequence[0][i] (unless i happens to be 0). Suffix operators in C are all higher precedence than prefix operators.

Note that int *fib[] is parsed as int* (fib)[] ; that is, an unbounded array of int* . You probably meant int (*fib)[] : a pointer to an unbounded array of integers. Once you make that change, your first example no longer compiles (as it should), but (*fib_sequence)[i] and fib_sequence[0][i] both work (also as they should).

However, *fib_sequence = malloc(sizeof(int[count])) is now an error, because you can't assign an array value. That means that you would have to move malloc outside of the function, or give up the int (*fib)[] syntax and use int** fib instead.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM