Ethical Hacking Programming, Blogging, Hosting, All Computer Software, PC Software Download, JAVA in hindi, HTML, PHP, C, C++, Free Learning, Software's Download, Technical Videos, Technical Tricks and Tips, How Make Money

Pointers What is a Pointer C programming Class 25

Pointers


A pointer is a variable that contains the address of a variable [KR88, page 93].

Pointers provide a mechanism for the direct manipulation of memory. They are arguably the most powerful, and the most dangerous, feature of the C programming language. To the novice program-mer who has not before encountered address-based computation, pointers can be a di cult concept to grasp. But with a little experience, they can be used to produce concise and e cient code.

Points have been described as a great way to create non-comprehensible programs with Goto Statement. This is certainly true when they are used casually, and pointers are easy to make, which is somewhere unpredictable, with discipline, however, pointers should also be used to achieve clarity and simplicity. Could  [KR88, page 93].

7.1 What is a Pointer?

To explain the operation of a pointer, it is first necessary to understand, at least in a basic sense, the way in which memory is organised. Figure 7.1 shows a simplified picture of a layout of computer memory. A typical machine has an array of consecutively numbered memory cells. These numbers are termed addresses. Each cell consists of a set of bits, and the cell bit-pattern is the cell’s value.

When a variable is defined, it is allocated a portion of memory. Thus, the variable has a value and an address for where that value resides. A pointer is a variable whose value is the address of another variable. Consider an example. (We will ignore, for the moment, various details such as the di erent byte-sizes for di erent types.) Let x be defined and initialised to the value 3.

char x = 3;

Assume this variable is stored at address 62. A pointer px is subsequently defined, assume it is stored at address 25, and initialised with the address of x as follows.

char *px = &x;

The value of px, therefore, is 62. Notice that a pointer is just another type of variable; it, also, has an address and may in turn be pointed-to by a pointer-to-a-pointer variable.

Memory cells may be grouped together to represent di erent variable types. On most machines, a cell is 8-bits long (i.e., one-byte). A char is usually one cell, a short int two cells, and a long int four cells. Each type (e.g., a double) has an associated pointer type (e.g., a double *), which is aware of the number of cells that the type occupies, and enables the compiler to behave appropriately with sequences of a particular type (e.g., an array of doubles).

On most machines, indicator variables also require multi-cell storage; Typically a pointer type is two-bytes for a 16-bit machine, and the pointer type is four-bytes for a 32-bit machine. However, it is not silly to make a perception about the type of indicator because such code is likely to be non-portable.

Figure 7.1: A simple memory model, where memory is an array of cells with constant addresses. At each address, a cell holds a particular value (i.e., bit-pattern). A variable x is defined that refers to the cell at address 62, and holds the value 3. A second variable px refers to the cell at address 25; it is defined as a pointer and holds the value 62, which is the address of x.

Aside. The one assumption about pointer sizes mandated by the C standard is that the pointer of type void* is large enough to store the value of any other pointer type. Zero * indicator type is a special general object pointer; It is designed to facilitate advanced techniques, which we see in chapter 14.


The size of a pointer type determines the maximum value it can represent, and hence the maxi-mum range of addresses it can deal with.For example, a 16-bit pointer can only handle addresses between 0 and 216 - 1 (i.e., 65535). The main reason for the development of 32-bit machines was to enable more memory addressing; A 32-bit indicator can address the bytes of memory from 0 to 232 - 1 (i.e., 42 9 497272).

7.2 Pointer Syntax

A pointer of a particular type is declared using the * symbol, and the address of a variable is obtained using the “address-of” operator &. For example,

int i;

int *j = &i;

defines a pointer-to-int variable j and initialises it with the address of i. This operation might equivalently have been written,

int *j, i;

j = &i;

It is worth noting that the * in a list of definitions refers only to the adjacent variable, and the spacing is irrelevant. For example, in the following,

int* i, j, * k;

i and k are pointers-to-int, while j is a plain int. The best style for such definitions is usually to place the * against the variable to which it refers.

int *i, *k, j;

The value of the variable to which a pointer points can be obtained using the indirection or dereferencing operator *.

int i = 2;

int *j = &i; /* Define a pointer-to-int j, and initialise with address of i. */ int x = *j; /* x is assigned the value of i (that is, 2). */

The dereferencing use of * should not be confused with its use in pointer-declaration syntax. The declaration *, meaning “is a pointer-type variable” occurs only in variable or function declarations, and in all other circumstances the * means dereference or “access the pointed-to object”.
Some examples of simple pointer operations are shown below.

char c = ’A’;

char *pc = &c; /* pc points to c */

double d = 5.34;

double *pd1, *pd2;

*pc = ’B’; /* Dereferenced pointer: c is now equal to ’B’. */ pd1 = &d; /* pd1 points to d */

pd2 = pd1; /* pd2 and pd1 now both point to d. */ *pd1 = *pd2 * 2.0; /* Equivalent to d = d * 2.0; */

Notice that pointers have di erent types specifying the type of object to which they can point. It is an error to assign a pointer to an object of a di erent type without an explicit cast.1

float i = 2.f;

unsigned long *p1 = &i; /* Error: type mismatch, won’t compile. */ unsigned long *p2 = (unsigned long *)&i; /* OK, but strange. */

The exception to this rule is the void* pointer which may be assigned to a pointer of any type without a cast.

It is dangerous practice to leave a pointer uninitialised, pointing to an arbitrary address. If a pointer is supposed to point nowhere, it should do so explicitly via the NULL pointer. NULL is a symbolic constant defined in the standard headers stdio.h and stddef.h. It is usually defined as

#define NULL ((void*) 0)

The constant values 0 or 0L may be used in place of NULL to specify a null-pointer value, but the symbolic constant is usually the more readable option.

Pointers may be declared const; and this may be done in one of two ways. The first, and most common, is to declare the pointer const so that the object to which it points cannot be changed.

int i = 5, j = 6;

const int *p = &i;

*p = j; /* Invalid. Cannot change i via p. */

However, the pointer itself may be changed to point to another object.

int i = 5, j = 6;

const int *p = &i;

p = &j; /* Valid. p now points to j. */

*p = i; /* Invalid. Cannot change j via p. */

The second form of const declaration specifies a pointer that may only refer to one fixed address.

That is, the pointer value may not change, but the value of the object to which it points may change.

int i = 5, j = 6;

int * const p = &i;

*p = j; /* Valid. i is now 6 */

p = &j; /* Invalid. p must always point to i. */

It is possible to combine these two forms to define a non-changing pointer to a non-changeable object.

int i = 5, j = 6;
const int * const p = &i;
*p = j; /* Invalid. i cannot be changed via p. */
p = &j; /* Invalid. p must always point to i. */

Share:

No comments:

Post a Comment

Follow On YouTube