Skip to content Skip to sidebar Skip to footer

You Can Only Assign an Address to a Pointer Variable

Pointers

In earlier chapters, variables accept been explained equally locations in the estimator's memory which can be accessed by their identifier (their proper noun). This way, the plan does not need to care about the physical address of the data in memory; information technology only uses the identifier whenever it needs to refer to the variable.

For a C++ programme, the retentivity of a estimator is like a succession of retentiveness cells, each 1 byte in size, and each with a unique accost. These unmarried-byte retentivity cells are ordered in a way that allows data representations larger than one byte to occupy memory cells that have sequent addresses.

This fashion, each jail cell can be easily located in the memory past means of its unique address. For instance, the memory cell with the address 1776 e'er follows immediately afterward the cell with address 1775 and precedes the ane with 1777, and is exactly one thousand cells after 776 and exactly grand cells earlier 2776.

When a variable is declared, the retentiveness needed to store its value is assigned a specific location in retention (its memory address). Generally, C++ programs do not actively decide the exact retentivity addresses where its variables are stored. Fortunately, that job is left to the environment where the program is run - by and large, an operating system that decides the particular retentivity locations on runtime. However, it may be useful for a program to exist able to obtain the address of a variable during runtime in lodge to admission information cells that are at a certain position relative to it.


Address-of operator (&)

The address of a variable can be obtained by preceding the name of a variable with an ampersand sign (&), known as address-of operator. For example:

This would assign the address of variable myvar to foo; past preceding the name of the variable myvar with the accost-of operator (&), we are no longer assigning the content of the variable itself to foo, but its address.

The actual address of a variable in retentivity cannot be known before runtime, but allow's assume, in order to assistance clarify some concepts, that myvar is placed during runtime in the retentivity address 1776.

In this case, consider the following lawmaking fragment:

                      1
2
three
                      myvar = 25; foo = &myvar; bar = myvar;                    

The values contained in each variable later on the execution of this are shown in the following diagram:

Offset, nosotros take assigned the value 25 to myvar (a variable whose accost in memory we assumed to be 1776).

The 2d argument assigns foo the accost of myvar, which we have causeless to exist 1776.

Finally, the 3rd statement, assigns the value independent in myvar to bar. This is a standard consignment operation, as already done many times in before chapters.

The main divergence between the second and third statements is the appearance of the accost-of operator (&).

The variable that stores the address of some other variable (similar foo in the previous example) is what in C++ is called a pointer. Pointers are a very powerful characteristic of the language that has many uses in lower level programming. A chip later, nosotros will see how to declare and utilize pointers.


Dereference operator (*)

As just seen, a variable which stores the address of another variable is called a pointer. Pointers are said to "point to" the variable whose address they shop.

An interesting holding of pointers is that they can exist used to access the variable they point to straight. This is done past preceding the pointer proper name with the dereference operator (*). The operator itself can exist read as "value pointed to past".

Therefore, post-obit with the values of the previous example, the following statement:

This could be read as: "baz equal to value pointed to by foo", and the statement would really assign the value 25 to baz, since foo is 1776, and the value pointed to by 1776 (following the example higher up) would be 25.


It is important to clearly differentiate that foo refers to the value 1776, while *foo (with an asterisk * preceding the identifier) refers to the value stored at accost 1776, which in this case is 25. Notice the difference of including or not including the dereference operator (I have added an explanatory comment of how each of these two expressions could be read):

                      1
2
                      baz = foo;                        // baz equal to foo (1776)                        baz = *foo;                        // baz equal to value pointed to past foo (25)                                                                  

The reference and dereference operators are thus complementary:

  • & is the accost-of operator, and can be read only as "address of"
  • * is the dereference operator, and can be read as "value pointed to past"

Thus, they take sort of contrary meanings: An address obtained with & can be dereferenced with *.

Earlier, we performed the following 2 assignment operations:

                      one
2
                      myvar = 25; foo = &myvar;                    

Right subsequently these two statements, all of the following expressions would give true as consequence:

                      1
2
iii
four
                      myvar == 25 &myvar == 1776 foo == 1776 *foo == 25                    

