[C Language] Detailed Explanation of Elementary Pointers

Table of contents

1. What is a pointer?

1. Pointer variable 

2. Pointer size

2. Pointer type

Three, wild pointer

4. Pointer arithmetic

1. Pointer + - integer

2. Pointer-Pointer 

3. Relational operations on pointers

5. Pointers and arrays

6. Secondary pointer

Seven, pointer array


1. What is a pointer?

  • A pointer is the number of the smallest unit in memory, that is, the address
  • Usually verbal pointers usually refer to pointer variables (variables used to store memory addresses)

When it comes to pointers, we also need to understand memory. Memory is a particularly important memory on a computer. Programs in a computer are all run in memory. Therefore, in order to use memory effectively, the memory is divided into small memory units, and the size of each memory unit is 1 byte.

In order to be able to effectively access each unit of the memory, the memory units are numbered, and these numbers are called the address of the memory unit.

 

Variables are created in memory (space is allocated in memory), and each memory unit has an address, so variables also have addresses. 

1. Pointer variable 

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

#include<stdio.h>
int main() 
{
	int a = 10;
	int* p = &a;//&a拿到a的地址
	//注意a占用4个字节,这里只是将a的第一个字节的地址放到p变量中
	//p 是一个指针变量
	return 0;
}

A pointer variable is a variable used to store an address. (The value stored in the pointer is treated as an address)

2. Pointer size

The pointer is used to store the address, and the address is the only one that identifies an address space

The pointer size is 4 bytes on 32-bit platforms and 8 bytes on 64-bit platforms

Here is a brief introduction to the address line

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) 

00000000 00000000 00000000 00000000

00000000 00000000 00000000 00000001

...

11111111 11111111 11111111 11111111

2 ^ 32 (2 to the 32nd power bit to GB is 4GB, that is, a space as large as 4G can be addressed)

On a 32-bit machine, the address is a binary sequence composed of 32 0s or 1s, and the address must be stored in 4 bytes, so the
size of a pointer variable should be 4 bytes.
Then if on a 64-bit machine, if there are 64 address lines, the size of a pointer variable is 8 bytes to store an address

2. Pointer type

We know that defining a variable has many types such as int, float and so on. Of course pointers also have types

char  *pc = NULL;
int  *pi = NULL;
short *ps = NULL;
long  *pl = NULL;
float *pf = NULL;
double *pd = NULL;

 type *

The pointer of char* type is used to store the address of char type variable.
The short* type pointer is used to store the address of the short type variable.
A pointer of type int* is used to store the address of a variable of type int

The meaning of the pointer type The pointer type determines how many bytes are accessed when the dereference operation is performed

pointer + - integer

The type of the pointer determines how far the pointer takes one step forward or backward (distance)

pointer dereferencing

The type of the pointer determines how much authority you have when dereferencing the pointer (how many bytes can be manipulated)

 The pointer dereference of char* can only access one byte, while the dereference of the pointer of int* can access four bytes

The code below is debugged to get the first three lines of code executed 

 In one line of execution we get

Here you can see the difference between dereferencing different permissions

Three, wild pointer

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

Causes of wild pointers

1. The pointer is not initialized

#include<stdio.h>
int main() 
{
	int* p;//因为局部变量指针未初始化,默认为随机值,不知道指针指向哪里
	*p = 20;
	return 0;
}

2. Pointer out-of-bounds access

#include <stdio.h>
int main()
{
  int arr[10] = {0};
  int *p = arr;
  int i = 0;
  for(i=0; i<=11; i++)
 {
    //当指针指向的范围超出数组arr的范围时,p就是野指针
    *(p++) = i;
 }
  return 0;
}

*(p++) first dereferences in ++, can be changed to *p = i; p++;

Here, the pointer is accessed out of bounds, and you cannot access the space that does not belong to you.

3. Release the space pointed to by the pointer

So how do we avoid wild pointers ?

  • pointer to initialize
  • Careful pointer out of bounds
  • The pointer points to the space freed and set to NULL
  • Avoid returning the address of a local variable
  • Check the validity of the pointer before using it
//检查有效性
#include <stdio.h>
int main()
{
	int arr[10] = { 0 };
	int* p = arr;
	int i = 0;
	for (i = 0; i <= 11; i++)
	{
		//当指针指向的范围超出数组arr的范围时,p就是野指针
		*(p++) = i;
	}
	return 0;
}

4. Pointer arithmetic

1. Pointer + - integer

#include<stdio.h>
int main() 
{
	int i = 0;
	int arr[10] = {1,2,3,4,5,6,7,8,9,10};
	int* p = arr;
	for (i = 0; i < 10;i++)
	{
		printf("%d ",*p+i);
	}
	return 0;
}

2. Pointer-Pointer 

Pointer - The absolute value of the pointer is the number of elements between the pointer and the pointer (provided that they point to the same area and the pointers are of the same type)

Here is an analog strlen() to illustrate

#include<stdio.h>
int my_strlen(char * str) 
{
	char* a = str;
	while (*a != '\0')
		a++;

	return a - str;
}
int main()
{
	char* p = "abcdef";
	int ret = my_strlen(p);
	printf("%d\n",ret);
	return 0;
}

 【result】

return a - str ; //return the number of elements between (that is, the number of characters) 

3. Relational operations on pointers

Note: A pointer to an array element is allowed to be compared with a pointer to a memory location after the last element of the array, but not with a pointer to a memory location before the first element.

5. Pointers and arrays

#include <stdio.h>
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,0 };
	printf("%p\n", arr);
	printf("%p\n", &arr[0]);
	return 0;
}

We found that the array name and the address of the first element of the array are the same

here again we will say

The array name generally represents the address of the first element of the array

Special case sizeof(arr), &arr means the whole array

Then store the array name as an address in a pointer

#include <stdio.h>
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,0 };
	int*p = arr; //指针存放数组首元素的地址
	int sz = sizeof(arr) / sizeof(arr[0]);
	for (int i= 0; i < sz; i++)
	{
		printf("&arr[%d] = %p  <====> p+%d = %p\n",i,&arr[i],i,p + i);
	}
	return 0;
}

Results of the

 Found the same, so p+i actually calculates the address of the subscript i of the array arr

int main()
{
	int arr[] = { 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;
	//arr-->p
	//arr == p
	//arr+i  ==  p+i
	//*(arr+i) == *(p+i) == arr[i]
	//*(arr+i) == arr[i]
	//*(i+arr) == i[arr]
	//3+5
	//5+3
	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;
}

6. Secondary pointer

We have already learned that the pointer variable stores the variable of the address, and the pointer variable is also a variable, so where to put the address of the pointer variable?

Secondary pointers to store pointer variables

 

*ppa dereferences the address in ppa, so that it finds pa, *ppa actually visits pa 

//**ppa 先通过 *ppa 找到 pa ,然后对 pa 进行解引用操作: *pa ,那找到的是 a
int b = 20;
*ppa = &b;//等价于 pa = &b;
**ppa = 30;
//等价于*pa = 30;
//等价于a = 30;

Seven, pointer array

An array of pointers is an array    , a number that stores pointers

int*arr[5];

array of integer pointers 

Guess you like

Origin blog.csdn.net/qq_72505850/article/details/132189124