[C language] Pointer basics (detailed knowledge combing)

Article directory

foreword

The pointer problem in C language learning, its knowledge points are difficult, complicated but very important. Xiao Zhao will describe the pointer knowledge separately. This article is a detailed description of the basic knowledge of pointers. There will be updates to advanced knowledge in the future. Please pay more attention to the children~


提示:以下是本篇文章正文内容,下面案例可供参考,欢迎家人们批评指正!

1. What is a pointer

Two key points for pointer understanding:

         1. The 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

We can use & (address operator) to take out the actual address of the variable's memory, 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变量占用4个字节的空间,这里是将a的4个字节的第一个字节的地址存放在p变量中,p就是一个之指针变量。

    return 0;
}

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.

On a 64-bit machine, there are 64 address lines, and the size of that pointer variable is 8 bytes to store an address.

 Summary: Pointer variables are used to store addresses, and addresses uniquely identify a memory unit.

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

2. Pointers and pointer types

Variables have different types, integer, floating point, etc. Of course pointers also have types. 

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

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.

The pointer of type int* is used to store the address of variable of type int.

The meaning of the pointer type:

1. Pointer + - integer

Code example:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
	int n = 10;
	char* pc = (char*)&n;//强制类型转换,将整型指针转换为字符型指针
	int* pi = &n;

	printf("%p\n", &n);

	printf("%p\n", pc);
	printf("%p\n", pc + 1);

	printf("%p\n", pi);
	printf("%p\n", pi + 1);
	return 0;
}

operation result:

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

for example:

int* pointer + 1, meaning to skip an integer, that is, go backward 4 bytes

char* pointer + 1, which means to skip a character type, that is, go backward 1 byte

short* pointer + 1, meaning to skip a short integer, that is, go backward 2 bytes

double* pointer + 1, which means to skip a double, that is, go back 8 bytes

2. Dereference of pointers

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

For example: char* pointer dereference can only access 1 byte

            The dereference of the pointer of int* can access 4 bytes

            The dereference of the double* pointer can access 8 bytes

Three, wild pointer 

The wild pointer is the position pointed by the pointer is unknown (random, incorrect, not clearly limited)

1. 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;
}

3) The space pointed to by the pointer is released

2. How to avoid wild pointers 

1) Pointer initialization

2) Beware of pointer out of bounds

3) The pointer points to the space to release, and set NULL in time

#include <stdio.h>
int main()
{
    int *p = NULL;
    //....
    int a = 10;
    p = &a;
    if(p != NULL)
   {
        *p = 20;
   }
    return 0;
}

4) Avoid returning the address of a local variable

5) Check the validity of the pointer before using it

4. Pointer arithmetic

1. Pointer + - integer

Example one:

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

	return 0;
}

Example two:

#include<stdio.h>
int main()
{
	int arr[10] = { 0 };
	int* p = arr; 
	//数组名就是首元素的地址arr->&arr[0]
	int i = 0;

	for (i = 0; i < 10; i++)
	{
		*(p + i) = i + 1;
	}
	/*for (i = 0; i < 10; i++)
	{
		*p = i + 1;
		p++;
	}*/

	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	//1~10
	return 0;
}

2. Pointer-Pointer

Example one:

int my_strlen(char* str)
{
	char* start = str;
	while (*str)
		str++;
	return str - start;  //指针-指针
}

int main()
{
	char arr[] = "abcdef";
	//int len = strlen(arr);
	int len = my_strlen(arr);    //函数调用结果与strlen()结果一样
	printf("%d\n", len);
	return 0;
}

Example two:

int main()
{
	//两个指针相减的前提是:指针指向同一块连续的空间
	int arr[10] = { 0 };
	printf("%d\n", &arr[9] - &arr[0]);
	printf("%d\n", &arr[0] - &arr[9]);

	int a = 10;
	char c = 'w';
	printf("%d\n", &a - &c);
	return 0;
}

Note: The premise of subtracting two pointers is that the pointers point to the same continuous space.

3. Relational operations on pointers

int main()
{
	float arr[5] = { 1,2,3,4,5 };
	float* p;
	int i = 0;
	for (p = &arr[4]; p >= &arr[0]; p--)
	{
	    *p = 0;
		printf("%lf ", *(p + i));
	}
	return 0;
}

standard regulation:

        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

(Arrays and pointers are not the same thing)

An array can store a group of elements, continuous space, and the size of the array depends on the number of elements.

The pointer is a variable that stores the address, 4/8 bytes.

connect:

        Array names are addresses (pointers)

        After the address of the first element of the array is given to a pointer variable, the array can be accessed through the pointer.

#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;
}

Example:

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

6. Secondary pointer

A pointer variable is also a variable, and a variable has an address, so where is the address of the pointer variable stored?

The operations on secondary pointers are:

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

int b = 20;
*ppa = &b;  //等价于 pa = &b;

        **ppa first finds pa through *ppa, and then dereferences pa: *pa, then finds a 

**ppa = 30;
//等价于*pa = 30;
//等价于a = 30;

Seven, pointer array

Is an array of pointers a pointer or an array?

An array of pointers is an array, an array of pointers.

int arr1[5];  //整型数组
char arr2[6]; //字符数组
int* arr3[5]; //整型指针数组

Example:

int main()
{
	int a = 10;
	int b = 20;
	int c = 30;
	int d = 40;
	int e = 50;
	int* arr3[5] = { &a,&b,&c,&d,&e }; //存放整型指针的数组
	int i = 0;
	for (i = 0; i < 5; i++)
	{
		printf("%d ", *(arr3[i]));
	}
	return 0;
}


at last

 Happy time is always short. The above is what I want to talk about today. This article introduces Xiao Zhao's preliminary understanding of the basic knowledge of pointers and use cases in detail. Family members are welcome to criticize and correct. Comrade Xiao Zhao continues to update, the motivation for continuous learning is the support of Baozi with one button and three consecutive links~

          

Guess you like

Origin blog.csdn.net/weixin_70411664/article/details/128835475