2. The relationship between C and C++

The relationship between C and C++

1. C++ inherits all C features

2. C++ is based on the C language, and has enhanced object-oriented support, type enhancement, function enhancement, and exception handling.

3. Variables in the language must be defined at the beginning of the scope, and c++ can be defined when needed.

4. The register keyword requests the compiler to store local variables in registers, but the compiler can refuse. The C++ compiler has its own optimization methods, and variables may also be stored in registers, so register is rarely seen in C++, just for compatibility with C language. The address of register variable cannot be obtained in c language. C++ can get the address of the register variable.

5. Multiple global variables with the same name can be defined in C language, but multiple global variables with the same name are not allowed in C++.

6. Enhancement of struct keyword

    The struct in the c language defines a set of variables, not a new type (if you want to treat it as a new type, you need to use the typedef keyword to rename it). C++ defines struct as a new type after type enhancement.

7. All identifiers in C++ must display the declared type. Unlike the default type in the C language, C++ does not support the default type, and it is not allowed to not write the function return type.

    A quick question: is there a difference between int f() and int f(void)?

    The two functions in C++ have the same meaning, which means a parameterless function that returns an int. The two functions in the c language are different. int f() represents a function that returns an int and accepts any parameters, while int f(void) represents a parameterless function that returns an int.

8. The evolution of the const keyword

    The const-modified variable in C language is read-only, which makes the variable have read-only attribute, and it is still a variable in essence. The local variable it modifies will also allocate space on the stack, which is only valid at compile time and invalid at runtime. In particular, const-modified global variables allocate space in read-only storage, so modifying const-modified global variables will crash. A variable modified by const is not a real constant, it just tells the compiler that the variable cannot appear on the left side of an assignment symbol, so const cannot define a real constant. The only real constants in C language are enumerations. The value of a variable modified by const can be modified through a pointer.

    In C++, a constant is placed in the symbol table when a const declaration is encountered. If a constant is found to be used during compilation, it is directly replaced with the value in the symbol table. A symbol table is a data structure generated by the compiler during compilation. If the following conditions are found during compilation, storage space is allocated to the corresponding constant: 

    (1) Extern is used for const constants, that is, when const constants are global and need to be used in other files. (2) When using the & operator to take the address of a const constant. 

    Note: C++ compilers may allocate space for const constants, but will not use the value in their storage space. The reason is for compatibility with C language.

The difference with macros: const constants are handled by the compiler, and the compiler performs type checking and scope checking on const constants (macro does not). There is no concept of macros in the compiler, macro definitions are handled by the preprocessor, pure text replacement (literal), no type checking and no concept of scope.

    const int *p=&x; bottom layer

    int * const p=&x; top level

    const int *const p=&x; The const on the right is the top level, and the one on the left is the bottom const

9. Newly added bool base types and references in c++

C++ (type enhancement and object-oriented features) adds the bool type (boolean type) to the basic type system of the C language. The only possible values ​​are true and false, and theoretically it only occupies one byte. true is represented by 1 and false is represented by 0. It is not rigorous to use int instead of bool in C language.

   C++ has upgraded the ternary operator. The ternary operator in the c language returns the variable value and cannot be used as an lvalue. If the ternary operator in c++ is a variable, it directly returns the variable itself, which can be used as an rvalue or an lvalue (only when all possible return values ​​are variables).

    Note: If one of the possible values ​​returned by the ternary operator is a constant value, it cannot be used as an lvalue.

References in C++: The essence of variable names is an alias for storage space. The concept of reference is newly added in C++, which can be regarded as an alias for a defined variable.

Type& name=var;

 Question: What does c++ do with the ternary operator?

    When the possible returns of the ternary operator are all variables, a variable reference is returned. When there is a constant in the possible returns of the ternary operator, the value is returned.

10. The nature of citations

    References can be used instead of pointers in some cases, such as the swap function. References as function parameters do not require initialization. Initialization is required when the function is called.

const reference: A const reference allows a variable to have read-only properties, but it can also modify the value through a pointer.

Special references: When a const reference is initialized with a constant, the C++ compiler allocates space for the constant value and uses the reference name as an alias for this space. Initializing a const reference with a literal constant results in a read-only variable.

    Question: Do references have their own storage space?

The internal implementation of a reference in C++ is a pointer constant, so a reference occupies the same amount of space as a pointer. From a usage point of view, a reference is just an alias, and C++ hides the details of the reference storage space for practicality.

References in C++ are designed to replace pointers in most cases, avoiding pointer errors. In some cases, memory operation errors cannot be avoided, such as functions returning a reference to a local variable, do not return a reference to a local variable. A reference to a static local variable can be returned.

11. A new concept in C++: inline functions

        const constants in c++ can replace macro constant definitions

Such as: const int A=3; == #define A 3 (the preprocessor replaces the A text with 3 before compiling, no syntax checking)

Is there a solution in c++ to replace macro snippets?

        In C++, it is recommended to use inline functions instead of macro code fragments, and use inline to declare inline functions