The beginning expression is quite clear, considering that the assignment operation performed on myvar was myvar=25. The second one uses the address-of operator (&), which returns the accost of myvar, which nosotros assumed it to have a value of 1776. The third ane is somewhat obvious, since the 2d expression was true and the assignment performance performed on foo was foo=&myvar. The fourth expression uses the dereference operator (*) that can be read every bit "value pointed to by", and the value pointed to by foo is indeed 25.

So, after all that, you may too infer that for as long as the address pointed to by foo remains unchanged, the following expression volition likewise be true:



Declaring pointers

Due to the ability of a pointer to directly refer to the value that information technology points to, a pointer has different properties when it points to a char than when it points to an int or a bladder. Once dereferenced, the type needs to be known. And for that, the declaration of a pointer needs to include the information type the pointer is going to point to.

The declaration of pointers follows this syntax:

type * proper name;

where type is the data type pointed to by the pointer. This blazon is not the blazon of the arrow itself, but the type of the information the pointer points to. For case:

                      1
ii
3
                                              int                        * number;                        char                        * graphic symbol;                        double                        * decimals;                    

These are three declarations of pointers. Each ane is intended to point to a unlike data type, just, in fact, all of them are pointers and all of them are likely going to occupy the aforementioned amount of space in memory (the size in retentiveness of a pointer depends on the platform where the program runs). All the same, the information to which they betoken to do not occupy the same amount of infinite nor are of the same type: the first one points to an int, the 2nd 1 to a char, and the last one to a double. Therefore, although these three example variables are all of them pointers, they really have different types: int*, char*, and double* respectively, depending on the type they point to.

Note that the asterisk (*) used when declaring a pointer only means that information technology is a pointer (information technology is part of its type chemical compound specifier), and should not be confused with the dereference operator seen a bit earlier, only which is likewise written with an asterisk (*). They are simply two different things represented with the same sign.

Permit's see an example on pointers:

                      i
2
3
4
5
6
7
8
9
x
eleven
12
thirteen
14
xv
xvi
17
                                              // my first pointer                        #include <iostream>                        using                        namespace                        std;                        int                        chief () {                        int                        firstvalue, secondvalue;                        int                        * mypointer;    mypointer = &firstvalue;   *mypointer = x;   mypointer = &secondvalue;   *mypointer = 20;   cout <<                        "firstvalue is "                        << firstvalue <<                        '\north';   cout <<                        "secondvalue is "                        << secondvalue <<                        '\due north';                        return                        0; }                    
                      firstvalue is 10 secondvalue is 20                    

Observe that even though neither firstvalue nor secondvalue are directly gear up any value in the programme, both end upwardly with a value set indirectly through the utilise of mypointer. This is how it happens:

First, mypointer is assigned the address of firstvalue using the address-of operator (&). Then, the value pointed to past mypointer is assigned a value of x. Considering, at this moment, mypointer is pointing to the memory location of firstvalue, this in fact modifies the value of firstvalue.

In guild to demonstrate that a pointer may point to different variables during its lifetime in a program, the example repeats the procedure with secondvalue and that same pointer, mypointer.

Here is an example a little flake more elaborated:

                      1
2
iii
4
5
half-dozen
seven
8
9
10
11
12
13
fourteen
15
16
17
xviii
19
xx
                                              // more pointers                        #include <iostream>                        using                        namespace                        std;                        int                        main () {                        int                        firstvalue = v, secondvalue = 15;                        int                        * p1, * p2;    p1 = &firstvalue;                        // p1 = accost of firstvalue                        p2 = &secondvalue;                        // p2 = address of secondvalue                        *p1 = 10;                        // value pointed to by p1 = 10                        *p2 = *p1;                        // value pointed to by p2 = value pointed to past p1                        p1 = p2;                        // p1 = p2 (value of pointer is copied)                        *p1 = xx;                        // value pointed to by p1 = 20                        cout <<                        "firstvalue is "                        << firstvalue <<                        '\n';   cout <<                        "secondvalue is "                        << secondvalue <<                        '\n';                        return                        0; }                    
                      firstvalue is 10 secondvalue is 20                    

Each assignment operation includes a comment on how each line could be read: i.e., replacing ampersands (&) by "address of", and asterisks (*) by "value pointed to past".

Notice that in that location are expressions with pointers p1 and p2, both with and without the dereference operator (*). The meaning of an expression using the dereference operator (*) is very dissimilar from ane that does not. When this operator precedes the arrow name, the expression refers to the value being pointed, while when a pointer name appears without this operator, it refers to the value of the pointer itself (i.e., the accost of what the pointer is pointing to).

