简体   繁体   English

C语言中的pointer [0]和* pointer之间的区别?

[英]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[] . 因此,我在C中将以下数组fib_sequence传递给了*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 . 仅供参考,这里是整个函数, 分配给索引1时失败。

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]) . 这意味着*fib_sequence[i]实际上是*(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] . 然后,通过您正确理解的等价*(E)(E)[0] ,该表达式表示(fib_sequence[i])[0] ,我们可以从中fib_sequence[i][0]不必要的括号以获得fib_sequence[i][0]

Remember postfix versus unary/prefix: *E , ++E , &E and others are all unary operators. 记住后缀与一元/前缀: *E++E&E和其他都是一元运算符。 E(...) , E[] , E->memb , E.memb are postfix. E(...)E[]E->memb E.membE.memb是后缀。

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] . 将postfix与postfix结合使用时,很明显:它们沿一个方向,从左侧的根表达式向右侧: 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 . 当一元合并时,相同的东西朝相反的方向: 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: 一旦我们扫过一元运算符以找到E ,优先级情况就是这样:

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). 附带说明:在某些情况下, *p不等于p[0] ,尽管它始终等价于*(p + 0) (在此处注意指针算法)。

Therefore, you may find p[0] refuses to compile when p is a function pointer, because it cannot participate in pointer arithmetics. 因此,当p是函数指针时,您可能会发现p[0]拒绝编译,因为它无法参与指针算术。 For data pointers, *p and p[0] doesn't really make any difference, however. 对于数据指针, *pp[0]并没有真正的区别。

*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). *pointerpointer[0]在C中完全相同。但这意味着*fib_sequence[i]fib_sequence[i][0]相同,后者与fib_sequence[0][i] (除非i碰巧是0)。 Suffix operators in C are all higher precedence than prefix operators. C中的后缀运算符都比前缀运算符具有更高的优先级。

Note that int *fib[] is parsed as int* (fib)[] ; 注意,将int *fib[]解析为int* (fib)[] ; that is, an unbounded array of int* . 也就是int*的无界数组。 You probably meant int (*fib)[] : a pointer to an unbounded array of integers. 您可能是说int (*fib)[] :指向无界整数数组的指针。 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). 做出更改后,第一个示例将不再编译 (应按其要求进行编译 ),但(*fib_sequence)[i]fib_sequence[0][i]均可以进行(也应按其要求进行)。

However, *fib_sequence = malloc(sizeof(int[count])) is now an error, because you can't assign an array value. 但是, *fib_sequence = malloc(sizeof(int[count]))现在是错误的,因为您无法分配数组值。 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. 这意味着您将不得不将malloc移出malloc之外,或者放弃int (*fib)[]语法,而改用int** fib

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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