int bar[10]和int (*bar)[10]的区别是什么?

4
int bar[10]; /* bar is array 10 of int, which means bar is a pointer to array 10 of int */

int (*bar)[10]; /* bar is a pointer to array 10 of int */

据我所知,它们两个是相同的,我错了吗?请告诉我。

编辑:int *bar [10] 完全不同。

谢谢 Raja


数组不是指针,指针也不是数组。请阅读comp.lang.c faq的第6章。既然您已经在那里了,还可以阅读其他章节 :-) - pmg
5个回答

9

它们是完全不同的。第一个是数组,第二个是指向数组的指针。

你在第一个 bar 声明后的注释绝对是错误的。第一个 bar 是一个由10个 int 组成的数组。这就是它的全部。它不是一个指针(也就是说,你所说的 "which means" 部分没有任何意义)。

可以这样表达:

typedef int T[10];

你的第一个bar的类型是T,而你的第二个bar的类型是T *。你理解TT *之间的区别了吗?


哦!所以在第二种情况下,当我执行bar ++时,它会跳过所有的10并指向下一个数组集? - Raja
2
我认为OP感到困惑是因为在C语言中,数组在某些情况下会自动衰减为指向其第一个元素的指针。在您的代码中,第一个“bar”可能是指针,但不像您的第二个示例那样是指向数组的指针。 - Carl Norum

3
你可以这样做:
int a[10];

int (*bar)[10] = &a;  // bar now holds the address of a

(*bar)[0] = 5;  // Set the first element of a

但是您不能这样做:
int a[10];

int bar[10] = a;  // Compiler error!  Can't assign one array to another

1

这两个声明并不声明相同的类型。

第一个声明声明了一个int数组。

第二个声明声明了一个指向int数组的指针。


0
这是一个关于 C 语言“右左规则”的链接,当阅读复杂的 C 声明时我发现它很有用:http://ieng9.ucsd.edu/~cs30x/rt_lt.rule.html。它也可能帮助你理解 int bar[10]int (*bar)[10] 之间的区别。
引自文章:
First, symbols.  Read

     *      as "pointer to"         - always on the left side
     []     as "array of"           - always on the right side
     ()     as "function returning" - always on the right side

as you encounter them in the declaration.

STEP 1
------
Find the identifier.  This is your starting point.  Then say to yourself,
"identifier is."  You've started your declaration.

STEP 2
------
Look at the symbols on the right of the identifier.  If, say, you find "()"
there, then you know that this is the declaration for a function.  So you
would then have "identifier is function returning".  Or if you found a 
"[]" there, you would say "identifier is array of".  Continue right until
you run out of symbols *OR* hit a *right* parenthesis ")".  (If you hit a 
left parenthesis, that's the beginning of a () symbol, even if there
is stuff in between the parentheses.  More on that below.)

STEP 3
------
Look at the symbols to the left of the identifier.  If it is not one of our
symbols above (say, something like "int"), just say it.  Otherwise, translate
it into English using that table above.  Keep going left until you run out of
symbols *OR* hit a *left* parenthesis "(".  

Now repeat steps 2 and 3 until you've formed your declaration.

这里有另一种更容易理解的思考方式:https://www.bookofbrilliantthings.com/book/eic/the-golden-rule-of-pointers /cc @BoReal - Chris Westin

0

还有cdecl(1)http://cdecl.org/

$ cdecl explain 'int bar[10]'
declare bar as array 10 of int

$ cdecl explain 'int (*bar)[10]'
declare bar as pointer to array 10 of int

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接