Another thing that may call your attention is the line:

This declares the 2 pointers used in the previous example. But notice that there is an asterisk (*) for each pointer, in club for both to take type int* (pointer to int). This is required due to the precedence rules. Note that if, instead, the code was:

p1 would indeed be of type int*, only p2 would be of type int. Spaces practice not matter at all for this purpose. Merely anyway, simply remembering to put ane asterisk per pointer is enough for well-nigh pointer users interested in declaring multiple pointers per argument. Or fifty-fifty improve: use a unlike statement for each variable.


Pointers and arrays

The concept of arrays is related to that of pointers. In fact, arrays piece of work very much like pointers to their get-go elements, and, really, an assortment tin always exist implicitly converted to the pointer of the proper blazon. For example, consider these two declarations:
                      1
two
                                              int                        myarray [20];                        int                        * mypointer;                    

The following assignment performance would be valid:

After that, mypointer and myarray would exist equivalent and would have very similar properties. The master difference being that mypointer can be assigned a different address, whereas myarray can never be assigned anything, and will e'er represent the same block of 20 elements of type int. Therefore, the post-obit assignment would not exist valid:

Let's see an example that mixes arrays and pointers:

                      i
2
iii
four
five
half-dozen
7
8
9
10
eleven
12
xiii
fourteen
15
16
17
                                              // more pointers                        #include <iostream>                        using                        namespace                        std;                        int                        main () {                        int                        numbers[5];                        int                        * p;   p = numbers;  *p = 10;   p++;  *p = 20;   p = &numbers[2];  *p = thirty;   p = numbers + 3;  *p = xl;   p = numbers;  *(p+4) = 50;                        for                        (int                        n=0; northward<5; north++)     cout << numbers[n] <<                        ", ";                        return                        0; }                    
                      10, 20, 30, xl, l,                                          

Pointers and arrays support the same set of operations, with the same meaning for both. The master difference being that pointers tin can exist assigned new addresses, while arrays cannot.

In the chapter near arrays, brackets ([]) were explained every bit specifying the alphabetize of an element of the array. Well, in fact these brackets are a dereferencing operator known as offset operator. They dereference the variable they follow just equally * does, but they likewise add the number between brackets to the address beingness dereferenced. For example:

                      ane
2
                      a[5] = 0;                        // a [offset of 5] = 0                        *(a+5) = 0;                        // pointed to by (a+v) = 0                                                                  

These two expressions are equivalent and valid, not only if a is a arrow, but also if a is an array. Remember that if an array, its name tin can be used just like a pointer to its first element.


Pointer initialization

Pointers can be initialized to point to specific locations at the very moment they are defined:
                      1
ii
                                              int                        myvar;                        int                        * myptr = &myvar;                    

The resulting state of variables afterward this code is the same as subsequently:

                      1
2
3
                                              int                        myvar;                        int                        * myptr; myptr = &myvar;                    

When pointers are initialized, what is initialized is the accost they point to (i.e., myptr), never the value being pointed (i.eastward., *myptr). Therefore, the lawmaking above shall not be confused with:

                      1
2
3
                                              int                        myvar;                        int                        * myptr; *myptr = &myvar;                    

Which anyway would not make much sense (and is non valid code).

The asterisk (*) in the pointer declaration (line 2) but indicates that information technology is a arrow, it is not the dereference operator (as in line 3). Both things just happen to use the same sign: *. Equally ever, spaces are not relevant, and never change the meaning of an expression.

Pointers can be initialized either to the accost of a variable (such as in the case above), or to the value of another arrow (or assortment):

                      i
two
3
                                              int                        myvar;                        int                        *foo = &myvar;                        int                        *bar = foo;                    


Arrow arithmetics

To conduct arithmetical operations on pointers is a trivial different than to behave them on regular integer types. To begin with, only improver and subtraction operations are allowed; the others make no sense in the world of pointers. Only both addition and subtraction accept a slightly different behavior with pointers, according to the size of the data blazon to which they bespeak.

When cardinal information types were introduced, nosotros saw that types have unlike sizes. For example: char ever has a size of ane byte, brusque is more often than not larger than that, and int and long are even larger; the verbal size of these being dependent on the system. For example, let's imagine that in a given system, char takes ane byte, brusque takes 2 bytes, and long takes iv.

