2
#include <stdio.h>

int multi[2][3] = {{17, 23, 19}, {72, 34, 44}};

int main()
{
    printf("%p\n", multi);    //line 1
    printf("%p\n", *multi);   //line 2

    if(*multi == multi)
        puts("They are equal!");

    return 0;
}

第 1 行和第 2 行有何不同?

我得到输出:

They are equal

也有人可以参考一个关于指针及其与多维数组一起使用的好教程......

4

4 回答 4

2

值相同,但类型不同。

multi是类型int [2][3],并且在评估时将其转换为类型int (*)[3]

*multi是 typeint [3]并且在评估时它是 type int *

实际上:

*multi == multi

被编译器接受,但表达式在 C 中无效,因为运算符的两个操作数==属于不同类型。要执行比较,您需要转换两个操作数之一。

于 2012-08-04T13:35:51.560 回答
2

当你编译你的代码时,你的答案是由 gcc 给出的:

ml.c:10: warning: comparison of distinct pointer types lacks a cast

multi是一种二维int数组。那是int[][]

where*multi是一维int数组的类型。那是int[]

这就是为什么它们不是同一个对象。一个必须被铸造才有资格进行比较。让我们看看这个错误的代码是如何在幕后工作的。

令人惊讶的是,根本没有任何cmp指令!(用 编译-g -O0)。其实这里不需要cmp。因为multi将衰减为指向&multi[0][0]. 并且*multi会腐烂到&multi[0]. 因此,从内存的角度来看,它们是相同的,并且 c 编译器会愉快地优化它们(即使使用-O0:))。

(gdb) disassemble 
Dump of assembler code for function main:
   0x0000000000400504 <+0>: push   rbp
   0x0000000000400505 <+1>: mov    rbp,rsp
=> 0x0000000000400508 <+4>: mov    eax,0x400648
   0x000000000040050d <+9>: mov    esi,0x600900
   0x0000000000400512 <+14>:    mov    rdi,rax
   0x0000000000400515 <+17>:    mov    eax,0x0
   0x000000000040051a <+22>:    call   0x4003f0 <printf@plt>
   0x000000000040051f <+27>:    mov    edx,0x600900
   0x0000000000400524 <+32>:    mov    eax,0x400648
   0x0000000000400529 <+37>:    mov    rsi,rdx
   0x000000000040052c <+40>:    mov    rdi,rax
   0x000000000040052f <+43>:    mov    eax,0x0
   0x0000000000400534 <+48>:    call   0x4003f0 <printf@plt>
   0x0000000000400539 <+53>:    mov    edi,0x40064c
   0x000000000040053e <+58>:    call   0x400400 <puts@plt>
   0x0000000000400543 <+63>:    mov    eax,0x0
   0x0000000000400548 <+68>:    leave  
   0x0000000000400549 <+69>:    ret

它在调用之前唯一要做的puts()就是将它应该打印的字符串的地址移动到参数寄存器中。

gdb) x/10cb 0x40064c
0x40064c <__dso_handle+12>: 84 'T'  104 'h' 101 'e' 121 'y' 32 ' '  97 'a'  114 'r' 101 'e'
0x400654 <__dso_handle+20>: 32 ' '  101 'e'

你去吧,你把编译器弄糊涂了:)它通过优化去除了cmp可能。always true:)

专家 C 编程有一章名为(惊喜!惊喜!)

第 4 章令人震惊的真相:C 数组和指针不一样!

强烈推荐。

于 2012-08-04T14:12:51.350 回答
0

In brief in C a matrix is stored as a series of consecutive arrays wich are the rows of the matrix :

m has type pointer to array of 3 ints and is the address of the first array / row of the matrix

m* has type pointer to int and is the address of the first element of the first row

the same apply to m+1 wich is the address of the second array and for *( m + 1 ) wich is the address of the first element of the second array/row.

hope this helps.

于 2012-08-04T19:26:08.167 回答
0

当您使用 -Wall 进行编译时,编译器会警告您该行(原因:)comparison of distinct pointer types

如果(*多==多)

multi是数组,在 C 中他的地址是他的第一个元素 aka 的地址multi[0]*multi是指向数组的第一个元素的指针,也就是 multi[0]。

您正在比较两个包含相同数据的地址:( {17, 23, 19}),这解释了为什么会得到此输出。

希望这有帮助。

问候。

于 2012-08-04T14:05:05.023 回答