首页>>c语言 >> 数组指针,指针数组,函数指针、传参、指针

数组指针,指针数组,函数指针、传参、指针

时间:2023-10-21 19:01:24 网络整理 点击:329

目录

前言

主要内容:数组指针,指针数组,函数指针、传参

一、指针

1、指针就是地址,而我们通常口头上说的指针其实是指针变量

2、指针大小:4/8(32位/64位计算机)个字节

3、指针的类型决定指针+-整数的步长,影响解引用后的结果

4、void *p 是无具体类型的指针,可以接收任意类型地址,不能解引用,也不能+-数

二、指针、数组 1、字符指针

意义:存放字符地址的指针变量

char*p = "abcdef";

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

p存放字符串的首元素地址

2、结构体指针

意义:存放结构体地址的指针变量

3、指针数组

意义:存放地址(指针)的数组

例如:

int arr1[] = {1,2,3,4}

int arr2[] = {3,4,5,6}

int arr3[] = {5,6,7,8}

int* parr[3] = {arr1,arr2,arr3} //因为指针就是地址,所以存放的是首地址

p先和[]结合,所以本质是数组,类型是int* 所以是指针,所以它是一个指针数组

4、数组指针

意义:存放数组地址的指针(指向数组的指针)

arr1[] = {1,2,3,4}

1、char (*p)[4] = &arr1 //&arr1表示整个数组,还有sizeof(数组名)在主函数中也是计算整个数组大小

p先和*结合,所以本质是一个指针,然后[3]表面他是数组,char是类型,所以它是一个存放char类型数组的数组指针

一个数组指针只能指向一个数组,且(*p)[4],[]内的数和arr1数组的个数相同

2、数组指针 存放 指针数组:

char* arr[4] = {2,3,4,5}

char* (*pc)[4] = &arr

3、数组指针数组 存放 (多个)数组:

char (*pc[10])[4] = {&arr1, &arr2, &arr3} //第一个[]表示数组指针的个数(即可以存放10个数组),第二个[]表示存放进来的数组元素个数

pc先和[]结合,本质是数组,然后只看(* )[4],它是一个数组指针,所以结果是一个数组指针数组,存放多个数组。

数组指针应用:

5、数组参数、指针参数 5.1、一维数组传参

整形数组传参:

int arr[10] = {0}

test(arr)

void test(int arr[])

void test(int arr[10])

void test(int* arr)

指针数组传参:

int* arr2[20] = {0}

test2(arr2)

void test2(int *arr2[20])

void test2(int** arr2) //arr2有20个int*,所以可以二级指针

注:二级指针是专门用来存放一级指针变量地址的指针

5.2、二维数组传参

整形二维数组

int arr[3][5]

test(arr)

void test(int arr[3][5])

void test(int arr[][5])

void test(int* arr) //不能这样写,对二维数组来说,arr数组名是第一行的地址,而不是第一行第一个元素的地址

void test(int* arr[5])不能这样写,它是指针数组,本质是一个数组,和arr为第一行地址不匹配,如:int arr[3] = {1,2,3} ,arr2[] = {3,4,5,6} int *arr[2] = {arr,arr2}

void test(int (*arr)[5]) //它是一个数组指针,和arr第一行地址相匹配

如:int a[5] = {1,2,3,4,5} int (*pa)[5] = &a

5.3、一级指针传参

void test(int* p)

int a=10;

int *ptr=&a;

int arr[10] = {0}

调用可为:

test(&a) 或 test(ptr)

test(arr)

5.4、二级指针传参

void test1(int** p)

int* p

int** pp

int* arr[2] //存放两个数组的首地址

调用可为:

test1(&p)或test1(pp)

test(arr)

三、函数、指针、数组 1、函数指针

意义:指向函数的指针

&函数名 或者 函数名:表示函数的地址

int Add(int x, int y)

int (*pf)(int, int) = &Add: (*pf)表示它是一个指针,(int, int)是它的参数类型

1.1、函数指针调用

1.2、复杂例子

一、(*(void(* )())0)()

1、把0强转为:void (* ) ()的函数指针类型,得到函数的地址

2、用*解引用得到该函数

3、调用该函数

二、void (* signal (int, void(*)(int)))(int)

1、声明的signal函数两个参数分别为int, 和函数指针

2、第二个参数函数指针的参数是int型,返回类型是void

3、singal函数返回的也是一个函数指针

1.3、函数指针的应用

模拟实现加法器,函数指针起到归纳连接相同功能函数的作用

#define _CRT_SECURE_NO_WARNINGS
#include
//函数指针的应用
//连接加法器中的相同功能的函数
void menu()
{
	printf("************************\n");
	printf("***** 1.Add  2.Sub *****\n");
	printf("***** 3.Mul  4.Div *****\n");
	printf("******** 0.exit ********\n");
	printf("************************\n");
}
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 cal(int (*p)(int,int))  //函数指针作参
{
	int x = 0;
	int y = 0;
	printf("请输入两个数:>\n");
	scanf("%d %d", &x, &y);
	int ret = (*p)(x, y);
	printf("%d\n", ret);
}
int main()
{
	int input = 0;
	do
	{
		menu();
		scanf("%d", &input);
		
		//输入两个数不能放switch外面,逻辑上讲不通
		switch (input)
		{
		case 1:
			cal(Add);  //传函数地址
			break;
		case 2:
			cal(Sub);
			break;
		case 3:
			cal(Mul);
			break;
		case 4:
			cal(Div);
			break;
		case 0:
			printf("退出计算器\n");
			break;
		default:
			printf("输入错误,请重新输入\n");
		}
	} while (input);
}

2、函数指针数组

意义:存放函数指针的数组

int (*pf)(int, int) = Add; // 这是函数指针

int (*arr[4])(int,int) = {Add,Sub,Mul,Div} //[4]表示存放的函数有四个

应用:可以将一系列函数保存在一个函数指针数组里,比起指针数组更有利于后期代码的维护(进阶二)

3、指向函数指针数组的指针

int (*pfarr[5])(int, int) = {0, Add, Sub, Mul, Div}

函数数组指针 存放 函数指针数组:

int(*(*pfarr)[5])(int, int) = &pfarr

qsort函数的使用 以及 实现优化冒泡排序(整数字符串结构体等均可排序)看进阶2

总结

函数、指针、数组三者的关系比较复杂,需要自己下来慢慢练习领会,后期还会加上结构体,链表。

《数组指针,指针数组,函数指针、传参、指针》
将本文的Word文档下载到电脑,方便收藏和打印
推荐度:
下载文档

文档为doc格式