A brief talk about pointers (1)

Table of Contents of Series Articles

Article directory


Preface

Purpose: Quickly understand the basics of pointers

One memory unit is one byte, one byte is 8 bits

How to understand addressing

Today we are concerned about a group of lines called the address bus.
We can simply understand that a 32-bit machine has 32 address buses.
Each line has only two states, indicating 0,1 [electrical pulse presence or absence] , then
one line can represent 2 meanings, 2 lines can represent 4
meanings, and so on. 32 address lines can represent 2^32 meanings, and each meaning represents an address. The address information is sent to the memory. In the memory, the data corresponding to the address can be found, and the data is transferred through the data bus. CPU internal register.



1. Relationship between memory and pointers

Memory unit number == address == pointer

Insert image description here

2. Pointer variables and addresses

2.1 Operator (&)-address operator

So how can we get the address of a?

#include <stdio.h>
int main()
{
    
    
 	int a = 10;
 	//&a取出a的地址
 	printf("%p\n", &a);//%p是用来打印地址的
 return 0;
}

Insert image description here

2.2 Pointer variable dereference operator (*)

#include <stdio.h>
int main()
{
    
    
 	int a = 10;
  	int* pa = &a;//取出a的地址并存储到指针变量pa中
  	return 0;
 }

*p is the value in the pointer variable, *p is a specific value (the content of the pointer variable), p is the pointer variable used to store the address

Changing the value of a variable is done as follows:

	int a = 10;
	int* p = &a
	*p = 20;/

Equivalent to
Insert image description here

3. Size of pointer variable

Assume that a 32-bit machine has 32 address buses. The electrical signal from each address line is converted into a digital signal and is 1 or 0. Then we regard the binary sequence generated by the 32 address lines as an address, then an The address is 32 bits and requires 4 bytes to store.

Similar to the 64-bit machine, assuming there are 64 address lines, an address is a binary sequence composed of 64 binary digits. To store it,
8 In the byte space, the size of the pointer is 8 bytes.
Output result in X86 environment:
Insert image description here
Output result in x64 environment:
Insert image description here

Conclusion:
• The address on the 32-bit platform is 32 bits, and the pointer variable size is 4 bytes.
• The 64-bit platform The lower address is 64 bits, and the pointer variable size is 8 bytes
• Note that the size and type of the pointer variable are irrelevant, as long as the pointer type variable is on the same platform , the sizes are the same, so the size of *p can be compared, but the pointer variable p cannot be compared

4. The meaning of pointer variable type

Insert image description here
Insert image description here
We can see from debugging that code 1 will change all 4 bytes of n to 0, but code 2 only changes the first byte of n to 0.
Conclusion: The type of the pointer determines how much authority you have when dereferencing the pointer (how many bytes can be operated at a time).
For example: dereferencing the pointer of char* can only access one byte, while dereferencing the pointer of int* can access four bytes.

5.const modified pointer

• If const is placed on the left side of *, it modifies the content pointed by the pointer, ensuring that the content pointed by the pointer cannot be changed through the pointer. But the content of the pointer variable itself is variable.

• If const is placed on the right side of *, it modifies the pointer variable itself, ensuring that the content of the pointer variable cannot be modified, but the content pointed to by the pointer can be changed through the pointer.

Case:

include <stdio.h>
int main()
{
    
    
 	int m = 0;
 	m = 20;//m是可以修改的
 	const int n = 0;
 	n = 20;//n是不能被修改的
 return 0;
}

In the above code, n cannot be modified. In fact, n is essentially a variable. However, after being modified by const, there are grammatical restrictions. As long as we modify n in the code, it will not comply with the grammatical rules and an error will be reported. As a result, n cannot be modified directly.

But if we bypass n and use the address of n, we can do it by modifying n, although doing so is breaking the grammatical rules, such as:

#include <stdio.h>
int main()
{
    
    
 	const int n = 0;
 	printf("n = %d\n", n);
 	int*p = &n;
 	*p = 20;
 	printf("n = %d\n", n);
 	return 0;
}

Output result:
Insert image description here

6. Wild pointer

Concept: A wild pointer means that the position pointed by the pointer is unknown (random, incorrect, and without clear restrictions)

Cause:
1. The pointer is not initialized: the local variable pointer is not initialized and defaults to a random value, occupying the memory of other variables.
2. Pointer out-of-bounds access: When the range pointed by the pointer exceeds the range of the array arr, p is a wild pointer.
3. The space pointed to by the pointer is released: destroyed after the creation function is used.

How to avoid wild pointers:
1. Pointer initialization: If you don’t know where the pointer should point, you can assign NULL to the pointer. For example:

int*p2 = NULL;

2. Be careful about pointer out-of-bounds: which spaces have been applied for in the memory sequentially, and which spaces can only be accessed through pointers
3. When the pointer variable is no longer used, set it in time NULL, the pointer is checked for validity before use.
4. Avoid returning the address of local variables

7. Pointer arithmetic

There are three basic operations on pointers, namely:
• Pointer±integer
• Pointer-pointer
• Relational operations on pointers

7.1 Pointer ± Integer
Because the array is stored continuously in the memory, as long as you know the address of the first element, you can find all the following elements by following the clues.
Case:

#include <stdio.h>
//指针+- 整数
int main()
{
    
    
 	int arr[10] = {
    
    1,2,3,4,5,6,7,8,9,10};
 	int *p = &arr[0];
 	int i = 0;
 	int sz = sizeof(arr)/sizeof(arr[0]);
 	for(i=0; i<sz; i++){
    
    
 		printf("%d ", *(p+i));//p+i 这⾥就是指针+整数
 	}
 return 0;
}

7.2 Pointers - pointers

//指针-指针
#include <stdio.h>
int my_strlen(char *s)
{
    
    
 	char *p = s;
 	while(*p != '\0' )
 	p++;
 	return p-s;
}
int main()
{
    
    
 	printf("%d\n", my_strlen("abc"));
 	return 0;
}

Pointer - a pointer represents the number of elements between two pointers in an array

7.3 Relational operations on pointers

//指针的关系运算
#include <stdio.h>
int main()
{
    
    
 	int arr[10] = {
    
    1,2,3,4,5,6,7,8,9,10};
 	int *p = &arr[0];
 	int i = 0;
 	int sz = sizeof(arr)/sizeof(arr[0]);
 	while(p<arr+sz) //指针的⼤⼩⽐较
 	{
    
    
 		printf("%d ", *p);
 		p++;
 	}
 return 0;
}

Next time we will learn more about it.
If you have seen it here, please give it a like, thank you all.

Guess you like

Origin blog.csdn.net/chendemingxxx/article/details/134495896