Suppose at present that nosotros define three pointers in this compiler:

                      1
2
three
                                              char                        *mychar;                        short                        *myshort;                        long                        *mylong;                    

and that nosotros know that they point to the memory locations k, 2000, and 3000, respectively.

Therefore, if we write:

                      1
2
3
                      ++mychar; ++myshort; ++mylong;                    

mychar, equally one would expect, would comprise the value 1001. But not so plainly, myshort would contain the value 2002, and mylong would incorporate 3004, even though they have each been incremented only once. The reason is that, when adding one to a pointer, the arrow is made to point to the following element of the aforementioned type, and, therefore, the size in bytes of the type it points to is added to the pointer.


This is applicable both when adding and subtracting any number to a pointer. It would happen exactly the aforementioned if nosotros wrote:

                      i
2
3
                      mychar = mychar + ane; myshort = myshort + one; mylong = mylong + i;                    

Regarding the increment (++) and decrement (--) operators, they both tin can be used as either prefix or suffix of an expression, with a slight difference in beliefs: every bit a prefix, the increment happens before the expression is evaluated, and equally a suffix, the increment happens subsequently the expression is evaluated. This also applies to expressions incrementing and decrementing pointers, which can become part of more complicated expressions that likewise include dereference operators (*). Remembering operator precedence rules, we can recall that postfix operators, such as increment and decrement, have college precedence than prefix operators, such as the dereference operator (*). Therefore, the following expression:

is equivalent to *(p++). And what it does is to increase the value of p (so it now points to the next element), merely because ++ is used as postfix, the whole expression is evaluated as the value pointed originally by the pointer (the address it pointed to before being incremented).

Essentially, these are the four possible combinations of the dereference operator with both the prefix and suffix versions of the increment operator (the same being applicable also to the decrement operator):

                      1
2
iii
4
                      *p++                        // same equally *(p++): increment pointer, and dereference unincremented address                        *++p                        // same as *(++p): increment arrow, and dereference incremented accost                        ++*p                        // same equally ++(*p): dereference pointer, and increment the value information technology points to                        (*p)++                        // dereference arrow, and post-increment the value it points to                                                                  

A typical -but not so simple- statement involving these operators is:

Because ++ has a higher precedence than *, both p and q are incremented, just because both increment operators (++) are used equally postfix and not prefix, the value assigned to *p is *q before both p and q are incremented. And so both are incremented. Information technology would exist roughly equivalent to:

Like always, parentheses reduce confusion by adding legibility to expressions.


Pointers and const

Pointers can exist used to access a variable by its address, and this access may include modifying the value pointed. Merely it is also possible to declare pointers that can admission the pointed value to read it, but non to change it. For this, it is enough with qualifying the type pointed to by the arrow as const. For example:
                      1
2
3
4
5
                                              int                        x;                        int                        y = 10;                        const                        int                        * p = &y; ten = *p;                        // ok: reading p                        *p = 10;                        // mistake: modifying p, which is const-qualified                                                                  

Here p points to a variable, only points to it in a const-qualified manner, meaning that it can read the value pointed, but it cannot modify information technology. Note as well, that the expression &y is of type int*, but this is assigned to a pointer of type const int*. This is allowed: a pointer to non-const can be implicitly converted to a pointer to const. But not the other manner effectually! As a safe characteristic, pointers to const are not implicitly convertible to pointers to non-const.

1 of the use cases of pointers to const elements is every bit function parameters: a function that takes a pointer to non-const equally parameter can modify the value passed as argument, while a function that takes a arrow to const as parameter cannot.

                      ane
2
3
iv
v
6
vii
eight
ix
10
11
12
13
14
fifteen
16
17
18
xix
20
21
22
23
24
25
26
27
28
29
                                              // pointers as arguments:                        #include <iostream>                        using                        namespace                        std;                        void                        increment_all (int* outset,                        int* stop) {                        int                        * current = first;                        while                        (electric current != end) {     ++(*current);                        // increment value pointed                        ++current;                        // increment pointer                        } }                        void                        print_all (const                        int* outset,                        const                        int* finish) {                        const                        int                        * electric current = outset;                        while                        (current != stop) {     cout << *current <<                        '\north';     ++electric current;                        // increase pointer                        } }                        int                        primary () {                        int                        numbers[] = {10,20,xxx};   increment_all (numbers,numbers+3);   print_all (numbers,numbers+3);                        return                        0; }                    
                      11 21 31                    

