远指针和大指针的区别:
我们知道默认情况下指针是near 例如:int *p 是一个near 指针。在 16 位编译器的情况下,near 指针的大小为 2 个字节。而且我们已经非常清楚,编译器的大小因编译器而异;它们只存储它所引用的指针地址的偏移量。仅由偏移量组成的地址范围为 0 - 64K 字节。
Far 和 huge 指针:
Far 和 huge 指针的大小为 4 个字节。它们存储段和指针引用的地址的偏移量。那么它们之间的区别是什么?
远指针的限制:
我们不能通过对其应用任何算术运算来更改或修改给定远地址的段地址。也就是说,通过使用算术运算符,我们不能从一个段跳转到另一段。
如果您将远地址增加超过其偏移地址的最大值而不是增加段地址,它将以循环顺序重复其偏移地址。这也称为环绕,即如果偏移量是0xffff,我们加1,那么它就是0x0000,类似地,如果我们将0x0000 减1,那么它就是0xffff,记住段没有变化。
现在我要比较大指针和远指针:
1.当远指针递增或递减时ONLY指针的偏移量实际上是递增或递减的,但在大指针的情况下,段和偏移值都会改变。
考虑以下示例,取自HERE:
int main()
{
char far* f=(char far*)0x0000ffff;
printf("%Fp",f+0x1);
return 0;
}
那么输出是:
0000:0000
段值没有变化。
如果指针很大:
int main()
{
char huge* h=(char huge*)0x0000000f;
printf("%Fp",h+0x1);
return 0;
}
输出是:
0001:0000
这是因为增量操作不仅偏移值而且段值也会改变。这意味着在far指针的情况下段不会改变,但在huge指针的情况下,它可以从一个段移动到另一个段。
2.当在远指针上使用关系运算符时,仅比较偏移量。换句话说,如果被比较的指针的段值相同,关系运算符将仅对远指针起作用。并且在不会发生这种情况的情况下,实际上会进行绝对地址的比较。让我们借助far指针的示例来理解:
int main()
{
char far * p=(char far*)0x12340001;
char far* p1=(char far*)0x12300041;
if(p==p1)
printf("same");
else
printf("different");
return 0;
}
输出:
different
在huge 指针中:
int main()
{
char huge * p=(char huge*)0x12340001;
char huge* p1=(char huge*)0x12300041;
if(p==p1)
printf("same");
else
printf("different");
return 0;
}
输出:
same
解释:我们看到p 和p1 的绝对地址是12341(1234*10+1 或1230*10+41)但在第一种情况下它们被认为不相等,因为在far 指针的情况下仅比较偏移量,即它将检查是否0001==0041。这是错误的。
并且在大指针的情况下,比较操作是在相等的绝对地址上执行的。
-
远指针从不规范化,但 huge 指针已规范化。规范化指针是在段中具有尽可能多的地址的指针,这意味着偏移量永远不会大于 15。
假设如果我们有0x1234:1234,那么它的规范化形式是0x1357:0004(绝对地址是13574)。
一个巨大的指针只有在对其执行一些算术运算时才会被规范化,而在赋值期间不会被规范化。
int main()
{
char huge* h=(char huge*)0x12341234;
char huge* h1=(char huge*)0x12341234;
printf("h=%Fp\nh1=%Fp",h,h1+0x1);
return 0;
}
输出:
h=1234:1234
h1=1357:0005
解释:huge指针在赋值的情况下没有被规范化。但是如果对其进行算术运算,它就会被规范化。所以,h是1234:1234,h1是1357:0005which已标准化。
4.由于规范化,巨大指针的偏移量小于16,而远指针则不然。
让我们举个例子来理解我想说的话:
int main()
{
char far* f=(char far*)0x0000000f;
printf("%Fp",f+0x1);
return 0;
}
输出:
0000:0010
如果是huge 指针:
int main()
{
char huge* h=(char huge*)0x0000000f;
printf("%Fp",h+0x1);
return 0;
}
Output:
0001:0000
解释:当我们将远指针增加 1 时,它将是 0000:0010。当我们将大指针增加 1 时,它将是 0001:0000,因为它的偏移量不能大于 15,换句话说它将被标准化。