求教指针运算

东边一耳 2011-10-24 06:45:48
int _tmain(int argc, _TCHAR* argv[])
{
int *ptr1,*ptr2;
ptr1 = (int *) -1;
ptr2 = NULL;
if(ptr1 > ptr2)
printf("ptr1 > ptr2\n");
else
printf("ptr2 > ptr1\n");
//printf("ptr1 - ptr2 = %x\n",ptr1 - ptr2);
//printf("0xffffffff - 0 = %d\n",0xffffffff - 0);
if(ptr1 - ptr2 > 0)
printf("ptr1 - ptr2 > 0\n");
else
printf("ptr2 - ptr1 > 0\n");
return 0;
}

为什么第一个if输出是ptr1>ptr2,而第二个输出是ptr2-ptr1>0,望高手指教
...全文
183 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
东边一耳 2011-10-27
  • 打赏
  • 举报
回复
恩,也只有理解了,感觉这个应该是编译器硬性规定的,也只有从结果去推断原因了


[Quote=引用 4 楼 zmlovelx 的回复:]

应该从语义上分析,
第一个:地址是没有负的,unsigned比较
第二个: 正常的signed比较。
[/Quote]
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 goldbeef 的回复:]
引用 4 楼 zmlovelx 的回复:

应该从语义上分析,
第一个:地址是没有负的,unsigned比较
第二个: 正常的signed比较。
++
[/Quote]
+++
free2011 2011-10-25
  • 打赏
  • 举报
回复
mark。受教育了。
机智的呆呆 2011-10-25
  • 打赏
  • 举报
回复
ptr1 = (int *) -1; 根据c99标准ptr1值由实现来定义
ptr1 > ptr2根据c99标准属于未定义行为
ptr1 - ptr2根据c99标准属于未定义行为
机智的呆呆 2011-10-25
  • 打赏
  • 举报
回复
ISO/IEC 9899:1999 (E)

6.3.2.3 Pointers
5 An integer may be converted to any pointer type. Except as previously specified, the result is implementation-defined, might not be correctly aligned, might not point to an entity of the referenced type, and might be a trap representation.56)

6.5.8 Relational operators
5 When two pointers are compared, the result depends on the relative locations in the address space of the objects pointed to. If two pointers to object or incomplete types both point to the same object, or both point one past the last element of the same array object, they compare equal. If the objects pointed to are members of the same aggregate object,pointers to structure members declared later compare greater than pointers to members declared earlier in the structure, and pointers to array elements with larger subscript values compare greater than pointers to elements of the same array with lower subscript
values. All pointers to members of the same union object compare equal. If the
expression P points to an element of an array object and the expression Q points to the last element of the same array object, the pointer expression Q+1 compares greater thanP. In all other cases, the behavior is undefined.

9 When two pointers are subtracted, both shall point to elements of the same array object, or one past the last element of the array object; the result is the difference of the subscripts of the two array elements. The size of the result is implementation-defined,and its type (a signed integer type) is ptrdiff_t defined in the <stddef.h> header.If the result is not representable in an object of that type, the behavior is undefined. In other words, if the expressions P and Q point to, respectively, the i-th and j-th elements of
an array object, the expression (P)-(Q) has the value i−j provided the value fits in an object of type ptrdiff_t. Moreover, if the expression P points either to an element of an array object or one past the last element of an array object, and the expression Q points to the last element of the same array object, the expression ((Q)+1)-(P) has the same value as ((Q)-(P))+1 and as -((P)-((Q)+1)), and has the value zero if the expression P points one past the last element of the array object, even though the expression (Q)+1 does not point to an element of the array object.88)
hondely 2011-10-25
  • 打赏
  • 举报
回复
mark
梦境传说 2011-10-25
  • 打赏
  • 举报
回复
#include "stdafx.h"
#include <iostream>
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{

int *ptr1,*ptr2;
ptr1 = (int *) -1;
ptr2 = NULL;
if(ptr1 > ptr2)
printf("ptr1 > ptr2\n");
else
printf("ptr2 > ptr1\n");
//printf("ptr1 - ptr2 = %x\n",ptr1 - ptr2);
//printf("0xffffffff - 0 = %d\n",0xffffffff - 0);
if(ptr1 - ptr2 > 0)
printf("ptr1 - ptr2 > 0\n");
else
printf("ptr2 - ptr1 > 0\n");

cout<<ptr1 - ptr2<<endl;

system("pause");
return 0;
}

在编译器下设置断点调试。。
赵4老师 2011-10-25
  • 打赏
  • 举报
