C (10), C language keyword

Source: Internet
Author: User
Tags define null

C (10), C language keyword

I. Memory layout of pointers

Let's take a look at the following example:

Int * p;

We all know that a pointer p is defined here. But what exactly is p? Remember the first chapter that said, "Can we treat any data type as a model? P, there is no doubt that a model has been written out.

We have also discussed that any model must have a specific size so that it can be used as a "click ". So what exactly does this model of p look like? How much space does it occupy? Use sizeof to test (32-bit system): the value of sizeof (p) is 4. Well, this indicates that the size of the model p produced by compaction is 4 bytes. Obviously, this model is not an "int", although it is also 4. Since it is not "int", it must be "int. Okay, now we can

Understand this definition:

A "int *" model outputs 4 bytes in memory, and then name the space of the 4 bytes as p, at the same time, the space of these four bytes can only store a memory address. Even if you store any other data, it will be processed as an address, in addition, the memory address can only store data of an int type for four consecutive bytes.

This is a bit of text, we still use graphs to parse it:


As shown in, we call p a pointer variable, and the memory at the memory address stored in p is called the memory pointed to by p. Here, I 'd like to take a look at it. It's a good image ~

Any data stored in the pointer Variable p will be processed as an address.

We can simply understand this: A Basic data type (including struct and other custom types) plus the "*" number constitutes a pointer type model. The size of this model is certain and has nothing to do with the data type before. The data type before "*" only indicates the Data Type stored in the memory to which the Pointer Points. Therefore, in a 32-bit system, all pointer types are 4 bytes in size. You can test sizeof (void *).

2. "*" and anti-leech key

How can I understand this? For example, when you get home, the first thing you want to do is to take out the key to unlock the house. Do you think the lock core of the anti-theft door is like this? If you want to enter the house, you must use the key. Do you also need a key to read and write a piece of memory? Is this "*" the best key for us? Without a pointer, you cannot read or write a memory block.

Iii. What is the difference between int * p = NULL and * p = NULL?

Many beginners cannot tell the difference between the two. Let's take a look at the following code:

Int * p = NULL;

In this case, we can use the compiler to check that the value of p is 0x00000000. This Code defines a pointer Variable p, which points to the memory that stores int-type data; set the value of p to 0x00000000 while defining the Variable p, instead of setting the value of * p to 0x00000000. This process is called initialization and is carried out during compilation.

After understanding what Initialization is, let's look at the following code:

Int * p;

* P = NULL;

Similarly, we can debug these two lines of code on the compiler. The first line of code defines a pointer Variable p, which points to data of the int type stored in the memory. However, the value of the Variable p itself is unknown, that is to say, the variable p may be an Invalid Address. In the second line of code, assign a value to * p to NULL, that is, assign a value to the memory pointed to by p to NULL. However, because the memory pointed to by p may be invalid, therefore, the compiler may report a memory access error during debugging. In this way, we can rewrite the above Code so that p points to a valid memory.

Int I = 10;

Int * p = & I;

* P = NULL;

After debugging on the compiler, we found that the memory pointed to by p has changed from 10 to 0, while the value of p itself, that is, the memory address, has not changed.

After the above analysis, I believe you have understood the differences between them. However, there is another issue to note, that is, This NULL. Beginners often make mistakes here.

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

# Define NULL 0

In many systems, apart from NULL, there are also NUL (on Visual C ++ 6.0, it is suggested that you do not know NUL ). NUL is the first character in the ASCII code table and represents an empty character. Its ASCII value is 0. Although the value is 0, it means completely different meanings. Similarly, NULL and 0 indicate completely different meanings. Do not confuse.

In addition, beginners mistakenly write NULL or null when using Null. These are all incorrect. The C language is very case sensitive. Of course, the system also defines null, which means no difference from NULL, but you do not need to use null, which affects the portability of your code.

4. How to store values to the specified memory address

Assume that an integer of 0x100 needs to be saved to the memory 0x12ff7c address. How can we achieve this? We know that data can be written to the memory address directed to by a pointer, so the memory address 0x12ff7c here is essentially not a pointer. So we can use the following method:

Int * p = (int *) 0x12ff7c;

* P = 0x100;

Note that the address 0x12ff7c must be forcibly converted when being assigned to the pointer Variable p.

* P = 0x100;

Note that the address 0x12ff7c must be forcibly converted when being assigned to the pointer Variable p.The reason is that the memory address 0x12ff7c is selected instead of another address, such as 0xff00. This is only for convenience

