我在C程序中找到了这个声明
char huge * far *p;
说明:p是巨大的指针,* p是远指针,** p是char类型 数据变量。
请详细解释声明。
PS:我不是在问这个巨大的指针。我是编程的新手答案 0 :(得分:2)
巨大的指针不是标准C的一部分。它们是C语言的borland扩展,用于管理DOS和Windows 16 / 32bit中的分段内存。在功能上,声明所说的是** p是一个字符。这意味着“取消引用p以获取指向char的指针,取消引用以获取char”
为了理解C指针声明符语义,请尝试使用此表达式:
int* p;
这意味着p是指向int的指针。 (提示:从右向左阅读)
int* const p;
这意味着p是一个指向int的const指针。 (所以你不能改变p的值) 这是一个证据:
p= 42; // error: assignment of read-only variable ‘p’
另一个例子:
int* const* lol;
这意味着lol是指向int的const指针的指针。所以lol指向的指针不能指向另一个int。
lol= &p; // and yes, p cannot be reassigned, so we are correct.
在大多数情况下,从右到左阅读是有道理的。现在从右到左阅读有问题的表达式:
char huge * far *p;
现在,巨大的和远的只是由borland创建的指针的行为说明符。实际意味着什么
char** p;
“p是指向char的指针”
这意味着无论p指向什么,都指向一个char。
答案 1 :(得分:2)
** p 是character.Now指向此角色地址的指针将具有值& (** p)。再次,如果你想指针指向这个指针,那么接下来将是&(* p),结果将只是p。
如果你从右到左阅读下面的句子,你将得到所有
p是巨大的指针,* p是远指针,** p是char类型的数据变量。
简而言之,Intel x86芯片上的虚拟地址有两个组件 - 选择器和偏移量。选择器是基址[2]表的索引,偏移量被添加到该基地址。这旨在让处理器访问20位(在8086 / 8,186),30位(286)或46位(386及更高版本)的虚拟地址空间,而无需大的寄存器。
'far'指针有一个明确的选择器。但是,当你对它们进行指针运算时,选择器不会被修改。
'巨大'指针有一个明确的选择器。当你对它们进行指针运算时,虽然选择器可以改变。
答案 2 :(得分:1)
回到8086的16位日,它会声明一个32位指针指向char的“标准化”32位指针(或者指向其第一个数组)。
存在差异是因为32位指针由段号和段之间的偏移量组成,并且段重叠(这意味着两个不同的指针可以指向相同的物理地址;例如:0x1200:1000
和{{ 1}})。 0x1300:0000
限定符使用最高段号强制进行标准化(因此,最低可能的偏移量)。
但是,这种规范化具有成本性能,因为在每次修改指针的操作之后,编译器必须自动插入如下代码:
huge
使用:
ptr = normalize(ptr);
优点是使用你的记忆就像是平坦的,而不用担心细分和偏移。
答案 3 :(得分:0)
澄清其他答案:
far
关键字是非标准的C,但它不仅仅是古代PC时代的一个旧的过时扩展。今天,有许多现代的8位和16位CPU使用“存储”存储器来将可寻址存储器的数量扩展到65k以上。通常,它们使用特殊寄存器来选择存储体,从而有效地结束24位地址。市场上所有具有RAM +闪存的小型微控制器> 64kb使用这样的功能。