Introduction to const in C Language (description of const keywords)

Source: Internet
Author: User
Const thinking

1. What is const?
A common type is a type described by the Type modifier Const. The values of variables or objects of a common type cannot be updated. (Of course, we can steal the bar for updating :)

2. Why is const introduced?
The initial purpose of const is to replace precompiled commands, eliminate its shortcomings, and inherit its advantages.

3. What are the main functions of cons?
(1) const constants can be defined and are non-mutable.
For example:
Const int max = 100;
Int array [Max];
(2) It is easy to perform type check, so that the compiler can learn more about the processing content and eliminate some hidden risks.
For example:
Void F (const int I ){.........}
The compiler will know that I is a constant and cannot be modified;
(3) it can avoid the appearance of numbers with fuzzy meanings and easily adjust and modify parameters.
Same as macro definition, it can be changed as long as it remains unchanged! For example, if you want to modify the content of Max in (1), you only need to: const int max = you want!
(4) It can protect modified things, prevent accidental modifications, and enhance program robustness.
In the above example, if I is modified in the function body, the compiler reports an error;
For example:
Void F (const int I) {I = 10; // error! }
(5) provides a reference for function overloading.
Class
{
......
Void F (int I) {...} file: // One/Function
Void F (int I) const {...} file: // overload of a function
......
};
(6) It can save space and avoid unnecessary memory allocation.
For example:
# Define PI 3.14159 file: // constant/macro
Const doulbe Pi = 3.14159; file: // This // pi is not put into Rom
......
Double I = PI; file: // This // allocates memory for PI and will not be allocated later!
Double I = PI; file: // macro replacement during compilation/translation and Memory Allocation
Double J = PI; file: // No/memory allocation
Double J = PI; file: // then use macro replacement to allocate memory again!
Const defines constants. From the assembly point of view, only the corresponding memory address is given, rather than the number of immediate values as # define. Therefore, the const-defined constants have only one copy during the program running, while the # define-defined constants have several copies in the memory.
(7) improved efficiency.
Generally, the compiler does not allocate storage space for common const constants, but stores them in the symbol table, which makes it a constant during compilation without the operation of storage and read memory, this makes it highly efficient.

3. How to Use const?
(1) Modifying General Constants
A constant is a constant of a simple type. When defining such constants, the modifier const can be used before or after the type specifier.
For example:
Int const x = 2; or const int x = 2;
(2) Modifying regular Arrays
Define or describe a regular array in the following format:
Int const A [5] = {1, 2, 3, 4, 5 };
Const int A [5] = {1, 2, 3, 4, 5 };
(3) modify a constant object
A constant object is an object constant. The definition format is as follows:
Class;
Const;
A const;
When defining a common object, Initialization is also required, and the object cannot be updated. The modifier const can be placed after the class name or before the class name.
(4) modify the constant pointer
Const int * A; file: // const/modifies the object to which a points. A is variable, and A is variable.
Int const * A; file: // const/modifies the object to which a points. A is variable, and A is variable.
Int * const A; file: // const/modifier pointer A, A immutable, object pointed by a variable
Const int * const A; file: // The object pointed to by needle a and a cannot be changed.
(5) Modify common references
The const modifier can also be used to describe the reference. The referenced object cannot be updated. The definition format is as follows:
Const double & V;
(6) modifying the common parameters of a function
The const modifier can also modify the passing parameters of a function. The format is as follows:
Void fun (const int var );
Tells the compiler that VaR cannot be changed in the function body, thus preventing unintentional or incorrect modifications.
(7) modifier return value:
The const modifier can also modify the return value of a function, which cannot be changed. The format is as follows:
Const int fun1 ();
Const myclass fun2 ();
(8) modify the member functions of the class:
The const modifier can also modify the member functions of the class in the following format:
Class classname
{
Public:
Int fun () const;
.....
};
In this way, the data in the class cannot be modified when the function fun is called.
(9) reference the const constant in another connection file
Extern const int I; file: // positive/exact reference
Extern const Int J = 10; file: // error/error! Constants cannot be assigned another value.
Note that constants must be initialized!
For example:
Const int I = 5;

4. Some points worth discussing:
(1) What does const mean?
So much, what do you think const means? A modifier? Interface abstraction? A new type?
Maybe all. When stroustup first introduced this keyword, it only made a possibility to put the object into Rom. For a const object, C ++ allows static initialization, he can also perform dynamic initialization. The ideal const object should be writable before its const function is completed, and can be written after the function execution starts. In other words, the const object has immutability from the completion of the construction function to the execution of the function. If this rule is violated, the result is undefined! Although we put the const into the Rom, this does not guarantee any const-style degradation. We will provide specific solutions later. Whether the const object is put into the ROM or protected by the storage protection mechanism, it can only be ensured that the object has not changed for the user. In other words, there is no problem with the modification of a const by the database system or the waste collector (which we will discuss in detail later.
(2) bitwise const v. S. Abstract const?
There are several methods to explain the keyword Const. The most common is bitwise const and abstract Const. Here is an example:
Class
{
Public:
......
A f (const A & );
......
};
If the abstract const is used for interpretation, the F function will not change the abstract value of the referenced object. If the bitwise const is used for interpretation, then the f function will not change any bitwise element of the referenced object.
We can see that the bitwise Element Interpretation is exactly the definition of const in C ++. The const member function is not allowed to modify any data member of its object.
Why? Because bitwise const has two advantages:
The biggest benefit is that it is easy to detect events that violate the bitwise const rules: the compiler only needs to find out whether to assign values to data members. In addition, if we use bitwise const, we can safely put some simple const objects into Rom. For some programs, this is undoubtedly an important optimization method. (For optimization processing, we will discuss it later)
Of course, bitwise const also has shortcomings. Otherwise, abstract const is unnecessary.
First, bitwise const is more abstract than abstract Const! As we all know, the lower the Abstraction Level of a library interface, the more difficult it is to use this library.
Second, the database interface using bitwise const exposes some implementation details of the database, which often brings some negative effects. Therefore, we should use abstract const in terms of library interfaces and program implementation details.
Sometimes, we may want to make some other explanations for const, so we should note that at present, most of the explanations for const are type insecure. Here we will not give an example, you can think about it yourself. In short, we try to avoid re-interpreting Const.
(3) What are the restrictions on constants placed inside the class?
Let's take a look at the example below:
Class
{
PRIVATE:
Const int C3 = 7 ;//???
Static int C4 = 7 ;//???
Static const float C5 = 7 ;//???
......
};
Do you think the above three sentences are correct? No! When using the internal initialization syntax of this type, the constant must be an integer or enumeration type initialized by a constant expression, and must be in the form of static and Const. This is obviously a very serious limitation!
So why does our Standards Committee make such a provision? Generally, classes are declared in a header file, and header files are contained in many mutually called units. However, to avoid complicated compiler rules, C ++ requires that each object has only one separate definition. If C ++ Allows defining an object that occupies the same memory as an object in the class, this rule will be destroyed.

(4) How to initialize constants inside the class?
One method is static and const, which are initialized internally, as shown in the preceding example;
Another common method is to initialize the list:
Class
{
Public:
A (INT I = 0): Test (I ){}
PRIVATE:
Const int I;
};
Another method is external initialization, for example:
Class
{
Public:
A (){}
PRIVATE:
Static const int I; file: // note/it must be static!
};
Const int A: I = 3;
(5) Is there any special combination of constants and arrays?
The following code is provided:
Const int size [3] = {10, 20, 50 };
Int array [size [2>;
Is there any problem? By the way, compilation and translation fail! Why?
Const can be used for collections, but the compiler cannot store a set in its symbol table, so memory must be allocated. In this case, const means "a block of storage that cannot be changed ". However, the value cannot be used during compilation because the compiler does not need to know the stored content during compilation. Naturally, the size of the array will not work :)
Let's take a look at the following example:
Class
{
Public:
A (INT I = 0): Test [2] ({1, 2}) {} file: // do you/think it is OK?
PRIVATE:
Const int test [2];
};
Vc6 is not available for further compilation. Why?
About this question, njboy asked me how it was going some time ago? I asked him, "What do you think ?" He thought about it and gave an explanation. You can see that we know that the compiler heap initialization list is performed within the constructor and before explicitly calling available code, the initialization order is based on the data Declaration Order. There should be no problem with the initialization time, so only the compiler has done something to the array! In fact, I don't know what to do, so I had to guess him: the compiler searched for test and found it was a non-static array, So I allocated him memory space, it should be noted that the allocation is complete, instead of assigning test [0] first, and then using the initialization list to initialize and reassign test [1]. as a result, array Initialization is actually a value! However, constants do not allow assignment, so they cannot pass.
Haha, I am so happy to see this story! Njboy: The C ++ standard does not allow unordered objects to be initialized within the class, the array is obviously unordered, so such initialization is incorrect! It can only be initialized outside the class. If you want it to pass through, you only need to declare it as static and then initialize it.
Here we can see that the combination of constants and arrays is nothing special! Everything is an array!
(6) is this pointer of the const type?
This pointer is a very important concept. How can we understand her? Maybe this topic is too big, so let's narrow down: What type is this pointer? This depends on the specific situation: in a non-const member function, the this pointer is only of the class type; In a const member function, the this pointer is of the const class type; in the volatile member function, the this pointer is of the volatile class type.
(7) is const an overloaded reference object?
First, let's look at the following example in the pipeline:
Class
{
......
Void F (int I) {...} file: // One/Function
Void F (int I) const {...} file: // overload of a function
......
};
There is no problem with the above heavy load. What about the following?
Class
{
......
Void F (int I) {...} file: // One/Function
Void F (const int I) {...} file ://????? /
......
};
This is incorrect, but it cannot be compiled. Does it mean that the const of the internal parameter is not reloaded? Let's look at the following example:
Class
{
......
Void F (Int &) {...} file: // One/Function
Void F (const Int &) {...} file ://????? /
......
};
This program is correct. It seems that the above conclusion is incorrect. Why? This involves interface transparency. When passing by value, this is transparent to users. users do not know what the function has done to the form parameter. In this case, it is meaningless to perform the overload, so it is required not to reload it! When a pointer or reference is introduced, the user will have a certain understanding of the function operations, and it is no longer transparent. In this case, re-loading is meaningful, so it is required to be reloaded.
(8) under what circumstances will the const allocate memory?
The following are possible situations that I think of. Of course, some compilers have been optimized and may not allocate memory.
A. As a non-static class member;
B. Used for collection;
C. When the address is obtained;
D. When the main function body obtains the value through the function;
E. When a const class or struct has a user-defined constructor, destructor, or base class ;.
F. When the const length is longer than the computer word length;
G. Const In the parameter;
H. When extern is used.
I don't know if there are any other situations. Thank you for your advice :)

(9) is the temporary variable a constant?
In many cases, the compiler must create a temporary object. Like any other object, they require a bucket and must be constructed and deleted. The difference is that we never see the compiler deciding on their leaving and the details of their existence. For the draft C ++ standard: Temporary objects automatically become constants. Because we usually do not have access to temporary objects and cannot use relevant information, it is possible to tell the temporary objects to make some changes. Of course, this is related to the compiler. For example, vc6 and vc7 are all extended. Therefore, the compiler does not report an error when using a temporary object as the left value.
(10) Is there a problem with static?
Assume there is a class:
Class
{
Public:
......
Static void F () const {......}
......
};
The compiler reports an error because static cannot coexist with const in this case!
Why? Because static does not have this pointer, but const modifies this pointer, so...
(11) how to modify constants?
Sometimes we have to modify the data in the class, but our interface has been declared Const. What should we do? My views on this issue are as follows:
1) standard usage: mutable
Class
{
Public:
A (INT I = 0): Test (I ){}
Void setvalue (int I) const {test = I ;}
PRIVATE:
Mutable int test; file: // process in!
};
2) forced conversion: const_cast
Class
{
Public:
A (INT I = 0): Test (I ){}
Void setvalue (int I) const
{Const_cast <int> (TEST) = I;} // process it here!
PRIVATE:
Int test;
};
3) Flexible pointer: int *
Class
{
Public:
A (INT I = 0): Test (I ){}
Void setvalue (int I) const
{* Test = I ;}
PRIVATE:
Int * test; file: // process in!
};
4) undefined Processing
Class
{
Public:
A (INT I = 0): Test (I ){}
Void setvalue (int I) const
{Int * P = (int *) & test; * P = I;} // process it here!
PRIVATE:
Int test;
};
Note: although the modification can be done here, the result is undefined and cannot be used!
5) internal processing: This pointer
Class
{
Public:
A (INT I = 0): Test (I ){}
Void setvalue (int I) const
{(A *) This)-> test = I;} // process it here!
PRIVATE:
Int test;
};
6) The most alternative solution: Spatial Layout
Class
{
Public:
A (INT I = 0): Test (I), C ('A '){}
PRIVATE:
Char C;
Const int test;
};
Int main ()
{
A A (3 );
A * pA = &;
Char * P = (char *) Pa;
Int * Pi = (int *) (p + 4); // Use edge Adjustment
* Pi = 5; file: // The value of test is changed here!
Return 0;
}
Although I have provided the method in step 6, I just want to explain how to change it. However, in addition to the first method, we do not advocate the other five methods. Don't write this because I did, this is how you use it. Otherwise, I will miss you :)
(12) Finally, let's discuss the dynamic creation of constant objects.
Since the compiler can dynamically initialize constants, it can naturally be dynamically created, for example:
Const int * Pi = new const int (10 );
Note the following two points:
1) The const object must be initialized! Therefore, (10) cannot be minimized.
2) the pointer returned by new must be of the const type.
Can we dynamically create an array?
The answer is no, because the new built-in array cannot be initialized.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.