C++ basic introductory tutorial (8) : function Pointers

  • 2020-04-02 02:58:59
  • OfStack

Recently, things are more, in fact, not busy, is that things affect my mind, so I have no idea to write an article.
Let's focus on the basics of functions today, but let's also explain one of the most confusing things for beginners -- when do I need to use pointer arguments?

Function prototype and function definition

As you all know, C++ requires you to declare prototypes of functions before you can define them, which is annoying for those used to other high-level languages like Java.
The following code:


//Declare function prototype
void startGame(int param);
//Function definition
void startGame(int param)
{
    //All kinds of logic
}

Function prototype is mainly used by the compiler, in the compilation of the function prototype to check the return value of the function, the number of parameters, parameter types, etc.
In short, the compiler is easy, the compiler is good, we are better.

But in practice, function prototypes also allow us to quickly understand what a class does.

That's easy. I won't nag you much.

Const qualifier and pointer

Const was briefly introduced before, for example, const int num = 10; Then num is a constant and cannot be assigned again.
What if I put const on a pointer?


    int num = 10;
    const int *p = #
 
    //Compilation results in an error
    *p = 100;

In the code above, an error is reported at compile time because the pointer p points to a const int, which is a constant.
So the value of *p is a constant and cannot be changed.

Again, or it'll get messy later:
1. P is a pointer
2. P points to a memory address containing a value of type const int
3.*p represents the value stored in the memory address pointed to by p
So *p is a value of type const int
5. In summary, *p cannot be assigned again.

I want to distinguish between p and *p, these are two concepts, one is a pointer, one is the value that the pointer points to.
P can be assigned again, but *p cannot be assigned.

Three, function pointer parameters

Take a look at the following code:


void notChangeNum(int num);
void changeNum(int* num);
int _tmain(int argc, _TCHAR* argv[])
{
    int num = 10;
  
    //This function does not change the value of num
    notChangeNum(num);
    cout << num << endl;
    //This function changes the value of num
    int* p = #
    changeNum(p);
    cout << num << endl;
    return 0;
}
void notChangeNum(int num)
{
    //Parameter is not a pointer
    num = 999;
}
void changeNum(int* num)
{
    //The argument is a pointer
    *num = 999;
}

There are two functions, one is the ordinary parameter (value passing), the other is the pointer parameter (address passing).

The first notChangeNum function does not change the value of num, because when num is passed to the function, a new value is copied, and the original num is unaffected.

When leaving the notChangeNum function, the num parameter of the function is released.

The argument to the second changeNum function is the pointer, and as we all know, the pointer is to some memory address, so the memory address that the argument to the function points to is the memory address of num.

Directly changing the value on the memory address affects the original num, so after leaving the changeNum function, the value of num is also changed, and the final value is 999.

That's what pointer arguments are for, and in some cases, we want the changes to the arguments in the function to really make a difference.

Four, why to use pointer parameters

Why use Pointers as arguments? Because the pointer can point directly to the memory address, you can modify the value directly in the function and still be valid after leaving the function.
Say so, but, of course, some people will be confused, why? Why is that?

For example, our function argument is a class:


void play(Sprite* sp) {
}

Both Sprite and Value are commonly used by cocos2d-x. Why is the parameter here a pointer?
Because the parameters referenced by the value are copied so that the original value is not affected, there is an additional overhead associated with copying.
General classes are expensive (relative to primitive types like int and float), so a copy is not appropriate.
Moreover, we all need to change the Sprite's coordinates, size and other properties in the function, if the value is passed, it cannot be changed (only the copy is changed).

Of course, this also depends on the specific project of the situation, I do not nag, too deep bad blow water.

Five, do not want to copy, and do not want the value to be modified, how to do?

Copying is expensive and using pointer arguments is likely to change the value of the function.
This is the time to use the const qualifier, as follows:


void play(const Sprite* sp) {
}

In this way, the value pointed to by sp will not be changed inside the function, and the extra overhead of value passing can be avoided.

Variables inside a function are released when they leave the function

As we said before, as long as the variable is not new, it will be automatically released when it leaves the scope.
But look at this function:


int getNum() {
    int num = 10;
    return num;
}

Since the variable is released after it leaves the scope, num is released after it leaves the getNum function.
What's the point of returning num? Can the getNum function really succeed in getting the number 10?
The answer is yes.

Because when return returns num, it actually copies it, returns the copied value, and releases the original variable.
So that's the secret of return.

But Pointers don't work. Take a look at this code:


//Suppose I have a structure that is
struct People {
   int age;
};
People* getNewPeople() {
    People nPeople;
    nPeople.age = 20;
    return &nPeople;
}

This function returns a memory address that points to the type of the People structure.
According to the rule of return, when you return, you actually make a copy, but what you copy is just a pointer, which is a memory address.
This memory address still points to the nPeople variable inside the function.

So even if the getNewPeople function successfully returns a pointer, the value at the memory address that the pointer points to is still freed.
In other words, we're just getting a wild pointer.

Seven, end

Ok, this article is a little bad, too much content, I just extract part to blow water ~


Related articles: