The document discusses pointers in C++. It defines what a pointer is and how it stores a memory address. It describes declaring and initializing pointer variables, dereferencing pointers, and pointers to other pointers. Common pointer operations like address-of, indirection, and null pointers are also covered.
Download as PPTX, PDF, TXT or read online on Scribd
Download as pptx, pdf, or txt
0 ratings0% found this document useful (0 votes)
10 views41 pages
Chapter2 Pointers
The document discusses pointers in C++. It defines what a pointer is and how it stores a memory address. It describes declaring and initializing pointer variables, dereferencing pointers, and pointers to other pointers. Common pointer operations like address-of, indirection, and null pointers are also covered.
Download as PPTX, PDF, TXT or read online on Scribd
Download as pptx, pdf, or txt
Download as pptx, pdf, or txt
You are on page 1/ 41
Chapter -2
Introduction to Pointers
Concepts on Address of a Variable
The address operator (&) returns the memory address of a variable. Every variable is allocated a section of memory large enough to hold a value of the variable’s data type. On a PC, for instance, it’s common for one byte to be allocated for chars, two bytes for shorts , four bytes for int, longs, and floats, and eight bytes for doubles. Cont’d… Each byte of memory has a unique address. A variable’s address is the address of the first byte allocated to that variable. Suppose the following variables are defined in a program: char letter; short number; float amount; Cont’d…
When the address operator (&) is placed in front of a
variable name, it returns the address of that variable. Here is an expression that returns the address of the variable amount: &amount And here is a statement that displays the variable’s address on the screen: cout << &amount; Cont’d… //Demonstrates the use of the address operator to display the address, size, and contents of a variable. #include <iostream.h> int main() { int x = 25; cout << "The address of x is " << &x << endl; cout << "The size of x is " << sizeof(x) << " bytes\n"; cout << "The value in x is " << x << endl; return 0; } What is pointer Pointer variables, which are often just called pointers, are designed to hold memory addresses. With pointer variables you can indirectly manipulate data stored in other variables. pointer, is a special variable that holds a memory address. Just as int variables are designed to hold integers, and double variables are designed to hold floating-point numbers, pointer variables are designed to hold memory addresses. Cont’d… A computer memory location has an address and holds a content. The address is a numerical number (often expressed in hexadecimal), which is hard for programmers to use directly. Typically, each address location holds 8-bit (i.e., 1-byte) of data. It is entirely up to the programmer to interpret the meaning of the data, such as integer, real number, characters or strings. Cont’d… Also, types (such as int, double, char) are associated with the contents for ease of interpretation of data. Each address location typically hold 8-bit (i.e., 1-byte) of data. A 4-byte int value occupies 4 memory locations. A 32-bit system typically uses 32-bit addresses. To store a 32- bit address, 4 memory locations are required. The following diagram illustrate the relationship between computers' memory address and content; and variable's name, type and value used by the programmers. Declarating Pointers A pointer variable (or pointer in short) is basically the same as the other variables, which can store a piece of data. Unlike normal variable which stores a value (such as an int, a double, a char), a pointer stores a memory address. Pointers must be declared before they can be used, just like a normal variable. SYNTAX Type_Name,*Variable_Name1, *Variable_Name2, . . .; EXAMPLE double *pointer1, *pointer2; The syntax of declaring a pointer is to place a * in front of the name. A pointer is associated with a type (such as int and double) too. Cont’d… 1. type *ptr; // Declare a pointer variable called ptr as a pointer of type. 2. type* ptr; 3. type * ptr; // I shall adopt this convention For example, int * iPtr; // Declare a pointer variable called iPtr pointing to an int (an int pointer) // It contains an address. That address holds an int value. double * dPtr; // Declare a double pointer Cont’d… a * in front of each pointer variable, in other words, * applies only to the name that followed. The * in the declaration statement is not an operator, but indicates that the name followed is a pointer variable. For example int *p1, *p2, i; // p1 and p2 are int pointers. // i is an int int* p1, p2, i; // p1 is a int pointer, p2 and i are int int * p1, * p2, i; // p1 and p2 are int pointers, i is an int Cont’d… ADDRESSES AND NUMBERS A pointer is an address, and an address is an integer, but a pointer is not an integer. That is not crazy—that is abstraction! C++ insists that you use a pointer as an address and that you not use it as a number. A pointer is not a value of type int or of any other numeric type. You normally cannot store a pointer in a variable of type int. When discussing pointers we usually speak of Pointing rather than speaking of addresses. When a pointer variable, such as p1 , contains the address of a variable, such as v1 , the pointer variable is said to point to the variable v1. Cont’d… Naming Convention of Pointers: Include a "p" or "ptr" as prefix or suffix, e.g., iPtr, numberPtr, pNumber, pStudent. int *ptr; The asterisk in front of the variable name indicates that ptr is a pointer variable. The int data type indicates that ptr can be used to hold the address of an integer variable. The definition statement above would read “ptr is a pointer to an int.” Remember, pointers only hold one kind of value: an address. Cont’d… Some programmers prefer to define pointers with the asterisk next to the type name, rather than the variable name. For example, the previous definition shown above could be written as: int* ptr; This style of definition might visually reinforce the fact that ptr’s data type is not int, but pointer-to-int. Both definition styles are correct. Cont’d… // demonstrates a very simple usage of a pointer: storing and printing the address of another variable #include <iostream.h> int main() { int x = 25; // int variable int *ptr; // Pointer variable, can point to an int ptr = &x; // Store the address of x in ptr cout << "The value in x is " << x << endl; cout << "The address of x is " << ptr << endl; return 0; } Pointer Initialization Pointers may be initialized with the address of an existing object. When you declare a pointer variable, its content is not initialized. You need to initialize a pointer by assigning it a valid address. This is normally done via the address-of operator (&). The address-of operator (&) operates on a variable, and returns the address of the variable. For example, if number is an int variable, &number returns the address of the variable number. You can use the address-of operator to get the address of a variable, and assign the address to a pointer variable. Indirection or Dereferencing Operator (*) The indirection operator (or dereferencing operator) (*) operates on a pointer, and returns the value stored in the address kept in the pointer variable. For example, if pNumber is an int pointer, *pNumberreturns the int value "pointed to" by pNumber. Cont’d… int number = 88; int * Pnumber = &number; //Remember that pointer is initialized with existing )Declare and assign the address of variable object i(n this case number=88
number to pointer pNumber (0x22ccec)
cout << pNumber<< endl; // Print the content of the pointer variable, which contain an address (0x22ccec) cout << *pNumber << endl; // Print the value "pointed to" by the pointer, which is an int (88) *pNumber = 99; // Assign a value to where the pointer is pointed to, NOT to the pointer variable cout << *pNumber << endl; // Print the new value "pointed to" by the pointer (99) cout << number << endl; // The value of variable number changes as well (99) Cont’d… Take note that the symbol * has different meaning in a declaration statement and in an expression. When it is used in a declaration (e.g., int * pNumber), it denotes that the name followed is a pointer variable. Whereas when it is used in a expression (e.g., *pNumber = 99; temp << *pNumber;), it refers to the value pointed to by the pointer variable. Cont’d… #include <iostream.h> int main() { int number = 88; // Declare an int variable and assign an initial value int * pNumber; // Declare a pointer variable pointing to an int (or int pointer) pNumber = &number; // assign the address of the variable number to pointer pNumber cout << pNumber << endl; // Print content of pNumber (0x22ccf0) cout << &number << endl; // Print address of number (0x22ccf0) cout << *pNumber << endl; // Print value pointed to by pNumber (88) cout << number << endl; // Print value of number (88) *pNumber = 99; // Re-assign value pointed to by pNumber cout << pNumber << endl; // Print content of pNumber (0x22ccf0) cout << &number << endl; // Print address of number (0x22ccf0) cout << *pNumber << endl; // Print value pointed to by pNumber (99) cout << number << endl; // Print value of number (99) // The value of number changes via pointer cout << &pNumber << endl; // Print the address of pointer variable pNumber (0x22ccec) } Null pointers It is always a good practice to assign the pointer NULL to a pointer variable in case you do not have exact address to be assigned. This is done at the time of variable declaration. A pointer that is assigned NULL is called a null pointer. The NULL pointer is a constant with a value of zero defined in several standard libraries, including iostream. Consider the following program You can initialize a pointer to 0 or NULL, i.e., it points to nothing. It is called a null pointer. Dereferencing a null pointer (*p) causes an STATUS_ACCESS_VIOLATION exception. Cont’d… #include <iostream.h> int main () { int *ptr = NULL; cout << "The value of ptr is " << ptr ; return 0; }
The output is:
The value of ptr is 0. Pointers to pointers
A pointer may point to another pointer.
C++ allows the use of pointers that point to pointers, that these, in its turn, point to data (or even to other pointers). The syntax simply requires an asterisk (*) for each level of indirection in the declaration of the pointer: char a; char * b; char ** c; a = 'z'; b = &a; c = &b; Cont’d… char c = 't'; char* pc = &c; char** ppc = &PC; char*** pppc = &ppc; ***pppc = ‘w’; // changes the value of c to 'W’ We can visualize these variables like this: Cont’d… #include<iostream.h> int main() { int n=44; cout << " n = " << n << endl; cout << " &n = " << &n << endl; int* pn=&n; // pn holds the address of n cout << " pn = " << pn << endl; cout << " &pn = " << &pn << endl; cout << " *pn = " << *pn << endl; int** ppn=&pn; // ppn holds the address of pn cout << " ppn = " << ppn << endl; cout << " &ppn = " << &ppn << endl; cout << " *ppn = " << *ppn << endl; cout << "**ppn = " << **ppn << endl; Pointer arithmetic Some mathematical operations may be performed on pointers are addition and subtraction and others. Both addition and subtraction have a slightly different behavior with pointers, according to the size of the data type to which they point. Some arithmetic operators can be used with pointers: - Increment and decrement operators ++, -- - Integers can be added to or subtracted from pointers using the operators +, -, +=, and -= Cont’d… Each time a pointer is incremented by 1, it points to the memory location of the next element of its base type. If “p” is a character pointer then “p++” will increment “p” by 1 byte. If “p” were an integer pointer its value on “p++” would be incremented by 2 bytes. A pointer may be subtracted from another pointer. Cont’d… Suppose now that we define three pointers in this compiler: 1. char *mychar; 2. short *myshort; 3. long *mylong; and that we know that they point to the memory locations 1000, 2000, and 3000, respectively. Therefore, if we write: 1. ++mychar; 2. ++myshort; 3. ++mylong; Cont’d… mychar contain the value 1001 myshort contain the value 2002 mylong would contain 3004 The reason is that, when adding one to a pointer, the pointer is made to point to the following element of the same type, and, therefore, the size in bytes of the type it points to is added to the pointer. Cont’d… 1. *p++ // same as *(p++): increment pointer, and dereference unincremented address
2. *++p // same as *(++p): increment pointer, and dereference
incremented address
3. ++*p // same as ++(*p): dereference pointer, and increment
the value it points to
4. (*p)++ // dereference pointer, and post-increment the value
it points to Cont’d… #include <iostream.h> int main() { const int SIZE = 8; int set[SIZE] = {5, 10, 15, 20, 25, 30, 35, 40}; int *numPtr; // Pointer int count; // Counter variable for loops // Make numPtr point to the set array. numPtr = set; // Use the pointer to display the array contents. cout << "The numbers in set are:\n"; for (count = 0; count < SIZE; count++) { cout << *numPtr << " "; numPtr++;} // Display the array contents in reverse order. cout << "\nThe numbers in set backward are:\n"; for (count = 0; count < SIZE; count++) { numPtr--; cout << *numPtr << " "; } return 0; Pointers and arrays The concept of arrays is related to that of pointers. In fact, arrays work very much like pointers to their first elements, and, actually, an array can always be implicitly converted to the pointer of the proper type. For example, consider these two declarations: int myarray [20]; int * mypointer; The following assignment operation would be valid: mypointer = myarray; mypointer and myarray would be equivalent and would have very similar properties. Cont’d… myarray = mypointer; // illegal Pointers and arrays support the same set of operations, with the same meaning for both. The main difference being that pointers can be assigned new addresses, while arrays cannot. In C/C++, an array's name is a pointer, pointing to the first element (index 0) of the array. For example, suppose that numbers is an int array, numbers is a also an int pointer, pointing at the first element of the array. That is, numbers is the same as &numbers[0]. Consequently, *numbers is number[0]; *(numbers+i) is numbers[i]. Cont’d… // Pointer and Array (TestPointerArray.cpp) #include <iostream.h> int main() { const int SIZE = 5; int numbers[SIZE] = {11, 22, 44, 21, 41}; // An int array // The array name numbers is an int pointer, pointing at the // first item of the array, i.e., numbers = &numbers[0] cout << &numbers[0] << endl; // Print address of first element (0x22fef8) cout << numbers << endl; // Same as above (0x22fef8) cout << *numbers << endl; // Same as numbers[0] (11) cout << *(numbers + 1) << endl; // Same as numbers[1] (22) cout << *(numbers + 4) << endl; // Same as numbers[4] (41) Cont’d… // more pointers #include <iostream.h> int main (){ int numbers[5]; int * p; p = numbers; *p = 10; p++; *p = 20; p = &numbers[2]; *p = 30; p = numbers + 3; *p = 40; p = numbers; *(p+4) = 50; for (int n=0; n<5; n++) cout << numbers[n] << ", "; return 0;} Cont’d… #include <iostream.h> int main() { const int SIZE = 5; // Size of the array int numbers[SIZE]; // Array of integers int count; // Counter variable // Get values to store in the array. // Use pointer notation instead of subscripts. cout << "Enter " << SIZE << " numbers: "; for (count = 0; count < SIZE; count++) Cin >> *(numbers + count); // Display the values in the array. // Use pointer notation instead of subscripts. cout << "Here are the numbers you entered:\n"; for (count = 0; count < SIZE; count++) cout << *(numbers + count)<< " "; cout << endl; return 0; const Pointers You can use the keyword const for pointers before the type, after the type, or in both places. For example, all of the following are legal declarations: const int * pOne; int * const pTwo; const int * const pThree; pOne is a pointer to a constant integer. The value that is pointed to can't be changed. pTwo is a constant pointer to an integer. The integer can be changed, but pTwo can't point to anything else. pThree is a constant pointer to a constant integer. The value that is pointed to can't be changed, and pThree can't be changed to point to anything else. Cont’d… If the type is to the right of the keyword, it is the value that is constant. If the variable is to the right of the keyword const, it is the pointer variable itself that is constant. const int * p1; // the int pointed to is constant int * const p2; // p2 is constant, it can't point to anything else Pointers and string literals
string literals are arrays containing null-terminated character
sequences. string literals have been used to be directly inserted into cout, to initialize strings and to initialize arrays of characters. For example Initialize to a character string. char* a = “Hello”; a is pointer to the memory location where ‘H’ is stored. Here “a” can be viewed as a character array of size 6, the only difference being that a can be reassigned another memory location. Cont’d… char* a = “Hello”; a gives address of ‘H’ *a gives ‘H’ a[0] gives ‘H’ a++ gives address of ‘e’ *a++ gives ‘e’ Cont’d… /* This program copies a character array into a given array */ #include <iostream.h> main( ) { char strA[80] = “Live ur life"; char strB[80]; char *ptrA; /* a pointer to type character */ char *ptrB; /* another pointer to type character */ ptrA = strA; /* point ptrA at string A */ ptrB = strB; /* point ptrB at string B */ while(*ptrA != '\0') { *ptrB++ = *ptrA++; // copying character by character } *ptrB = '\0'; cout << “String in strA = ” << strA << endl; /* show strA on screen */ cout << “String in strB = ” << strB << endl; /* show strB on screen */