C语言学习 指针(3)

2023.08.20

字符指针

使用字符指针变量指向一个字符串常量,通过字符指针变量引用字符串常量。

int main()
{
	char string[] = "I love China!";//定义一个字符数组
	char* ch = &string;
	int sz = sizeof(string) / sizeof(string[0]);
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%c", *(string + i));
	}	
	return 0;
}

注意:字符指针变量只能指向一个字符类型数据,而不是指向多个字符类型数据,更不是把整个字符串都赋给 *string,而是把首个字符的地址赋给字符指针变量。

数组指针

顾名思义,数组指针就是指针变量,是存放数组的地址的指针,指向的变量为数组。

指针的命名格式为: 类型名 * 指针变量名

数组指针当然也按照这个格式: 类型名 (*指针变量名)[常量表达式]

例如:int (*p) [10]  p先和*结合,说明p是一个指针变量,然后指着的是一个数组大小为10的整型数组。([ ]的优先级是要高于*的,加上( )才能保证p先和*结合成指针变量p)

数组指针变量的初始化

数组首元素的地址:数组名 或 &数组名[0]

数组的地址:&数组名

则数组指针变量初始化:  int (*p) [10]=&arr 

二维数组的地址

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

arr 是二维数组数组名,代表二维数组首元素的地址,这里的首元素不是一个整型元素,而由五个整型元素组成的一维数组,所以arr 代表的是首行(即a[0])的起始地址(同理,arr[1]代表的是第二行的起始地址)。

arr[0],arr[1],arr[2] 是一维数组名,代表一维数组中首元素的地址,即第0列元素的地址(即为&a[0][0])。

函数指针

在调用函数时,会从它的起始地址开始执行这段函数代码。函数名代表函数的起始地址,函数名就是函数的指针。

可以定义一个指向函数的指针变量,用来存放某一函数的起始地址,这个指针变量成为函数指针变量,可以指向该函数。

定义:类型名 (*指针变量名)(函数参数列表)

例如:int (*p) (int ,int )   定义一个指针变量,指向类型为整型(函数返回值的类型),有两个整型参数的函数。

函数指针的初始化:

① int (*p) (int ,int ) = &max;   //取函数max的地址赋给指针变量

② int (*p) (int ,int ) = max;     //函数名就是函数的地址,直接赋给指针变量也可以

*p 两边的括号必须加上,如果不加上则为int * p (int ,int ) = max; 即定义一个函数p,函数的返回值为指向整型变量的指针。

int Max(int x, int y)
{
	int z = 0;
	if (x > y) z = x;
	else z = y;
	return z;
}

int main()
{
	int a, b, c;
	int(*p)(int x, int y)=Max;//定义函数指针并初始化
    //p=Max 为将函数入口地址赋给p
    //p=Max(a,b) 为将函数返回值赋给p
	printf("Please enter a and b:");
	scanf("%d %d", &a, &b);
	c = (*p)(a, b);//等价于c=Max(a,b)
	printf("max is %d", c);
	return 0;
}

另外,对于指向函数的指针变量,进行加减运算时无意义的,p++,p--等都不能实现。运用函数指针可以先后指向不同的函数(必须是指针在定义时指定好的类型),先后调用不同的函数。

编写一个简单的四则运算法则计算器,用户输入两数,得到结果。

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

int calculate(int (*p)(int,int))//形参定义一个函数指针,接收函数名(地址)
{
	int a, b;
	int res = 0;
	printf("Please enter a and b:");
	scanf("%d %d", &a, &b);
	res = (*p)(a, b);//使用函数指针,调用对应的函数
	printf("The result is %d\n", res);
}

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 choice = 0;
	menu();
	do
	{
		printf("Please enter your choice:");
		scanf("%d", &choice);
		switch(choice)
		{
		case 1:calculate(Add); break;
		case 2:calculate(Sub); break;
		case 3:calculate(Mul); break;
		case 4:calculate(Div); break;
		case 0:printf("Ok,exit it right now.\n"); break;
		default:printf("Your choice is wrong!\n");
		}
	} while (choice);
	
	return 0;
}

使用函数指针,具有现实价值,制作一个菜单,根据输入的数字不同,调用的函数也不同(使用if语句实现),实现不同的功能(调用函数的不同),就不用在下次调用的时候修改调用函数,使得程序变得更加的简洁。

有两个整数a和b,输入1,2或者3。输入1程序求大数,输入2程序求小数,输入3程序执行求和。

void Max(int x, int y)
{
	int z = 0;
	if (x > y) z = x;
	else z = y;
	printf("Max=%d", z);
}

void Min(int x, int y)
{
	int z = 0;
	if (x > y) z = y;
	else z = x;
	printf("Min=%d", z);
}

void Add(int x, int y)
{
	printf("Add=%d", x + y);
}

int calculate(int(*p)(int, int),int x,int y)
{
	int temp = (*p)(x, y);
	return temp;
}

int main()
{
	int input=0;
	int a = 2;
	int b = 7;
	printf("输入操作:");
	scanf("%d", &input);
	switch (input)
	{
	case 1:calculate(Max,a,b); break;
	case 2:calculate(Min,a,b); break;
	case 3:calculate(Add,a,b); break;
	default:printf("选择错误。");
	}
	return 0;
}

由调用calculate函数将所需函数地址,a,b两数作为实参传递,在calculate函数中再次调用函数时,将形参a,b又作为实参传递给执行的函数。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值