Overview
The pointer is the essence of C language, but many beginners are often not deep in the concept of pointers, so that after learning as time goes by more and more blurred, feeling pointers difficult to grasp, this article through a simple example to try to explain the pointer, today's focus on several aspects:
What are pointer arrays and pointer function pointers
What is a pointer
Variables that hold the address of the variable we call "pointer variable", simply saying that the variable p is stored in the address of variable A, then p can be called a pointer variable, or that P points to a. When we visit a variable, it is the program that obtains a corresponding address based on a. Then we get the value of a in the storage space corresponding to this address, which we call a "direct reference", and when we get a through p, we first have to convert p to the corresponding storage address. And then based on this address to its corresponding storage space to get the contents of the storage, its content is actually the address of a, and then based on this address to the corresponding storage space to obtain the corresponding content, this content is a value, this through p to find a corresponding address to the value of the way to become "indirect reference." Here is a tabular listing of the stores of A and p to help you understand what is said:
Next, look at the pointer assignment.
//MAIN.C
//Point
////
Created by Kenshin Cui on 14-7-05.
Copyright (c) 2014 Kenshin Cui. All rights reserved.
#include <stdio.h>
int main (int argc, const char * argv[]) {
int a=1;
int *p;
p=&a; You can also assign a value directly to a pointer variable: int *p=&a;
printf ("Address (a) =%x,address (p) =%x\n", &a,p); Results: Address (a) =5fbff81c,address (p) =5fbff81c
printf ("a=%d,p=%d\n", a,*p);//Result: A=1,p=1
*p=2;
printf ("a=%d,*p=%d\n", a,*p); Results: a=2,p=2
int b=8;
Char c= 1;
int *q=&c;
printf ("Address (b) =%x,address (c) =%x\n", &b,&c);//Result:
printf ("c=%d,q=%d\n", C, *q);//Result: c=1,q= 2049, why is the value of Q not 1? return
0;
}
Need to note two points:
A.int *p only indicates that the P variable is a pointer variable; while printing *p, the *p is an operator that represents the storage space of the variable that the P pointer is pointing to (the current storage is 1), and we also see the *p==a; modified *p that is, modifying the contents of the storage space that P points to. Also modified A, so the second print a=2;
B. The type that the pointer points to must be the same as the type declared when the pointer is defined; The pointer q above is defined as an int while pointing to a char type, the result output *q 2049, for specific reasons see the following figure (assuming that the pointer length is 2 bytes under the 16-bit compiler)
Because local variables are stored on the stack, store B before storing A, p, when printing a *p, it's actually starting with the space corresponding to the address P points to two bytes of data (because when you define p it points to the int type, the length of the int type is 2 under the 16-bit compiler), Just defined B and C space continuously, so take to b one of the bytes, the last *p binary storage as "0000100000000001" (see above the yellow background content), decimal means 2049;
C. The space occupied by a pointer variable is independent of the type of variable it points to, and is related only to the number of compiler digits (and, to be exact, the addressing mode only);
Arrays and pointers
Since the storage of the array is contiguous, the array name is the address of the array, so the array and the pointer have a very subtle relationship, first look at the following example:
MAIN.C//point////Created by Kenshin Cui on 14-7-05. Copyright (c) 2014 Kenshin Cui.
All rights reserved.
#include <stdio.h> void changevalue (int a[]) {a[0]=2} void changeValue2 (int *p) {p[0]=3;}
int main (int argc, const char * argv[]) {int a[]={1,2,3}; int *p=&a[0];
Equivalent to: *p=a; printf ("len=%lu\n", sizeof (int));//Get int length 2//pointer plus 1 for the type of length (where the type is int, length 2)//That is to say that the direction of the address is pointing to the back of the path, and so on, and so on,
So we can also take out the array element for (int i=0;i<3;++i) {//printf ("a[%d]=%d\n", i,a[i) through pointers;
printf ("a[%d]=%d\n", i,* (P+i))//Since a represents the address of an array, it can also be written as * (A+i), but note that here * (P+i) can be written as * (p++), but * (A+i) cannot be written as * (a++) because the array name is a constant }/* Output result: a[0]=1 a[1]=2 a[2]=3 * * ChangeValue (P);
Equivalent to: ChangeValue (a) for (int i=0;i<3;++i) {printf ("a[%d]=%d\n", I,a[i]); }/* Output result: a[0]=2 a[1]=2 a[2]=3 * * CHANGEVALUE2 (a);
Equivalent to: ChangeValue2 (p) for (int i=0;i<3;++i) {printf ("a[%d]=%d\n", I,a[i]); }/* Output result: a[0]=3 a[1]=2 a[2]=3 */return 0; }
From the above example we can draw the following conclusion:
Array name a==&a[0]==*p; if p points to an array, then p+1 points to the next element of the array, noting that the length of the p+1 movement is not fixed, depending on the type of data that P points to; the pointer can be written in p++ form, but the array name is not allowed because the array name is a constant An array name or pointer can be used by arguments, regardless of whether the formal parameters of the function are arrays or pointers; extension--strings and pointers
Since a string is an array of characters in the C language, here's a look at the relationships between strings and arrays:
//MAIN.C
//point////
Created by Kenshin on
14-7-05.
Copyright (c) 2014 Kenshin Cui. All rights reserved.
#include <stdio.h>
int main (int argc, const char * argv[]) {
char a[]= ' Kenshin ';
printf ("%x,%s\n", a,a);//Result: 5fbff820,kenshin, the same variable A is an output string or an output address, depending on the format parameter
printf (a);//Result: Kenshin
printf ("\ n");
Char b[]= "Kenshin";
char *p=b;
printf ("b=%s,p=%s\n", b,p);//Result: B=kenshin,p=kenshin
//pointers store addresses, and array names store addresses, since character arrays can represent strings, so can pointers to characters, The following ways can be simpler to define a string
char *c= "Kenshin";//equivalent to char c[]= "Kenshin";
printf ("c=%s\n", c); Result: C=kenshin return
0;
}
The comments in the above code are basically clear, and here's why printf (a) can output strings directly?
Let's look at the definition of printf (): int printf (const char * __restrict, ...) __printflike (1, 2);
In fact, printf's parameter requirements are pointers to character types, and combining the above example and what we said earlier, if the function parameter is a pointer type, then the function name can be passed in, so the contents of the string can be correctly exported. Similar to the strcat (), strcpy () and other functions mentioned in the previous article.
function pointers
Before we get to the problem of the function pointer, let's take a look at the function that returns the pointer type data, after all, the pointer type is also the C language data type, and the following is a procedure for converting a string to uppercase characters, for example, In this example, you can see not only the function with the return value of the pointer type, but also the pointer move operation mentioned earlier:
//MAIN.C
//Point
////
Created by Kenshin Cui on 14-06-28.
Copyright (c) 2014 Kenshin Cui. All rights reserved.
#include <stdio.h>
char * toUpper (char *a) {
char *b=a;//Preserve the original address, because subsequent loops will change the string's original address
int len= ' A '-' a '; Uppercase and lowercase ASCII difference equal while
(*a!= ' ") {//character end
if (*a> ' a ' &&*a< ' Z ') {//If lowercase character
* (a++) = Len ; *a indicates that the corresponding character of the array (-32 becomes lowercase), the a++ is moved to the next character
} return
b;
int main (int argc, const char * argv[]) {
char a[]= "Hello";
Char *p=toupper (a);
printf ("%s\n", p); Result: HELLO return
0;
}
We all know that a function can only have a return value, if you need to return more than one value, what to do, in fact very simple, as long as the pointer to pass as a function parameter can be passed, in the following example we see the pointer as a parameter to pass.
//MAIN.C
//Point
////
Created by Kenshin Cui on 14-6-28.
Copyright (c) 2014 Kenshin Cui. All rights reserved.
#include <stdio.h>
int operate (int a,int b,int *c) {
*c=a-b;
return a+b;
}
int main (int argc, const char * argv[]) {
int a=1,b=2,c,d;
D=operate (A, B, &c);
printf ("a+b=%d,a-b=%d\n", d,c);//Result: A+b=3,a-b=-1 return
0;
}
Functions are also stored in memory, and of course the function also has a starting address (in fact the function name is the starting address of the function), here also need to understand the relationship between function pointers. The form of a function pointer definition: The return value type (* pointer variable name) (parameter 1, parameter 2), get the function pointer in fact we are equivalent to get the function, the function can be done through the pointer, and the previous example can see the pointer as a C language data type, can be used as a parameter, as a return value, Then of course the function pointer can also be used as a function parameter and return value:
//MAIN.C
//Point
////
Created by Kenshin Cui on 14-6-28.
Copyright (c) 2014 Kenshin Cui. All rights reserved.
#include <stdio.h>
int sum (int a,int b) {return
a+b;
}
int sub (int a,int b) {return
a-b;
}
Function pointers are passed as parameters
int operate (int a,int b,int (*p) (Int,int)) {return
P (a,b);
}
int main (int argc, const char * argv[]) {
int a=1,b=2;
Int (*p) (int, int) =sum;//function name is the first address, which is equivalent to: Int (*p) (int,int);p =sum;
int c=p (A,B);
printf ("a+b=%d\n", c); Result: a+b=3
//functions as Parameters pass
printf ("%d\n", Operate (A, B, sum));//Results: 3
printf ("%d\n", Operate (A, B, sub)); Result: -1 return
0;
}
function pointers can be passed as function parameters, it is too powerful, do you think of the delegates in C #? Remember that a C # book often mentions a delegate similar to a function pointer, which is actually the case above. It is important to note that the ordinary pointer can be written as a p++ to move, and function pointers written p++ does not make sense.