This is a small garden, I am gardener. I plant some small C flowers here. Every strain has its own colors, each has a unique fragrance. I carefully cultivate and share it with my friends.
First flower: NULL secret
The definition of NULL in C and C is different: #define null 0; // C Definition #define null? (Void *) 0) // c is the definition of NULL
Why have different definitions in these two languages? The pointer in C is a strong type, and it is not in C. Therefore, VOID * can only be converted to other types of pointers through explicit conversions in C . If NULL in C follows the statement char * p = null;
It is actually expanded to: char * p = (void *) 0; // The compiler will generate an error: Incompatible Pointer Types
This is why the two languages do different definitions in NULL.
Second flower: inline vs. __forceinline
MS Visual C , and several other compilers provide a non-standard keyword for controlling the inline, as a supplement to the standard keyword inline. Why add this non-standard keyword? Let's take a look at the limitations of Inline, decide whether a function is embedded for the function of the inline, depending on the judgment of the compiler. So Inline is just a suggestion, in some cases, for example, in some inline functions containing loops or this function is too big, even if this function is declared as inline, the compiler will also reject the embedding of this function.
In contrast, non-standard keyword __forceinline will ignore the judgment of the compiler and force the compiler to embed a function of which it should refuse to embed. I don't know the meaning of this keyword, which may make the executable bloated and reduce the hit rate of Cache. Fortunately, under some extreme conditions, the compiler may not accept any request from __forceinline. Therefore, in general, it is best to use standard inline, inline is portable and allow the compiler to make "correct choices". __forceinline should only be used in all the following conditions: Inline is not accepted by the compiler; your code does not need to be transplanted to other platforms; and you can affirm that this function will improve performance.
Third flowers: class members pointer
I often hear a lot of questions about class members pointers: "I use VC, why can't I use a pointer to a class method? Compile error message is: Cannot Convert Parameter 2 from 'long (unsigned long)' to'long (__cdecl *) (unsigned long) 'What should I do? "The following code is one of the solutions:
// in the headerclass ckernel: {long (* lpfunc); long Oleasendtc (DWORD dwinfo);}
// in the cpp filebool ckernel :: init () {lpfunc = Olesendtc; return true;
All class methods have a hidden parameters, a pointer to the class object. C uses this pointer to find any data in the class that this method may use. If you try and use a standard function pointer to call a class method, C will not pass this hidden parameters and cause problems. In order to solve this problem and improve type security, C adds three new operators, :: *,. *, With-> *, which can point to member functions or to member variables. Class ctest {public: bool init (); long OleasendTC (DWORD DWINFO);
Long (ctest :: * lpfunc) (DWORD DWINFO) = & ctest :: Olesendtc;
INT main () {ctest test; (Test. * lpfunc) (0); return 0;}
Long ctest :: OlesendTc (dword dwinfo) {cout << "in olesendtc / n"; return 0;}
This example shows an usage of these operators. Code uses :: * Declare the pointer to the LPFUNC for the class CTEST member function. Note that it is best to assign this point to this point when running, and a simple method is to initialize it at the time of declaration. Use it in the main function. * Run to call the method points to the LPFUNC. If TEST is this a pointer, you can use -> * instead. There are a lot of similar hidden features in C , we have to pay more attention to this in learning.