C (10)

Source: Internet
Author: User
Tags define null

First, the memory layout of the pointer

Let's look at the following example:

int *p;

As we all know, this defines a pointer p. But what is P exactly? Remember the first chapter that said, "Can we make it a model of any kind of data?" P, no doubt, is a certain mold.

We have also discussed that any mold must have a specific size so that it can be used to "click". What exactly is this mold of p? How much space does it occupy? Now test with sizeof (32-bit system): sizeof (P) has a value of 4. Well, this shows that the size of the die for P is 4 bytes. Obviously, this mold is not an "int", although it is also 4 in size. Since it is not "int" then it must be "int *". Okay, so now we can do this.

Understand this definition:

an "int *" type of mold in the memory of a 4-byte space, and then the 4-byte size of the space is named P, while limiting the 4 bytes of space can only store a certain memory address, even if you deposit any other data, will be treated as an address, and this memory address begins a continuous 4 You can only store data of an int type on a byte.

This is a paragraph of the note, we still use the figure to parse:


As shown, we refer to p as the pointer variable, and memory at the memory address stored in P is called the memory that P points to. Here is still more understanding, comparative image, Good O (∩_∩) o~

Any data stored in the pointer variable p will be treated as an address.

We can simply understand that a basic data type (including custom types such as structs) and a "*" number form a pointer-type mold. The size of the mold is certain, regardless of the data type in front of the "*" number. The data type in front of the "*" is simply a description of the data type stored in the memory pointed to by the pointer. So, under 32-bit systems, regardless of the type of pointer, it is 4byte in size. You can test sizeof (void *).

Second, "*" and the key of the security door

How do you understand this "*" number here? For example: When you go back to your doorstep, the first thing you want to do is get the key and unlock it. Do you think the lock core of the security door is much like this "*" number? You have to use the key when you enter the house, do you want to read and write a piece of memory and a key? Is the "*" Number our best key? With pointers, you can't read or write a chunk of memory without it.

three, int *p = null and *P = NULL What is the difference?

Many beginners are unable to distinguish between the two. Let's start by looking at the following code:

int *p = NULL;

At this time we can view the value of p to 0x00000000 through the compiler. This code means: Define a pointer variable p, which is pointing to the memory that holds the data of type int, and the value of P is set to 0x00000000 while defining the variable p, instead of setting the value of *p to 0x00000000. This process is called initialization and is done at compile time.

Understand what is initialized, and then look at the following code??

int *p;

*p = NULL;

Again, we can debug both lines of code on the compiler. The first line of code, defines a pointer variable p, which is pointing to the memory that holds the int type of data, but at this time the value of the variable p itself is not known, that is, the variable p is now stored may be an illegal address. The second line of code, assigning a value of NULL to *P, is null for the memory to which P points, but because the memory that P points to may be illegal, the compiler may report a memory access error when debugging. In this case, we can rewrite the above code to make P point to a piece of legitimate memory

int i = 10;

int *p = &i;

*p = NULL;

Debugging on the compiler, we find that the memory that P points to is changed from 10 to 0, and the value of P itself, the memory address, does not change.

Through the above analysis, I believe you have understood the difference between them. But here's one more question to note, which is the null. Beginners tend to make mistakes here.

Note that null is NULL, which is defined by the macro as 0:

#define NULL 0

There are many systems with the exception of NULL and NUL (the Visual C + + 6.0 suggests that you do not know nul). NUL is the first character of the ASCII code table, which represents a null character with an ASCII value of 0. Although the value is 0, the meaning of the expression is completely different. Similarly, the meaning of NULL and 0 is completely different. Be sure not to confuse.

There are also beginners who mistakenly write null or NULL when using NULL, and so on. These are not correct, C language is very sensitive to the case. Of course, there is also a system that also defines NULL, meaning it is not different from NULL, but you do not have to use NULL, which can affect the portability of your code.

Iv. how to store values in a specified memory address

Suppose you now need to put an integer number 0x100 into the memory 0x12ff7c address. How can we do that? We know that it is possible to write data through a pointer to the memory address to which it is pointing, so the memory address here 0x12ff7c its essence is not a pointer. So we can use the following method:

int *p = (int *) 0x12ff7c;

*p = 0x100;

It is important to note that the assignment of the address 0x12ff7c to the pointer variable p must be cast.

*p = 0x100;

It is important to note that the assignment of the address 0x12ff7c to the pointer variable p must be cast. As for why the memory address here 0x12ff7c, instead of choosing a different address, such as 0xff00. This is just for convenience

