Document directory
- One-dimensional array
- Multi-dimensional array
- Pointer Array
- Pointer
- Function pointer
- Function pointer Parameters
- Returns the pointer function.
Array pointer, pointer array, and pointer to pointer
When considering the array pointer, we need to consider both the type and dimension attributes. In other words, an array is excluded from the value stored in it, so the type and dimension can be used to represent its type.
One-dimensional array
In c and c ++, the array pointer is the starting address of the array (that is, the address of the first element ), in addition, the standard documentation specifies that the array name represents the address of the array (this is an array representation of the address value ). For example:
int a[10];int *p;
P = & a [0] // is equivalent to p =.
Because a is the array name, it is the address of the array. Because the first element is a [0], & a [0] also represents the address of the array. But is it true that an array name is the same as the & operation of the first element of the array? Yes in one dimension, but in high dimensions, we need to consider the impact of dimensions on arrays.
A [10] is an array, and a is an array name. It is an array type containing 10 int types, not a common pointer variable! (Although the standard documentation stipulates that direct conversion from int [] to int * in c ++ is acceptable, it seems that when the function parameter is a pointer in use, there is no difference in the assignment of the array name). a represents the first address of the array, which is the same as the address of a [10] At the numerical level. In this way, we can use pointer variables and a to operate on this array.
Therefore, pay attention to the following issues:
- Both p [I] And a [I] represent the I + 1 element of the array;
- P + I and a + I represent the address of the I + 1 element, so we can also use * (p + I) and * (a + I) to reference object elements;
- P + 1 does not add one to the number of pointers, but indicates skipping the space pointing to the type length from the current position. For win32 int, It is 4 bytes;
Multi-dimensional array
For two-dimensional array a [4] [6]; because the array name represents the starting address of the array, so a (the first layer) it is the same as the number of the address of the first element a [0] [0], but the meaning is different. We can understand this array as: a one-dimensional array (the first layer ), it has four elements: a [0], a [1], a [2], and a [3] (Layer 2 ), each element contains six elements, a [0] [0], a [0] [1], a [0] [2], a [0] [3], a [0] [4], a [0] [5] (Layer 3 ),... At this point, we finally access each element. In this process, we have gone through a-> a [0]-> a [0] [0];
Overall: a is a two-dimensional array with four rows and five columns. a indicates the first address of the array to which it points (the first element address & a [0]). at the same time, a [0] points to a row, it is the name of the row (the first address of the first element of the row is the same (the first element is the address & a [0] [0]). From the numerical point of view, a, a [0], and a [0] [0] are the same, but they are in different layers.
Since a represents a two-dimensional array, a + I represents the address of its I + 1 element * (a + I), while in a two-dimensional array
* (A + I) points to another array. * (a + I) + j indicates the address of the j + 1 element of the array, therefore, you can use * (a + I) + j) (that is, a [I] [j]) to access this element.
They are (dotted lines do not actually exist ):
The following statements are correct (for a [4] [6]):
- A is an array type. * a points to an array;
- A + I points to an array;
- A, * a and & a [0] [0] values are the same;
- A [I] + j and * (a + I) + j are the same concept;
To sum up, we point to array a [0, 1, 2, 3] for the two-dimensional pointer a, and use * to downgrade it to the second level, in this way, * a points to the first real array. We can also use the same method for other situations. We can use similar ideas for other dimensions and types of arrays.
When it comes to pointers to arrays, we can also declare a pointer variable to point it to an array. For example:
int (*p)[5];
In this case, P is a pointer that points to an array containing five int elements and points to other elements. In this case, what can we use for initialization? We can use * a, * (a + 1), a [2], and so on. The reason is simple: we are in a two-dimensional array, so the expressions have similar meanings to each other? Only a, * (a + 1), a [2], and so on.
Pointer Array
A pointer array means that each element in an array is a pointer. For example:
Int * P [10]; // instead of INT (* P) [10]
Or
char *p[10];
In this case, P is a pointer (the value is the same as & P [0]) with int T [10] in front.
Int * PT = T; // Use PT to point to T
So what do we use here to point to T in int * t [10? We want to use a pointer:
int **pt=t;
This is because, in int * t [10], each element is a pointer, and t points to this array, which is the same as & T [0, that is, pointing to T [0], pointing to a pointer variable, can be said to be a pointer, so naturally we need
int **pt;
Pointer
A pointer variable can store a value inside it. This value is the address of another object, so we can say that a pointer variable can point to a common variable, and this pointer variable also has an address, that is to say, there is something that can point to this pointer variable and then point to this object through this pointer variable. So how to point to this pointer variable? Since the pointer variable itself is already a pointer (the right value), we cannot use a general pointer here. We need to reflect these features on the pointer, we need to define the pointer (double pointer ).
int *p1=&i;int**p2=&p1;
Based on all the above points, we often see some matching (which is also a frequent error ):
int a[3],b[2][3],c,*d[3];void fun1(int *p);void fun2(int (*p)[3]);void fun3(int **p);void fun4(int p[3]); void fun5(int p[]);void fun6(int p[2][3]);void fun7(int (&p)[3]);
The function does not generate possible values at the time of compilation (but not all values are logical)
Function |
It does not generate possible values at the time of compilation (but not all values are logical) |
Fun1 |
A, & a [I], * B, B [I], & B [I] [j], & c, d [I] |
Fun2 |
B, B + I, |
Fun3 |
D |
Fun4 |
A, & a [I], * B, B [I], & B [I] [j], & c, d [I] |
Fun5 |
A, & a [I], * B, B [I], & B [I] [j], & c, d [I] |
Fun6 |
B |
Fun7 |
A |
The reason for such a combination is as follows:
- For fun1 fun4 fun 5: In the compiler's opinion, the declaration of fun1, fun4, and fun5 is the same. during compilation, the compiler removes the array size but considers it as a pointer, that is to say, whether the size description is the same, so the three forms are in the form of fun1 (in fact, as long as the int * pointer is provided );
- For fun7: the above explanation is not applicable to references. If the variable is declared as an array reference, the compiler should consider the array size, so it must be exactly the same as the statement (So fun7 is only a suitable );
- For fun2: p is an array pointing to a three-element array, so that B and B + I are suitable, but a is not (it points to a [0, not pointing to this array );
- For fun3: p is a pointer, and d points to d [0], and d [0] is a pointer, so d is a pointer. But B is not (it is a 2*3 matrix, that is, the year int [2] [3] type );
- For fun6, p is a 2*3 array type, exactly matches B;
Function pointers, function pointer parameters, and function pointers that return pointers
C ++ specifies that the address of a function is the name of the function. We need to point out that a pointer needs to specify a type for later usage during pointer parsing, And the pointer can be used to effectively and quickly access the object. So for the function pointer, which of the following features of the function can satisfy the uniqueness of the resolution? The answer is that a function has its parameter list and return type.
The following is an example of a function pointer:
int (*p)(int I,int j);
Cannot be
int *p(int I,int j),
In this way, it becomes the function declaration that returns the pointer. In C ++, the pointer should be of the same type as the object it points to. In other words, the features of the Function pointed to by the above pointer should be the same as that of it: for example, it can point to int min (int I, Int J. But it points to int min (double I, Double J); No. Function pointers are the same as other pointers. They are very afraid of "hanging" when used. Therefore, when used, you must determine the validity or initialize them when defining them.
int (*p)(int I,int j)=min;int (*p)(int I,int j)=&min;int (*p)(int I,int j)=0;
Function pointer Parameters
Function pointers can be used as function parameters. For example, we have an integral algorithm that can be used to integrate different mathematical functions (we assume that the functions are all in one dollar ), then our algorithm interface can be defined:
template<class T>T integrate( T lower, T upper , T (*)(T)=0 )throw(integrated_exp);
The final parameter here is a pointer to a function and is set to 0 by default. This function returns a value and requires a parameter. Assume that we have a function like this:
double line(double x){ return a*x+b;}
Then I can use it. The function pointer can also be used as the return type (note that it is not a function !!, A specific function cannot be used as the return type .) Hypothesis:
typedef int (*PF)(int );PF getProcessMethod( );//true
Returns the pointer function.
The return of a function is one of the important interfaces of the function. An important and powerful function of C ++ is the ability to design user-defined types that are complex and easy to use. At the same time, it is also very annoying to process and transmit these types. We don't want to spend our time on copies that do not really help us in our actual work, to solve this problem, we need to rely on our interface design: Both C and C ++ provide corresponding solutions. In C ++, we use references, they are used as the actual parameters of the function, or we use a pointer in the actual parameters of the function. We can also use a function to return a pointer: But this is a very difficult problem!
First, we are prone to errors: Pass the address of a local variable out! For example:
UserType * Process( ){ UserType ut(param-list); //process ut; return &ut;//}
This variable is destroyed at the end of our function. Although the address can be transferred out, this address does not exist and is no longer usable, I don't know about this function, so it is inevitable that an error will occur! At the same time, I still have a very troublesome problem: using new can easily cause memory leakage.
UserType * Process ( ){ UserTpye *put=new UserType(param-list ); //process put; return put;}
We used a new in the function and allocated a space. This is also acceptable! That is to say, the above problem will not occur. However, users usually forget to pay back the borrowed space outside the program! The memory space is leaked!
This may also be another helpless problem, so many programmers set the function parameters as pointers or references to replace this outward transmission! In short, be careful when using this function to return pointers!
Class member pointer
The class members and general external variables compare each other. The difference is that they are in different domains. This domain is very important and determines the scope of the variables that can be used. If a pointer points to a member function or member variable of the class, in addition to expressing its return type, parameter list, or type, it also specifies the variable (or function) domain to which it points. To illustrate this domain, we need to use the class domain limitation:
class NJUPT{ static double money=20000000; int num; public: NJUPT():num(10){}; int get(){return num;}; double getMoney(){reuturn money;}}
We define the member pointer
Int NJUPT: * p; // point to the int type member variable int (NJUPt: *) p () // point to the int f () type member function.
To use these pointers, we need to use these variables or pointers.
NJUPT s,*ps;
The call method is as follows:
cout<<s.*p;cout<<(s->*p)();
This looks strange! But as long as you think that the pointer we defined is limited to the class domain (we used NJUPT: at the beginning of the definition), it is quite natural to use it.
If a class has some static member variables and static member functions, do I want to use them like this?
The answer is no. we can define a pointer or function pointer to access a static member just like an external common member, the reason is that the type of the member is determined by its nature.
double *p=&NJUPT::money;double (*p)()=&NJUPT::getMoney():