Test on Visual C ++ 6.0. If you choose 0xff00, * p = 0x100 may be executed. When this statement is executed, the compiler reports a memory access error, you may not have the right to access the memory at address 0xff00. In this case, how do we know that a memory address can be accessed legally? That is to say, how do you know that the memory at address 0x12ff7c is accessible? In fact, this is very simple. We can first define a variable I

For example:

Int I = 0;

The memory where variable I is located must be accessible. Then, in the compiler's watch window, do you know the memory address if you observe the & I value? Here, I get the address 0x12ff7c. That's all. (different compilers may allocate different memory addresses to variable I each time, But Visual C ++ 6.0 is the same ). You can assign values to any address that can be legally accessed. After obtaining this address, delete the code "int I = 0. All "evidence of guilt" is completely destroyed, and it is simply done in a seamless manner.

Is there no other way except this? Not necessarily. We can even write code like this:

* (Int *) 0x12ff7c = 0x100;

This line of code is actually no essential difference from the above two lines of code. First, the address 0x12ff7c is forcibly converted, telling the compiler that this address will store an int type of data, and then write a data to this memory through the key.

As discussed above, the form of expression is not important. What is important is this way of thinking. That is to say, we have a way to write data to a specified memory address.

A pointer is a special variable. The value stored in it is interpreted as an address in the memory. To understand a pointer, we need to understand four aspects of the pointer: the pointer type, the pointer type, the pointer value, or the memory zone pointed by the pointer, there is also the memory zone occupied by the pointer itself. Let's explain it separately.

First, declare several pointers for example:

Example 1:

(1) int * ptr;

(2) char * ptr;

(3) int ** ptr;

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

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

Pointer type

From the syntax perspective, you only need to remove the pointer name in the pointer declaration statement, and the rest is the pointer type. This is the type of the pointer. Let's take a look at the type of each pointer in Example 1:

(1) int * ptr; // the pointer type is int *

(2) char * ptr; // the pointer type is char *

(3) int ** ptr; // the pointer type is int **

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

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

How is it? Is it easy to find the pointer type?

Type pointed to by pointer

When you access the memory area pointed to by the pointer, the type pointed to by the pointer determines what the compiler will regard the content in the memory area. In terms of syntax, you only need to remove the pointer name and the pointer declarative * on the left of the name in the pointer declaration statement, and the rest is the type pointed to by the pointer. For example:

(1) int * ptr; // The Pointer Points to an int type.

(2) char * ptr; // The Pointer Points to a char type.

(3) int ** ptr; // The type pointed to by the pointer is int *

(4) int (* ptr) [3]; // The type pointed to by the pointer is int () [3]

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

In pointer arithmetic operations, the type pointed to by the pointer has a great effect.

The pointer type (the pointer type) and the pointer type are two concepts. When you get familiar with C, you will find that, the concept of "type", which is mixed with pointers, is divided into two concepts: "pointer type" and "pointer type", which are one of the key points of mastering pointers. I have read a lot of books and found that some poorly written books bring together the two concepts of pointers. Therefore, the books seem to have conflicts and become more confused.

The pointer value, or the memory zone or address pointed to by the pointer.

The pointer value is the value stored by the pointer itself. This value will be treated as an address by the compiler rather than a general value. In a 32-bit program, the value of all types of pointers is a 32-bit integer, because the 32-bit program's memory address is all 32-bit long. The memory area pointed to by the pointer starts from the memory address represented by the pointer value, and the length is a memory area of si zeof (type pointed to by the pointer. Later, we will say that the value of a pointer is XX, which means that the pointer points to a memory area with XX as the first address. We will say that a pointer points to a memory area, it is equivalent to saying that the pointer value is the first address of the memory area.

The memory zone pointed to by the pointer and the type pointed to by the pointer are two completely different concepts. In example 1, the pointer points to a type that already exists, but since the pointer has not been initialized, the memory zone it points to does not exist, or it is meaningless.

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

Memory occupied by the pointer itself

How much memory does the pointer occupy? You just need to use the sizeof function (pointer type) to test it. On a 32-bit platform, the pointer occupies 4 bytes.

The memory occupied by pointers can be used to determine whether a pointer expression is left.

Arithmetic Operations on pointers

The pointer can be added or subtracted from an integer. The meaning of this operation of pointer is different from that of addition and subtraction of common values. For example:

