The difference between constant #define and const modifier in C++

Table of Contents

1. Constants require initialization values

2.1 Type and security inspection are different

2. 2 Compilers process different

2 and 3 have different storage methods

2 and 4 have different definition domains

2. Can 6 be used as function parameters?

3. const keyword

4. #define keyword

5. Application of const on pointers


1. Constants require initialization values
//Wrong writing
const double pi;//will report uninitialized local variables
pi=3.14

#define PI; //It will report that no expression has been entered.

//Correct writing
const double pi=3.14;

const int A; //Error, no initial value assigned.
extern const int A; //Correct, use extern's external variables.

#define PI 3.14;
2. Type 1 is different from the security check

Macro definition (#define) is a character replacement, with no difference in data type. At the same time, this replacement has no type safety check and may cause errors such as boundary effects.

A const constant is a declaration of a constant, which has type differences and requires type checking during the compilation phase.

2, 2 compiler processing is different

Macro definition is a “compile time” concept, which is expanded in the preprocessing stage. Macro definitions cannot be debugged. The life cycle ends with the compilation period;

const constant is a “runtime” concept, used when the program is running, similar to a read-only line of data

2 and 3 have different storage methods

The macro definition is a direct replacement, no memory is allocated, and is stored in the code segment of the program;

Const constants require memory allocation and are stored in the data segment of the program.

In terms of how it works

#define N 2 + 3 // Our expected N value is 5, we use it like this
Ndouble a = N/2; // We expected the value of a to be 2.5, but in fact the value of a is 3.5

In terms of space occupied

#define PI 3.14 //After preprocessing, it occupies code segment space
const float PI=3.14; // Essentially it is still a float, occupying data segment space
The definition domains of 2 and 4 are different
void f1 ()
{
    #define N 12
    const int n 12;
}
void f2 ()
{
    cout<<N <<endl; //Correct, N has been defined and is not restricted by the domain.
    cout<<n <<endl; //Error, n domain is only in the f1 function
}

2. Can 5 be canceled after definition?

Macro definitions can be #undef to invalidate previous macro definitions.

After a const constant is defined, it will be permanently valid within the domain of definition.

void f1()
{
  #define N 12
  const int n = 12;

  #undef N //After canceling the macro definition, N is invalid even in the f1 function.
  #define N 21//can be redefined after cancellation
}
Can 2 and 6 be used as function parameters

Macro definitions cannot be passed as arguments to functions

const constants can appear in the parameter list of a function

3. const keyword

const is the abbreviation of constant. As long as a variable is modified with const, it means that the data in the variable can be accessed but cannot be modified. In other words, const means readonly.

Rule: Whoever is closest to const cannot be modified;

When const modifies a variable, the variable must be initialized. If it is not initialized, it cannot be initialized later.

Essence: Whoever is behind the const cannot modify it. If const is at the front, it will be moved back by one position. The two are equivalent.

const keyword function

  • To convey very useful information to people reading your code, declaring a parameter as a constant tells the user the purpose of the parameter;
  • Making the keyword const may produce more compact code by giving the optimizer some additional information;
  • Reasonable use of the keyword const allows the compiler to naturally protect parameters that do not want to be modified, prevent unintentional code modifications, and reduce the occurrence of bugs;

const keyword application

  • To prevent a variable from being changed, you can use const. When defining the const variable, you need to initialize it first, so there will be no chance to change it later;
  • For pointers, you can specify the pointer itself as const, you can also specify the data pointed to by the pointer as const, or both at the same time;
  • In a function declaration, const can modify the formal parameter to indicate that it is an input parameter, and its value cannot be changed inside the function;
  • For member functions of a class, sometimes it must be specified as const type, indicating that it is a constant function and cannot modify the member variables of the class;
  • For member functions of a class, sometimes it is necessary to specify that the return value is of const type so that the return value is not an “lvalue”
4. #define keyword

After preprocessing #define variables are defined, semicolons cannot be used, otherwise calculation errors will occur, but the program will not report an error.

#define age 12
#define age1 10

#define age2 12;
#define age3 10;

int main()
{
   int dd;
   dd = age + age1;
   cout << "value=" << dd << endl; //value 22
   dd = age2 + age3;
   cout << "value=" << dd << endl; //value 12
    return 0;
}
5. Application of const on pointers

The const keyword appears to the left of *: the content pointed to by the pointer cannot be modified. It is called a pointer to a constant, which is also called the underlying const at this time.

The const keyword appears on the right side of *: the pointer itself cannot be modified, it is called a constant pointer, and it is also called top-level const at this time.

The const keyword appears on both sides of *: neither the content pointed to by the pointer nor the pointer itself can be modified. At this point you have both the bottom and top level const.

A few points to note:

(1) The content pointed to by the underlying pointer is not unmodifiable, but it cannot be modified through the pointer. In other words, the underlying pointer “sentimentally” believes that the content it points to cannot be modified. In fact, it can be modified through assignment and other methods. Change what it points to.

(2) In use, the top-level const is only used to modify pointers and cannot modify references (because references are not variables); while the bottom-level const can modify pointers and references, which means that the content pointed to or referenced is a constant. Just remember that the underlying const-qualified object points to or refers to a constant, and there are no restrictions on pointers or references; the top-level const-qualified pointer is a constant, and there are no restrictions on the content it points to.

(3) The underlying const will impose a restriction on the variable. When performing a copy operation, non-underlying const objects cannot assign values to variables with underlying const.

int main()
{
    int a = 1;
    //Underlying const, you can also use int const *p1 = & amp;a;.
    const int *p1 = & amp;a;
        
    //Illegal, the value of a cannot be changed through p1.
    *p1 = 2;
                  
    //Legal, the value of p1 (the address pointed to) can be changed.
    p1 + + ;
                     
    //Legal, but the value of a cannot be changed by dereferencing p1, other methods are possible.
    a = 2;

    //Top-level const, p2 is a constant.
    int *const p2 = & amp;a;
     
    //Legal, the content of the address pointed to by p2 can be changed.
    *p2 = 3;
    
    //Illegal, the value of p2 (the address pointed to) cannot be changed.
    p2 + + ;
    
    //Legal, the content of the address pointed to by p2 can be changed.
    a = 4;

    //With both bottom-level and top-level const, the value of p3 (the address pointed to) cannot be modified, and cannot be changed through p3 dereference.
    const int *const p3 = & amp;a;

    //Illegal, p1 is const *int (underlying const), and cannot be assigned to ordinary int*.
    int *p4 = p1;

    //Legal, p2 is *const int (top-level const), there is no restriction on assignment.
    int *p5 = p2;

    //Legal, p6 is also const *int (underlying const), and the assignment of p1 can be obtained.
    const int *p6 = p1;
}