Assignment of const char *, char *, const char **, and char **

Source: Internet
Author: User

Constraints for assigning values according to ansi c:

1. Both operands are pointers to compatible types with or without delimiters.

2. the type pointed to by the Left pointer must have all the qualifiers of the type pointed to by the right pointer.

1. Const char * and char *

The const char * type is: "pointing to a char type pointer with a const qualifier ". (The value cannot be modified)

The char * type is: "pointing to a char type Pointer ".

ThereforeBoth const char * and char * point to char type pointers, except that const char * points to const type char.

Therefore,Code:

Char * SRC;
Const char * DEST;
DeST = SRC;

The assignment is correct because:

* The operands all point to the char type, so they are compatible.

* The left operand has all the delimiters (the right operand has no delimiters) of the type indicated by the operand, And the right operand has its own delimiters (const)

In turn, the value assignment violates the constraint of the Value assignment: the value of the object to which SRC points can be modified, and the value of the object to which DEST points cannot be modified.
If SRC is set to direct to the unmodifiable object pointed to by DEST, isn't it legal to modify it?

Src = DEST; // The value is assigned in this way. The type pointed to by the left operand does not have the const qualifier pointed to by the right operand. It does not meet the constraint 2.

2. Const char ** and char **

The const char ** type is: "pointer to a char type pointer with a const qualifier ".

Char ** type: "pointer to a char type Pointer ".

For const char ** and char **, both are pointer types with no delimiters, But they point to different types. The former points to char *, and the latter points to const char *, therefore, they are incompatible, soThe Char ** type operand cannot be assigned to the const char ** type operand.

That is, for the following code, the compiler reports an error: Char ** SRC;
Const char ** DEST;
DeST = SRC;
// Error: Invalid conversion from 'Char ** 'to 'const char **'
Bytes -------------------------------------------------------------------------------------------------------------

Const
1. the qualifier declares that the variable can only be read
Const int I = 5;
Int J = 0;
...
I = J; // invalid, causing compilation errors
J = I; // valid
2. Initialization is required.
Const int I = 5; // valid
Const Int J; // invalid, causing compilation errors
3. reference the const constant in another connection file
Extern const int I; // valid
Extern const Int J = 10; // The constant cannot be assigned again.
4. Easy type check
The const method enables the compiler to learn more about the processing content.
# Define I = 10
Const long & I = 10;/* dapingguo reminder: Due to compiler optimization, I will not be allocated memory when const long I = 10, instead, 10 has been directly substituted into future references, so that there are no errors in future code. In order to achieve the teaching effect, I memory allocation is explicitly provided with & I. However, once you close all optimization measures, even if const long I = 10; will cause subsequent compilation errors. */
Char H = I; // No error
Char H = I; // compilation warning, which may result in incorrect value assignment due to number truncation.
5. Avoid unnecessary Memory Allocation
# Define string "abcdefghijklmn \ n"
Const char string [] = "abcdefghijklm \ n ";
...
Printf (string); // The first memory allocated to the string
Printf (string); // The memory is allocated once for the string and will not be allocated later
...
Printf (string); // The second memory is allocated for the string.
Printf (string );
...
Since the const definition constant only provides the corresponding memory address from the Assembly perspective,
Instead of giving an immediate number like # define, the constant defined by const is
Program There is only one copy during running, and # The constants defined by define are in the memory.
Several copies.
6. constants can be initialized through functions.
Int value ();
Const int I = value ();
Dapingguo said: assuming that the target Code cannot be rewritten when writing a program to Rom, this statement will be invalid, but it can be changed as follows:
Const Int & I = value ();
As long as the I address is out of Rom, it can be implemented: I is initialized through the function, and its value will not be modified.
7. Is it true that the constant value of const cannot be modified?
Observe the following code:
Const int I = 0;
Int * P = (int *) & I;
P = 100;
By force type conversion, the address is assigned to the variable and the constant value of const can be changed.
8. distinguish between numeric constants and pointer constants. The following statements are quite interesting:
Int II = 0;
Const int I = 0; // I is a constant and the I value will not be modified
Const int * p1i = & I; // The content indicated by the p1i pointer is a constant and may not be initialized.
Int * const p2i = & II; // the pointer p2i is a constant and can be modified.
Const int * const p3i = & I; // the pointer p3i is a constant and the content referred to is also a constant
P1i = & II; // valid
* P2i = 100; // valid

The usage of the const keyword in C ++ is very flexible, and the use of const will greatly improve the robustness of the program. For more information, see the const usage of Kang jiandong brother, I have supplemented and written this article.
1. Const constants, such as const int max = 100;
Advantage: const constants have data types, while macro constants do not. The compiler can perform type security checks on the former, while the latter only performs character replacement without type security checks. In addition, unexpected errors (marginal effect) may occur during character replacement)

2. Data Member of the const modifier class. For example:
Class
{

Const int size;

... }

