Overview Joel Spolsky believes that the understanding of the pointer is an APTITUDE, not through training. Even so, I still want to talk about the most powerful elements of this C / C language. Given the association of pointers and current computer memory structure, many C language is in essentially in which this article and sixth, the seventh or two will have a pointer as the main line, combined in actual programming. The problem will talk about several important aspects on pointers. The nature of the pointer type 1, the nature of the nature of the pointer: a composite data type. Below I will use several examples as an example: a), int * p; b), int ** p; c), int (* parvalue) [3]; d), int (* pfun) () Analysis: The so-called data type is a stuff with some data characteristics, such as data type char, its data characteristics is that the memory it occupies is 1 byte, and the pointer is also very similar. The value points to the pointer also occupies. With a piece of address in memory, the length of the address is related to the type of the pointer, such as the CHAR type pointer, the memory occupied by this pointer is one byte, so the pointer is also a data type, but we know that the pointer itself occupies a The memory space address, the length of the address, and the word length of the machine, such as in the 32-bit machine, this length is 4 bytes, so the pointer itself is also a data type, so we said that the pointer is actually a The composite data type, ok, now we can analyze the above examples. It is assumed that there is a definition:
INT nvalue; then, NValue is int, which is to remove the specific variable of NVALUE. Therefore, the above four declarations can analyze: a), int * * represents the value of the variable (pointer itself) Is an address, INT represents an integer in this address, which combines, int * defines a pointer to integers, the class is subgrade, int ** points to a pointer to the integer. C), int (*) [3] points to a pointer to an array with three integers. D), int (*) () points to a function of a function, this function parameter is empty, the return value is an integer. The analysis ends, can be seen from the above, the pointer includes two aspects, one is the value of its own, is the address in memory; the other is the point pointed to by the pointer, which is stored in this address. Significant data. 2. Analyze the value of the pointer itself The following example exams the value of the pointer itself (32-bit computer):
Void * p = malloc (100); please calculate SizeOf (P) =?
Char str [] = "hello"; char * p = Str; please calculate SIZEOF (P) =?
Void func (CHAR STR [100]) {Calculate SIZEOF (STR) =? // At this time, Str has degraded into a pointer, see / / see // Next Pointer and array} Analysis: The above example, answer They are all 4, because from the above discussion, the value of the pointer itself corresponds to an address in the memory, and its size is only related to the word length of the machine (ie it is determined by the system's memory model), at 32 bits This length is 4 bytes in the machine. 3. Analysis of the pair pointed to the pointer now analyzes the second part of the composite type of the pointer, the meaning of the point referred to by the pointer. Above we have got the type of pointer itself, then remove the type of the pointer itself to the "*" to get the type of point to the pointer, which is as follows: a), and INT is an integer. B), INT * The finger is a pointer to integer. C), int () [3] () is empty, can be removed, becoming int [3], the pointed part is an array with three integers. D), int () () first () is empty, can be removed, becoming int (), the finger is a function, the parameter of this function is empty, the return value is an integer. 4, additional analysis] About the problem of the pointer itself, different from c in C , here I also talk about it. In C , it is not necessarily 4 bytes for pointers to the object member. This is mainly because some additional information needs to be passed through this pointer when introducing multiple virtual inheritance and virtual functions. The pointer to the object is increased, whether it is pointing to member data, or a member function, and the implementation is related to the compiler, you can write a small C program to verify. In addition, for a static member of a class (Static Member, it can be a static member variable or a static member function), pointing to its pointer is just a normal function pointer, not a pointer to the class member, so its size is not Increased, still 4 bytes. Pointer operators & and * "& and *", they are a pair of opposite operations, '&' gets the address of one thing (that is, the pointer itself), '*' gets the item in an address (pointer points to . This thing can be a value (object), a function, an array, a class member, and the like. We can understand & and * in terms of analysis above. Use the benefits of the pointer? We have discussed the nature of the pointer and the basic operator we discussed, here, I want to talk about the necessity and benefits of using the use of pointers in the generals, and make a good pavement for our future use and understanding of the following chapters. In short, the pointer has the following benefits: 1), convenient to use the array of dynamic allocation. This explanation I am explained in the sixth article of this series. 2) For multiple variables of the same type (even similar type), universal access. That is to use a pointer variable constantly finger between multiple variables, so that it is very flexible, but this trick is more dangerous, it needs to be used: Because the pointer to the error is a very taboo thing in programming. 3) Variable phase changes the value transfer characteristics of a function. To put it bluntly, it is the transmission of the pointer, transmitting the address of a variable as the parameter to the function, so that the function can modify the variable. 4) Save function call cost.
We can use parameters, especially large parameters (eg, structures, objects, etc.) to transmit their address as a parameter, which can save the compiler to make the space and time of the copy. 5) Dynamically expand the data structure. Because the pointer can dynamically use the Malloc / New to generate a stack, it is very useful when needed to dynamically expand the data structure; such as for trees, linkers, haveh tables, etc., this is almost essential. 6), correspond to the current computer's memory model, can be directly accessed according to the memory address, which makes C very suitable for some of the lower apparatus. This is also a powerful advantage of the C / C pointer, and I will introduce this advantage in detail when the underlying operation of the C language is described later. 7), traverse the array. According to an example, when you need to operate the string array, you want to think about it, you must use a string pointer to sweep it on the string. ... Too much, you can slowly add ^ _ ^. Pointer Its Issue 1, Problem: The definition of empty pointer has been seen .H file defines NULL to 0L, why? Answer and Analysis: This is a question about empty pointer macro. The pointer is often used in the C language, sometimes it needs to be placed as an empty pointer, such as when the pointer variable is initialized. The null pointer in the C language is the same position in the NIL in the Pascal or Lisp language. How do you define an empty pointer? The following statement is correct: char * p1 = 0; int * p2; if (p! = 0) {...} p2 = 0; that is, in the initialization, assignment, comparison operation of the pointer variable, 0 It will be understood by the compiler to set the needle to an empty pointer. As for the internal representation of the empty pointer, it is determined by different machine types, but it is usually 0. However, in additional occasions, such as the parameter prototype of the function is a pointer type, if 0 is incorporated, the compiler cannot be understood as an empty pointer. At this time, a clear type conversion is required, for example:
Void Func (Char * P); FUNC ((char *) 0); Usually, 0 is available in the code and pointer association, but some programmers (the quantity is not much!) may include you are Inside) Don't like 0, it is considered that it cannot represent a special meaning of a pointer, so a macro NULL is to be defined to explicitly represent the empty pointer. This is also right, and people C language standards are clearly said: "NULL should be defined as a related empty pointer often". But what kind of value is defined for NULL? I think you must have seen several ways to define NULL:
#define null 0 # define null (char *) 0 # define null (void *) 0 On the vast majority computing system we use, for example, the PC is capable of working. However, there are still many other types of computers in the world, and its CPU is not Intel. On some systems, the size and internal representation of the pointer and integer are inconsistent, even the size of different types of pointers is inconsistent. In order to avoid this portability problem, 0L is the most secure, conflicted way of definition. The meaning of 0L is: "Integer constant expression" value of 0 ". This is exactly the same as the empty pointer definition given by the C language. Therefore, it is recommended to use 0L as the value of the empty pointer regular NULL. In fact, NULL definition values, and the platform of the operating system, define a pointer as NULL, which is intended to protect the operating system, because through the pointer to access any piece of address, however, some data is not allowed to access, such as operation The core data of the system. When we go to orientation through an empty (NULL) pointer, the system will prompt illegal, then how the system knows? ? Taking the Windows 2000 system as an example, the system specifies that the start address (0x00000000) of each process in the system is stored in the system data, and the user process cannot be accessed, so when the user uses an empty pointer (0) In fact, the access is the system data of the 0x0000000000, since the address data is protected by the system, so the system will prompt the error (pointer access illegal). This means that NULL values do not necessarily be defined to be 0. Started by defining the address space of the system's protection range, such as defining (0x00000001, 0x00000002) will play the same role, but in order to take into account portability, general Defined as 0. 2, question: Programming rules related to the pointer & rule analysis pointer is so important, and it is easy to make mistakes, then there is no way to reduce the emergence of these pointers related issues? Answers and analysis: Reduce an error is a thorough understanding of the pointer. In the method, follow a certain coding rule may be the most immediate way. Here I explain the program rules related to the pointer: 1) Unused pointer initializes to NULL. 2) Before assigning space to the pointer, it shall be judged after allocation. 3) The pointer itself should also be cleared after the content pointed to by the pointer. To keep in mind that the pointer is the essence of a compounded data structure, so we should simultaneously take care of the pointer itself (the above rules 1, 3) and the pointer to the content (the above rules 2, 3). Follow these rules to effectively reduce pointer errors, let's look at the example below: void test (void) {char * str = (char *) malloc (100); strcpy (str, "hello"); free (STR); IF (str! = null) {struct (str, "world"); printf (str);}} What kind of results will there be a Test function? A: Tamper with the content of the dynamic memory area, the consequences are difficult to expect, very dangerous. Because Free (STR); then, the STR becomes a wild pointer, if (str! = Null) statement does not work. If we keep in mind the rule 3, add statements after Free (STR):
Str = NULL; then, such an error can occur.