C language learning (8) pointer


The soul of C language, the most important link.

1. Pointer


1.1 What is a pointer

Fundamentally, a pointer is a variable (or data object) whose value is a memory address. Just as a variable of type char is a character, a variable of type int is an integer, and the value of a pointer variable is an address.

Simply put, a pointer is a variable, but it stores the address of the variable.

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

# include <stdio.h>

int main(void){
    
    

	// 声明一个变量
	int a = 10;	
	// 声明一个int类型的指针p,该指针存放的值为a变量在内存中的地址。
	int* p = &a;
	// 打印a变量的地址,也就是p的值。
	printf("%p", p);	// 结果为:000000000061FE14
	
	return 0;
}

In the above example, "%p" is the control character of the output pointer type variable, please refer to format input/output for details .

" * " is the dereference operator. & is an address character. You can read the operator article, which explains operators in detail.


1.2 Definition of pointer

The definition of the pointer has been seen in the above example. The structure is as follows:

数据类型 *指针变量名
// 定义一个char类型指针变量,char_p为指针变量名。等号后面为char_p的值。
char* char_p = &a;
// 定义一个int类型指针变量,int_p为指针变量名。等号后面为int_p的值。
int* int_p = &b;
// 定义一个short类型指针变量,short_p为指针变量名。等号后面为short_p的值。
short* short_p = &c;
// 定义一个float类型指针变量,float_p为指针变量名。等号后面为float_p的值。
float* float_p = &d;
// 定义一个double类型指针变量,double_p为指针变量名。等号后面为double_p的值。
double* double_p = &e;

1.3 Types of pointers

In 1.2, we declared pointer variables of type int, char, etc. Through the above example, we saw that pointers also have types, and the types of pointers are:

type *	// type指的是数据类型。例如 int,char等等

// 示例
int* p = &a;	// int*表示指针类型为int*,p为指针变量的名称。&a为指针变量的值。

The type of the pointer determines the size of the space that the pointer can access during the dereference operation (how many bytes can be manipulated). For example: char * pointer dereference can only access one byte, and int * pointer dereference can access 4 bytes.

# include <stdio.h>

int main(void){
    
    

int a = 10;
char* ch = &a;
int* p = &a;

// 打印a的地址
printf("%p\n", &a);	// 000000000061FE0C
// char类型的指针只能访问一个字节,当char类型的指针+1时,
// 只能后移一个字节,则ch+1的地址就是a的地址+1。0C+1 = 0D
printf("%p\n", ch+1);	// 000000000061FE0D
// int类型的指针只能访问4个字节,当int类型的指针+1时,
// 后移4个字节,则p+1的地址就是a的地址+4。0C+4 = 10 
printf("%p\n", p+1);	// 000000000061FE10
	return 0;
}

The size of a pointer variable is 4 bytes on a 32-bit machine and 8 bytes on a 64-bit machine .


Two, wild pointer

2.1 What is a wild pointer

The wild pointer is the address pointed to by the pointer is unknown (uncertain, random)


2.2 Why wild pointers are generated

1、指针未初始化。
2、指针数组越界。
3、指针指向的空间释放
# include <stdio.h>

int main(void){
    
    

	int *p;	// 指针未初始化,随机值
	*p = 10;

	return 0;
}
# include <stdio.h>

int main(void){
    
    

	int arr[5] = {
    
    0, 1, 2, 3, 4};

	int *p = arr;
	for (int i = 0; i < 6; i++)
	{
    
    
		// 当超出数组时,指针就是野指针
		*(p++) = i;
	}

	return 0;
}

2.3 How to avoid wild pointers

1、指针记得初始化。
2、不要使指针数组越界。
3、指针指向空间释放后置指针为NULL。
4、避免返回局部变量的地址。
5、指针使用前检查有效性。

3. Pointer arithmetic

3.1 Assignment

Assignment means that you can assign an address to a pointer. But note that the type of the address must be the same as that of the pointer, for example: you cannot assign an address of type char to a pointer of type int.

# include <stdio.h>