Const data members are constants only within the lifetime of an object, but they are variable for the entire class. Because the class can create multiple objects, the values of the const data members of different objects can be different. Therefore, the const data member cannot be initialized in the class declaration, because the compiler does not know the value of the const data member when the class object is not created. For example
Class
{
Const int size = 100; // Error
Int array [size]; // error, unknown size
}

Const data member initialization can only be performed in the class constructor initialization table. To create a constant in the entire class, use the enumerated constant in the class. For example
Class
{...
Enum {size1 = 100, size2 = 200 };
Int array1 [size1];
Int array2 [size2];
}

Enumerated constants do not occupy the storage space of objects. They are fully evaluated during compilation. However, the implicit data type of an enumerated constant is an integer, and its maximum value is limited. It cannot represent a floating point.

3. For details about how to modify the pointer in const, see the following formula:
Int B = 500;
Const int * A = & [1]
Int const * A = & [2]
Int * const A = & [3]
Const int * const A = & [4]

If you can differentiate the above four situations, congratulations! you have taken a great step. I don't know. It doesn't matter. We can refer to the practice on item21 in Objective C ++. If const is on the left side of the asterisk, 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 of the asterisk, the const modifies the pointer itself, that is, the pointer itself is a constant. Therefore, [1] is the same as [2], and the content pointed to by the pointer is a constant (The position of the const in the variable declaration is irrelevant ), in this case, the content cannot be changed, for example, * A = 3; [3] indicates that the pointer itself is a constant, and the content pointed to by the pointer is not a constant, in this case, the pointer itself cannot be changed. For example, a ++ is incorrect. [4] indicates that the pointer itself and the content pointed to are constants.

4. Const Initialization

Let's take a look at the initialization of the const variable.
1) Non-pointer const constant initialization: a B;
Const A = B;

2) const constant initialization:
A * D = new ();
Const A * c = D;
Or: const A * c = new ();
3) const constant initialization:
A f;
Const A & E = f; // in this case, e can only access the function declared as const, but cannot access

General member functions;

[Thinking 1]: Is the following assignment method correct?
Const A * c = new ();
A * E = C;
[Think 2]: Is the following assignment method correct?
A * const c = new ();
A * B = C;

5. In addition, some powerful functions of const are its application in function declaration. In a function declaration, const can modify the return value of a function or a parameter. For a member function, it can also be modified as a whole function. The usage of A & operator = (const A & );
Void fun0 (const A * );
Void fun1 () const; // fun1 () is a class member function.
Const A fun2 ();

1) modify the const of the parameter, such as void fun0 (const A * A); void fun1 (const A & );
When you call a function, use the corresponding variable to initialize the const constant. In the function body, perform the constant operation according to the Section modified by the const. For example, if the parameter is const A *, the content of the passed pointer cannot be changed to protect the content pointed to by the original pointer. If the parameter is const A & A, the passed referenced object cannot be changed, protects the attributes of the original object.
[Note]: The const parameter is usually used when the parameter is a pointer or reference, and can only modify the input parameter. If the input parameter uses the "value transfer" method, because the function will automatically generate a temporary variable for copying this parameter, this parameter does not need to be protected, so it does not need to be modified by the const.

[Conclusion] for non-Internal data type input parameters, the "value transfer" method should be changed to "const reference transfer" to improve efficiency. For example, change void func (A) to void func (const A &)
For internal data type input parameters, do not change the "value transfer" method to "const reference transfer ". Otherwise, the function can not improve the efficiency, but also reduce the comprehensibility of the function. For example, void func (int x) should not be changed to void func (const Int & X)

2) modify the const of the returned value, such as const A fun2 (); const A * fun3 ();
After the return value is declared, const is modified according to the "Modification Principle" to provide corresponding protection. Const rational operator * (const rational & LHS, const rational & RHs)
{
Return rational (LHS. numerator () * RHS. numerator (),
LHS. denominator () * RHS. denominator ());
}

The return value can be modified with const to prevent such operations from being allowed: Rational A, B;
Radional C;
(A * B) = C;

The const is usually used to modify the return value to the object itself (non-referenced and pointer). It is often used when the binary operator reloads a function and generates a new object. [Summary]

1. Generally, when the return value of a function is an object, if it is declared as a const, it is mostly used for the overloading of operators. In general, it is not recommended to use const to modify the type of the function's return value to an object or to reference an object. The reason is as follows: if the returned value is that an object is const (const a test = a instance) or an object is referenced as const (const A & test = a instance ), if the returned value has the const attribute, only the public (protected) data member and the const member function in Class A can be returned, and the value assignment operation is not allowed, this is rarely used in general.

2. if you add const to the return value of a function that uses the "pointer transmission" method, the content of the function return value (that is, the pointer) cannot be modified, the returned value can only be assigned to the same type pointer with const modifier. For example:

