Theoretical Paper
- Computer Organization
- Data Structure
- Digital Electronics
- Object Oriented Programming
- Discrete Mathematics
- Graph Theory
- Operating Systems
- Software Engineering
- Computer Graphics
- Database Management System
- Operation Research
- Computer Networking
- Image Processing
- Internet Technologies
- Micro Processor
- E-Commerce & ERP
Practical Paper
Industrial Training
Pointers
printf ( "%u%u%u%u", &a, &ch, &i ) ; /* prints addresses of a, ch and i */
b = &a ; /* assigns address of a to b */
dh = &ch ; /* assigns address of ch to dh */
j = &i ; /* assigns address of i to j */
printf ( "%u%u%u", *b, *dh, *j ) ; /* prints value at address stored in b,
dh and j respectively */
printf ( "%u%u%u%u", b, dh,j ) ; /* prints the value in b, dh, j which is
the address of a, ch, j respectively*/
b++ ; /* makes the pointer b point to a location adjacent to variable a */
dh++ ; /* makes the pointer dh point to a location adjacent to variable ch */
j++ ;/* makes the pointer j point to the location adjacent to variable i */
/* += -= operators can be used in pointer arithmetic */
b+= 3 ; dh += 8 ;
j-= 3 ;
printf ( "%u%u%u%u", b, dh, j );
}
near, far and huge Pointer
(The information that follows is specific to DOS operating system only)
While working under DOS only 1 mb (10,48,580 bytes) of memory is accessible. Any of these memory locations are accessed using CPU registers. Under DOS the CPU registers are only 16 bits long. Therefore, the minimum value present in a CPU register could be 0, and maximum 65,535. Then how do we access memory locations beyond 65535th byte? By using two registers (segment and offset) in conjunction. For this the total memory (1 mb) is divided into a number of units each comprising 65,536 (64 kb) locations. Each such unit is called a segment. Each segment always begins at a location number which is exactly divisible by 16. The segment register contains the address where a segment begins, whereas the offset register contains the offset of the data/code from where the segment begins. For example, let us consider the first byte in B block of video memory. The segment address of video memory is B0000h (20-bit address), whereas the offset value of the first byte in the upper 32K block of this segment is 8000h.
Since 8000h is a 16-bit address it can be easily placed in the offset register, but how do we store the 20-bit address B0000h in a 16-bit segment register? For this out of B0000h only first four hex digits (16 bits) are stored in segment register. We can afford to do this because a segment address is always a multiple of 16 and hence always contains a 0 as the last digit. Therefore, the first byte in the upper 32K chunk of B block of video memory is referred using segment:offset format as B000h:8000h. Thus, the offset register works relative to segment register. Using both these, we can point to a specific location anywhere in the 1 mb address space.
Suppose we want to write a character `A' at location B000:8000. We must convert this address into a form which C understands. This is done by simply writing the segment and offset addresses side by side to obtain a 32 bit address. In our example this address would be 0xB0008000. Now whether C would support this 32 bit address or not depends upon the memory model in use. For example, if we are using a large data model (compact, large, huge) the above address is acceptable. This is because in these models all pointers to data are 32 bits long. As against this, if we are using a small data model (tiny, small, medium) the above address won't work since in these models each pointer is 16 bits long.
What if we are working in small data model and still want to access the first byte of the upper 32K chunk of B block of video memory? In such cases both Microsoft C and Turbo C provide a keyword called far, which is used as shown below,
char far *s = 0XB0008000;
A far pointer is always treated as 32 bit pointer and contains both a segment address and an offset.
A huge pointer is also 32 bits long, again containing a segment address and an offset. However, there are a few differences between a far pointer and a huge pointer.
A near pointer is only 16 bits long, it uses the contents of CS register (if the pointer is pointing to code) or contents of DS register (if the pointer is pointing to data) for the segment part, whereas the offset part is stored in the 16-bit near pointer. Using near pointer limits your data/code to current 64 kb segment.
The following table captures the essence of these different types of pointers along with the pointer type supported by each memory model.