I. Possible combinations:
(1) const char * P
(2) Char const * P
(3) char * const P
(4) const char ** P
(5) Char const ** P
(6) char * const * P
(7) Char ** const P
Of course, there are several cases of inserting a const in (5), (6), and (7), but after analyzing the above 7, the other can be done!
2. Understanding the magic weapon of mnemonic:
1. The key is who const modifies.
2.Because there is no const * operation, if the const * form appears, the const actually modifies the previous.
For example: Char const * P. Because there is no const * operation, const actually modifies the previous char, soChar const * P is equivalent to const char * P. That is to say, in the above seven cases, (1) and (2) are equivalent. Similarly, (4) and (5) are equivalent. In (6), since there is no const * operation, const actually modifies the previous char *, but cannot be converted into const (char *) * P during definition, because "()" is a function.
3. in-depth understanding of 7 combinations
(0)Program The space opened during execution is in the memory (RAM), while the memory unit in Ram isReadable and writableOf;A pointer is only a tool used to specify or locate the data to be operated. It is only used to read and write the working pointer of memory units in Ram.. If no limitations are imposed on pointers, a pointer in the program can point to any location in RAM (except for system sensitive areas, such as the operating system kernel Area) and perform read and write operations on the memory units it points to (determined by the read/write attributes of RAM ); the readable and writable attributes of memory units in Ram do not change because of the limitation on the working pointer (see the 4th points below ).All the const limits on pointers are just for thisPointerOf Read and Write Permissions(Including read and write locations) are limited.
(1) char * P: P is a working pointer and can be usedAny location (Non-system sensitive area)Read and Write operations Read and Write one byte at a time (char occupies one byte ).
(2) const char * P or char const * P (because there is no const * P operation, the const modifier is the previous char): can be any location (non-system sensitive area) proceed"Read-only" Operation. ("Read-only" is the content limited by char * P)
(3) char * const P (const modifies P): Only"A fixed position" Read and Write operations, and Initialization is required when P is defined (because "P = .. so it cannot be initialized later, so it can only be initialized at definition ). ("A fixed bit" is the content defined relative to char * p)
The preceding three points can be summarized as follows: the pointer P in char * P is usuallyUniversal Working pointer While (2) and (3) are only on the basis of (1)Some specific restrictions are added. These restrictions are not necessary in the program. They are only intended to prevent the carelessness of programmers and lead to counterproductive errors.
In addition, you must understand"Each memory space can have a name; the content of each memory space can be changed (unless Limited)". For example, the char s [] = "hello" defined in the function; in fact, 6 variables are opened up in the stack memory of the Process in 6 bytes, the six character variables are named as follows: s1 [0], S1 [1], S1 [2], S1 [3], S1 [4], S1 [5] (content: '\ 0 ')
{
To be verified :There is also a 4-byte pointer variable s . However, S is "Limited" and belongs to the char * const type, that is, (3). In this case, s always points to s [0], (* s = s [0] = 'H'). You can use * s = 'K' to change the value of S [0] pointed to by S, however, it cannot be executed (char * H = "AAA"; S = H;) to assign values to S.
}
(4) The above (2) and (3) only limit P, neither can nor can it limit the space pointed to by P, for "char s [] =" hello "; const char * P = s;" although it cannot pass * (p + I) = 'X' or P [I] = 'x' to modify the array element S [0] ~ The value of S [4], but the value of the original array element can be modified through * (S + I) = 'X' or s [I] = 'X --The readable and writable attributes of memory units in Ram do not change because of the limitation on the working pointer, but only because of its limitation.. For example, const char c = 'A', C is the name of a memory unit (8 bytes) in Ram. The content of this memory unit is only readable and cannot be written.
(5) const char ** P or char const ** P: two pointers, P and * P, are involved. Since const modifies char, there is no limit on the pointer P, and the pointer * P is limited in the case above (2.
(6) char * const * P: contains two pointers, P and * P. Because const modifies the char * above, that is, it limits the content * P pointed to by P (also belongs to the preceding situation (2 )). For * P, because it cannot be assigned another value through "* P =...", it is the limitation of the preceding case (3.
(7) Char ** const P: involves two pointers, P and * P. Const modifies P and limits P in the above case (3), while * P, there are no limits.
Iv. Compatibility of char ** P and const char ** P types
1. Problem
Char * P1; const * P2 = p1; // valid
Char ** P1; const char ** P2 = p1; // invalid. Warning: initialization from incompatible pointer type
Char ** P1; char const ** P2 = p1; // invalid. Warning: initialization from incompatible pointer type
Char ** P1; char * const * P2 = p1; // valid
2. Judgment Rules
Define the object modified by const! For pointers P1, and P2,To enable P2 = p1, read :
"P1 is a pointer to the X type, and P2 is a pointer to the X type with the const limitation ." ".
Char * P1; const * P2 = p1; // valid: P1 is a pointer to the (char) type, and P2 is a pointer to the (char) type with a const limitation.
Char ** P1; const char ** P2 = p1; // invalid: P1 is a pointer to the (char *) type, P2 is a pointer to (const char )*) type pointer.
Char ** P1; char const ** P2 = p1; // invalid; equivalent to upper.
Char ** P1; char * const * P2 = p1; // valid: P1 is a pointer to the (char *) type, p2 is a pointer to the (char *) type with a const limitation.
V. Others
1. Unified reading of single-or double-layer pointers containing const:
"P is a pointer. It is a [" with const limitation "] pointing to [" with const limitation "] X type pointer ".
2. The object modified by const during definition is definite, but cannot be enclosed in brackets during definition. Otherwise, it is confused with the function type represented by "()" during definition! Therefore, you cannot write (char *) const * P or (const char) ** P during definition.
6. Question (because the post-blog message has a limit on the number of characters, move the reply here)
Question 1 (See Post-blog posts ):The explanation is very good, but there is a question to be explored: const char Wang [] = {"Wang"}; char * P; P = Wang; is wrong. Therefore, P in char * P cannot point to a constant variable. (1) Supplementary correction is required.
Reply: Hello! Thank you for your correction! I did the following tests under Ubuntu 10.04 (GCC 4.4.3:
// Test_const.c
# Include <stdio. h>
Int main ()
{
Const char Wang [] = {"Wang "};
Char * P;
P = Wang;
P [2] = 'C ';
Printf ("P is % s \ n", P );
Return 0;
}
Compile:
Gcc-O test_const test_const.c
Output::
Test_const.c: In function 'main ':
Test_const.c: 17: Warning: Assignment discards qualifiers from pointer target type
Run:
./Test_const
P is wacg
Conclusion: According to the compatibility problem, which is the fourth point in this article, assigning the const Wang value to P is illegal. However, the compiler only provides a warning. Therefore, the data in the read-only zone is modified through P during execution. This should be due to the lax processing of the compiler. I Don't Know What compiler you are using?
Question 2AnswerHttp://www.linuxsir.org/bbs/showthread.php? T = 239058Problems mentioned
InC LanguageLi
// Test. c
Int main (){
Const char * S1 = "test ";
Char * S2 = S1;
S2 = "It's modified! ";
Printf ("% s \ n", S1 );
}
Out: It's modified !;
Is that okay? According to my understanding, isn't the const qualifier just set up one in the C language?
Reply:
(1) firstCodeDuring compilation, the following error occurs: Warning: initialization discards qualifiers from pointer target type,
Because char * S2 = S1 is the same as that mentioned in question 1, it does not comply with compatible rules.
(2) the output result is correct. The code analysis is as follows:
int main () {
const char * S1 = "test "; // In the read-only data zone (after objdump-h test. in the rodata area), open up the 5-byte storage "test", and use S1 to point to the first character 'T '.
char * S2 = S1; // S2 also points to the first character 'T' of "test" in the read-only data zone '.
S2 = "It's modified! "; // 15-byte storage in the read-only data zone" It's modified! ", And direct S2 from pointing to 'T' to" It's modified! The first character 'I '.
printf ("% s \ n", S1 ); // output the string "test" starting from the 'T' indicated by S1 ".
}
(3) Conclusion: the misunderstanding of the questioner is that S2 = "It's modified! "Is to re-assign a value to the region where" test "is located. In fact, here we just point the" omnipotent "working pointer S2 to another newly opened area. For example, if you execute S2 [2] = 'A' after char * S2 = S1, a write operation is performed on the "test" region. A segment error occurs during execution. However, this error is not related to const, because the "test" area is read-only. To prevent understanding errors, assign values to pointers (for example S2 = "It's modified! " ), Then read it: Direct S2 to" It's modified! The first character of the region.
(4) Additional gains: after running gcc-O test. C, "test" and "it's modified !" And "% s \ n" are all stored as string constants in the read-only zone of the binary file test.
Domain (. rodata ). In fact, from compiling to running a program, the allocation of variable space is as follows:
A. The assigned global or static variable => is placed in the. Data Segment of the executable file.
B. Unassigned global variables or static variables => are placed in the. BSS segment of the executable file.
C. The String constant that appears in the code or a => with const added is placed in the. rodata segment of the executable file.
D. General local variables => do not occupy space in the executable file. Stack space is allocated only when the binary file is used as a process in the memory.
E. In the code, malloc or the new variable => does not occupy space in the executable file. The heap space is allocated only when the binary file is used as a process in the memory.
Question 3: (to be further analyzed) Check whether space is allocated for S as mentioned in Article 3 (3). The initial analysis result is: no space is allocated! In this article, S is only the address code of S [0.
# Include <stdio. h>
Int main (){
Int A = 3;
Char S1 [] = "test ";
Int B = 4;
Char S2 [] = "Test2 ";
Printf ("the address of a is % u \ n", & );
Printf ("S1 is % u \ n", S1 );
Printf ("the address of S1 is % u \ n", & S1 );
Printf ("the address of B is % u \ n", & B );
Printf ("S2 is % u \ n", S2 );
Printf ("the address of S2 is % u \ n", & S2 );
}
Output result:
The address of a is 3213037836
S1 is 3213037827
The address of S1 is 3213037827
The address of B is 3213037832
S2 is 3213037821
The address of S2 is 3213037821
The results show that the compiler has made some optimizations.
7. Other related ClassicsArticleReprinted
Wang Haining,Huaqing vision embedded CollegeLecturer,Understanding of the const keyword
Http://www.embedu.org/Column/Column311.htm
During the C language tutorial, many students have a great misunderstanding about the keyword Const. I would like to summarize the misunderstanding of this keyword and hope to use the const keyword flexibly in future programming.
1. Whether the variable modified by const is a constant or a variable
Many people think that the variable modified by const cannot be changed, and the result is that the variable becomes a constant. So how do I understand the variable modified by const?
Here is an example:
Int main
{
Char Buf [4];
Const int A = 0;
A = 10;
}
This is easy to understand. The Compiler directly reports an error because the variable modified by const is assigned a value later. It seems that the variable modified by the const cannot be modified. If so, let's modify the example below:
Int main
{
Char Buf [4];
Const int A = 0;
Buf [4] = 97;
Printf ("The A is % d \ n", );
}
In the last sentence, printf aims to check whether the value of variable A has changed. According to const's understanding, if const modifies that the variable cannot be modified, then the value of a will not change. It must be 0. However, in the actual running results, we found that the value of a has changed to 97. This indicates that the variable a modified by const has been modified by our program.
Let's take a look at these two examples. For the second example, the reason for modification is the assignment operation of BUF [4, we know that the Buf [4] variable has caused cross-border access to the Buf array variable. The members of the Buf array are only 0, 1, 2, and 3, so who is the Buf [4] accessed? The Buf is allocated according to the address of the local variable, we can know that the address of BUF [4] is the same as that of int A, so Buf [4] Actually accesses const int A; then the Buf [4] is modified, naturally, we modified the space of const int A, which is why we saw the result 97 when printing the value of.
Now we can understand that the const modified variables do not have the characteristics that cannot be modified. How can we explain the phenomenon in the first example.
In the first example, errors are provided during program compilation. Note that no executable file is generated at this time, it indicates whether the variable modified by const can be modified is protected by the compiler. In the second example, the variable is modified when the executable program is executed, indicating that A is still a variable.
To sum up, we can draw a conclusion that the variable modified by const is essentially to tell the programmer or compiler that the variable is read-only, if the programmer modifies a read-only variable displayed in the program, the compiler will give an error without mercy. The compiler is powerless for changes in the running process caused by program non-standard writing such as array overflow and implicit modification. It also shows that the variable modified by const still has the property of the variable.
2. The variable modified by const will be protected by the operating system to prevent modification.
If you have an understanding of the first question, it is very easy to know the answer. The variable modified by const is not protected by the operating system.
The reason is that the operating system only protects constants, rather than reading and writing variables. So what is a constant? For example, the string "Hello world" is called a String constant.
For another proof of this problem, you can look at the following program:
Int main
{
Const int;
Char * Buf = "Hello World ";
Printf ("The & A is % P, the Buf is % P \ n", & A, Buf );
}
It can be found that the address saved by BUF is near 0x08048000, while the address of a is near 0xbf000000, and the address near 0x08048000 is a code segment in our Linux operating system. This also shows that constants and variables are stored in different regions, and the natural operating system will protect constants.
If we know the truth, let's look at the following questions:
Int main
{
Char * Buf = "hello ";
Buf [0] = 'a ';
Printf ("The Buf is % s \ n", Buf );
}
We can think about what the running result of this program will be?