The final part of the pointers. The source code for this module is: C/C++ pointers program source codes. The lab worksheets for your practice are:C/C++ pointers part 1 andC/C++ pointers part 2. Also the exercises in theIndirection Operator lab worksheet 1,lab worksheet 2 and labworksheet 3.
| 8.11 Null Pointer Constant
/* declare a pointer to type char */ char *bufptr; /* allocate memory on the heap */ bufptr = malloc(1000); /* verify the memory allocation if fail… */ if (bufptr == NULL) { printf("Memory allocation is failed lol!\n"); } /*If OK….*/ else { /* call the LoadBuffer() function */ LoadBuffer(bufptr); } ... /* free up memory on the heap */ free(bufptr); bufptr = NULL;
8.12 void Pointers
|
#include <stdio.h>
/* void pointer */
int func(void *thePtr);
int main()
{
/* assigning a string to the pointer */
char *theStr = "abcd1234";
func(theStr);
return 0;
}
int func(void *thePtr)
{
printf("%s\n", thePtr);
return 0;
}
A pointer can only be copied from a pointer of the same type, or from a pointer to void. A pointer to void is a generic pointer that can be used to hold an address, but cannot be 'de-referenced', that means you can’t use it with an asterisk before it to update a variable. It acts as a placeholder.
void pointers are commonly used in the parameter list of built-in functions, such asmemcpy() and memset(). This is why you can use the same function to copy strings (pointer to character) and structures (pointer to structure).
On the other hand, when neither pointer is of type pointer to void, the only way to copy an address from a pointer of a different type is to cast the second pointer to the type of the first pointer as shown below:
char *bufptr;
struct record *recptr;
recptr = (struct record *)bufptr;
----------------------------------------------------------Have a break!------------------------------------------------------------
Passes arguments in a function definition header by reference.
function_name (¶meter, ..., ...)
{statements}
The default function calling convention is to pass by value. The reference operator can be applied to parameters in a function definition header to pass the argument by reference instead.
The reference types created with the & operator, create aliases for objects and let you pass arguments to functions by reference.
When a variable x is passed by reference to a function, the matching formal argument in the function receives an alias for x. Any changes to this alias in the function body are reflected in the value of x.
When a variable x is passed by value to a function, the matching formal argument in the function receives a copy of x. Any changes to this copy within the function body are not reflected in the value of x itself. The function also can return a value that could be used later to change x, but the function cannot directly alter a parameter passed by value.
The reference operator is only valid when used in function definitions as applied to one or more of its parameters. It can be used to obtain the address of a variable.
Study the following illustration and memorize it, you will remember what the pointer and reference are, forever :o).
*ptr - a pointer variable
var - a normal variable
// declare a pointer variable ptr of type int
int *ptr;
// declare and initialize normal variable var of type int
int var = 123;
// assign the address of normal variable var to pointer ptr.
ptr = &var;
So, the pointer ptr now is pointing to the data value 123, hold by variable var.
The & and * operators work together to reference and dereference pointers that are passed to functions.
Syntax
&expression e.g. &var
*expression e.g. *ptr
Referencing operator ( & )
Use the reference operator to pass the address of a pointer to a function. The expression operand must be one of the following:
• A function designator - an lvalue (left value) designating an object that is not a bit field and is not declared with a register storage
• Class specifier
If the operand is of type type, the result is of type pointer to type. Consider the following generic code examples:
type varA = 1, varB = 2;
type *ptr = &varA; // initialized pointer
*ptr = varB; // same as varA = varB
type *ptr = &varA is treated as
type *ptr;
ptr = &varA;
So it is ptr, or *ptr, that gets assigned. Once ptr has been initialized with the address &varA, it can be safely de-referenced to give the lvalue *ptr.
Use the asterisk (*) in a variable expression to create pointers. And use the indirect operator in external functions to get a pointer's value that was passed by reference. If the operand is of type pointer to function, the result is a function designator.
If the operand is a pointer to an object, the result is an lvalue designating that object.
The result of indirection is undefined if either of the following occurs:
Other pointer declarations that you may find and can make you confused :o) are listed below.
Pointer declaration | Description |
int *x | x is a pointer to int data type. |
int *x[10] | x is an array[10] of pointer to int data type. |
int *(x[10]) | x is an array[10] of pointer to int data type. |
int **x | x is a pointer to a pointer to an int data type – double pointers. |
int (*x)[10] | x is a pointer to an array[10] ofint data type. |
int *funct() | funct is a function returning an integer pointer. |
int (*funct)() | funct is a pointer to a function returning int data type – quite familiar constructs. |
int (*(*funct())[10])() | funct is a function returning pointer to an array[10] of pointers to functions returning int. |
int (*(*x[4])())[5] | x is an array[4] of pointers to functions returning pointers to array[5] ofint. |
And something to remember:
* | - is a pointer to |
[ ] | - is an array of |
( ) | - is a function returning |
& | - is an address of |
-------------------------------------------------------Have a break!-------------------------------------------------------
// program that changes the value of a pointer variable
#include <iostream>
using namespace std;
void main()
{
// declare and initialize twofloat variables
float var1 = 58.98;
float var2 = 70.44;
// declare a float pointer variable
float *ptr_var;
// make ptr_var point to variable var1...
ptr_var = &var1;
// prints 58.98
cout<<"\nThe first value is(var1) "<<*ptr_var;
cout<<"\nThe address of the first data is "<<ptr_var<<"\n";
cout<<"\nThen let the same pointer (*ptr_var)";
cout<<"\npoint to other address...\n";
// make ptr_var point to variable var2...
ptr_var = &var2;
// prints 70.44
cout<<"\nThe second value is(var2) "<<*ptr_var;
cout<<"\nThe address of the second data is "<<ptr_var<<endl;
}
This program demonstrates how you can make a pointer point to different values in memory. The program defines two floating-point values.
A floating-point pointer points to the first variable var1 and is used in thecout statement. The same pointer is then changed to point to the second variablevar2.
// illustrates that function receives addresses
// of variables and then alters their contents
#include <iostream>
using namespace std;
void main()
{
int x = 4, y = 7;
// function prototype...
void addcon(int*, int*);
cout<<"\nInitial value of x = "<<x;
cout<<"\nInitial value of y = "<<y;
cout<<"\nThen calls function addcon()\n";
cout<<"\nBringing along the &x = "<<&x<<endl;
cout<<"and &y = "<<&y<<"\n";
cout;
// function call, address of x any y are passed to addcon()
addcon(&x, &y);
cout<<"\nAdd 10...";
cout<<"\nNew value of x = "<<x;
cout<<"\nminus 10...";
cout<<"\nNew value of y = "<<y<<endl;
}
// a function definition, parameters are pointers...
void addcon(int *px, int *py)
{
// adds 10 to the data stored in memory pointed to by px
*px = *px + 10;
// minus 10 to the data stored in memory pointed to by py
*py = *py - 10;
}
The program illustrates the use of pointers. The function main() invokes the function addcon() with two arguments of type pointer, the first one gives the address of variable x and the second the address of variable y.
The addcon() function then uses the addresses received from the function main() to reference the value of x and y. It then increments the values of x by 10 and decrement the value ofy by 10 and restore the results. After execution, x will have the value 14 and y the value of -3.
This program outputs the values in the array nums, using a pointer rather than index/subscript. In the first loop iteration,*(nums + dex) refers to the first value (given by index 0) in the array nums (that is 92); in the second iteration, it refers to the second value (given by index 1) in the array (that is 81), and so on.
// a program that uses pointers to print the values of an array
#include <iostream>
using namespace std;
void main()
{
// declare and initialize an array nums
int nums[ ] = {92,81,70,69,58};
cout<<"\nArray's element Memory address";
cout<<"\n----------------------------------";
// using for loop, displays the elements
// of nums and their respective memory address
for(int dex=0; dex<5; dex++)
cout<<"\n\t"<<*(nums + dex)<<"\t\t"<<(nums + dex);
cout<<"\n----------------------------------\n";
}
----------------------------------------------------------------
This program first reads an arbitrary number of temperature readings into the array temper using pointers (rather than subscripts).
Then, again using pointers, it computes the average temperature. The program terminates when the value entered for temperature is 0.
// to compute the average of an arbitrary number of temperature readings
#include <iostream>
using namespace std;
void main()
{
float temper[40], sum = 0.0, *ptr;
int num, day = 0;
// set a pointer to an array...
ptr = temper;
do
{
// prompt for input user input...
cout<<"Enter temperature for day "<<++day;
//store in an array, pointed by ptr...
cout<<"\n(0-Terminate, Enter-Proceed): ";
cin>>*ptr;
// test if data entered is 0, then point to the next array position
} while ((*ptr++) > 0);
// reset the pointer ptr to an array temper
ptr = temper;
num = (day – 1);
// looping through the array temper...
for(day = 0; day < num; day++)
// do the summing up...
sum += *(ptr++);
// display the result...
cout<<"\nAverage temperature = "<<(sum/num)<<" Degree Celsius"<<endl;
cout<<"for "<<num<<" readings"<<endl;
}
// using subscript and pointer notations with arrays
#include <stdio.h>
void main()
{
int i, offset, b[ ] = {10, 20, 30, 40};
// set bPtr to point to array b
int *bPtr = b;
printf("So many notations?????....\n");
//....separating code in multiple lines
printf("Array b printed with: \n"
"Array subscript notation\n");
for(i=0; i<=3; i++)
printf("b[%d] = %d\n", i, b[i]);
printf("\nPointer/offset notation where \nthe pointer is the array name\n");
for(offset = 0; offset <=3; offset++)
printf("*(b + %d) = %d\n", offset, *(b + offset));
printf("\nPointer subscript notation\n");
for(i=0; i<=3; i++)
printf("bPtr[%d] = %d\n",i,bPtr[i]);
printf("\nPointer/offset notation\n");
for(offset = 0; offset <=3; offset++)
printf("*(bptr + %d) = %d\n", offset, *(bPtr + offset));
}
Output:
// a program that changes the value of a pointer variable
// compiled using VC++/VC++ .Net, C++ codes…
#include <iostream>
using namespace std;
void main()
{
// declare and initialize two float variables
double var1 = 58.98;
double var2 = 70.44;
// declare a float pointer variable
double *ptr_var;
// make ptr_var point to variable var1...
ptr_var = &var1;
// prints 58.98
cout<<"The first value is(var1) "<<*ptr_var;
cout<<"\nThe address of the first data is "<<ptr_var<<"\n";
cout<<"\nThen let the same pointer (*ptr_var)";
cout<<"\npoint to other address...\n";
// make ptr_var point to variable var2...
ptr_var = &var2;
// prints 70.44
cout<<"\nThe second value is(var2) "<<*ptr_var;
cout<<"\nThe address of the second data is "<<ptr_var<<endl;
}
Previous C program example of function pointer, compiled usinggcc.
/* ******** myptr.c ************ */
#include <stdio.h>
int main()
{
int i, offset, b[ ] = {10, 20, 30, 40};
// set bPtr to point to array b
int *bPtr = b;
printf("So many notations?????....\n");
//....separating code in multiple lines
printf("Array b printed with: \n"
"Array subscript notation\n");
for(i=0; i<=3; i++)
printf("b[%d] = %d\n", i, b[i]);
printf("\nPointer/offset notation where \nthe pointer is the array name\n");
for(offset = 0; offset <=3; offset++)
printf("*(b + %d) = %d\n", offset, *(b + offset));
printf("\nPointer subscript notation\n");
for(i=0; i<=3; i++)
printf("bPtr[%d] = %d\n", i, bPtr[i]);
printf("\nPointer/offset notation\n");
for(offset = 0; offset <=3; offset++)
printf("*(bptr + %d) = %d\n", offset, *(bPtr + offset));
return 0;
[bodo@bakawali ~]$ gcc myptr.c -o myptr
[bodo@bakawali ~]$ ./myptr
So many notations?????....
Array b printed with:
Array subscript notation
b[0] = 10
b[1] = 20
b[2] = 30
b[3] = 40
Pointer/offset notation where
the pointer is the array name
*(b + 0) = 10
*(b + 1) = 20
*(b + 2) = 30
*(b + 3) = 40
Pointer subscript notation
bPtr[0] = 10
bPtr[1] = 20
bPtr[2] = 30
bPtr[3] = 40
Pointer/offset notation
*(bptr + 0) = 10
*(bptr + 1) = 20
*(bptr + 2) = 30
*(bptr + 3) = 40
Previous C++ program example compiled usingg++.
/////////////////funcref.cpp//////////////////
// illustrates that function receives addresses
// of variables and then alters their contents
#include <iostream>
using namespace std;
int main()
{
int x = 4, y = 7;
// function prototype...
void addcon(int*, int*);
cout<<"\nInitial value of x = "<<x;
cout<<"\nInitial value of y = "<<y;
cout<<"\nThen calls function addcon()\n";
cout<<"\nBringing along the &x = "<<&x<<endl;
cout<<"and &y = "<<&y<<"\n";
cout;
// function call, address of x any y are passed to addcon()
addcon(&x, &y);
cout<<"\nAdd 10...";
cout<<"\nNew value of x = "<<x;
cout<<"\nminus 10...";
cout<<"\nNew value of y = "<<y<<endl;
return 0;
}
// a function definition, parameters are pointers...
void addcon(int *px, int *py)
{
// adds 10 to the data stored in memory pointed to by px
*px = *px + 10;
// minus 10 to the data stored in memory pointed to by py
*py = *py - 10;
}
[bodo@bakawali ~]$ g++ funcref.cpp -o funcref
[bodo@bakawali ~]$ ./funcref
Initial value of x = 4
Initial value of y = 7
Then calls function addcon()
Bringing along the &x = 0xbfed7944
and &y = 0xbfed7940
Add 10...
New value of x = 14
minus 10...
New value of y = -3
Further C and C++ pointers related reading and digging:
Also the exercises in theIndirection Operator lab worksheet 1,lab worksheet 2 and labworksheet 3.