C_指针_2

指针数组

指针数组,顾名思义是一个数组,是一个用来存放指针的数组,数组里可以是整形,浮点型,当然也可以是指针类型.

int *arr1[3];
char *arr2[3];
char **arr3[1][2];

数组指针

数组指针是一个指针,有能力指向一个数组

int (*p)arr[3];//p先和*结合,说明p是一个指针,指向一个大小为3的整形数组,[]的优先级要高于*,所以要加上()保证*先与p结合

我们先来看一段代码

int arr[3] = {0};
printf("%p\n", arr);
printf("%p\n", arr + 1);
printf("%p\n", &arr + 1);

这产生的结果是截然不同的,数组首元素的地址和数组的地址的值是相同的,但是意义是不同的,给arr+1,是加上一个元素的大小,给&arr+1,是加上整个数组的大小.

这样为了区分普通元素的地址与整个数组的地址,就需要数组指针来保存整个数组的地址.

int arr[3] = { 0 };
int (*pi)arr[3] = &arr;

数组和指针传参

一维数组传参

#include<stdio.h>
void test(int arr[])
{}
void test(int arr[10])
{}
void test(int *arr)
{}
void test2(int *arr[10])
{}
void test2(int **arr)
{}
int main()
{
    int arr[10] = {0};
    int *arr2[10] = {0};//指针数组
    test(arr);
    test2(arr2);
    return 0;
}

任何数组传参,都会降维成指向其内部元素的指针.

二维数组传参

void test(int arr[3][5])
{}
void test(int arr[][5])//二维或多维数组传参,第一个[]中的数字可以省略,其他数字绝对不能省略
{}
void test(int **arr)
{}
void test(int (*arr)[5])//数组指针
{}
int main()
{
    int arr[3][5] = {0};
    test(arr);
    return 0;
}

一级指针传参

#include<stdio.h>

void print(int *p, int sz)
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d\n", *(p + i));
	}
}

int main()
{
	int arr[10] = { 0,1,2,3,4,5,6,7,8,9 };
	int *p = arr;
	int sz = sizeof(arr) / sizeof(arr[0]);
	print(p, sz);
	system("pause");
	return 0;
}

当一个函数的参数部分为一级指针的时候,函数能接受一级指针和一维数组 

二级指针传参

#include<stdio.h>

void test(int **ptr)
{
	printf("num = %d\n", **ptr);
}

int main()
{
	int n = 20;
	int *p = &n;
	int **pp = &p;
	test(pp);
	test(&p);
	system("pause");
	return 0;
}

当函数的参数为二级指针时,可以接受二级指针和指针数组

函数指针

 在C程序中,所有变量都有地址,那么函数有没有地址呢

#include<stdio.h>
void test(int **ptr)
{
	printf("hehe\n");
}
int main()
{
	printf("%p\n", test);
	printf("%p\n", &test);
	system("pause");
	return 0;
}

 函数是有地址的,函数的地址想要保存起来,要怎么保存呢.首先要保存地址,那么就必须是一个指针,这就是函数指针

void (*pfun)();

 函数指针数组

数组是一个存放相同数据类型的存储空间,已经知道了指针数组.,那么要把函数的地址存放到一个数组中,那么这个数组就叫做函数指针数组

int (*part[10])()//part先和[]结合,说明prat是一个数组,数组里面存放着函数地址

函数指针数组的用途:转移表

#include<stdio.h>
int add(int x, int y)
{
	return x + y;
}
int sub(int x, int y)
{
	return x - y;
}
int mul(int x, int y)
{
	return x * y;
}
int div(int x, int y)
{
	return x / y;
}
void menu()
{
	printf("****************************\n");
	printf("***  1.add        2.sub  ***\n");
	printf("***  3.mul        4.div  ***\n");
	printf("***        0.exit        ***\n");
	printf("****************************\n");
}

int main()
{
	int input = 0;
	int ret = 0;
	int x, y;
	int(*p[4])(int x, int y) = { add, sub, mul, div };
	do
	{
		menu();
		printf("请选择功能->");
		scanf("%d", &input);
		if (input >= 1 && input <= 4)
		{
			printf("请输入操作数:");
			scanf("%d%d", &x, &y);
			ret = (*p[input - 1])(x, y);
			printf("结果是:%d\n", ret);
		}
		else if (input != 0)
		{
			printf("输入值error,请重新输入\n");
		}

	} while (input);
	
	system("pause");
	return 0;
}

指向函数指针数组的指针

指向函数指针数组的指针是一个指针,指针指向一个数组,数组的元素是函数指针

回调函数

回调函数就是一个通过函数指针调用的函数,如果把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数.回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应.

使用回调函数,模拟实现qsort

#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
int my_int_comp(const void *x, const void *y)
{
	if(*(int *)x > *(int *)y)
		return 1;
	else if(*(int *)x < *(int *)y)
		return -1;
	else
		return 0;
}
int my_char_comp(const void *x, const void *y)
{
	if(*(char *)x > *(char *)y)
		return 1;
	else if(*(char *)x < *(char *)y)
		return -1;
	else
		return 0;
}
void swap(char *dst, char *str,int size)
{
	while(size--)
	{
		*dst ^= *str;
		*str ^= *dst;
		*dst ^= *str;
		dst++,str++;
	}
}

void my_qsort(void *base, int x, int size, int (*my_comp)(const void *x, const void *y))
{
	int i = 0;
	assert(base);
	for(i = 0; i < x - 1; i++)
	{
		int j = 0;
		int flag = 0;
		for(; j< x - 1 - i; j++)
		{
			if(my_comp((char *)base + j*size, (char *)base + (j+1)*size) > 0)
			{
				flag = 1;
				swap((char *)base + j*size, (char *)base + (j+1)*size, size);
			}
		}
		if(flag == 0)
			break;
	}
}
int main()
{
	int i = 0;
	int arr[] = {1,2,85,6,56,59,1,4,9,659,4,6,93,29,5,32,59};
	char brr[] = "ansuxizhxasnjopmxioashubshasaa";
	int sz = sizeof(arr)/sizeof(arr[0]);
	int num = strlen(brr);
	my_qsort(arr, sz, sizeof( int ), my_int_comp);
	for(i = 0; i < sz; i++)
	{
		printf("%d ",arr[i]);
	}
	printf("\n");
	//my_qsort(brr, num, sizeof( char ), my_char_comp);
	//printf("%s\n", brr);
	return 0;
}

 

 

 

 

 

猜你喜欢

转载自blog.csdn.net/yikaozhudapao/article/details/81138018