int main(void){
    
    

	// 定义一个char类型的变量
	char a = 10;
	// 定义一个char类型的指针并将char类型变量的地址赋值给char类型的指针
	char *p = &a;

	return 0;
}
// 将char类型的变量不能赋值给int类型的指针
int *tp = &a;

3.2 Dereference

The * operator gives a pointer to the value stored at the address. *p has a value of 10, which is stored at the address.


3.3 Pointer Integer Addition

You can add pointers with the + operator, or integers with pointers. In either case, the integer is multiplied by the size (in bytes) of the type pointed to by the pointer, and the result is added to the initial value. There are examples in Pointer Types 1.3.


3.4 Pointer minus an integer

An integer can be subtracted from a pointer using the - operator. A pointer must be the first operand, and an integer is the second operand. This integer will be multiplied by the size of the type pointed to by the pointer in bytes, and the product will be subtracted from the initial address.

If the result of the subtraction exceeds the range of the array pointed to by the initial pointer, the excess part is a wild pointer. C guarantees that the pointer is valid unless it is just beyond the first position past the end of the array.


3.5 Incrementing and decrementing pointers

Increment and decrement also work with pointers, incrementing a pointer to an array element moves that pointer to the next element of the array.

# include <stdio.h>

int main(void){
    
    

	int arr[5] = {
    
    0, 1, 2, 3, 4};

	int *p = arr;
	for (int i = 0; i < 5; i++)
	{
    
    
		// 通过指针的递增来遍历数组
		*(p++) = i;
	}

	return 0;
}

3.6 Pointer difference

The difference between two pointers can be calculated. Usually, the two pointers for difference point to different elements of the same array, and the distance between the two elements is calculated and divided. The units of the difference are the same as the units of the data type.

# include <stdio.h>

int main(void){
    
    

	int arr[]={
    
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
	
	// 取数组首元素的地址
	int *first = &arr[0];
	// 取数组尾元素的地址
	int *last = &arr[9];
	// 两个指针相减,为数组的长度
	int ret = *last - *first;
	printf("arr[0]为:%d\n", arr[0]);	// 结果为:0
	printf("arr[9]为:%d\n", arr[9]);	// 结果为:9
	printf("数组长度为:%d\n", ret);	// 结果为:9

	return 0;
}

3.7 Pointer Comparison

Use relational operators to compare the values ​​of two pointers, provided both pointers point to objects of the same type.

# include <stdio.h>

int main(void){
    
    

	int arr[]={
    
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

	int *first = &arr[0];
	int *last = &arr[9];
	// 两个相同类型的指针比较,因为last大于first,所以输出的结果为0
	int ret = *last < *first;

	printf("ret结果为:%d\n", ret);	// 结果为:0

	return 0;
}

Fourth, the secondary pointer

As mentioned earlier, a pointer variable is also a variable, a variable has an address, and the pointer that stores the address of the pointer variable is a secondary pointer

# include <stdio.h>

int main(void){
    
    

	// 定义int类型的变量
	int a = 10;
	// 定义int类型的指针变量并赋值为a的地址
	int *pta = &a; 
	// 定义一个二级指针变量指向*pta的地址
	int **ppta = &pta;

	return 0;
}

The address of a is stored in pta, the address of pta is stored in ppta, pta is a first-level pointer, and ppta is a second-level pointer.

# include <stdio.h>

int main(void){
    
    

	// 定义int类型的变量
	int a = 10;
	// 定义int类型的指针变量并赋值为a的地址
	int *pta = &a; 
	// 定义一个二级指针变量指向*pta的地址
	int **ppta = &pta;

	printf("a的地址为:%p\n", a);	// 000000000000000A
	printf("*pta的地址为:%p\n", *pta);	// *pta的地址为:000000000061FE14
	printf("**ppta的地址为:%p\n", **ppta); // **ppta的地址为:000000000061FE08
	return 0;
}

Five, the pointer array

The essence of an array of pointers is still an array. However, pointers are stored in the array

# include <stdio.h>

int main(void){
    
    

	// arr是一个数组,里面有6个元素,每个元素都是一个整型指针。其他类型的指针数组同理。
	int *arr[6];

	return 0;
}

Guess you like

Origin blog.csdn.net/qq_46292926/article/details/127568865