I. Use of const in C
From: http://blog.chinaunix.net/u/26828/showart_667881.html
Const is a key word in C language. It specifies that a variable cannot be changed. Using const can improve the robustness of the program to a certain extent. In addition, while watching other people's code, you can clearly understand the role of const and help you understand the program of the other party.
Although it sounds very simple, in fact, the use of const is also a subtle place in C language, where is the subtlety?
See the following questions.
Question 1: const variable & Constant
Why does the ansi c compiler report an error when I use a const variable to initialize an array like in the following example?
Const int n = 5; int A [n];
Answer and analysis:
1) the difference between "constant" and "Read-Only variable" is discussed. Constants must be read-only, for example, 5, "ABC", etc. They must be read-only, because there is no place in the program to store its value, and of course it cannot be modified. The "Read-Only variable" is to open a place in the memory to store its value, but this value is limited by the compiler and cannot be modified. The const keyword in C language is used to restrict a modifier that cannot be changed ). In the above Code, variable N is modified as a read-only variable. Unfortunately, the modification is not a constant. Ansi c requires that the dimension of an array definition must be "constant" and "Read-Only variables" are not allowed.
2) Note: in ansi c, this writing method is incorrect, because the array size should be a constant, while const int N and n are just a variable (constant! = Immutable variables, but in the Standard C ++, this defines a constant, which is correct). In fact, according to the compilation process and memory allocation, this method should have been reasonable, but ansi c imposes restrictions on arrays.
3) So what are constants defined in ansi c? The answer is the enum type and the # define macro, both of which can be used to define constants.
Question 2: Content limited by the const variable & Const
The following code compiler reports an error. Which statement is wrong?
Typedef char * pstr;
Char string [4] = "ABC ";
Const char * P1 = string;
Const pstr P2 = string;
P1 ++;
P2 ++;
Answer and analysis: the problem lies in P2 ++.
1) the basic form of const: const char m; the limit m is immutable.
2) Replace M, const char * PM in the 1 formula; Limit * PM is immutable, of course PM is variable, so P1 ++ is correct in the problem.
3) Replace 1 char, const newtype m; Limit m is immutable, charptr in the problem is a new type, so P2 is not variable in the problem, P2 ++ is wrong.
Question 3: const variable & String constant
What is the problem with the following code?
Char * P = "I'm hungry! "; P [0] = 'I ';
Answer and analysis: the above Code may cause illegal memory write operations. The analysis is as follows: "I'm hungry" is essentially a String constant, while constants are often placed in the read-only memory area by the compiler and cannot be written. P initially points to this read-only memory zone, while P [0] = 'I' attempts to write this place, And the compiler certainly won't agree.
Question 4: const variable & String constant 2
Is char a [3] = "ABC" Legal? What are the risks of using it?
Answer and analysis: This is legal in Standard C (Note: An error is reported in C ++, error c2117: "A": array limit overflow ), however, its survival environment is very small. It defines an array of 3 and is initialized as "ABC". Note that it does not have the usual string Terminator '/0 ', therefore, this array only looks like a string in C language, but it is not actually. Therefore, all functions that process strings, such as strcpy and printf, cannot be used on this fake string.
Question 5: const & pointer
In the type declaration, const is used to modify a constant, which can be written in the following two ways,
So, what is the immutable content defined by const below?
1) const is in front
Const int nvalue; // nvalue is const
Const char * Pcontent; // * Pcontent is const, and Pcontent is variable
Const (char *) Pcontent; // Pcontent is const, * Pcontent is variable
Char * const Pcontent; // Pcontent is const, * Pcontent is variable
Const char * const Pcontent; // both Pcontent and * Pcontent are const
2) const is behind and equal to the above statement
Int const nvalue; // nvalue is const
Char const * Pcontent; // * Pcontent is const, and Pcontent is variable
(Char *) const Pcontent; // Pcontent is const, * Pcontent is variable
Char * const Pcontent; // Pcontent is const, * Pcontent is variable
Char const * const Pcontent; // both Pcontent and * Pcontent are const
Answer and analysis:
Using const and pointer together is a common confusion in C language. In actual development, especially when looking at other people's code, it is often difficult to judge the author's intention because of this, the following describes my judgment principles:
Draw a line along the number *. If the const is on the left side of *, the const is used to modify the variable pointed to by the pointer, that is, the pointer points to a constant. If the const is on the right side, const is to modify the pointer itself, that is, the pointer itself is a constant. You can view the actual meaning of the above statement based on this rule, and I believe it will be clear at a glance.
Ii. Differences between const in C and const in C ++
C is strange and has many defects, but has achieved great success.
-- Dennis Ritchie
It is undeniable that C language is a very successful and popular language (I like C very much), but it is inevitable that there are some incredible things in C language.
Read-Only variables & Constants
In C, is a constant modified by const? Is it true that the mountains do not change?
Compile the following code. What do you think?
Const int A = 10;
Int * pA = &;
* PA = 20;
Printf ("% d/N", * pA );
Printf ("% d/N", );
The compiler does not report an error as you would expect, but only provides a warning (warning c4090: "initialization": Different "const" delimiters)
You can see that the value of a has been changed. Changed to 20
The const keyword cannot change the variable to a constant! Adding a qualifier const before a symbol only indicates that it cannot be assigned a value. In other words, its value is read-only for this symbol, but it cannot prevent internal (or external) use of the program) to modify the value.
The variable modified by const in the C language is only a read-only variable. For example:
Const int n= 100;
Int A [n]; (C does not advocate such writing, and can be replaced by macros)
But this is not the case in C ++. The const modifier in C ++ is undoubtedly a constant, and its value is determined at compilation.
Const int A = 10;
Int * pA = &;
* PA = 20;
Printf ("% d/N", * pA );
The above code is incorrect in C ++ and compilation errors will certainly occur. (Error c2440: "initialization": cannot be converted from "const int *" to "int *")
The following code is common in C ++.
Const int n= 100;
Int A [n];
In addition, such expressions are very common and well-advocated notation (macros are not recommended in C ++, and macros can be replaced by constants and inline functions ).
The const attribute in C ++ can be removed, and can be forcibly converted through const_cast. Have you tried this code?
# Include <iostream>
Using namespace STD;
Int main ()
{
Const int A = 10;
Const int * pA = &;
Int * pb = const_cast <int *> (PA );
* Pb = 20;
Cout <* Pa <Endl;
Cout <* pb <Endl;
Cout <A <Endl;
Return 0;
}
The output result is
20
20
10
Iii. Differences between inner connection and outer connection
Const variable must be initialized during definition and is visible inside the file. This is because in C ++, the const variable is Internal Linkage by default ). (For the reason, see later) That is to say, it can only be used within the file defining it, but cannot be seen by other compilation units during connection. For example, const int I = 0; // and the compiler generally puts const variable into a/symbol table instead of allocating memory ), so that constant folding can be implemented during compilation ). However, if the following definition is performed: extern const int I;, the compiler is forced to allocate memory space for the variable. Because extern means that external links (external linkage) are used ). When you remove a const variable address, the memory is also allocated. For example, const int I = 9; Long Address = (long) & I; From the above we can see that the compiler does not always succeed to avoid allocating memory for constants, in both cases, the memory must be allocated. Therefore, if const variable is an external connection by default, it may cause the same constant to be allocated memory in different CPP files (for example, a constant address must be obtained in multiple files ). This will make the compiler think that the same constant has repeated definitions and an error is reported. If a constant is an internal join by default, this means that the constant is valid only within the file that defines it, And the connector does not try to connect to constants in other compilation units. In this way, a constant with the same name in multiple CPP files will not conflict. In this way, the compiler can effectively implement constant folding. In addition, we know that in C ++, const int I = 0; the value of I is in the symbol table, which means that the value of I is visible during compilation. Therefore, the following code is feasible: const int I = 0; const Int J = I + 1; // OK! Because the I value is known during compilation, J is also const, which is different from const in C. Const in C is an external connection by default, so it is always allocated memory space. This means that in C, const int bufsize = 100; during compilation, the compiler does not know the value of bufsize. Therefore, the following code is incorrect: const int bufsize = 100; char Buf [bufsize]; // error is different: const int bufsize; this code can be used in C, and the compiler considers it a declaration. Memory is allocated for this constant somewhere, but in C ++, this code cannot. There are two ways to modify it: (1) const int bufsize = 100; // initialization at definition (2) extern const int; // Of course, this statement is also possible in C
//////////////////////////////////////// //////////////////////////////////////// ////
In C:
Const int size;
This statement is correct because it is regarded by the C compiler as a declaration indicating that the bucket is allocated elsewhere. however, this write in C ++ is incorrect. const in C ++ is an internal connection by default. To achieve the above effect in C ++, you must use the extern keyword.
In C ++, const uses internal connections by default. In C, external connections are used.
Internal join: the compiler only creates a bucket for the files being compiled. Other files can use the same identifier.
Or use the static keyword to specify the connection in the global variable. C/C ++.
External Connection: create a separate bucket for all compiled files. Once the bucket is created, the connector must be unbound.
References to this bucket. The global variables and functions are connected externally. The key is extern.
Statement to access the corresponding variables and functions from other files.
* ********************** C ++ code ************ ******************
Header. h
Const int test = 1;
Test1.cpp
# Include
# Include "header. H"
Using namespace STD;
Int main ()
{
Cout <"in test1:" <test <Endl;
}
Test2.cpp
# Include
# Include "header. H"
Using namespace STD;
Void print ()
{
Cout <"in Test2:" <test <Endl;
}
The above code compilation connection won't go wrong, but if you change header. h:
Extern const int test = 1;
The following error message is displayed during connection:
Test2 error lnk2005: "int const test "(? Test @ 3hb) has been defined in test1.obj
Because the extern keyword tells the C ++ compiler that test will be referenced elsewhere, the C ++ compiler will create a bucket for test, instead of simply storing it in the name table. therefore, when two files contain both headers. h, there will be a name conflict.
This situation is similar to const in C:
Header. h
Const int test = 1;
Test1.c
# Include
# Include "header. H"
Int main ()
{
Printf ("in test1: % d/N", test );
}
Test2.c
# Include
# Include "header. H"
Void print ()
{
Printf ("in Test2: % d/N", test );
}
Error message:
Test3 fatal error lnk1169: locate one or more symbols with multiple definitions
Test3 error lnk2005: _ test has been defined in test1.obj
In C ++, whether to allocate space for the const depends on the specific situation.
If the keyword extern is added or the const variable address is obtained, the compiler allocates storage space for the const.
// For more information, see
// What should be placed in the header file? What is external connection?