Example 2:

1. char a [20];

2. int * ptr =;

3. ptr ++;

In the preceding example, the pointer ptr is of the int type * and it points to the int type. It is initialized to the integer variable. In the next 3rd sentences, the pointer ptr is added with 1, and the compiler processes it like this: it adds the value of the pointer ptr with sizeof (int), in a 32-bit program, is added with 4. Because the address is in bytes, the address pointed by ptr is increased by four bytes from the address of the original variable a to the high address. Because the length of the char type is one byte, the ptr originally points to the four bytes starting from Unit 0th of array, this point points to the four bytes starting from Unit 4th in array.

We can use a pointer and a loop to traverse an array. For example:

Example 3:

Int array [20];

Int * ptr = array;

For (I = 0; I <20; I ++)
{
(* Ptr) ++;
Ptr ++;
}

In this example, the value of each unit in the integer array is added to 1. Since every loop adds the pointer ptr to 1, each loop can access the next unit of the array.
Let's look at the example:

Example 4:

1. char a [20];

2. int * ptr =;

3. ptr + = 5;

In this example, ptr is added with 5, and the compiler processes it like this: add the value of the pointer ptr to the value of the 5-bysizeof (int ), in the 32-bit program, 5 is multiplied by 4 = 20. Because the address unit is byte, the current ptr points to the address, compared to the address pointed by the ptr after the addition of 5, move 20 bytes to the high address. In this example, if the ptr before 5 is not added, it points to the four bytes starting with unit 0th of array a. After 5 is added, the ptr points out of the valid range of array. Although this situation may cause problems in applications, it is possible in terms of syntax. This also reflects the flexibility of pointers.

If in the above example, ptr is subtracted from 5, the processing process is similar, except that the ptr value is subtracted from 5 by sizeof (int ), the new ptr points to an address that moves 20 bytes to the lower address direction than the original ptr.

To sum up, after a pointer ptrold is added with an integer n, the result is a new pointer ptrnew. The type of ptrnew is the same as that of ptrold, ptrnew points to the same type as ptrold. The value of ptrnew will be increased by n multiplied by sizeof (type pointed to by ptrold) bytes than the value of ptrold. That is to say, ptrnew will point to a memory area that moves n byte by sizeof (type pointed by ptrold) to the high address direction than the memory area pointed to by ptrold. After a pointer ptrold is subtracted from an integer n, the result is a new pointer ptrnew. The type of ptrnew is the same as that of ptrold, and the type of ptrnew is the same as that of ptrold. The value of ptrnew will be less than the value of ptrold by n multiplied by sizeof (type pointed to by ptrold) bytes, that is, the memory area to which ptrnew points will move n times of sizeof (type pointed by ptrold) bytes to the lower address direction than the memory area to which ptrold points.

Operators & and *

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

& The operation result of a is a pointer, And the pointer type is a plus *. The Pointer Points to the type, and the Pointer Points to the address, that is the address of.

* P's computation results are varied. In short, the result of * p is what p points to. It has these characteristics: its type is p-pointed, and its occupied address is the address pointed to by p.

Example 5:

Int a = 12;

Int B;

Int * p;

Int ** ptr;

P = &;

// The result of & a is a pointer, whose type is int *, which is int and.

* P = 24;

// * P result. Here, the type of p is int, and the address occupied by p is the address pointed to by p. Obviously, * p is variable.

Ptr = & p;

// The result of & p is a pointer. the pointer type is p type plus *. Here it is int **. The Pointer Points to the p type. Here it is int *. The Pointer Points to the address of p itself.

* Ptr = & B;

// * Ptr is a pointer, and the result of & B is also a pointer, and the types of the two pointers are the same as those pointed, therefore, it is no problem to assign a value to * ptr using & B.

** Ptr = 34;
// * The ptr result is what ptr points to. Here it is a pointer. Perform another operation on this pointer. The result is an int type variable.

Pointer expression

If the final result of an expression is a pointer, the expression is called a pointer table. Below are some examples of pointer expressions:
Example 6:

Int a, B;

Int array [10];

Int * pa;

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

Int ** ptr = & pa; // & pa is also a pointer expression.

* Ptr = & B; // * ptr and & B are pointer expressions.

Pa = array;

Pa ++; // This is also a pointer expression.


Copyright Disclaimer: you are welcome to reprint it. I hope you can add the original article address while reprinting it. Thank you for your cooperation.

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.