Visualc++ 6.0 on the test. If you choose 0xff00, perhaps in executing *p = 0x100; This statement, the compiler will report a memory access error because the memory at address 0xff00 you may not have the power to access. In that case, how do we know that a memory address can be legitimately accessed? So how do you know that the memory at address 0x12ff7c can be accessed? In fact, this is very simple, we can first define a variable i

Like what:

int i = 0;

The memory of the variable i is definitely accessible. Then look at the value of &i on the Watch window of the compiler do not know its memory address? Here I get the address is 0x12ff7c, that's all (the different compilers may assign the variable I memory address differently each time, just as the Visual C + + 6.0 each time). You can assign a value to any address that can be legitimately accessed. Get this address and then put "int i = 0;" This code is removed. All the "evidence" was destroyed completely, and it was done flawlessly.

Is there any other way besides this? Not necessarily. We can even write this code directly:

* (int *) 0x12ff7c = 0x100;

This line of code is actually different from the two lines above. The address 0x12ff7c is cast first, telling the compiler that the address will store an int type of data, and then write a data to the memory through the key "*".

The above discussed so much, in fact, the expression of the form is not important, it is important that the way of thinking. That means we have a way of writing data to a specified memory address.

A pointer is a special variable, and the value stored in it is interpreted as an address in memory. To make sense of a pointer, you need to be aware of the four aspects of the pointer: the type of pointer, the type that the pointer points to, the value of the pointer, the memory area that the pointer points to, and the memory area occupied by the pointer itself. Let's explain separately.

Let's declare a few pointers for example:

Example one:

(1) Int*ptr;

(2) Char*ptr;

(3) Int**ptr;

(4) int (*PTR) [3];

(5) int* (*PTR) [4];

Type of pointer

From a grammatical point of view, you simply remove the pointer name from the pointer declaration statement, and the remainder is the type of the pointer. This is the type that the pointer itself has. Let's look at the types of pointers in example one:

(1) The type of int*ptr;//pointer is int*

(2) The type of char*ptr;//pointer is char*

(3) The type of int**ptr;//pointer is int**

(4) int (*ptr) [3];//pointer is of type int (*) [3]

(5) int* (*ptr) [4];//pointer type is int* (*) [4]

What do you think? Is it easy to find out the type of pointers?

The type that the pointer points to

When you use a pointer to access the memory area pointed to by the pointer, the type that the pointer points to determines what the compiler will look for in that memory area. Syntactically, you only have to remove the pointer name and the pointer to the left of the name in the pointer declaration, and all that remains is the type that the pointer points to. For example:

(1) The type that the int*ptr;//pointer points to is int

(2) The type that the char*ptr;//pointer points to is Char

(3) The type that the int**ptr;//pointer points to is int*

(4) int (*ptr) [3];//pointer to a type that is int () [3]

(5) int* (*ptr) [4];//pointer to the type is int* () [4]

In the arithmetic operation of a pointer, the type that the pointer points to has a great effect.

The type of the pointer (that is, the type of the pointer itself) and the type that the pointer points to are two concepts. As you become more familiar with C, you will find that the concept of "type", which is mixed with pointers, is divided into "types of pointers" and "types pointed to by pointers", which is one of the key points of mastery of pointers. I read a lot of books, found that some poorly written books, the pointer to the two concepts stirred together, so look at the contradiction between the book, the more confused look.

The value of the pointer, or the memory area or address that the pointer points to

The value of the pointer is the value stored by the pointer itself, which is treated as an address by the compiler, not a generic value. In a 32-bit program, the value of all types of pointers is a 32-bit integer because the memory address in the 32-bit program is all 32 bits long. The memory area that the pointer points to is the memory address from which the value of the pointer is represented, and the length of the memory area of the SI zeof (the type to which the pointer is pointing). Later, we say that the value of a pointer is XX, which is equivalent to saying that the pointer to an XX-led address of a piece of memory area; we say that a pointer points to a region of memory, which is equivalent to saying that the value of the pointer is the first address of the memory area.

The memory area that the pointer points to and the type that the pointer points to are two completely different concepts. In example one, the pointer points to a type that already exists, but because the pointer is not initialized, the memory area it points to is nonexistent, or meaningless.

Later, every time you encounter a pointer, you should ask: What is the type of this pointer? What type is the pointer pointing to? Where does the pointer point?

The memory area occupied by the pointer itself

How much memory does the pointer itself occupy? You just have to use the function sizeof (the type of the pointer) to find out. In a 32-bit platform, the pointer itself occupies a length of 4 bytes.

The concept of memory occupied by the pointer itself is useful when judging whether a pointer expression is an lvalue.

Arithmetic operations of pointers