Annotation that print_all uses pointers that point to constant elements. These pointers point to constant content they cannot change, but they are not constant themselves: i.e., the pointers can still be incremented or assigned different addresses, although they cannot modify the content they point to.

And this is where a 2d dimension to constness is added to pointers: Pointers tin can likewise be themselves const. And this is specified by appending const to the pointed type (after the asterisk):

                      1
ii
three
4
5
                                              int                        x;                        int                        *       p1 = &x;                        // non-const pointer to non-const int                        const                        int                        *       p2 = &10;                        // non-const pointer to const int                        int                        *                        const                        p3 = &x;                        // const pointer to non-const int                        const                        int                        *                        const                        p4 = &x;                        // const pointer to const int                                                                  

The syntax with const and pointers is definitely tricky, and recognizing the cases that best adapt each use tends to require some experience. In whatsoever example, it is of import to get constness with pointers (and references) right sooner rather than later, merely you should not worry too much about grasping everything if this is the first fourth dimension yous are exposed to the mix of const and pointers. More apply cases volition prove upward in coming chapters.

To add a little bit more confusion to the syntax of const with pointers, the const qualifier can either precede or follow the pointed blazon, with the exact same meaning:

                      ane
ii
                                              const                        int                        * p2a = &x;                        //      non-const pointer to const int                        int                        const                        * p2b = &ten;                        // also non-const pointer to const int                                                                  

As with the spaces surrounding the asterisk, the society of const in this case is simply a matter of manner. This affiliate uses a prefix const, as for historical reasons this seems to be more than extended, simply both are exactly equivalent. The merits of each style are however intensely debated on the internet.


Pointers and string literals

Equally pointed earlier, string literals are arrays containing goose egg-terminated character sequences. In earlier sections, string literals have been used to be directly inserted into cout, to initialize strings and to initialize arrays of characters.

But they can also be accessed directly. String literals are arrays of the proper array blazon to contain all its characters plus the terminating nix-character, with each of the elements being of type const char (as literals, they can never be modified). For case:

                                          
                                              const                        char                        * foo =                        "hello";                                          

This declares an assortment with the literal representation for "howdy", and and so a arrow to its beginning element is assigned to foo. If we imagine that "hello" is stored at the memory locations that start at accost 1702, nosotros can stand for the previous announcement as:


Annotation that here foo is a arrow and contains the value 1702, and not 'h', nor "hello", although 1702 indeed is the accost of both of these.

The pointer foo points to a sequence of characters. And because pointers and arrays behave essentially in the same style in expressions, foo tin exist used to access the characters in the same way arrays of nothing-terminated character sequences are. For example:

Both expressions have a value of 'o' (the fifth chemical element of the array).


Pointers to pointers

C++ allows the utilise of pointers that bespeak to pointers, that these, in its turn, point to information (or even to other pointers). The syntax only requires an asterisk (*) for each level of indirection in the declaration of the pointer:
                      i
2
3
4
5
6
                                              char                        a;                        char                        * b;                        char                        ** c; a =                        'z'; b = &a; c = &b;                    

This, assuming the randomly chosen memory locations for each variable of 7230, 8092, and 10502, could exist represented equally:


With the value of each variable represented inside its respective cell, and their respective addresses in retentivity represented by the value under them.

The new thing in this example is variable c, which is a arrow to a pointer, and tin can be used in 3 different levels of indirection, each one of them would correspond to a different value:

  • c is of type char** and a value of 8092
  • *c is of type char* and a value of 7230
  • **c is of type char and a value of 'z'

void pointers

The void type of arrow is a special type of pointer. In C++, void represents the absenteeism of type. Therefore, void pointers are pointers that point to a value that has no type (and thus also an undetermined length and undetermined dereferencing properties).

This gives void pointers a cracking flexibility, by being able to point to any data type, from an integer value or a bladder to a string of characters. In exchange, they accept a great limitation: the data pointed to past them cannot be directly dereferenced (which is logical, since we have no blazon to dereference to), and for that reason, any accost in a void arrow needs to be transformed into some other pointer type that points to a concrete data type before being dereferenced.

