简体   繁体   中英

Explain variable declaration in C

I found this declaration in a C program

 char huge * far *p;

Explanation: p is huge pointer, *p is far pointer and **p is char type data variable.

Please explain declaration in more detail.

PS: I'm not asking about huge or far pointer here. I'm a newbie to programming

Huge and far pointers are not part of standard C. They are borland extensions to the C language for managing segmented memory in DOS and Windows 16/32bit. Functionally, what the declaration says is **p is a char. That means "dereference p to get a pointer to char, dereference that to get a char"

In order to understand C pointer declarator semantics try this expression instead:

int* p; 

It means p is a pointer to int. (hint: read from right to left)

int* const p;

This means p is a const pointer to int. (so you can't change the value of p) Here's a proof of that:

p= 42; // error: assignment of read-only variable ‘p’

Another example:

int* const* lol; 

This means lol is a pointer to const pointer to int. So the pointer which lol points at cannot point at another int.

lol= &p; // and yes, p cannot be reassigned, so we are correct.

In most cases reading from right to left makes sense. Now read the expression in question from right to left:

char huge * far *p;

Now the huge and far are just behaviour specifiers for pointers created by borland. What it actually means is

char** p;

"p is a pointer to pointer to char"

That means whatever p points to, points to a char.

**p is character.Now a pointer pointing to address of this character will have value & (**p). Again if you want to take pointer to this pointer then next will be &(*p) and result will be p only.

If you read below sentence from right to left, you will get it all

p is huge pointer, *p is far pointer and **p is char type data variable.

In a nutshell virtual addresses on an Intel x86 chip have two components - a selector and an offset. The selector is an index into a table of base addresses [2] and the offset is added onto that base address. This was designed to let the processor access 20 bit (on a 8086/8, 186), 30 bit (286) or 46 bit (386 and later) virtual address spaces without needing registers that big.

'far' pointers have an explicit selector. However when you do pointer arithmetic on them the selector isn't modified.

'huge' pointers have an explicit selector. When you do pointer arithmetic on them though the selector can change.

Back in the 16-bit days on 8086, it would have declared a 32-bit pointer to a "normalized" 32-bit pointer to char (or to the first of an array thereof).

The difference exists because 32-bit pointers were composed of a segment number and offset between that segment, and segments overlapped (which meant two different pointers could point to the same physical address; example: 0x1200:1000 and 0x1300:0000 ). The huge qualifier forced a normalization using the highest segment number (and therefore, the lowest possible offset).

However, this normalization had a cost performance-wise, because after each operation that modified a pointer, the compiler had to automatically insert a code like this:

ptr = normalize(ptr);

with:

void huge * normalize(void huge *input)
{
    unsigned long input2 = (unsigned long)input;
    unsigned short segment = input >> 16;
    unsigned short offset = (unsigned short)input;

    segment += (offset >> 4);
    offset &= 0x000F;

    return ((unsigned long)segment) << 16 | offset;
}

The upside was the advantage of using your memory like it was flat, without worrying about segments and offsets.

Clarification to the other answers:

The far keyword is non-standard C, but it is not just an old obsolete extension from ancient PC days. Today, there are many modern 8 and 16 bit CPUs that uses "banked" memory to extend the amount of addressable memory beyond 65k. Typically they use a special register to pick a memory bank, effectively ending up with 24-bit addresses. All small microcontrollers on the market with RAM+flash memory > 64kb use such features.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM