Elementary Pointer (Super Detailed Explanation)

1. What is a pointer

What are pointers?

Two key points for pointer understanding:

  1. A pointer is the number of the smallest unit in memory, that is, the address
  2. The pointer in the spoken language usually refers to the pointer variable, which is a variable used to store the memory address
    (unit number == address == in C language: pointer)

Then we can understand it like this:

memory :
insert image description here

Pointer variable
We can use & (address operator) to take out the actual address of the variable memory, and store the address in a variable, this
variable is a pointer variable

int main()
{
    
    
	int a = 10;//是向内存中的栈区空间申请4个字节的空间,这4个字节用来存放10这个数值
	int* pa = &a;//这里我们对变量a,取出它的地址,可以使用&操作符。
    //a变量占用4个字节的空间,这里是将a的4个字节的第一个字节的地址存放在p变量中,p就是一个之指针变量。
	//pa 0x000112233
	return 0;
}

Summarize:

A pointer variable is a variable used to store an address. (The value stored in the pointer is treated as an address).
The questions here are:
1. How big is a small unit? (1 byte)
2. How to address?
After careful calculation and weighing, we found that it is more appropriate to assign a byte to a corresponding address.
For a 32-bit machine, assuming that there are 32 address lines, then assuming that each address line generates a high level (high voltage) and a low level (low voltage) when addressing is (1 or 0); then
32 The address generated by the address line will then be:
insert image description here
insert image description here

  1. The memory is divided into memory units, and the size of each memory unit is 1 byte
  2. Each byte of memory unit has a number, this number is the address, and the address is the pointer in C language
  3. If the address is to be stored, place it in a pointer variable
  4. Each memory unit has a unique address to identify
  5. The size of the address on a 32-bit machine is 4 bytes, so the size of the pointer variable is also 4 bytes.
    Similarly: the size of the address on a 64-bit machine is 8 bytes, so the size of the pointer variable is also 8 bytes Festival

2. Pointers and pointer types

Let's look at the following code:

int main()
{
    
    
	printf("%d\n", sizeof(char*));
	printf("%d\n", sizeof(short*));
	printf("%d\n", sizeof(int*));
	printf("%d\n", sizeof(double*));
}

insert image description here
insert image description here

2.1 pointer ± integer

Code demo:

int main()
{
    
    
	int a = 0;
	int* pa = &a;
	char* pc = &a;
	printf("%d\n", pa);
	printf("%d\n", pa+1);
	printf("%d\n", pc);
	printf("%d\n", pc+1);
}

operation result:
insert image description here

The pointer type is meaningful.
The pointer type determines the pointer +1/-1 to skip the pointer of several bytes of
char +1 to skip the pointer of 1 byte
short
+1 to skip the pointer of 2 bytes of
int +1 jump Over 4 bytes of
double
pointer + 1 to skip 8 bytes

2.2 Dereferencing of pointers

insert image description here
insert image description here
The pointer type is meaningful.
The pointer type determines how many bytes are accessed when the pointer is dereferenced.
For example, the dereference of the pointer of char* can only access one byte, while the dereference of the pointer of int* can access four bytes.

3. Wild Pointer

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

3.1 Causes of wild pointers

  1. Pointer is not initialized
    Code demo:
int main()
{
    
    
	int* p;//未初始化
	*p = 20;
	return 0;
}
  1. Pointer access out of bounds
    Code demonstration:
int main()
{
    
    
	int arr[10] = {
    
     0 };
	int* p = arr;
	int i = 0;
	for (i = 0; i <= 10; i++)//指针访问越界
	{
    
    
	  //当指针指向的范围超出数组arr的范围时,p就是野指针
		*p = -1;
		p++;
	}
	return 0;
}
  1. The space pointed to by the pointer is released
    Code demonstration:
int* test()
{
    
    
	int a = 10;//0x0040fe44
	return &a;//地址已返回出函数销毁
}
int main()
{
    
    
	//0x0040fe44
	int* p = test();
	//p就是野指针
	printf("%d", p);
	return 0;
}

3.2 How to avoid wild pointers

  1. pointer initialization
    insert image description here

  2. Careful pointer out of bounds

  3. The pointer points to the space to release even if it is set to NULL

  4. Avoid returning the address of a local variable

  5. Check the validity of the pointer before using it

int main()
{
    
    
	int* p = NULL;
	*p = 20;//空指针不允许访问
	//....
	if (p != NULL)
	{
    
    
		//...确保非控指针在使用
	}
	return 0;
}

4. Pointer arithmetic

4.1 Pointer ± Integer

Code demo 1:

int main()
{
    
    
	int arr[10] = {
    
     1,2,3,4,5,6,7,8,9,10 };
	             // 0 1 2 3 4 5 6 7 8 9 
	//是指针打印数组内容
	int* p = arr;
	int i = 0;
	//p --> arr
	//p == arr
	//p+i == arr+i
	//*(p+i) == *(arr+i) == arr[i]
	//*(arr+i) == arr[i]
	//*(i+arr) ==i[arr]//[]仅为操作符
	for (i = 0; i < 10; i++)
	{
    
    
		printf("%d ", *(p + i));
		//printf("%d ", *(arr + i));
		//printf("%d ", arr[i]);
		//printf("%d ", i[arr]);
		//p指向的是数组首元素
		//p+i是数组下标为i的元素地址
		//p+i起始时跳过i*sizeof(int)个字节
	}
	return 0;
}

