C language errata---pointer

This article mainly introduces the errors that are easy to occur in the use of pointers

table of Contents

This article mainly introduces the errors that are easy to occur in the use of pointers

1. Character pointer (constant string is assigned to pointer)

2. The use of pointer arrays (array of pointers)

3. Array pointer (pointer to array)

4. Function pointer

5. Function pointer array

6. Callback function

7. Passing parameters


Understand nouns:

A hexadecimal address occupies one byte

p[0] = *(p+0)

char *p (character pointer) - int *p (integer pointer) - int p[10] (integer array) 

int *p [10] (Pointer array: there are 10 elements in the array, and each element type is int *)

int (*p)[10] (Array pointer: *p is a pointer, pointing to an array, there are 10 elements in the array, and each element type is int) 

int *p() (pointer function)

int (*p)(int,int) (function pointer)

int(*p[10])(int) (function pointer array)

int (*p[10])[5] (an array, there are 10 elements in the array, each element type is an array pointer, the array pointer points to 5 elements, each element type is int) For this type of data , First find the subject---number------take it out-----the remaining int (*p)[5]-----array pointer

void *: can accept any type of address, can not dereference, can not perform ++-- and other operations, if you want to dereference, you need to perform a coercion (such as * (int *) p)

1. Character pointer (constant string is assigned to pointer)

(1) First look at the following code

#include<stdio.h>
int main(int argv,char *argc[])
{
	
	char *p = "abcdef";
	printf("%s\n",p);
	printf("%c\n",*p);

	*p = 'A';

    return 0;
}

Output result

The above results show that the pointer stores the first address of the string element, not the entire string (the pointer occupies 4/8 bytes in a 32-bit/64 system)

                        Why is there a segfault? That's because "abcdef" is a constant string and cannot be changed

(2) Look at the following code again

#include<stdio.h>
int main(int argv,char *argc[])
{
	char arr1[] = "abcdef";
	char arr2[] = "abcdef";
	char *p = "abcdef";
	char *n = "abcdef";

	if(arr1 == arr2){
		printf("arr1 == arr2\n");
	}
	else{
		printf("arr1 != arr2\n");
	}
	if(p == n){
		printf("p == n\n");
	}
	else{
		printf("p != n\n");
	}

    return 0;
}

Output result

The above results show that the string assigned by the pointer is a constant string. In our operating system, in order to save memory, the constant string will only be saved once. That is, the pointer p and the pointer n both point to a (the first address of the string element)

                         The string array can be opened multiple times.

2. The use of pointer arrays (array of pointers)

int * arr [10] (according to priority, arr is first combined with [10], arr[10] stores int*)

#include<stdio.h>
int main(int argv,char *argc[])
{
	char arr1[] = {1,2,3,4};
	char arr2[] = {5,6,7,8};
	char arr3[] = {9,10,11,12};

	char *p[3] = {arr1,arr2,arr3};

	for(int i = 0;i < 3;i ++)
	{
		for(int j = 0;j < 4;j ++)
		{
			printf("%d",*(p[i]+j));
		}
		printf("\n");
	}
//	printf("%d\n",*(p[0]+1));

    return 0;
}

3. Array pointer (pointer to array)

int (* arr) [10] (according to the priority, arr is first combined with *, and the pointer *arr points to int [10])

Assume a one-bit array int arr[10]

Then int *p = arr; then arr[i] == p[i] == *(p+i) == *(arr+i) 

Assuming a two-dimensional array int arr[3][5]

Then int arr[3][5] = int (*p)[5] then ----> arr[i][j] == p[i][j] == *(*(p+i) + j) == *(p[i] + j)

4. Function pointer

Compare array pointers to understand function pointers

int (*p)(int a,int b)

int add(int a,int b)
{
    return a+b;
}
int main()
{
    int a = 10;
    int b =20;
    
                                //数组指针int (*p)[10]
    int (*p)(int,int) = add;    //函数指针 指针p指向add,*p相当于调用
    printf("sum = %d\n",(*p)(2,3));
    printf("sum = %d\n",p(2,3));  //*没有实际意义
}

1) Look at the following code segment (* (void (*) ()) 0) (); equivalent to a function call

(*(xxx)xxx)() means call

2)

signal is a function declaration

The return type of the function is a function pointer , the function pointer points to the parameter int, and the return type is void

The first parameter of the function is , the type of the second parameter is a function pointer , the function pointer points to int, and the return type is void

Note: Rename function pointers with typedef

void (*signal(int, void(*)(int)))(int);

typedef void (*function)(int);
function signal(int,function);

5. Function pointer array

The pointer array is used to store pointers, and the function pointer array is used to store function pointers. There is a difference between the two

Function pointer array representation: void(*p[4])(int,int) / void(*p[4])()........

initialization 

//void(*p[4])(int,int);
void SUM(int,int)
{}
void SUB(int,int)
{}
void MUL(int,int)
{}
void DIV(int,int)
{}

int main(int,int)
{
    void(*p[4])(int,int) = {SUM,SUB,MUL,DIV};
}

Example of use:

                    1.char *(*pf)(char *,const char *)

                    2.char *(*pf[4])(char *,const char *)

Used for scenarios where the calculator adds, subtracts, multiplies, and divides the same parameters and different functions ( transfer table )

6. Callback function

  A callback function is a function called through a function pointer. If you pass a function pointer (address) as a parameter to another function, when this pointer is used to call the function pointed to, we say that this is a callback function. The callback function is not called directly by the implementer of the function, but is called by another party when a specific event or condition occurs, and is used to respond to the event or condition. ( Not calling this function directly-indirectly )

 
#include <stdio.h>
//回调函数
int ADD(int (*callback)(int,int), int a, int b){
	return (*callback)(a,b);//此处回调add函数...
}
//普通函数
int add(int a, int b){
	return a + b;
}
 
int main(void){
	printf("%d\n",add(1,2));
	printf("%d\n",ADD(add,1,2));
	return 0;
}

7. Passing parameters

Two-dimensional array parameter transfer ----- If the array name of a two-dimensional array represents the first element, it is the first row of the array

void test(int arr[5][10])
{}
void test1(int arr[][10])
{}
void test3(int arr[5][])  //error
{}
void test4(int arr[][])  //error
{}
void test5(int **arr)  //error  二级指针用来存放一级指针的变量的地址,arr对于二维数组来说就是第一行数组的地址,数组的地址不能存放在二级指针里边
{}
void test6(int (*arr)[10])//指向数组的指针,可以用来存贮一位数组
{}
int main()
{
    int arr[5][10] = {0};
    test(arr);
    test1(arr);
    test6(arr);
}

Second-level pointer transfer

void test(char **p)
{
    printf("%c\n",**p);
}

int main()
{
    char a = 'b';
    char *p = &a;
    char **pp = &p;
    char *buff[32] = {p};
    test(pp); //用二级指针传参
    test(&p); //用一级指针的地址传参
    test(buff);//用指针数组传参
}

Function pointer passing parameters (pointer to function, used to store the address of the function)

int add(int a,int b)
{
    return a+b;
}
int main()
{
    int a = 10;
    int b =20;
    
                                //数组指针int (*p)[10]
    int (*p)(int,int) = add;    //函数指针 指针p指向add,*p相当于调用
    printf("sum = %d\n",(*p)(2,3));
    printf("sum = %d\n",(p)(2,3)); //*其实没有实际意义
}

 

 

Guess you like

Origin blog.csdn.net/qq_45604814/article/details/112844269