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

Pass By Reference Pointers and Arrays C programming Class 26

7.3 Pass By Reference


When a variable is passed to a function, it is always passed by value. That is, the variable is copied to the formal parameter of the function argument list. As a result, any changes made to the local variables within the function will not a ect the variables of the calling function. For example, the following code to swap two variables will not work as intended.

swap(a, b); /* Pass values of a and b, respectively. */

void swap(int x, int y)

/* x and y are copies of the passed arguments. */

{

int tmp = x; /* The variable x is unrelated to the variable a */

x = y; /* so this operation does not affect a. */

y = tmp;

}

The variables x and y are di erent to a and b; they are stored at di erent addresses, and are simply initialised with the values of a and b.
The desired e ect of this function can be achieved by using pointers. Pointers, as with any other variable, are passed by value, but their values are addresses which, when copied, still point to the original variables.

swap(&a, &b); /* Pass pointers to a and b, respectively. */

void swap(int* px, int* py)

/* px and py are copies of the passed pointer arguments. */

{

int tmp = *px; /* The value of px is still the address of a */

*px = *py; /* so this dereferencing operation is equivalent to a = b. */

*py = tmp;

}

Pointers provide indirect access to variables. This is why the * operator is called the indirection operator. Passing pointers as function arguments, therefore, is known as “pass-by-reference”.

Pass by reference semantics is useful for implementing functions, such as swap() above, that require multiple return values. It is also useful as a mechanism to avoid copying large objects between functions; rather than make a copy of a large object, it is su cient to pass a pointer to the object. (Arrays are a good example2 of this and, in C, arrays are passed by reference by default. When passed as a function argument, an array name is automatically converted to a pointer to its first element.) It is possible to prevent unwanted change to a pass-by-reference argument by declaring the parameter const. For example,

void cannot_change(const double *array, int len)

/* May perform read-only operations on array */

{

int i;

for (i = 0; i<len; ++i) {

*(array + i) = 3.2; /* Invalid. Pointed-to objects cannot be changed. */

array[i] = 5.4; /* Invalid. */

printf("%f ", array[i]); /* Valid. */

}

}


Other forms of “large object” may be defined by the programmer as user-defined types, such as structs (see Chapter 11).

A const-pointer declaration has two purposes. It enables the compiler to enforce compile-time checks that the passed object is not changed within a function (i.e., it assists in ensuring the function is correct), and it informs the users of a function that the function will not modify the object they pass to it (i.e., it specifies a “non-modifying” guarantee).

7.4 Pointers and Arrays


Indicators and arrays are strongly related; So many programmers often believe that they are doing the same thing. This is often the case, but not always when an array name appears in an expression, it automatically gets an indicator converted into its first element. for example,

unsigned buffer[256];

unsigned *pbuff1 = buffer; /* Buffer converted to pointer, & not required. */

unsigned *pbuff2 = buffer + 5; /* A "pointer-plus-offset" expression. */

Here pbuff1 points to element 0 of the array, and pbuff2 points to element 5. Similarly, when an array name is passed to a function, it is converted to a pointer.Thus, in the following example, pdouble and Darray are equivalent; They are both indicators

void func(double *pdouble, int len);

void func(double darray[], int len);

An array name and a pointer to an array may be used interchangeably in many circumstances, such as array indexing. Consider the following example, where, within each commented group, the statements perform exactly the same operation.

char letters[26];

char *pc1 = letters; /* Equivalent pointer values. */

char *pc2 = &letters;

char *pc3 = &letters[0];

letters[4] = ’e’; /* Equivalent indexes. */

pc1[4] = ’e’;

*(letters + 4) = ’e’;

*(pc2 + 4) = ’e’;

pc3 = &letters[10]; /* Equivalent addresses. */
pc3 = &pc1[10];
pc3 = letters + 10;
pc3 = pc2 + 10;

Notice that, for an array, its name (e.g., letters) when used in an expression is equivalent to its address (e.g., &letters), which is equal to the address of its first element (e.g., &letters[0]). The elements of an array can be accessed via the index operator (e.g., pc1[4]) or by a dereferenced pointer o set (e.g., *(pc2 + 4)). And the address of an array element can be obtained using the address-of operator (e.g., &letters[10]) or directly from the pointer o set (e.g., letters + 10).

However, an array is not equivalent to a pointer, and there are several important di erences.

First, an array is not a variable; its value cannot be changed.

int a1[10], a2[10];

int *pa = a1;

a1 = a2; /* Error: won’t compile. */

a1++; /* Error: won’t compile. */

pa++; /* Fine, a pointer is a variable. */

Second, an array name always refers to the beginning of a portion of the allocated memory, whereas one indicator can be anywhere (e.g., allocated memory, free storage, NULL). And third, the size of an array is the number of characters in memory allocated, while the size of a pointer is just the size of the pointer variable.

double a1[10];

double *pa = a1;

size_t s1 = sizeof(a1); /* s1 equals 10 * sizeof(double) */ size_t s2 = sizeof(pa); /* s2 equals sizeof(double *) */

Share:

No comments:

Post a Comment

Follow On YouTube