The secret of the C-language asterisk

Source: Internet
Author: User

The secret of the C-language asterisk

The secret of the asterisk

1 , multiplication operators 2 , define pointersint *p = 0; or int* p = 0;? The latter is easier to understand: Define a variable p, which is a pointer type (in more detail, a pointer to int), and the previous definition seems to define the strange thing about *p. But the latter is an easy misunderstanding: int* P1, p2; it seems to be the definition of two pointer-type variables p1 and P2, but, in fact, this intuition is wrong, the correct way of understanding is int *p1, p2; that is, P1 is a pointer type, and P2 is an integral type. In MS VC + + 6.0, it is written in the following format. 3 , what is a pointer? The pointer simply represents an address in memory? Also, notice that when we define pointers, we associate a type, such as Int,char, or string, and so on, if the pointer simply represents an address in memory, why should we associate so much change? It is possible to make a DWORD p=0 to solve the problem. What is the associated data type used for? It can instruct the compiler how to interpret the contents of memory on a particular address, and how much of the memory area should be spanned. such as int *p; The compiler can get information from this definition: 1, p points to the memory is the integer data, 2, because the memory region only holds one data, spanning the memory area is 4 bytes, that is, p+1 effect is to skip four bytes. Another example of complexity, such as struct a{int x1;short x2;a *next; Define pointer a *p; So what does the compiler say about this pointer? 1, p points to the memory area of the storage of three types of data, respectively, Int,short and a pointer-type data. 2. P points to a memory area that spans 12 bytes, that is, the effect of p+1 is to skip 12 bytes. (Why not 10?) However, a special pointer is defined in C + + to interpret the contents and size of the memory area in a generic pointer to meet a specific need, such as we only need the first address of a block of memory, and do not need to consider the data type and size. This form is void *; This type of pointer can be assigned to a pointer of any data type, such as a * type above, void *q = P; The only exception to this is that you cannot assign a function pointer to it. 4 , about const modifierWhen the const encounters a pointer, the trouble comes, look: const int* p; int* const P; const int* const p; These three expressions, the first one means P is a pointer, p itself is very ordinary, but the object that P points to is a special object-integer constant, the second means: this P pointer is not a normal pointer, it is a constant pointer, that can only initialize it, and cannot be assigned to the value , in addition, the object pointed to by this pointer is an ordinary int variable, the third one combines the first two: pointers and pointed objects are extraordinary, are constants. With const, the problem of assignment becomes troublesome, first, for the const int* p; Here because the object that P points to is a constant, you cannot assign a value to the object by using p to refer to it! For a constant object, you cannot point to a normal pointer, but you must use this pointer to a constant, for the simple reason that you can change the value pointed to by a normal pointer, but for a very large object, the normal variable, could you assign its address to a pointer to a constant? Yes, but once this is pointed, since the pointer itself defines a pointer to a constant, the compiler uniformly considers it to be a pointer to a variable, and thus cannot modify the value of the object being pointed at this point. Second, for the int* const p; Here p itself is a constant pointer, so it cannot be assigned at all, so there is no question of assigning a value. It cannot be initialized with a constant because it is not a pointer to a constant, it can only be initialized with a variable. Third, for const int* const p; Here, it can only be initialized and cannot be assigned a value. You can initialize with a constant, or you can initialize it with a variable, but you cannot assign a value to the variable using that pointer. Const int* p this pointer to a constant object is often used as a formal parameter to some function, and is intended to prevent the user from modifying the parameters passed in the function from the compiler's perspective, although the user itself can be avoided, but it is more reliable one o'clock-when the user accidentally makes changes to the argument's behavior, The compiler discovers and blocks this behavior. The this pointer is a const xx* const type. 5 , functions, and pointersPointer to function: You can use it instead of the function name to invoke the function. How to define a function pointer, because a program can use more than one function name in the same situation (that is, the function of overloading), so when defining a function pointer, you must include the parameters of the function, so that the pointer can be accurately pointed to a function. Definition: Int (*p) (const char*, int); Indicates that P is a pointer to a function with two arguments of const char* and int, and the function returns an int value. It is easy to confuse: int *p (const char *, int); A parenthesis is missing, at which point the compiler interprets int* p (const char*, int), meaning that it is a declaration of a function whose name is P, which returns a pointer to type int. Then int* (*p) (const char*, int) defines a function pointer p, which points to a function whose two arguments are const char* and int, which returns an initialization and initialization of pointer function pointers to type int: The function name is like the array name, The compiler interprets it as a pointer to a function of that type, so it can be initialized or assigned to a function pointer using the function name, or the & functions, and the pointer can be initialized and assigned with another function pointer. The important point is that the pointer and function name, pointers and pointers must have exactly the same parameter table and return type (must be exactly the same, no difference at all). There is no implicit type conversion, and the user must ensure full consistency. Initializes or assigns a value of 0, indicating that no function is pointed. Invoking a function with a function pointer can be called by P (x, y) or (*p) (x, y), provided that P has been correctly assigned or initialized. function return pointer: You can return an object of a non-primitive type. 6 , arrays, and pointersint a[3] = {A,a[0], &a, and &a[0] the meanings of these three expressions: first, the numeric result of these three expressions is the same--the first address of the array (that is, the address of the No. 0 element in the array), but the compiler interprets the three differently: for a , the compiler interprets it as a pointer to an integer data, thus using a+1 to point to the first element in the array, a+2 points to the second element. For a this pointer has some special properties: A is not a normal pointer, it is also an array name, which is associated with an array, so some properties are different from ordinary pointers. The normal pointer can be assigned a value, that is, you can use an address or another pointer to modify the direction of the current pointer, but for a this association of an array of pointers, if allowed to assign a value, then the elements in the array will not be accessible, so do not allow the value of the pointer represented by the group name. At this point A is equivalent to a pointer constant, which can only be initialized and cannot be assigned.     Although a cannot be assigned, it is perfectly possible to assign a to other elements, which is no different from normal pointers. In summary, A is equivalent to a pointer constant. (type* const type)   essentially a[i] operation is interpreted by the compiler as A * (a+i) operation, that is, the [] operator is implemented by an array-name pointer, and thus &a[0] means & (*A), which is clearly preceded by a pointer * (dereference), and then & ( Reference), equivalent to nothing to do, or the pointer itself, so a is completely equivalent to &a[o],--(&a[0]) [i] equivalent to a[i], the form is a bit strange, hehe. And for &a This expression, it is strange that this is also the first address of the array, so that is, the first address of this array holds a pointer constant (that is, the array name), but the first address of the array is not stored in an int type number? What's going on here? Can an address store two things? For the time being, it can be assumed that when the compiler discovers this combination of & and array names, it returns the first address of the arrays, except that, this is just a purely address, it no longer has the property of pointers, that is, the compiler no longer interprets it as a pointer, and the user cannot access the next array element through the +1 operation. +1 of it is mathematically +1.   When an array becomes multidimensional, how does the problem turn out? Consider a two-dimensional array of int b[4][3] = {{4,5,6}, {7,8,9}, {10,11,12}}; B,&b, B[0], &b[0], &b[0][0] The meaning of several expressions: first, the storage of array elements in C + +Put is the order of the main sequence, that is, the first paragraph to store the first row of data, the second paragraph holds the second row of data, .... First consider the array name B, the compiler also interprets the array name B as a pointer, but obviously this pointer is not a normal pointer. This b points to the first address of all the elements in the array, which is undoubted, so how big is the memory of this pointer stepping across? In this example, the B step spans 12 bytes, that is, b steps across a row of elements in the array, and B is actually a pointer to a pointer, or a pointer to a pointer, that is, the content that B points to is a pointer, (also for b+1,b+2), B[i][j] This access method is essentially: first through +i, The pointer jumps to line I, thus obtaining a pointer to the beginning address of the first b[i], and then through this pointer, and then through the +j, Jump J step, reached the J element, that is, the first row, the element J column. So b is pointer to pointer, b[i] is pointer, here, B[i] is similar to a in one dimension. What about &b? &b is still the first address of the array, but similar to the one-dimensional, this is a purely address, no longer has the characteristics of pointers, its +1 is mathematically +1, can not take advantage of the next element to access. The same is true for the &b[i],& operator, after which it was originally used as a pointer to the b[i] to qualify for the stripped pointer, returning a purely address. In fact, because [] is essentially a reference to a pointer, we can access the array element in a manner that is a[i][j], which can be: (* (A+i)) [j], or * (A[I]+J), or * (* (a+i) +j), which are equivalent. For &b[i][j]? We put B[i][j] in a different way, written as * (* (b+i) +j), so the problem is easy to see clearly, the original *b[i][j] is equivalent to & (* (* (b+i) +j), we can take the outermost bracket off, it becomes * (b+i) +j, that is, B[i]+j, Obviously this is a pointer to line I, column J of the element's pointer, and the interpretation of that pointer is a data that spans an int type at a time.   Let us pervert a little, consider three-dimensional situation, although the three-dimensional array is rare, or consider it, after all, space coordinates are expressed in three-dimensional. int C[2][3][4] = {{{1,2,3,4},{5,6,7,8},{9,10,11,12}}, {{13,14,15,16},{17,18,19,20},{21,22,23,24}}}; First, array name C, The compiler interprets C as a pointer to the first address of the array, because the row order is the main order, so the pointer spans 12 integers, a total of 48 bytes, which actually spans a two-dimensional array. ForAmp;c, like the one-dimensional two-dimensional case, is a purely address. C[i]? It can be speculated that c[i] is similar to B in two dimensions, that is, a pointer to a pointer, C[i] one step across 4 integers, 16 bytes. C[i] is a pointer to a pointer, then C is a pointer to a pointer to the pointer (halo ~). C[i] is also equivalent to * (C+i) as to C[i][j], this is the real int pointer, that is, a pointer to the real data, one step across an int, 4 bytes. Similar to the two-dimensional, for &c[i][j], the compiler returns an address, although it is the same as the value of c[i][j], but only a pure address, spanning the unit to one byte. For C[i][j][k], do not need nonsense, for &c[i][j][k], this is an address? Is this a pointer? We still have to use [] another way of expression: C[i][j][k] is equivalent to * (* (* (c+i) +j) +k), then &c[i][j][k] is equivalent to * (* (c+i) +j) +k, that is, c[i][j]+k, that is, point (i,j, k) A pointer to an element, one step across the unit for an int type. Let's take a look at the I,J,K elements: 1, c[i][j][k]2, * (C[I][J]+K) 3, * (* (C[I]+J) +k) 4, * (* (* (c+i) +j) +k) 5, (* (C+i)) [J][k]6] C+i) (+j)) [K]7, * ((* (c+i)) [J]+k] 8, (* (C[i]+j)) [K] visible, a total of eight kinds of writing, in fact, there is a total of three solution references, select with [] or with *, so that there are 8 combinations altogether. (then two-dimensional is 4 kinds, one-dimensional 2 kinds)   7 , typedef with the pointertypedef seems very simple, such as typedef int integer; However, these simple typedef statements are prone to misunderstandings, and TypeDef is a kind of macro substitution that replaces the later custom types with the previously known ones. Obviously not! Consider the question: How do you define a pointer type that points to an integral type? How do I define a function pointer type? The first question is simple: typedef int* Int_pointer; Now, for the second question, it seems that it is not so simple, first of all, look at the method of defining the function pointer: Int (*P) (const&, int); The function that this P points to must return int, and the parameter must be const& and int. Now to name this pointer type Func_pointer, the method is defined as follows: TypeDef int (*func_pointer) (const&, int), which can be understood as: typedef int integer; The typedef is removed, that is the definition of a variable, here is the definition of an int variable integer, considering what the integer is, then this typedef statement is to define the integer as this type. a typedef int (*func_pointer) (const& int), in which a typedef is removed, is defined as a function pointer, i.e. func_pointer is defined as a function pointer type variable. Then the original typedef will be func_pointer defined as the function pointer type. 8 , functions, arrays, and pointersInt (*testcases[10]) (); What does this expression mean? pointers, arrays, functions blend together and the problem gets complicated. It defines the array, testcases[10], the element in the array is a function pointer, the type of the function pointer is int (*) (); How do you understand this definition? First consider the definition of the array, the definition of the general pattern is: type array name [size]; Consider this expression, it seems to define an array, but the array name [size] is sandwiched between the middle, then the type is what, the discovery type is not a simple data type, but a function pointer type int (*P), This function has no parameters and returns an int type. Thus the meaning of this expression is: Defines an array of function pointer types, the size is 10. typedef can be used to simplify this definition: typedef int (*PFV) (); PFV testcases[10];  actually int (*testcases[10]) (); Here we define an array of function pointers, and the array is the body. Consider the following question: How do you define a pointer to an array? A pointer to an array, as if it were fresh, a pointer to an array, that is, a step across the pointer is an array, with a pointer to an integral type one step across an integral type. In fact, a pointer to an array, such as a two-dimensional array name, is actually a pointer to an array, which spans one row of data at a time, actually spanning a one-dimensional array, and the three-dimensional array name is also a pointer to an array that spans a two-dimensional array of low dimensions at a time. The definition of an array pointer (that is, a pointer to an array): Int (*ptr) [3];   This expression defines an array pointer ptr,ptr one-dimensional array that spans one 3 int. The way that it is defined is similar to the way a function pointer is defined, except that () is replaced by []. Further, if you want to define a pointer to an array, and the element in the array is not a simple int, but rather a complex type, how do you define it? In fact, the array pointer this kind of thing is already rare enough, general programming absolutely will not use, we just need to be able to read some more complex things on the line, we do not need to construct such a complex type.   More complex expressions:       1, int (* (* (*p ()) []) ()) []; First, p () is the function, and then according to P () the preceding * The function returns a pointer, the following is the pointer to what the class is new, we can replace the *p () with a *pointer, the pointer is the function p returns the pointer, thatis an int (* (* (*pointer) []) ()) []; Again (*pointer) [], which shows that the pointer pointer is an array of points, so what is the type of the element in this array? Since the array name is actually a pointer, we replace (*pointer) [] (i.e. (*p ()) []) with an array, so that it becomes an int (* (*array) ()) []; the array is a function pointer, so that each element in the array is a function pointer, And this function, and return a pointer type, the (*array) () with Func instead, it becomes an int (*func) []; This shows that the Func function returns a pointer to the array, and the elements in the array are of type int. This expression is cool enough!!! 2, p = (int (* (*) [x]) [x]) Q; This is a forced type conversion, Q is coerced into a type of pointer type, the pointer is a line with 20 elements of an array, the elements of this array is a pointer, is pointing to another array, This array is a one-dimensional array containing 10 int data.   can be seen, when analyzing complex expressions (the so-called complex, that is, a mixture of pointers, arrays, functions three, the absence of the same will not be complicated), from the innermost layer of parentheses, the innermost thing is the complex expression "root node", and then take off, off the time, such as the inner layers are the number of groups, So what is the element of this array, that is, the outer layer, if the innermost is a function with a return value, then what value does the function return? That is the outer layer of the thing, so that the expression is resolved in layers.    There's something to say about typedef: TYPEDEF  INT (*PFV) (); This is defined as a function pointer, then PFV p; You can define a pointer to a function. typedef int (*P[10]) (); This is the definition of P as a function pointer array, then P array; statement can define a function pointer array, the array name is Array,array This array contains 10 elements. typedef int (*parray) [3]; This defines a pointer to an array of integers, then parray ptr; Defines a pointer to an array. How to assign or initialize this ptr? In fact, it is assigned (initialized) by a two-dimensional array name, because a two-dimensional array is a pointer to an array, spanning an array at a time. typedef int A[3][3]; What does this statement mean? This is the integer array type that defines a as a 3*3. When a B= {1} completes the work of defining initialization of a 3x3 integer array. Similarly, a bit simpler typedef int A[3]; This statement defines a as a one-dimensional array type. typedef  void func (int); This statement defines a function type. Through this typedef, we can clearly define the function pointer, func* p;  typedef char* string;const string str; what type of STR is this? const char * str, which is a pointer type that points to a constant? In fact, the answer is somewhat magical, and STR is a constant pointer, not a pointer constant, that is, the const modifier is for pointers, not char.   9 , references, and pointersA reference is similar to a pointer constant, which can only be initialized and not assignable. Aliases (alias) are another term for references (reference). Manipulating objects can be manipulated indirectly by reference. Constant references, such as constant pointers to constants, and initialization of constant references, are a bit special and can be initialized with constants, variables, and even constants. For a constant reference to be initialized with a variable, the variable cannot be modified by this reference, but the original variable name can. At this point, a variable-like address is assigned to a constant pointer. The variable can not be modified by a constant pointer, but the variable name of the variable itself can. You can have a reference to a pointer, such as int a = 1; int* p = &a; int* &r = p; Then R is a reference to the pointer p. If the const int* p = &a; description is a constant pointer, define the reference so that it is defined as const int* &R = p; This statement shows that R is a reference to a pointer, which is a pointer variable to a constant. It does not mean that the reference is a constant reference. So if this pointer is not just a constant pointer, but also a pointer constant, that is, const int* const p; Then you should be aware of the const int* const &R = p When defining the reference, so that the reference is a constant reference. Here's a problem when initializing a reference with the address of a variable, such as int a = 22; int* Const &PI_REF = &a; need to be aware that a constant reference should be made, because &a is not a variable name, but a similar constant. And if the const int a = 22, then the const int* Const &PI_REF = &a; That is the middle of the const is used to define the constant reference, whereas the preceding const reflects the Const object that refers to the object (pointer) to which the reference is pointing. We have object names, or pointers to objects, which can manipulate objects, why introduce the concept of reference? In fact, references are most commonly used as formal parameters for functions. To manipulate an external object in a function, it is a good idea to use a reference. About references first, the reference can only be initialized, not be assigned, because, after the initialization of the reference, it becomes the alias of the referenced object, and then the assignment, it is not the reference itself assignment, but the reference to the object is assigned. Come from:http://blog.csdn.net/keensword/archive/2005/06/22/400577.aspx

The secret of the C-language asterisk

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.