Running result:
insert image description here
code demo 2:

#define N_VALUES 5
int main()
{
    
    
	float values[N_VALUES];
	float* vp;
	for (vp = &values[0]; vp < &values[N_VALUES];)
	{
    
    
		*vp++ = 0;
	}
	return 0;
}

analyze:
insert image description here

4.2 Pointer-Pointer

Case 1:

int main()
{
    
    
	int arr[10] = {
    
     0 };
	//
	//指针-指针的前提:两个指针指向同一块区域,指针类型时相同的
	//指针-指针差值的绝对值,指针和指针之间的元素个数
	//
	printf("%d\n", &arr[9] - &arr[0]);
	printf("%d\n", &arr[0] - &arr[9]);
	return 0;
}

Shipping Results:
insert image description here
Case 2:

//模拟实现strlen
//1.计算器
//2.递归
size_t my_strlen(char* str)
{
    
    
	char* start = str;
	while (*str)
	{
    
    
		str++;
	}
	return str - start;
}
int main()
{
    
    
	char arr[] = "abcdef";
	size_t len = my_strlen(arr);
	printf("%zd\n", len);
	return 0;
}

Shipping result:
insert image description here

4.3 Relational operations on pointers

Code demo 1:

int main()
{
    
    
	float values[N_VALUES];
	float* vp;
	for (vp = &values[N_VALUES]; vp > &values[0];)
	{
    
    
		*--vp = 0;
	}
	return 0;
}

Analysis:
insert image description here
Code 2 (Code 1 is modified as follows):

#define N_VALUES 5
int main()
{
    
    
	float values[N_VALUES];
	float* vp;
	for (vp = &values[N_VALUES - 1]; vp >= &values[0]; vp--)
	{
    
    
		*vp = 0;
	}
	return 0;
}

analyze:
insert image description here

In fact, the task can be successfully completed on most compilers, but we should still avoid writing this way, because the standard does not guarantee that it will work.
The standard stipulates that
a pointer pointing to an array element is allowed to be compared with a pointer pointing to the memory location after the last element of the array, but it is not allowed to
compare with a pointer pointing to the memory location before the first element.

5. Pointers and arrays

  • A pointer is a pointer, a pointer variable is a variable, the address of the storage, the size of the pointer variable is 4/8
  • An array is an array, which can store a set of numbers. The size of the array depends on the type and number of elements
  • The array name of the array is the address of the first element
  • Array elements can be accessed through a pointer

The array name indicates the address of the first element of the array, with two exceptions

  • sizeof (array name), the array name is placed inside sizeof alone, the array name represents the entire array, the calculation is the size of the array, and the unit is byte
  • &Array name, the array name represents the entire array, the address of the array is taken out, the value of the address of the array is the same as the address of the first element of the array, but the type and meaning are different

Code case 1:

int main()
{
    
    
	int arr[10] = {
    
     0 };
	printf("%d\n", arr);
	printf("%d\n", arr+1);
	//
	printf("%d\n", &arr[0]);
	printf("%d\n", &arr[0]+1);
	//
	printf("%d\n", &arr);
	printf("%d\n", &arr+1);
	//
	printf("%d\n", sizeof(arr));
}

insert image description here
Code case two:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
    
    
	int arr[10] = {
    
     0 };
	int* p = arr;
	int i = 0;
	for (i = 0; i < 10; i++)
	{
    
    
		printf("%p===%p\n", p+i, arr+i);
	}
	return 0;
}

operation result:
insert image description here

6. Secondary pointer

A pointer variable is also a variable, and a variable has an address. Where is the address of the pointer variable stored?
This is the secondary pointer .
insert image description here
The secondary pointer variable is to store the address of the primary pointer variable

Code case 1:

int main()
{
    
    
	int a = 10;
	int* pa =  &a;//pa是指针变量,一级指针变量
	int* * ppa = &pa;//ppa指针变量,二级指针变量
	**ppa = 20;//*ppa得出pa-->**ppa==*pa==a
	printf("%d", a);
	return 0;
}

operation result:
insert image description here

  • *ppa dereferences the address in ppa, so that it finds pa, *ppa actually visits pa
  • **ppa first finds pa through *ppa, and then dereferences pa: *pa, then finds a.

Code case 2:

7. Array of pointers

Is an array of pointers a pointer or an array?

is an array. is an array of pointers.
Arrays We already know integer arrays, character arrays.
int arr1[5];
char arr2[5]
pointer array:
int* arr3[5];
insert image description here

Code example:

int main()
{
    
    
	int arr1[] = {
    
     1,2,3,4,5 };
	int arr2[] = {
    
     1,2,3,4,5 };
	int arr3[] = {
    
     1,2,3,4,5 };
	int* arr[] = {
    
     arr1,arr2,arr3 };
	int i = 0;
	for (i = 0; i < 3; i++)
	{
    
    
		int j = 0;
		for (j = 0; j < 5; j++)
		{
    
    
			printf("%d", arr[i][j]);
		}
		printf("\n");
	}
	return 0;
}

operation result:
insert image description here

Unconsciously, the pointer began to come to an end. You must have gained a lot from reading the full text, let us continue to forge ahead together for C language learning.

Guess you like

Origin blog.csdn.net/2201_75642960/article/details/132013473