When an inline function is declared, the inline keyword must be combined with the function definition, otherwise the compiler will directly ignore the inline request (just a request, the compiler can refuse). The C++ compiler directly inserts the function body into the place where the function is called, without the extra overhead (push stack, jump, return) of ordinary function calls.

        An inline function has the characteristics of a normal function (parameter checking, return type, etc.), and after being compiled inline, the function body expands directly to the place where it is called. Side effects are possible as macro code snippets are processed by the preprocessor for simple text replacement without any compilation process. Modern C++ compilers are capable of compilation optimizations, and some functions may be compiled inline even if they are not declared inline. Some modern C++ compilers are able to force inlining of functions.

Restriction of inline inline compilation: The function body cannot be too complex

        There cannot be any form of loop statement

        There cannot be too many conditional judgment statements

        The function body cannot be too large    

        Function cannot be fetched

        Function inline declaration must precede the call

12. Expansion of function parameters

        In C++, it is possible to provide a default value for a parameter when a function is declared (there is no such feature in C language). When the function is called without providing a value for the parameter, the default value is used.

        Default values ​​for parameters must be specified in the function declaration, not when the function is defined. Rules for function default parameters:

Default values ​​for parameters must be provided from right to left. When a function is called with a default value, subsequent parameters must use the default value (otherwise the order of the parameters is called).

        In C++ it is possible to provide placeholder parameters for functions.

Placeholder parameters only have parameter type declarations, but no parameter name declarations. In general, placeholder parameters cannot be used inside a function body.

        The meaning of function placeholder parameters:

The placeholder parameter is used in combination with the default parameter, which is compatible with the irregular writing method that may appear in the C language program. Because void func() in c language is different from void func( void ), the first one represents a function that accepts arbitrary parameters, while c++ is different. In order to avoid irregular writing in c, function placeholder parameters are proposed . So that when an error occurs when a function with parameters calls a function without parameters, it is only necessary to provide placeholder parameters in the declaration. The combination of placeholder parameters and default values ​​makes it legal when func(); and func(1, 2); appear at the same time.

13. Function overloading analysis

        The qualitative leap from c language to c++: function overloading

Concept: The same identifier has different meanings in different contexts. Define different functions with the same function name. When the function name is matched with different parameters, the meaning of the function is different.

        Function overloading satisfies at least one of the following conditions:

The number of parameters is different

different parameter types

Argument order is different

        What happens when the function default parameter int func(int a, int b, int c=0) encounters the function overload int func(int a, intb)? 

Call: int c=func(1,2); The result will be an error, but it will not compile.

        Guidelines for the compiler to call overloaded functions:

make all functions of the same name as candidates

Try to find feasible candidate functions (exactly match the actual parameters, match the actual parameters through the default parameters, and match the actual parameters through the default type conversion). If all candidates cannot be matched, the function is undefined and compilation fails.

        Note on function overloading:

Overloaded functions are essentially different functions independent of each other

Overloaded functions have different function types

Function return value cannot be used as the basis for function overloading

Note: Function overloading is determined by the function name and parameter list, not the return value.

        Function overloading meets function pointers:

When assigning an overloaded function name to a function pointer 1. According to the overloading rules, select the candidates whose overloaded function parameter list is consistent with the function pointer parameter list. 2. Strictly match the function type (including the return value type) of the candidate and the function pointer. Function type (point to the same, different from above)

typedef int(*PFUNC)(int a); //Defines a function pointer type PFUNC

PFUNC p=func; //A function pointer p is defined through the function pointer type PFUNC, and the func identifier is assigned to the p pointer variable

c=p(1); //Call the function through the pointer variable p 

The function call is int func(int x)       

Strictly match parameter lists and function types (including return value types)

        Note: function overloading must happen in the same scope

                  The compiler needs to use the parameter list for function selection (the function pointer also needs to have the same function type)

                  The entry address of the overloaded function cannot be obtained directly through the function name

print("%p\n",(int(*)(int,int))add); // Cast function address add to int(*)(int, int)

        c++ and c call each other:

The c++ compiler will preferentially use the c++ compilation method, and the extern keyword can force the c++ compiler to compile the c method (c++ compiler)

