Pointers in C

Source: Internet
Author: User

1. Three Two-dimensional arrays are described below. 1: int ** Ptr; 2: int * Ptr [5]; 3: int (* Ptr) [5]; the preceding three examples are two-dimensional arrays of integers, you can access the content in the format of Ptr [1] [1]. However, the differences between the two methods are quite large. I will discuss them in four aspects: 1.1. The content itself is a pointer, and their final content is an integer. Note that I am talking about the final content, not the intermediate content. For example, if you write Ptr [0], the content of the three is an integer pointer, that is, int *; ptr [1] [1] is the final content. 1.2. Significance 1: int ** Ptr indicates the pointer to an integer pointing to "a group. 2: int * Ptr [5] indicates Five Pointers pointing to integers. 3: int (* Ptr) [5] indicates the pointer pointing to "a group" to 5 integer arrays. 1.3. The occupied space (1), int ** Ptr, and (3), int (* Ptr) [5] are 4 bytes in 32-bit platforms, A pointer. (2) Different from int * Ptr [5], it is five pointers, which occupy 5*4 = 20 bytes of memory space. 1.4 usage (1), int ** Ptr because it is a pointer, it requires two memory allocations to use its final content. First, Ptr = (int **) new int * [5]; after the allocation is completed, it has the same meaning as (2; then we need to allocate memory for the Five Pointers separately, for example, Ptr [0] = new int [20]; it means to allocate 20 Integers to The 0th pointers. After the allocation, ptr [0] is an array pointing to 20 integers. In this case, you can use the subscript usage Ptr [0] [0] To Ptr [0] [19. If there is no first memory allocation, this Ptr is a "wild" pointer and cannot be used. If there is no second memory allocation, Ptr [0] and so on are also a "wild" pointer, it is also unavailable. Of course, it is allowed to point to a defined address. It is another method (similar to the practice of "taking the opportunity"), which is not discussed here (the same below ). (2) If int * Ptr [5] is defined as this, the compiler has allocated five pointer spaces for it, which is equivalent to the first memory allocation in (1. According to the discussion on (1), we can see that we need to allocate memory once. Otherwise, it is the "wild" pointer. (3) I think int (* Ptr) [5] is rather difficult to understand. Maybe I am not used to this definition. How to describe it? It indicates a group of pointers, each pointing to an array of five integers. To assign k pointers, write Ptr = (int (*) [5]) new int [sizeof (int) * 5 * k]. This is a one-time memory allocation. After the allocation, Ptr points to a contiguous address space, in which Ptr [0] points to the first address of 0th five integer arrays, ptr [1] points to the first address of the 1st five integer arrays. In conclusion, I think we can understand them as follows: int ** Ptr <=> int Ptr [x] [y]; int * Ptr [5] <==> int Ptr [5] [x]; int (* Ptr) [5] <==> int Ptr [x] [5]; here, x and y represent several meanings. 2. function pointer and pointer function 2.1. An example of a common function call for a common function call is as follows: 1: void MyFun (int x); // The declaration here can also be written as follows: void MyFun (int); 2: int main (int argc, char * argv []) 3: {4: MyFun (10); // call MyFun (10) here ); function 5: return 0; 6:} 7: void MyFun (int x) // define a MyFun function 8: {9: printf ("% d \ n ", x); 10:} This MyFun function is a function with no return value and does not accomplish anything. You should be familiar with this function calling format! Look at the writing format of the MyFun function called in the main function: MyFun (10). At the beginning, we only understood the MyFun function in terms of functionality or mathematics, knowing that the MyFun function name represents a function (or a piece of code ). Until the function pointer concept is learned. I had to think: what is the function name? [Functions in js] (don't think this is meaningless! You can see it later .) 2.2. the Declaration of the function pointer variable is like that the memory address of a Data variable can be stored in the corresponding pointer variable, the first address of the function is also stored in a function pointer variable. In this way, I can call the function pointed to through this function pointer variable. In the C series language, any variable must be affirmed before it can be used. So should the function pointer variable be affirmed first? How can we declare it? In the preceding example, I declare a function pointer variable FunP that can point to the MyFun function. The following describes how to declare the FunP variable: void (* FunP) (int); // You can also write it as void (* FunP) (int x, the Declaration format of the entire function pointer variable is the same as that of the function MyFun, except that we changed MyFun to (* FunP, in this way, there is a pointer FunP that can point to the MyFun function. (Of course, this FunP pointer variable can also point to all other functions with the same parameters and return values .) 2.3 call the function using the function pointer variable. After the function has the FunP pointer variable, we can assign a value to MyFun and call the MyFun function through FunP. See how I call the MyFun function through the FunP pointer variable: (For details, refer to the C ++ virtual function table parsing) 1: void MyFun (int x ); // This statement can also be written as void MyFun (int); 2: void (* FunP) (int); // It can also be declared as void (* FunP) (int x. 3: int main (int argc, char * argv []) 4: {5: MyFun (10); // This is a direct call to the MyFun Function 6: FunP = & MyFun; // assign the address of the MyFun function to the FunP variable 7: (* FunP) (20); // call the MyFun function using the function pointer variable FunP. 8:} 9: void MyFun (int x) // define a MyFun function 10: {11: printf ("% d \ n", x); 12 :} run it. Well, it's good. The program runs well. Oh, my feeling is: the relationship between MyFun and FunP is similar to that between int and int. The function MyFun seems to be an int variable (or constant), while FunP is a pointer variable like int. Int I, * pi; pi = & I; // compare with FunP = & MyFun. (How do you feel ?) Haha, it's not --..... 2.4 call other writing format function pointers of functions can also be used as follows to accomplish the same thing: 1: void MyFun (int x); 2: void (* FunP) (int); // declare a pointer variable to point to the same parameter, return value function. 3: int main (int argc, char * argv []) 4: {5: MyFun (10); // call MyFun (10) here; Function 6: funP = MyFun; // assign the address of the MyFun function to the FunP variable 7: FunP (20); // call the MyFun function using the function pointer variable. 8: return 0; 9 :}10: void MyFun (int x) // here defines a MyFun function 11: {12: printf ("% d \ n", x ); 13:} run it! Same success. Why? FunP = MyFun; the same value of MyFun can be assigned to FunP in this way. Is it true that MyFun and FunP are of the same data type (like the relationship between int and int ), instead of having a relationship between int and int? (Are you confused ?) It seems a little different from the previous code, right! That's why I said it! Please let me not explain it to you for the time being. continue to look at the following situations (these can be code that can be correctly run !): Code 3: 1: int main (int argc, char * argv []) 2: {3: MyFun (10); // call MyFun (10) here ); function 4: FunP = & MyFun; // assign the address of the MyFun function to the FunP variable 5: FunP (20); // call the MyFun function using the function pointer variable. 6: return 0; 7:} code 4: 1: int main (int argc, char * argv []) 2: {3: MyFun (10 ); // here MyFun (10) is called; function 4: FunP = MyFun; // assign the address of MyFun function to FunP variable 5: (* FunP) (20 ); // This is to call the MyFun function through the function pointer variable. 6: return 0; 7:}. It's really okay! 1: int main (int argc, char * argv []) 2: {3: (* MyFun) (10); // check, the function name MyFun can also be called in the format of 4: return 0; 5:}. You may see it for the first time: the function name call can also be written like this! (It's just that we do not normally write like this .) So what are the explanations? Haha! Based on the previous knowledge and experience, I think "New Discoveries" in this article will certainly come to the following conclusion: 1. in fact, MyFun function names and FunP function pointers are the same, that is, all function pointers. The MyFun function name is a function pointer constant, and FunP is a function number pointer variable, which is their relationship. 2. However, if function names are called like (* MyFun) (10), it is inconvenient to write and read. Therefore, the designers of C language can design and allow MyFun (10); this form of calling (this is much more convenient and the function form in mathematics is the same, isn't it ?). 3. for uniformity, FunP function pointer variables can also be called in the form of FunP (10. 4. When assigning values, you can use FunP = & MyFun, or FunP = MyFun. Whatever you like about the above Code! Please understand this! This helps you to apply function pointers! Note: In the Declaration of the function: void MyFun (int); // It cannot be written as void (* MyFun) (int ). Void (* FunP) (int); // It cannot be written as void FunP (int ). (Please refer to the notes. 2.5 define the pointer type of a function, just like the custom data type. We can also define a function pointer type, and then use this type to declare the function pointer variable. Let me give you an example of a custom data type. 1: typedef int * PINT; // defines a PINT alias for int * type 2: int main () 3: {4: int x; 5: PINT px = & x; // It is equivalent to int * px = & x. PINT type is actually int * type 6: * px = 10; // px is the int * type variable 7: return 0; 8:} According to the comment, it should be difficult to understand it! (Although you may rarely use this definition, it will often be seen later when learning Win32 programming .) Next, let's take a look at the definition and usage of the function pointer type: (Please compare with the above !) 1: void MyFun (int x); // The statement can also be written as void MyFun (int); 2: typedef void (* FunType) (int ); // define a function pointer type 3: FunType FunP; // use the FunType type to declare the global FunP variable 4: int main (int argc, char * argv []) 5: {6: // FunType FunP; // The function pointer variable can also be local, so please declare it here. 7: MyFun (10); 8: FunP = & MyFun; 9: (* FunP) (20); 10: return 0; 11:} 12: void MyFun (int x) 13: {14: printf ("% d \ n", x); 15:} First, a typedef is added before void (* FunType) (int. In this way, only a pointer type named FunType is defined, instead of a FunType variable. Then, the FunType FunP; statement declares a FunP variable like PINT px. Others are the same. The entire program has done the same thing. The advantage of this method is that with the FunType type, we can easily declare multiple function pointer variables of the same type with the FunType type. FunType FunP2; FunType FunP3 ;//...... 2.6 function pointer as a function parameter since the function pointer variable is a variable, it can also be used as a function parameter. Therefore, you should also know how function pointers are transmitted and used as parameters of a function. For example: Requirement: I want to design a CallMyFun function. This function can call the functions MyFun1, MyFun2, and MyFun3 by using different function pointer values in the parameter. (Note: the format of the three functions must be the same ). Implementation similar to delegate in C #: Code: 1: void MyFun1 (int x); 2: void MyFun2 (int x); 3: void MyFun3 (int x ); 4: typedef void (* FunType) (int); // ②. define a function pointer type FunType, and 1 to 5: void CallMyFun (FunType fp, int x); 6: int main (int argc, char * argv []) 7: {8: CallMyFun (MyFun1, 10); // ⑤. call three different functions 9: CallMyFun (MyFun2, 20), 10: CallMyFun (MyFun3, 30), 11:} 12: void CallMyFun (FunType fp, int x) // ③. the type of the parameter fp is F. UnType. 13: {14: fp (x); // ④. use the fp pointer to execute the passed function. Note that the fp function refers to a 15:} 16: void MyFun1 (int x) // ①. this is a function with a parameter. The following two functions are also the same: 17: {18: printf ("output in function MyFun1: % d \ n", x); 19:} 20: void MyFun2 (int x) 21: {22: printf ("output in function MyFun2: % d \ n", x); 23:} 24: void MyFun3 (int x) 25: {26: printf ("function MyFun3 outputs: % d \ n", x); 27:} output result: analysis: (see my comments. You can analyze it by yourself in the order of my comments ① ③ ④ .) A pointer function not only brings back the value of an integer, the value of a character type and the value of a real type, but also brings back the data of the pointer type to point it to an address unit. The function that returns the pointer. The format is generally defined as: type identifier * function name (parameter table) int * f (x, y). where x and y are form parameters, and f is the function name, after the call, an address pointer pointing to the integer data is returned. F (x, y) is a function and its value is a pointer. For example, char * ch (); indicates a function that returns a struct pointer. See the following example: in C, the return value of the function is int by default. [Example] Copy string 1 (str1) to string 2 (str2) and output string 2. 1: # include "stdio. h "2: 3: main () 4: 5: {6: 7: char * ch (char *, char *); 8: 9: char str1 [] = "I am gglad to meet you! "; 10: 11: char str2 [] =" Welcom to study C! "; 12: 13: printf (" % s ", ch (str1, str2); 14: 15:} 16: 17: char * ch (char * str1, char * str2) 18: 19: {20: 21: int I; 22: 23: char * p; 24: 25: p = str2 26: if (* str2 = NULL) exit (-1); 27: 28: do 29: 30: {31: 32: * str2 = * str1; 33: 34: str1 ++; 35: 36: str2 ++; 37: 38:} while (* str1! = NULL); 39: 40: return (p); 41: 42:} through analysis, the function pointer is a pointer to the function, the pointer function only indicates that it is a function whose return value is a pointer. It can be used to point to a function. 3. array pointer and pointer array 3.1, array pointer (also called row pointer) defines int (* p) [n]; () The priority is high. First, p is a pointer, point to a one-dimensional array of an integer. The length of this one-dimensional array is n, or the step of p. That is to say, when p + 1 is executed, p must span the length of n integer data. To assign a two-dimensional array to a pointer, the value should be: 1: int a [3] [4]; 2: int (* p) [4]; // This statement defines an array pointer pointing to a one-dimensional array containing four elements. 3: p = a; // assign the first address of the Two-dimensional array to p, that is, a [0] Or & a [0] [0] 4: p ++; // after the statement is executed, that is, p = p + 1; p crosses row a [0] [] and points to row a [1] []. Therefore, an array pointer is also called a pointer to a one-dimensional array or a row pointer. 3.2. The pointer array defines int * p [n]; [] It has a high priority. It is first combined with p into an array, and then int * indicates that this is an integer pointer array, it has n pointer-type array elements. The execution of p + 1 here is incorrect, so the value assignment is also incorrect: p = a; Because p is an unknown representation, only p [0], p [1], p [2]... p [n-1], and they are pointer variables that can be used to store variable addresses. But it can be like this * p = a; here * p represents the value of the first element of the pointer array and the value of the first address of. To assign a two-dimensional array to a pointer array: 1: int * p [3]; 2: int a [3] [4]; 3: for (I = 0; I <3; I ++) 4: p [I] = a [I]; here int * p [3] represents a one-dimensional array with three pointer variables in memory, they are p [0], p [1], and p [2]. Therefore, assign values respectively. In this way, the difference between the two is suddenly clear. The array pointer is just a pointer variable. It seems that the C language is specifically used to point to a two-dimensional array, which occupies the storage space of a pointer in the memory. A pointer array contains multiple pointer variables in memory and occupies the storage space of multiple pointers. It also needs to be noted that when it is used to point to a two-dimensional array, its reference is the same as the array name reference. For example, to represent an element in column j of row I in the array: * (p [I] + j), * (p + I) + j), (* (p + I) [j], p [I] [j]

Related Article

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.