在C中解释变量声明

时间:2013-06-05 07:34:13

标签: c pointers declaration

我在C程序中找到了这个声明

 char huge * far *p;
  

说明:p是巨大的指针,* p是远指针,** p是char类型   数据变量。

请详细解释声明。

PS:我不是在问这个巨大的指针。我是编程的新手

4 个答案:

答案 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使用这样的功能。