Array and pointer-both are "degraded ".

Source: Internet
Author: User

My personal understanding, and I welcome criticism and correction.

1. What is the array type?

Below is the original saying in c99:
An array type describes a contiguously allocated nonempty set of objects with
Particle member object type, called the element type.36) array types are characterized by their element type and by the number of elements in the array. an array type is said to be derived from its element type, and if its element type is t, the array type is sometimes called ''array of t ''. the construction of an array type from an element type is called ''array type derivation ''.

Obviously, the array type is also a data type, and its essential functions are similar to those of other types: defines the size of memory space occupied by the data type and the operations (and how to operate) that can be performed on the data type ).

2. What is the data defined by the array type? Is it a variable or a constant?
Char s [10] = "China ";
In this example, the array type is array of 10 chars. The defined data is obviously an array S.

Below is the original saying in c99:
An lvalue is an expression with an object type or an incomplete type other than void; if an lvalue does not designate an object when it is evaluated, the behavior is undefined. when an object is said to have a participant type, the type is specified by the lvalue used to designate the object. A modifiable lvalue is an lvalue that does not have array type, does not have an incomplete type, does not have a const-qualified type, and if it is a structure or union, does not have any member (including, recursively, any member or element of all contained aggregates or unions) with a const-qualified type.

After reading the above definition, we should understand the difference between modifiable lvalue and lvalue. We should also note that array type defines lvalue rather than modifiable lvalue. So s is lvalue.

S refers to the entire array, and s content obviously refers to the data in the entire array. It is China/0 ***** (here * represents any character ). s content can be changed. In this sense, S is obviously a variable.

3. When will the array "degrade"

Below is the original saying in c99:
When t when it is the operand of the sizeof operator or the unary & operator, or is a string literal used to initialize an array, an expression that has type ''array of type'' is converted to an expression with type ''pointer to type'' that points to the initial element of the array object and is not lvalue.

The above statement makes it clear that in addition to the three situations, the array should be degraded to a pointer pointing to the first element.
For example, for char s [10] = "China ";
The three exceptions are:
(1) sizeof (s)
(2) & S;
(3) "China" used to initialize S ";

In addition to the preceding three cases, s degrades to & S [0], which is the operation method of array variables.

4. What is the difference between arrays and pointers?
4.1 different Initialization
Char s [] = "China ";
Char * P = "China ";

In the first sentence, the 6 consecutive bytes of memory starting with & S [0] are assigned the following values:
'C', 'h', 'I', 'n', 'A', '/0'

In the second sentence, P is initialized as an address of the Data Segment of the program. This address is the first address of the string "China ".

4.2 different sizeof

Sizeof is the number of bytes of memory occupied by a data type. For S and P in 4.1
Sizeof (s) should be 6, and sizeof (p) should be the size of a "Pointer.

This result can be obtained from the definition of the array type in 1 and when the array in 3 will not "degrade.

4.3 & operator

For & operators, arrays will not degrade.
After S and P in 4.1 take the addresses respectively, the meaning is:
The type of & S is pointer to array of 6 chars.
The type of & P is pointer to Char.

Why can't it be modified after 4.4 s of degradation?

In addition to the three cases, the array s will be degraded to "pointer to the first element of the array" in the expression, both & S [0]

For example
Int;
(& A) ++; // Who Do You Want To ++? This is obviously incorrect.

For (& S [0]) ++ operations (& A) ++, it is also incorrect. This leads to the unmodifiable S.

4.5 two-dimensional array and second-level pointer

Char s [10]; and char * P;
Char S2 [10] [8]; and char ** P2;

Is the relationship between S and P, and between S2 and P2 the same?
It's time to stick to the definition.
In addition to the three conditions, the array will be degraded to "pointer to the first element of the array" in the expression ".

After s degradation, it is called & S [0] and the type is pointer to Char, which is the same as p.
After S2 degrades, it is called & S2 [0] and its type is pointer to array of 8 chars, which is different from p2.

4.6 array as function parameter

There is no doubt that the array will degrade.

Void func (char s [10]); <==> void func (char * s );

Void func (char s [10] [8]); <==> void func (char (* s) [8]);

4.7 define char s [8] in one file and declare extern char * s in another file. Can this be done?

--------- File1.c ---------
Char s [8];

--------- File2.c ---------
Extern char * s;

The answer is no. Generally, using * s in file2.c will cause core dump. Why?

Consider the int example first.
--------- File1.c ---------
Int;

--------- File2.c ---------
Extern int;