extern "C"    {  #include "add.h" }

    How to guarantee that a piece of c code will only be compiled in the c way?

_cplusplus is a standard macro definition built into the C++ compiler, meaning:

Ensure that the c code is compiled into object files in a unified c way

#ifdef _cplusplus

extern " C" {

#endif

#include "add.h"

#ifdef _cplusplus

}

#endif

Precautions:

     c++ compiler cannot compile overloaded functions in c way

    The compilation method determines the target name after the function name is compiled (the C++ compilation method compiles the function name and parameter list into the target name. The c compilation method only compiles the function name as the target name)

summary:

        Function overloading is an important upgrade of C++ to C        

        Function overloading distinguishes different functions of the same name by the function parameter list

        The extern keyword can realize the mutual call of c and c++

        The compilation method determines the final target name of the function name in the symbol table

14. New members in c++

        Dynamic memory allocation in c++:

Dynamic memory application through new keyword in c++

Dynamic memory application in c++ is based on type

The delete keyword is used for memory release (to release the object pointed to by the pointer)

        In the c language, it is done with the library function malloc. C is a low-level language and may not be supported on the hardware platform. In C++, new becomes a keyword and is part of C++. Dynamic memory allocation is possible on any platform. The other is that malloc performs dynamic memory allocation based on bytes, and dynamic memory allocation in C++ is based on type allocation. new can be initialized when applying for a single type variable, malloc does not have the characteristics of memory initialization.

        namespaces in c++

There is only one global scope in c language, all global identifiers in c language share the same scope, and conflicts between identifiers may occur. The concept of namespace is proposed in c++: namespace divides the global scope into different parts

            Identifiers in different namespaces can have the same name without conflict

            Namespaces can be nested within each other

            The global scope is also called the default namespace

15. New Type Conversion

        Coercion type conversion in c language: (Type) (Expression) ==> is too crude, conversion can be performed between any type, and it is difficult for the compiler to judge its correctness. It is difficult to locate, and it is impossible to quickly locate all the statements that use casts in the source code.

        In c++, the cast is divided into 4 different types: xxx_cast<Type>(Expression), the compiler can help check potential problems, it is very convenient to locate in the code, and supports dynamic type recognition (dynamic_cast)

static_cast: static, used for conversion between basic types, not for conversion between basic type pointers, conversion between class objects with inheritance relationship and conversion between class pointers.

        int i = 0x12345;
        char c = 'c';
        int* pi = &i;
        char* pc = &c;
        c = static_cast<char>(i); //can pass  
        pc = static_cast<char*>(pi);/ /error cannot be used to convert between pointers of primitive types

const_cast: used to remove the read-only attribute of the variable, the target type of the cast must be a pointer or a reference.

        const int& j = 1;
        int& k = const_cast<int&>(j); // for
        const int x = 2;
        int& y = const_cast<int&>(x); // for
        int z = const_cast<int>(x) ; // error The target type of the cast must be a pointer or reference

dynamic_cast: dynamic, used for conversion between class pointers with inheritance relationship, for conversion between class pointers with cross relationship, with type checking function (null pointer will be returned if unsuccessful), and the support of virtual functions is required.

       int i = 0;
       int* pi = &i;
       char* pc = dynamic_cast<char*>(pi); // error has no virtual function

reinterpret_cast: For cast between pointer types, cast between integer and pointer types (integer <=> pointer).

      int i = 0;
      char c = 'c';
      int* pi = &i;
      char* pc = &c;
      pc = reinterpret_cast<char*>(pi);  //  对
      pi = reinterpret_cast<int*>(pc);    //   对
      pi = reinterpret_cast<int*>(i);      //    对

      c = reinterpret_cast<char>(i); // error basic type conversion not supported

16. Criteria for const constants

         Only const constants initialized with literals will enter the symbol table

         const constants initialized with other variables are still read-only variables   

         const constants decorated with volatile do not enter the symbol table

  A const identifier whose initial value cannot be directly determined between compilers is treated as a read-only variable.

     The type of the const reference is the same as the type of the initialized variable: the initialized variable becomes a read-only variable. The initial type is different: a new read-only variable is generated

const int x=1; // symbol table

const int& rx=x; // rx refers to the unused space allocated by the compiler for x, representing a read-only variable

int& nrx=const_cast<int&>(rx); //Remove the const attribute

The addresses of x, rx, and nrx are the same.

    The criteria for determining whether it is a constant is: whether its value can be determined at compile time.

    References and pointers: how to understand "the essence of reference is pointer constant?"

A pointer is a variable:

        The value is a memory address that does not require initialization and can hold different addresses.

        The value in the corresponding memory address can be accessed through the pointer.

        Pointers can be const modified into constants or read-only variables.

A reference is just a new name for a variable:

        Operations on references (assignment, address take, etc.) are passed to the represented variable.

        A const reference makes the variable it represents a read-only property.

        References must be initialized at definition time and cannot represent other variables thereafter.

    From the perspective of using the C++ language, references have nothing to do with pointers, references are the new names of variables, and operations on references are operations on the corresponding variables.

   From the point of view of the C++ compiler, in order to support the new concept "reference", an efficient solution is necessary. Inside the compiler, pointer constants are used to implement "reference", so "reference" must be initialized when it is defined,

     In the development of engineering projects, when programming in C++, the reference is directly viewed from the perspective of use, which has nothing to do with the pointer. The reference is the alias of the variable. When debugging and analyzing C++, if you encounter some special cases, you can consider the reference from the perspective of the C++ compiler.

  Note: Reference arrays are not supported in C++ (will make the difference between the addresses of adjacent array elements not expected)

         pointer is a variable

         A reference is a new name for a variable.

         A const reference can create a new read-only variable.

         "References" are implemented internally by the compiler using pointer constants.

        A const identifier whose initial value cannot be determined directly at compile time is a read-only variable.

             





Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325886037&siteId=291194637