Const char * getstring (void );

The following statement causes a compilation error:

Char * STR = getstring ();

The correct usage is:

Const char * STR = getstring ();

3. There are not many cases where the function return values adopt "reference transfer". This method is generally only used in the class's callback value function to achieve chained expression. For example:

Class
{...
A & operate = (const A & other); // negative value function
}
A A, B, C; // A, B, C is the object of
...
A = B = C; // normal
(A = B) = C; // abnormal, but valid

If the return value of the negative value function is modified with const, the content of the returned value cannot be modified. In the previous example, a = B = C is still correct. (A = B) = C is incorrect.
[Think 3]: Can I define a value assignment operator to overload a function?
Const A & operator = (const A & );

6. Use of const in class member functions
Generally placed behind the function body, such as void fun () const;
Any function that does not modify data members is declared as const type. If the const member function is accidentally modified or other non-const member functions are called, the compiler reports an error, which greatly improves the robustness of the program. For example:

Class Stack
{
Public:
Void push (int elem );
Int POP (void );

Int getcount (void) const; // const member function
PRIVATE:
Int m_num;
Int m_data [100];
};

Int Stack: getcount (void) const

{
+ + M_num; // compilation error. An attempt is made to modify the data member m_num.
Pop (); // compilation error in an attempt to call a non-const Function
Return m_num;
}

7. Const suggestions

1. Be bold in using const, which will bring you endless benefits, but the premise is that you must understand the original principles;
2. Avoid the most common assignment errors. For example, assign values to the const variable;
3. When using const in parameters, you should use references or pointers instead of common object instances, for the same reason as above;
4. Const should be well used in three member functions (parameters, return values, and functions;
5. Do not set the function return value type to const easily;
6 except for the overload operator, do not set the return value type as a const reference to an object;

[Questions and Answers]
1. This method is incorrect because the declared pointer aims to change the content it points to, and the declared pointer E points to a constant, so it is incorrect;
2. This method is correct because the content pointed to by the Declaration pointer is variable;
3. This is incorrect;
In const A: Operator = (const A & A), the const In the parameter list is correctly used. When such a value is assigned consecutively, the problem occurs:
A A, B, C:
(A = B) = C;
Because the return value of A. Operator = (B) is a const reference to a, c cannot be assigned to a const constant.

Why should I use const char * inputstring in C function parameters?
The data pointed to by the real parameter pointer is not accidentally rewritten.
Const char * inputstring; // defines the pointer to a constant
The address value of the pointer can be increased or decreased, or the pointer can be changed to a constant. However, the content to be pointed to has a constant property and cannot be changed.. That is:
Inputstring ++; // This is acceptable.
(* Inputstring) ++; // This is forbidden.

The essence of forced type conversion is to tell the compiler, "this is feasible, this line of communication... as to whether the program will go wrong, the compiler does not care, because you all say it is feasible ."

Both operands are pointer to compatible types with or without delimiters. The type pointed to by the Left pointer must have all the delimiters of the type pointed to by the right pointer.

This condition allows the real parameter char * in the function call to match the const char * in the form parameter (in the C standard library, all string processing functions are like this).

When using functions, there is a very important concept:Value Transfer, pointer transfer, reference transfer value (These three statements ).

I think we should first understand this knowledge point.How different types of variables allocate storage in memory, and how long their lifecycles are.Then, you can understand the three situations.Function parameters are generally

It is allocated on the stack, so its lifecycle is within the function to which it belongs. When the function is executed, its memory will be recycled.

If we want to operate on the actual parameters in the function (not a copy of the form parameter), we generally use reference, that is, to declare the form parameter of the function as the reference type, for example, char * Fun (char * & P). In this way, the real parameters and form parameters are the sameFor a variable, we operate the parameter P in the function, which is equivalent to directly operating the real variable.When I read a C ++ grammar book, the book says this is another benefit,When calling a function, you no longer need to allocate memory for formal parameters.In this way, the execution efficiency will be a little higher.

The following are several cases where the function parameter is a pointer:

# Include <iostream>
Using namespace STD;

Char * func1 (char * P );
Void func2 (char * P );
Void func3 (char * & P );

Char S1 [] = "original ";
Char S2 [] = "pointing to me ";

Int main ()
{
Char * PTR = S1;
Cout <PTR <Endl;
PTR = func1 (PTR); // the return value changes PTR to point it to another address.
// Func2 (PTR); // the pointer of PTR is not changed. All changed in func2 is its copy (a local variable)
// Func3 (PTR); // Changes the pointer of PTR. The form parameter of the func3 function is the reference type, and the real parameter and the form parameter are the same variable.
Cout <PTR <Endl;
Return 0;
}

Char * func1 (char * P)
{
P = S2;
Return P;
}
Void func2 (char * P)
{
P = S2;
}
Void func3 (char * & P)
{
P = S2;
}

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.