After file1.c and file2.c are compiled, the address of a in the symbol table of file2.o is not resolved.
After file1.o and file2.o are linked, the address of a in file2.o is determined. Assume that the address is 0xbf8eafae.

The use of this address in file2.o is completely performed according to the declaration of extern int A;, that is, 0xbf8eafae will be considered as the address of shaping
For example, a = 2; its pseudo code will correspond to * (int *) 0xbf8eafae) = 2;

Now let's look at the original example.

--------- File1.c ---------
Char s [8];

--------- File2.c ---------
Extern char * s;

Similarly, after file1.c and file2.c are compiled, the s address in the file2.o symbol table is not resolved.
After file1.o and file2.o are linked, the s address in file2.o is determined. Assume that the address is 0xbf8eafae.

The use of this address in file2.o is based entirely on the declared extern char * s; that is, 0xbf8eafae will be considered as the address of the pointer s
For example, * s = 2; its pseudo code will correspond to * (char **) 0xbf8eafae) = 2;

* (Char **) 0xbf8eafae) What is the result?
This operation means that 0xbf8eafae is used as a second-level character pointer, and 0xbf8eafae is the four bytes starting from the address (32-bit machine) as the first-level character pointer.
That is, concatenate s [0], s [1], s [2], and s [3] In file1.o into a character pointer.

Then * (char **) 0xbf8eafae) = 2; the result is for S [0], s [1], s [2] In file1.o, s [3] Concatenates the address corresponding
The value of memory is 2.
How can this be true?

Let's take a look at the correct method:

--------- File1.c ---------
Char s [8];

--------- File2.c ---------
Extern char s [];

Similarly, after file1.c and file2.c are compiled, the s address in the file2.o symbol table is not resolved.
After file1.o and file2.o are linked, the s address in file2.o is determined. Assume that the address is 0xbf8eafae.

The use of this address in file2.o is based entirely on the declaration of extern char s [];, that is, 0xbf8eafae will be considered as the address of array s
For example, * s = 2; its pseudo code will correspond to * (char (*) []) 0xbf8eafae) = 2;

* (Char (*) []) 0xbf8eafae) What is the result?
This operation means: Use 0xbf8eafae as a pointer to the character array, and then perform * operations on the pointer.
This uses an important attribute of the array:
For the array char AAA [10];, & AAA [0], & AAA, * (& AAA) are the same in values (in fact, * (& AAA) in the program
Will be equal to & AAA [0] In the value, which is also the result of degradation: * (& AAA) is the array name AAA, AAA degrades to & AAA [0]).
Therefore, the * (char (*) []) 0xbf8eafae) result is still 0xbf8eafae in the value, and degrades the type to "pointer to the first element of the array"

Then * (char (*) []) 0xbf8eafae) = 2;
Its pseudo code becomes * (char *) 0xbf8eafae) = 2; the first element of array S is set to 2

5. Conclusion

(A) The array type is a special type, which defines an array variable, which is an lvalue but not a modifiable lvalue.
(B). In addition to the three cases (sizeof, &, used as a string array for Array initialization), the array will degrade to "pointer to the first element of the array"
(C). Do not simply think of array names as corresponding pointers that cannot be modified. They are still different.

 

 

1. Introduction
Pointers are characteristic of the C/C ++ language, while array names are too similar to pointers. In many cases, array names can be used as pointers. As a result, many
The program designer is confused. Many university teachers, in their C language teaching process, have to explain to the students: "array name is Pointer ".
Fortunately, my college teacher is one of them. Today, I am developing C/C ++ projects day after day, and it is still full
Programmers keep the misunderstanding that "array name is Pointer.
Presumably, this misunderstanding is rooted in a famous Chinese C Programming Tutorial. If this article can correct the incorrect array name and pointer by many Chinese programmers
I am not very pleased with the solution. In this article, I stand among countless Chinese programmers who are hungry for knowledge and deeply hope for computer books in China.
Writers can take the book writing work in an in-depth exploration-oriented way of thinking and a strict attitude towards perfection. I hope there will be more ideas on the market.
The painstaking efforts of the test!
2. Magic array name
Please refer to the Program (this program is compiled on the Win32 platform ):
1. # include <iostream. h>
2. Int main (INT argc, char * argv [])
3 .{
4. Char STR [10];
5. char * pstr = STR;
6. cout <sizeof (STR) <Endl;
7. cout <sizeof (pstr) <Endl;
8. Return 0;
9 .}
2.1 array name is not a pointer
Let's overturn the argument that "array name is a pointer" and use reverse identification.
Verify that the array name is not a pointer
Assume that the array name is a pointer;
Then: Both pstr and STR are pointers;
This is because the pointer length is 4 on the Win32 platform;
Therefore, the output of rows 6th and 7th should be 4;
The actual situation is: 6th rows output 10, 7th rows output 4;
So: if not, the array name is not a pointer.
2.2 array name-like pointer
We have proved that the array name is indeed not a pointer, but let's look at the 5th rows of the program. In this row, the program directly assigns the array name to the pointer.
60

