SoFunction
Updated on 2025-03-04

C++ basic introduction tutorial (7): Some more special basic grammar summary

This time we have come to a relatively simple content, introducing some basic loop control, relational expressions, logical control, etc.
Here I will simply draw some slightly more special content to blow water. No, let’s summarize it~

1. i++ and ++i

No, I am not here to explain the difference between i++ and ++i, but the book mentions that when using for loops, is there any difference between i++ and ++i?
The answer is: almost no, whatever you use.
 
However, we need to pay a little attention to the internal processing methods of the two methods:

i++: First copy a copy of i, then add 1 to i, and finally return a copy of i.
++i: Add i to 1, and then return i.
 
In this way, everyone knows who is more efficient, but for today's compilers, they will automatically optimize (but I don't know if all compilers are like this).
Then, C++ allows custom operator behavior, that is, we can define ++ operations for our own class. At this time, copying a copy of the class will obviously not be ignored.

I won't say much about this.

2. Comma operator

The comma operator can put multiple statements together, such as:

Copy the codeThe code is as follows:

    for (int i = 2, j = 10 * i; i < 999; i++) {
        cout << j;
        break;
    }

int i = 2, j = 10 * i; is a comma expression, so what is the value of j? That's right, it's 20.
Come again, like this:
Copy the codeThe code is as follows:

int num = 0;
num = 10, 50;

Note that comma expressions cannot be used when declaring variable assignments. You will know this by yourself after compiling it in the compiler. There is no need to memorize the rules.
What is the num value here? That's right, it's 10. Because the assignment is higher than the comma expression, 10 is assigned to num first, and the subsequent 50 is discarded.
So, what about this: num = (10, 50); The result is 50. Because the parentheses have higher priority than the assignment statement, the comma expression has a lot of benefits, so in the end, 50 is assigned to num.
 
However, if anyone uses such an assignment form in a special case, then I promise not to kill him.

3. Type alias (typedef)

This is another pain point for novices. Most friends who are first exposed to Cocos2d-x must have been scared to death by these two statements:

Copy the codeThe code is as follows:

typedef void (Ref::*SEL_SCHEDULE)(float);
#define schedule_selector(_SELECTOR) static_cast<cocos2d::SEL_SCHEDULE>(&_SELECTOR)

What exactly is this seemingly complicated thing? This is actually what we need to use when using the schedule timer function.
Let's put it here first.
 
Let's first look at the simplest typedef usage:

Copy the codeThe code is as follows:

typedef int IQ;
IQ mutouIQ = 250;
int normalIQ = 1;

The so-called type alias means giving a nickname to a certain type of name, for example, we use IQ instead of int, as shown in the above code.
Using typedef int IQ means that int has been given an alias name, called IQ, and you can use IQ to define integers in the future.
To put it bluntly, IQ is int, and int is IQ, please understand~
 
Let’s take a look at this: typedef char* mpointer;
Then, we can use mpointer to define a pointer of type char in the future.
 
Have you noticed anything?
If you remove the typedef, it becomes like this:

Copy the codeThe code is as follows:

int IQ;
char* mpointer;

Yes, IQ and mpointer are like a variable name (in the above code they are variable names).
The result is that after declaring the variable, typedef is preceded, and the variable becomes an alias for the type.
It's easy to understand, right? When you see that typedef is very complicated, you can remove the typedef and see which variable it is declared. Then this alias represents such a variable.
 
Next, let’s go back to the two complicated sentences of God:

Copy the codeThe code is as follows:

typedef void (Ref::*SEL_SCHEDULE)(float);
#define schedule_selector(_SELECTOR) static_cast<cocos2d::SEL_SCHEDULE>(&_SELECTOR)

Let’s look at the first item first, it’s very complicated. We remove the typedef and turn it into: void (Ref::*SEL_SCHEDULE)(float);
Actually, I can't explain what this is. I'm very watery in C++, but this is obviously a "function variable" (that's why it is called for the time being).
A function with a return value of void and a parameter float, and its class is limited to Ref, it is easy to understand.
 
Put typedef back, this code defines SEL_SCHEDULE as the function mentioned above.
Let's look at the second code, which is a macro:
1. schedule_selector is the name of the macro
2._SELECTOR is a parameter of a macro
3.static_cast<cocos2d::SEL_SCHEDULE>(&_SELECTOR) is simplified to static_cast<SEL_SCHEDULE>(&_SELECTOR), which is a cast type conversion that converts the passed in _SELECTOR to a certain type
4. Why does the conversion type? That's right, it's the SEL_SCHEDULE type. What type is SEL_SCHEDULE? As explained just now, a function with a return value of void, a parameter of float, and a class of Ref
 
Finally, let’s see how we usually use schedule_selector:

Copy the codeThe code is as follows:

this->schedule(schedule_selector(HelloWorld::update));

The result is that our HelloWorld update function is converted to the SEL_SCHEDULE type and passed it to the schedule function.
 
Huh, I understand this time, finally see how our update function is defined: void update(float dt);
The return value is void and the parameter is float. The HelloWorld class inherits Layer (and ultimately inherits Ref).
The type of the update function is basically the same as that of SEL_SCHEDULE, except for the type of the class.
But because the final base class of Layer is Ref, the update function can be cast to the SEL_SCHEDULE type.
 
Okay, if I continue to explain, it will become increasingly difficult to explain. Let’s just stop here~

4. New for loop (c++11)

C++11 has added a for loop syntax, which can easily traverse arrays, vectors and arrays.
It is very simple to use, as follows:

Copy the codeThe code is as follows:

    int nums[3] = { 1, 2, 3 };
    for (int num : nums) {
    }

In this way, the value of nums can be assigned to num, thereby traversing the entire array. I won't say much~

5. cctype standard library

I'll ask you a question, give you a letter A, and you want to judge whether it is capital or lowercase. How do you judge it?
(Xiaoruo: You said it was the letter A, of course it was capitalized! Do you want to make a judgment?)
 
Ahem~! program! We are programmers, we can’t make a judgment so simply! This is not rigorous!
We should do this:

Copy the codeThe code is as follows:

char c = 'A';
if(c >= 'A' and c <= 'Z') {
// Well, it's capital
}

Most people think so, right? (Xiaoruo: No, most people know that A is capitalized, so there is no need to judge)

In fact, this is not safe. What if the character encoding is not ASCII? Maybe the answer is different.
So, we should write this:

Copy the codeThe code is as follows:

    char c = 'A';
    if (isupper(c)) {
// Well, it's capital
        cout << "yes";
    }

isupper is a function of the cctype library, used to determine whether letters are capitalized.
This makes it more convenient and universal.
 
The cctype library is in the header file (or in the cctype). There will be many more functions for this library on Baidu~

6. End

Okay, let’s get to this time. C++ is indeed not something I like. There are fewer places to blow water (all are more rigorous things). How long can I last? ~