Qingquan-Li / blog

My Blog
https://Qingquan-Li.github.io/blog/
132 stars 16 forks source link

C++ Pointers Basic #205

Open Qingquan-Li opened 2 years ago

Qingquan-Li commented 2 years ago

Reference: Book: Starting Out with C++ from Control Structures to Objects, byTony Gaddis, ninth edition

Contents:

  1. Getting the Address of a Variable

  2. Pointer Variables

    2.1 Reference Variables vs Pointer Variables

    2.2 Creating and Using Pointer Variables


1. Getting the 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 1 byte to be allocated for chars, 2 bytes for shots, 4 bytes for ints, longs, and floats, and 8 bytes for doubles.

Each byte of memory has a unique address. A variable's address is the address of the first byte allocated to that variable.

// This program uses the & operator to determine a variable's
// address and the sizeof operator to determine its size.

#include <iostream>
using namespace std;

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;
}

Output:

The address of x is 0x16db4b648
The size of x is 4 bytes
The value in x is 25

Note: The address of the variable x is displayed in hexadecimal.


2. Pointer Variables

Concept: 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.

// swap the pointer value

#include <iostream>
using namespace std;

int main() {
    int num1 = 10;
    int num2 = 20;
    int* xp = &num1;
    int* yp = &num2;
    cout << "xp is: " << xp << endl;
    cout << "yp is: " << yp << endl;

    int* temp;

    temp = xp;
    xp = yp;
    yp = temp;
    cout << "xp is now: " << xp << endl;
    cout << "yp is now: " << yp << endl;

    return 0;
}

Output:

xp is: 0x16b357648
yp is: 0x16b357644
xp is now: 0x16b357644
yp is now: 0x16b357648

2.1 Reference Variables vs Pointer Variables


2.1.1 Reference Variables:

A reference variable acts as an alias for another variable. It is called a reference variable because it references another variable in the program. Anything you do to the reference variable is actually done to the variable it references.

For example, suppose we have the variable jelly_donuts and we pass the variable to the get_order function, as shown here:

#include <iostream>
using namespace std;

void get_order(int&);

int main() {
    int jelly_donuts;
    get_order(jelly_donuts);
    return 0;
}

void get_order(int &donuts) {
    // donuts is a reference variable
    cout << "How many doughnuts da you want? ";
    cin >> donuts;
}

In the function, the donuts parameter is a reference variable, and it receives the address of the jelly_donuts variable. It works like a pointer because it "points" to the jelly_donuts. Inside the get_order function, the donuts parameter references the jelly_donuts variable. Anything done to the donuts parameter is actually done to the jelly_donuts variable. When the user enters a value. the cin statement uses the donuts reference variable to indirectly store the value in the jelly_donuts variable.

Notice the connection between the donuts reference variable and the jelly_donuts argument is automatically established by C++ when the function is called. When you are writing this code, you don't have to go through the trouble of finding the memory address of the jelly_donuts variable then properly storing that address in the donuts reference variable.

When you are storing a value in the donuts variable, you don't have to specify that the value should actually be stored in the jelly_donuts variable. C++ handles all of that automatically.

2.1.2 Pointer Variables:

In C++, pointer variables are yet another mechanism for using memory addresses to work with pieces of data. Pointer variables are similar to reference variables, but pointer variables operate at a lower level. By this, I mean that C++ does not automatically do as much work for you with pointer variables as it does with reference variables.

In order to make a pointer variable reference another item in memory, you have to write code that fetches the memory address of that item and assigns the address to the pointer variable.

Also, when you use a pointer variable to store a value in the memory location that the pointer references, your code has to specify that the value should be stored in the location referenced by the pointer variable, and not in the pointer variable itself.

Reference variables are easier to work with. In C++, pointers are useful, and even necessary, for many operations.

One such operation is dynamic memory allocation. When you are writing a program that will need to work with an unknown amount of data, dynamic memory allocation allows you to create variables, arrays, and more complex data structures in memory while the program is running.

Pointers are also very useful in algorithms that manipulate arrays and work with certain types of strings. In object-oriented programming, pointers are very useful for creating and working with objects, and for sharing access to those objects.

2.2 Creating and Using Pointer Variables

An example of the definition of a pointer variable.

int *ptr;
// Or
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 defination statement above would read "ptr is a pointer to an int."

It is never a good idea to define a pointer variable without initializing it with a valid memory address. In C++ 11, the nullptr key word was introduced to represent the address 0. So, assigning nullptr to a pointer variable makes the variable point to the address 0.

#include <iostream>
using namespace std;

int main() {
    int var1 = 25;
    int* ptr = nullptr;

    // Store the address of var1 in ptr.
    ptr = &var1;

    cout << "Print var1 and *prt:\n";
    cout << var1 << endl;
    cout << *ptr << endl;

    // Assign 100 to the location pointed to by ptr.
    // This will actually assign 100 to var1.
    *ptr = 100;

    cout << "Print var1 and *prt again:\n";
    cout << var1 << endl;
    cout << *ptr << endl;

    return 0;
}

Output:

Print var1 and *prt:
25
25
Print var1 and *prt again:
100
100

pointers-in-c++ (source: https://simplesnippets.tech/cpp-pointers-concept-with-example/)