The array name is indeed a pointer!
We can also find examples of array names that look like pointers:

1. # include <string. h>
2. # include <iostream. h>
3. Int main (INT argc, char * argv [])
4 .{
5. Char str1 [10] = "I love u ";
6. Char str2 [10];
7. strcpy (str2, str1 );
8. cout <"String Array 1:" <str1 <Endl;
9. cout <"String Array 2:" <str2 <Endl;
10. Return 0;
11 .}
The two parameters that can be accepted in the original form of the strcpy function in the Standard C library are char pointers, but what we pass to it in the call is two array names!
Function output:
String Array 1: I love u
String Array 2: I love u
The array name looks like a pointer again!
Since the array name is not a pointer, why use the array name as a pointer everywhere? As a result, many programmers come to the conclusion that the array name (primary) is)
It is not a pointer (BIN ).
The entire Devil.
3. array name Disclosure
So it is time to expose the essence of the array name. First, we will give three conclusions:
(1) The meaning of array name is that it refers to an object as a data structure, which is an array;
(2) the extension of an array name is that it can be converted into a pointer pointing to its object, and it is a pointer constant;
(3) the pointer to the array is another variable type (in Win32 platform, the length is 4), which only means the address of storing the array!
3.1 array name represents a Data Structure: Array
Now we can explain why the output of 1st rows of 6th programs is 10. According to conclusion 1, the meaning of the array name STR is a data structure, that is
Char array with a length of 10, so sizeof (STR) results in the memory size occupied by this data structure: 10 bytes.
Let's look at it again:
1. Int intarray [10];
2. cout <sizeof (intarray );
The output result of rows 2nd is 40 (The memory size occupied by integer arrays ).
If the C/C ++ program can be written as follows:
1. Int [10] intarray;
2. cout <sizeof (intarray );
We all understand that intarray is defined as an instance of the int [10] data structure. Unfortunately, C/C ++ currently does not support this definition method.
3.2 array names can be used as pointer Constants
According to conclusion 2, the array name can be converted to a pointer pointing to the object. Therefore, the array name of row 5th in program 1 is directly assigned to the pointer, and the program 2 7th
The row directly uses the array name as the pointer parameter.
Is the following program established?
1. Int intarray [10];
2. intarray ++;
You can compile it to discover compilation errors. The reason is that although the array name can be converted to a pointer pointing to its object, it can only be seen as
61

Pointer constant, cannot be modified.
Pointers, whether directed to struct, array, or basic data types, do not contain the meaning of the original data structure. On the Win32 platform, sizeof
The operation result is 4.
By the way, we can correct another misunderstanding of many programmers. Many Programmers think that sizeof is a function. In fact, it is an operator,
It looks like a function. The statement sizeof (INT) indicates that sizeof is indeed not a function, because the function accepts the form parameter.
(A variable), no C/C ++ function in the world accepts a data type (such as INT) as a "form parameter ".

3.3 Data names may lose their data structure Connotation
It seems that the magic problem of the array name has been successfully solved, but the calm lake has once again set off a wave. See the following program:
1. # include <iostream. h>
2. Void arraytest (char STR [])
3 .{
4. cout <sizeof (STR) <Endl;
5 .}
6. Int main (INT argc, char * argv [])
7 .{
8. Char str1 [10] = "I love u ";
9. arraytest (str1 );
10. Return 0;
11 .}
The output result of the program is 4. Impossible?
4. A terrible number, as mentioned above, is the length of the pointer!
Conclusion 1: the meaning of Data names is the data structure of arrays. In the arraytest function, STR is the array name. Why is the result of sizeof?
Is the pointer length? This is because:
(1) When the array name is used as a function parameter, In the function body, it loses its own meaning and is just a pointer;
(2) Unfortunately, it also loses its constant feature while losing its connotation. It can perform auto-increment, auto-subtraction, and other operations and can be modified.
Therefore, when the data name is used as a function parameter, it is completely reduced to a common pointer! Its aristocratic identity is denied, and it becomes the only possession of 4
Bytes.
The above is conclusion 4.
 

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.