The pointer can add or subtract an integer. The meaning of this operation of the pointer is not the same as that of the usual numerical subtraction operation. For example:

Example two:

1, Char a[20];

2, int *ptr=a;

3, PTR + +;

In the example above, the type of the pointer ptr is int*, and the type it points to is int, which is initialized to point to the shaping variable A. In the 3rd sentence, the pointer ptr is added 1, which is handled by the compiler: it adds the value of the pointer ptr to sizeof (int), and in the 32-bit program, it is added 4. Since the address is in bytes, the address pointed to by PTR is incremented by 4 bytes from the address of the original variable A to the high address direction. Since the length of the char type is one byte, the original ptr is the four bytes starting at Unit No. 0 of array A, pointing to the four bytes from array a starting at unit 4th.

We can use a pointer and a loop to iterate through an array, looking at an example:

Example three:

int array[20];

int *ptr=array;

for (i=0;i<20;i++)
{
(*ptr) + +;
PTR + +;
}

This example adds 1 to the value of each cell in an integer array. Because each loop has a pointer ptr plus 1, each loop has access to the next cell of the array.
Look again at the example:

Example four:

1, Char a[20];

2, int *ptr=a;

3, PTR +=5;

In this example, PTR is added with 5, and the compiler handles this by adding the value of the pointer ptr to 5 by sizeof (int), which adds 5 times 4=20 to the 32-bit program. Because the unit of the address is byte, the current PTR points to an address that is 20 bytes to the high address direction than the address pointed to by PTR after 5. In this example, PTR, which is not added to 5, points to the four bytes starting at Unit No. 0 of array A, plus 5, and PTR points to the legal range of array A. Although this situation may be problematic in application, it is syntactically possible. This also shows the flexibility of the pointer.

If PTR is subtracted by 5 in the example above, then the process is much the same, except that the value of PTR is subtracted by 5 by sizeof (int), and the new PTR points to an address that moves 20 bytes to the lower address direction than the address pointed to by the original PTR.

Summing up, after a pointer ptrold plus an integer n, the result is a new pointer ptrnew,ptrnew of the same type as the Ptrold, and the same type that ptrnew points to and the type that ptrold points to. The value of ptrnew will increase by N by sizeof (the type that the Ptrold points to) by more than the value of Ptrold. That is, the memory area pointed to by Ptrnew will move n by sizeof (the type that the Ptrold points to) bytes than the memory area pointed to by Ptrold to the high address direction. After a pointer ptrold minus an integer n, the result is a new pointer ptrnew,ptrnew of the same type as the Ptrold, and the same type that ptrnew points to and the type that ptrold points to. The value of ptrnew will be less than the value of Ptrold by sizeof (the type that the Ptrold points to) bytes, that is, the memory area that the ptrnew points to will move n by sizeof (the type that the Ptrold points to) than the memory area pointed to by Ptrold A byte.

Operators & and *

Here & is the fetch address operator, * is ... The book is called the "indirect operator."

The result of the &a operation is a pointer, the type of the pointer is a type of a, a pointer to the type of a, the pointer to the address, that is the address of a.

The result of *p's operation is very multifarious. In short *p The result is what P points to, this thing has these characteristics: its type is the type of P, which occupies the address that P points to.

Example five:

int a=12;

int b;

int *p;

int **ptr;

p=&a;

The result of the &a is a pointer to the type int*, the type is int, and the address to a is the address of a.

*p=24;

*p the result, where its type is int, and it occupies the address that P points to, it is clear that *p is the variable A.

ptr=&p;

The result of the &p is a pointer, the type of the pointer is the type of P plus a *, here is the int * *. The type that the pointer points to is the type of P, which is int*. The address that the pointer points to is the pointer P's own address.

*ptr=&b;

*ptr is a pointer, and the result of &b is also a pointer, and the two pointers are of the same type as the type they are pointing to, so assigning a value to *ptr with &b is no problem.

**ptr=34;
The result of the *ptr is what PTR points to, and here is a pointer to do another * operation on the pointer, and the result is a variable of type int.

Pointer expression

The final result of an expression if it is a pointer, then the expression is called a pointer-table. Here are some examples of pointer expressions:
Example VI:

int A, B;

int array[10];

int *pa;

Pa=&a;//&a is a pointer expression.

int **PTR=&PA;//&PA is also a pointer expression.

Both *ptr=&b;//*ptr and &b are pointer expressions.

Pa=array;

pa++;//This is also an expression of pointers.


Copyright NOTICE: Welcome reprint, Hope in your reprint at the same time, add the original address, thank you with

C (10)

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.