1 of its possible uses may be to laissez passer generic parameters to a function. For example:

                      1
2
3
4
5
vi
7
8
9
10
eleven
12
13
fourteen
fifteen
xvi
17
eighteen
19
20
21
                                              // increaser                        #include <iostream>                        using                        namespace                        std;                        void                        increment (void* information,                        int                        psize) {                        if                        ( psize ==                        sizeof(char) )   {                        char* pchar; pchar=(char*)data; ++(*pchar); }                        else                        if                        (psize ==                        sizeof(int) )   {                        int* pint; pint=(int*)data; ++(*pint); } }                        int                        primary () {                        char                        a =                        'x';                        int                        b = 1602;   increment (&a,sizeof(a));   increase (&b,sizeof(b));   cout << a <<                        ", "                        << b <<                        '\north';                        return                        0; }                    
                      y, 1603                    

sizeof is an operator integrated in the C++ language that returns the size in bytes of its argument. For non-dynamic data types, this value is a constant. Therefore, for example, sizeof(char) is 1, because char has always a size of ane byte.


Invalid pointers and nothing pointers

In principle, pointers are meant to bespeak to valid addresses, such as the accost of a variable or the address of an element in an assortment. Merely pointers can actually point to any address, including addresses that do non refer to whatsoever valid element. Typical examples of this are uninitialized pointers and pointers to nonexistent elements of an array:
                      1
2
3
4
                                              int                        * p;                        // uninitialized pointer (local variable)                        int                        myarray[x];                        int                        * q = myarray+twenty;                        // element out of bounds                                                                  

Neither p nor q point to addresses known to contain a value, merely none of the above statements causes an error. In C++, pointers are immune to take any address value, no matter whether there actually is something at that address or not. What can cause an error is to dereference such a pointer (i.e., actually accessing the value they bespeak to). Accessing such a pointer causes undefined behavior, ranging from an error during runtime to accessing some random value.

But, sometimes, a pointer actually needs to explicitly bespeak to nowhere, and not just an invalid address. For such cases, there exists a special value that whatsoever pointer type can accept: the nil arrow value. This value tin be expressed in C++ in two ways: either with an integer value of cipher, or with the nullptr keyword:

                      ane
2
                                              int                        * p = 0;                        int                        * q =                        nullptr;                    

Here, both p and q are null pointers, pregnant that they explicitly point to nowhere, and they both actually compare equal: all null pointers compare equal to other null pointers. It is also quite usual to run across the divers constant Naught exist used in older lawmaking to refer to the aught arrow value:

NULL is defined in several headers of the standard library, and is defined as an alias of some null pointer constant value (such as 0 or nullptr).

Exercise not confuse zilch pointers with void pointers! A nothing pointer is a value that any pointer can take to correspond that it is pointing to "nowhere", while a void pointer is a type of pointer that tin can point to somewhere without a specific type. One refers to the value stored in the pointer, and the other to the blazon of data it points to.


Pointers to functions

C++ allows operations with pointers to functions. The typical use of this is for passing a function as an argument to another part. Pointers to functions are declared with the same syntax as a regular function declaration, except that the name of the function is enclosed betwixt parentheses () and an asterisk (*) is inserted before the name:
                      1
two
3
iv
five
six
7
viii
ix
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
                                              // pointer to functions                        #include <iostream>                        using                        namespace                        std;                        int                        addition (int                        a,                        int                        b) {                        return                        (a+b); }                        int                        subtraction (int                        a,                        int                        b) {                        return                        (a-b); }                        int                        operation (int                        10,                        int                        y,                        int                        (*functocall)(int,int)) {                        int                        g;   1000 = (*functocall)(x,y);                        return                        (g); }                        int                        main () {                        int                        m,due north;                        int                        (*minus)(int,int) = subtraction;    m = operation (7, 5, improver);   n = operation (20, g, minus);   cout <<n;                        return                        0; }                    
                      8                    

In the instance above, minus is a pointer to a function that has ii parameters of blazon int. It is directly initialized to indicate to the office subtraction:

                                          
                                              int                        (* minus)(int,int) = subtraction;                    

evanshols1939.blogspot.com

Source: https://www.cplusplus.com/doc/tutorial/pointers/

Post a Comment for "You Can Only Assign an Address to a Pointer Variable"