A Free Trial That Lets You Build Big!
Start building with 50+ products and up to 12 months usage for Elastic Compute Service
C and C ++ string literal (string literal) have similarities and differences. Understanding this content is helpful for deepening the understanding of strings and related concepts, and clarifying some common concepts and misunderstandings. This article takes the literal "hello" as an example to describe the following.
The string literal is an object.
Objects in C/C ++ refer to a storage area. The string literal is an object that can be used without the need to create a process. Therefore, it does not have a declaration or definition like a variable (the string literal is an unknown object ), you do not need to dynamically allocate objects as you do. For this reason, type delimiters (such as const and volatile) and storage class delimiters (such as extern, static, auto, and register) used to restrict variables cannot be used to modify strings.
The string literal is an object of the array type, so it has all the characteristics of the array. This is further explained below.
Static Storage Period
Objects in C/C ++ can be divided into three types based on their storage properties: static storage duration and Automatic Storage duration) and dynamic storage duration ). Correspondingly, objects can be divided into static objects, automatic objects, and dynamic objects according to the nature of the storage period.
The string literal is a static object, so it will always exist during the program running.
The string literal is the left value and cannot be changed.
For example, "hello" in char s  = "hello"; is the left value of the array type (lvalue), used to initialize the S array; sizeof ("hello ") and "hello" in & "hello" are also left values. In these cases, "hello" is in the context of the left-valued semantic context, so no conversion from the array to the pointer will be mentioned below.
In addition, some operations require not only the left value of the operand, but also variable. For example, assign values, auto-increment, and auto-subtraction to objects. Because the array is a left value that cannot be changed, you cannot perform these operations on the array. That is to say, there are no values, auto-addition, auto-subtraction, and other operations on the array.
A string literal can be converted to a pointer pointing to its first character.
The string literal in the context of the right-valued semantics is converted to the pointer pointing to the first character by default. For example, "hello" in char * P = "hello"; is used to initialize the pointer Variable P after being converted to a character pointer; in the expression "hello"  (equivalent to * ("hello" + 0) or * "hello"), "hello" is also converted to a pointer and involved in subscript calculation.
This is also a feature of the array type. In the context of right-valued semantics, the value of a general type object is determined by the content it stores. The value of an array object is different from that of its content, it comes from the address of the first element of the array object. This is the most special part of the array and a misunderstanding.
Address fetch operation
A string literal is an object that can be accessed. For example, & "hello" is a legal expression.
The static object address can be determined during compilation, so its address (for example, & "hello") is a constant; the string literal can be automatically converted from the array type to the pointer (for example, after "hello" is converted to the pointer, it is equivalent to & "hello" ). therefore, the string literal can be directly used as an address constant expression.
The act of modifying the string literal is undefined.
The following operations attempt to modify the first character in the string literal to change the string literal, so the result is undefined:
"Hello"  = 'a';/* undefined */
Char * P = "hello"; * P = 'a';/* undefined */
It is wrong to use a program with no defined behavior. It is the responsibility of the programmer to avoid non-defined behavior in the program.
The string literal in C "hello" is an array type char  (correspondingly, each character element is a char type without the const limitation ); when used as the right value, it is converted to char * of the pointer type *.
In C ++, "hello" is of the char const  type (correspondingly, the type of each character element is Char const ); when converting to a pointer, It is Char const *. In special cases, it can also be char *.
In C, the string literal is not a const array (that is to say, the type of each character element is not Char const ), it is because C needs to take care of or take into account the large amount of code that already exists before standard preparation-at that time, the C language does not have the const keyword. If it is required to be a const array, char * P = "hello "; this initialization or char * q; q = "hello"; is invalid because the char const * on the right cannot be converted to the char * on the left by default *).
Similarly, in order to allow the above Code to pass the compilation process smoothly, C ++ adopts another policy: it specifies that the string literal type is a const array, at the same time, it is specified that the string literal can be converted to a pointer pointing to a very large number (char * for "hello *), this solves the problems in the above Code. However, conversion to char * mainly aims to be compatible with the previous Code. This type of conversion is marked as "deprecated" by the C ++ standard, so it should not be dependent on this type of conversion when writing a program.
The string literal in C ++ is a constant, but not a constant in C.
It is precisely because of the different types of standards that cause differences in the character string constants in C and C ++.
In C, except string literals and compound literals (c99 only), other literals are constants. In C ++, all literals, including string literals, are constants (Note: Compound literals does not exist in C ++ .)
In reality, we can often see that "String constant" is used to refer to "string literal". In fact, this is incorrect for C, in C, the string literal volume does not belong to a constant. For C ++, the "String constant" and "string literal volume" are actually the same thing, but the angle of the problem is different.
By the way, constants in C ++ can be divided into object constants (such as strings, objects limited by const) and non-object constants. constants in c do not contain objects, their most obvious feature is that they cannot perform address fetch operations. Therefore, constants can only be used as non-left values (that is, the right value.
Differences in syntax and Semantics
In C, the literal value of a string is not a constant, and each character element is not a constant. Therefore, the immutable character element is only represented at the semantic level, but it is not required in terms of syntax and constraints. In C ++, the string literal is a constant, and each character element is also a constant. Therefore, each character element must not be changed in terms of semantics and constraints. In addition, for compatibility considerations, C ++ still has a special case of conversion to a non-const pointer.
The following code describes the above content.
* "Hello" = 'a ';
The expression * "hello" represents the first character Element Object of the string literal. The above statement tries to change the first element through the value assignment operation. Of course, such behavior is not defined in C and C ++. In addition to the similarities, there are also some minor differences:
In C ++, * "hello" is a const object (its type is const char. Note: "Hello" here is not converted to char * pointer, so * "hello" is not char type ), therefore, the above assignment violates the constraint that the left operand of the assignment number must be a changeable left value. In this case, the standard requires that the diagnostic information be provided.
In C, * "hello" is a non-const object (whose type is Char) and a changeable left value. Therefore, it does not violate the constraints of the value assignment. In this case, although this assignment operation is undefined, the criteria do not require diagnostic information.
Char * P = "hello ";
Char * q; q = "hello ";
Void Foo (char * s); Foo ("hello ");
In the above initialization and value assignment statements, "hello" can be converted to the char * pointer type, so it is legal. In C ++, although "hello" is of the char const * type as a pointer, in this case (initialization or assignment cannot be true if it is not of the char * type) it can be converted to char * based on special provisions on the string literal volume.
Note that there is a limit on converting the string literal to a pointer pointing to a very large number in C ++. This conversion can only be performed if there are clear target type requirements, otherwise, it is invalid. For example:
Char * P = "hello" + 1;
Char * q; q = "hello" + 1;
Void Foo (char * s); Foo ("hello" + 1 );
The above is a valid C code, but it is invalid as a C ++ code. The reason is invalid: "Hello" is converted to Char const * pointer type, but cannot be converted to char *, because the + operator has no direct requirement on converting its operand type to char * (because both char const * and char * can perform pointer addition operations ), therefore, the result of the pointer addition expression is still of the char const * type. In this way, the initialization or assignment operation of the pointer above violates the type constraints and requires diagnostic information.
This article from the csdn blog, reproduced please indicate the source: http://blog.csdn.net/vvincol/archive/2007/09/12/1782570.aspx
Start building with 50+ products and up to 12 months usage for Elastic Compute Service