The essence of a pointer: A variable, a pointer variable is a pointer variable
int *p: Two variables, one p (the pointer variable itself) is of type int *
The other is *p (the variable that the pointer points to) is of type int
Note: The pointer is plainly a pointer type, the previously defined int type is to illustrate the type of the number that the pointer points to, so the pointer is parsed by address.
(Whether you're a char or double, parsing is an address) and the type of the number you're pointing to depends on how you define it.
For example:
int *a
A is parsed according to the address, and *a is parsed according to the int type.
(1) All types of data are stored in memory and are stored in binary format. So memory only knows 0 and 1, do not know whether it is int, or float or other types
You can query how these types of storage (number converted to binary into memory)
The storage types of int, char, shoort, etc. are the same except that the memory lattice size is different (so these kinds of shaping are called Binary compatibility format);
The storage modes of float and double are different from each other, and are more different from shaping.
For example:
1 int 5 ; 2 3 printf ("a =%d.\n", a); // 5 4 printf ("a =%f.\n", a); // garbled 5 Summary: How to define how to take,int5; Allocate 4 cells to install 0b1010, and then deposit in cell
Example 2:
int - ; char *p1 = &a;printf ("*p1 =%d.\n", *p1); Note: The range of char is - 127~127, out of this range will not be wrong, if it is out of the error, so use int to take char can not be wrong, but Char takes int it is possible to make an error or error
Difficulties:
void fun (int b[100])
{
sizeof (b);
}
Note:
(1) Function arguments, which can be used in arrays
(2) When the function parameter is an array, the actual pass is not the entire array, but the first element of the array's first address. That is, the function parameter is passed by an array, which is actually equivalent to passing the pointer (the pointer points to the first element of the array).
// Func is exactly the same as Func1 void func (int a[]) {printf (" array size =%d.\n"sizeof (a));} void func1 (int *a) {printf (" array size =%d.\n" sizeof(a));
Second, wild pointer (there is no specific address to define the pointer, it can be arbitrarily pointed to any address)
1. When a pointer is a wild pointer, it is not easy to dereference, which can cause a lot of problems.
2. Because the pointer to the address is unpredictable, there are 3 situations:
The first is to point to inaccessible (the operating system does not allow access to sensitive addresses, such as kernel space) address, the result is a trigger segment error, this is the best case;
The second is to point to a usable, and nothing special space (such as once used but no use of stack space or heap space), this time the program will run without error, and will not cause damage to the current program, this situation will cover up your program errors, so you think the program is not a problem, in fact, there are problems;
The third situation is to point to a usable space, and this space is actually being used in the program (for example, a variable x of the program), then the dereference of the wild pointer will just modify the value of the variable x, causing the variable to be inexplicably changed, the program has a bizarre error. It usually eventually causes the program to crash, or the data is compromised. This is the greatest hazard.
3. If the pointer variable is a local variable, it is allocated on the stack, itself in accordance with the law of the stack (repeated use, not erase, so it is dirty, the default value of the variable allocated on the stack is the last time the stack space is used when the remaining value), the wild pointer is also a certain regularity, but meaningless
4. Avoid the wild pointer method: Before the pointer is dereferenced, make sure that the pointer points to an absolutely available space.
The general practice is to:
int*p = NULL;//First step: When defining pointers, initialize to null at the same time//a bunch of code//Step two: When using pointers in this period, give it a meaningful address//int a = 3;//p = &a;if(NULL! = P)//The third step: Before the pointer dereference, the first to determine whether the pointer is null{*p =5;} P= NULL;//Fourth step: After the pointer is used, assign the value to nullNote: Generally, when judging whether the pointer is a wild pointer, it is writtenif(NULL! = p) instead of writtenif(P! =null) The reason is: If NULL is written in the back, when the middle is= = number, sometimes easy to forget to write =, this time the program is actually wrong, but the compiler will not error.
This error (for newbies) is difficult to check out, and if you get used to writing null in front, the compiler will give an error when the wrong = = is written.
5. What is null
(1) NULL is defined in C + + as:
1 #ifdef _cplusplus // Define this symbol to indicate that the C + + environment is currently 2#define NULL 0 // in C + +, NULL is 03#else4#define null (void *) 0 / / NULL in C is 0 5 #endif the coercion type is converted to void *
(2) in C language, int *p; you can p = (int *) 0; but not p = 0; Because the types are different.
(3) so the essence of NULL is actually 0, then we give the pointer the initial value is null, in fact, the pointer is pointing to the 0 address. First, 0 address as a special address (we think the pointer is pointed here to indicate that the pointer is not initialized, it is a wild pointer); second, 0 addresses are inaccessible in the general operating system, If a C programmer does not follow the rules (to dereference without checking if it is equal to null), writing the code directly to Dereference will trigger a segment error.
Three, array
Understanding of several key symbols (a a[0] &a &a[0]) (provided that the int a[10])
1.a is the name of the array. A left value represents the entire array of all the space (10x4=40 bytes), and because the C language specifies that the array operation to be independent of a single operation, can not operate the array as a whole, so a can not do the left value; a rvalue indicates the first address of the first element of the array (the No. 0 element of the array, i.e., a[0]) , which is the address of the first byte in 4 bytes). A Do right value equals to &a[0];
2.a[0] Represents the first element of the array, which is the No. 0 element of the array. The left value represents the memory space of the No. 0 element of the array (4 consecutive bytes), and the value of the No. 0 element of the array (that is, the number stored in the memory space corresponding to the No. 0 element of the array) when the right value is done.
The 3.&a is the address of the array name A, which is the literal meaning of the array. &a cannot do Lvalue (&a is a constant, not a variable and therefore cannot be assigned, so it is not natural to do the lvalue.) &a is the first address of the entire array when the right value is done.
4.&a[0] literally means the first address of an array of No. 0 elements. When you do the left value, the first element of the array corresponds to the memory space, the right value is the address of the first element of the array, the right value when &a[0] is equivalent to a.
Summarize:
The difference between 1:&a and a is when the right value is: &a is the first address of the entire array, and a is the first address of the first element of the array. The two are equal in numbers, but have different meanings. Different meanings can cause them to behave differently when they are involved in the operation.
2:a and &a[0] are the addresses that represent the first element when they are right, and can be replaced entirely.
3:&a are constants and cannot be left-valued.
4:a does an lvalue to represent the entire array of space, so a cannot do the left-hand value.
1. Functions and pointers
1.1. When a variable is passed in as a formal parameter (value call)
eg.
1 voidSWAP1 (intAintb)2 {3 inttmp;4TMP =A;5A =b;6b =tmp;7printf"in Swap1, a =%d, B =%d.\n", A, b);8 }9 Ten voidSWAP2 (int*a,int*b) One { A inttmp; -TMP = *A; -*a = *b; the*b =tmp; -printf"In swap1, *a =%d, *b =%d.\n", *a, *b); - } - + intMainvoid) - { + intx =3, y =5; A swap1 (x, y); atprintf"x =%d, y =%d.\n", x, y);//x=3,y=5, Exchange failed - - intx2 =3, y2 =5; -SWAP2 (&X2, &y2); -printf"x =%d, y =%d.\n", x2, y2);//x=5,y=3 Exchange Success - in return 0; - } to Note: The first is a value call, and the second is a call to address +The essence: All is a value call, the first pass is the value of the variable, the second pass is the value of the pointer variable
2. Array as function parameter
2.1. The group name as the formal parameter, the actual pass is not the entire array, but the first element of the array's initial address (the first element of the pointer)
2.2. The first address of the first element of the array obtained in the incoming parameter of the sub-function, and the value of the first address of the first element obtained from the outside array is the same. Similar to "call-to-address"
3, the pointer as a function parameter
The array is the same as the function parameter
Example:
1 voidFUNC3 (int*a)2 {3printf"sizeof (a) =%d.\n",sizeof(a));4printf"in func3, a =%p.\n", a);5 }6 7 voidFunc2 (inta[])8 {9printf"sizeof (a) =%d.\n",sizeof(a));Tenprintf"in Func2, a =%p.\n", a); One } A - intMainvoid) - { the inta[5]; -printf"A =%p.\n", a); -Func2 (a);/* - a = 0x7ffff2bdc8b0. + sizeof (a) = 8. (I have a 64-bit system) - in Func2, a = 0x7ffff2bdc8b0. + */ A at inta3[5]; -printf"A =%p.\n", A3); -FUNC3 (A3);//Ibid . - } -Note: The array name is printed directly and the group name is the parameter, and the pointer is the same result as the formal parameter
4, the structure as a formal parameter (follow-up ..... )
V, const keyword and pointer
1.4 Types of const modifier pointers
(1) The const keyword, which is used in the C language to modify a variable to indicate that the variable is a constant. (A const keyword can only modify one variable)
(2) There are 4 types of const modifier pointers:
the const int *p1;//p itself is not cosnt, and the variable p points to is const (*P1 immutable)
The int const *p2;//p itself is not cosnt, and the variable p points to is const (*P2 immutable)
The int * Const P3;//p itself is cosnt, and the variable p refers to is not const (P3 cannot be changed)
the const int * Const P4;//p itself is cosnt, and the variable P refers to is also const (P4 and *P4 are immutable)
If you really need to modify the value on the const, you need to modify with coercion type conversion, cheat the compiler, and ordinary global variables like the code in the data section,
In this way, when the program runs, there is no const keyword before discovering the data, it runs directly (some SCM cannot be modified)
2. Use the const pointer in the function pass parameter
Example:
1 Char*P1;2 Const Char*P2;3 Char*pstr ="Hello";4 //char pstr[]= "Hello";5P1 =pstr;6P2 =pstr;7*P1 =A;8*P2 =A;9PRITF ("pstr =%c.\n", *P1);//the compiler will not report an error if char *pstr is used, but there will be a segment error when executingTenPRITF ("pstr =%c.\n", *P2);//if char *pstr is used, the compiler will report an error, *P2 is a const type, read-only One A Note: The reason for a segment error is that the string is stored in a code snippet, which is a zone that cannot be changed, and all execution errors occur -If the char pstr[] array is used, the *P1 can be changed, and the array appears to be stored in the data area (not very sure)
Add:
#define Dpchar char * char *tpchar; // a typedef is used to rename a type, or to create a user-defined type. Dpchar p1, p2; // expanded: char *p1, p2; equivalent to char *p1, char p2; Tpchar P3, P4; // equivalent to: Char *p3, char *p4;
(Refer to Zhu Youpeng teacher)
Understanding and relation of pointers and arrays