回复
VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
想要从本质上理解C指针,必须学习汇编以及C和汇编的对应关系。
从汇编的角度理解和学习C语言的指针,原本看似复杂的东西就会变得非常简单!
指针即地址。“地址又是啥?”“只能从汇编语言和计算机组成原理的角度去解释了。”

提醒:
“学习用汇编语言写程序”

“VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
想要从本质上理解C指针,必须学习C和汇编的对应关系。”
不是一回事!

不要迷信书、考题、老师、回帖;
要迷信CPU、编译器、调试器、运行结果。
并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。
聪明的愚者 2011-10-25
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 goldbeef 的回复:]

引用 4 楼 zmlovelx 的回复:

应该从语义上分析,
第一个:地址是没有负的,unsigned比较
第二个: 正常的signed比较。
++
[/Quote]
深奥的地址问题。
心死 2011-10-25
  • 打赏
  • 举报
回复
坑爹的面试题,实际用不到的
绿野耕夫 2011-10-25
  • 打赏
  • 举报
回复
地址是个无符号型
地址的差值是个有符号型
goldbeef 2011-10-24
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 zmlovelx 的回复:]

应该从语义上分析,
第一个:地址是没有负的,unsigned比较
第二个: 正常的signed比较。
[/Quote]++
ouen333 2011-10-24
  • 打赏
  • 举报
回复
接着上面的(3,4是或的关系)。因为3不行,所以是4.
ouen333 2011-10-24
  • 打赏
  • 举报
回复
地址是无符号的
第一个没问题
第2个我觉得是这样的。。。
|ptr1| > |ptr2| -----------------------------1
由1得
|ptr1| - |ptr2| > 0-----------------------------2
因为ptr1为-1

-ptr1-ptr2 > 0 -----------------------------3
-ptr1+ptr2 > 0 -----------------------------4
3是不能成立的,因为地址取-是不允许的
SO...


「已注销」 2011-10-24
  • 打赏
  • 举报
回复
printf("%d",ptr2-ptr1);结果为0.
goodluckme2013 2011-10-24
  • 打赏
  • 举报
回复
ptr1 = 0xffffffff ptr2 = 0x00000000
ptr1与ptr2比较时是无符号的比较
ptr1-ptr2结果是有符号的
Song9007206710328 2011-10-24
  • 打赏
  • 举报
回复
第一个是因为地址的不同,因为第一个为-1,所以地址为0xFFFFFFFF,而第二个为0x00000000所以。。。
第二个是因为地址的相减自动转为unsigned int值,相减超出范围自动截断,所以。。。
帅得不敢出门 2011-10-24
  • 打赏
  • 举报
回复

.file "main.cpp"
.section .rodata
.LC0:
.string "ptr1 > ptr2"
.LC1:
.string "ptr2 > ptr1"
.LC2:
.string "ptr1 - ptr2 > 0"
.LC3:
.string "ptr2 - ptr1 > 0"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
movl %esp, %ebp
.cfi_offset 5, -8
.cfi_def_cfa_register 5
andl $-16, %esp
subl $32, %esp
movl $-1, 28(%esp)
movl $0, 24(%esp)
movl 28(%esp), %eax
cmpl 24(%esp), %eax
jbe .L2 //注意这里,
movl $.LC0, (%esp)
call puts
jmp .L3
.L2:
movl $.LC1, (%esp)
call puts
.L3:
movl 28(%esp), %edx
movl 24(%esp), %eax
movl %edx, %ecx
subl %eax, %ecx
movl %ecx, %eax
cmpl $3, %eax
jle .L4 //另一个是这里
movl $.LC2, (%esp)
call puts
jmp .L5
.L4:
movl $.LC3, (%esp)
call puts
.L5:
movl $0, %eax
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (SUSE Linux) 4.5.1 20101208 [gcc-4_5-branch revision 167585]"
.section .comment.SUSE.OPTs,"MS",@progbits,1
.string "ospwg"
.section .note.GNU-stack,"",@progbits


size 0110 JBE/JNA CF=1 or ZF=1 Jump if below or equal/not
above (unsigned comparisons)

size 1110 JLE/JNG ZF=1 or SF <> OF Jump if less or equal/not
greater (signed comparisons)

东边一耳 2011-10-24
  • 打赏
  • 举报
回复
回复2楼:我也想着指针是地址,是无符号的,那么第一个if成立。那第二个if ,当两个指针相减的时候,如果是无符号值的话,0xffffffff - 0 肯定比0大啊,为什么ptr1-ptr2的值又不大于0了呢???
帅得不敢出门 2011-10-24
  • 打赏
  • 举报
回复
应该从语义上分析,
第一个:地址是没有负的,unsigned比较
第二个: 正常的signed比较。

加载更多回复(3)

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