当你编译你的代码时,你的答案是由 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 数组和指针不一样!
强烈推荐。