一、字符指针变量
我们知道一种字符指针类型是 char*。
int main()
{
char p = 'w';
char* pa = &p;
*pa = 'w';
return 0;
}
还有另外一种
int main()
{
const char* pa = "hello";
printf("%s\n", pa);
return 0;
}
这个代码其实是把字符串“hello”的首地址放到了pa里。
二、 数组指针变量
2.1
在指针(二)中我们学习了指针数组,指针数组本质上是一个数组,存放的是指针。今天我们学习数组指针。
之前我们学习过整型指针变量int*pa,存放的是整型变量的地址,指向整型数据的指针。我们用类比法,数组指针变量存放的是数组的地址,指向数组数据的指针。
int(*p)[10];
(*p)说明p是一个指针变量,然后指向存放十个元素的整型数组。
2.1 数组指针变量怎么初始化
如果要存放个数组的地址,就得存放在数组指针变量中
int(*p)[10]=&arr;
在这里,(*p)p是数组指针变量名,【10】是p指向的元素个数,int是指向的元素类型。
三、 ⼆维数组传参的本质
二维数组可以看做每个元素是一维数组的数组,那么二维数组的首元素就是第一行是一个一维数组。根据数组名是数组首元素的地址这一规则,那么二维数组的数组名就是表示的第一行的地址。根据上图第一行数组的类型就是arr[5],那么第一行地址的类型就是数组指针类型int*[5].那就意味着⼆维数组传参本质上也是传递了地址,传递的是第⼀⾏这个⼀维数组的地址。
#include <stdio.h>
void test(int (*p)[5], int r, int c)
{
int i = 0;
int j = 0;
for(i=0; i<r; i++)
{
for(j=0; j<c; j++)
{
printf("%d ", *(*(p+i)+j));
}
printf("\n");
}
}
int main()
{
int arr[3][5] = {{1,2,3,4,5}, {2,3,4,5,6},{3,4,5,6,7}};
test(arr, 3, 5);
return 0;
}
⼆维数组传参,形参的部分可以写成数组,也可以写成指针形式。
四、 函数指针变量
函数指针变量的写法和数组指针变量的写法相类似。
void test()
{
printf("hehe\n");
}
void (*pf1)() = &test;
void (*pf2)()= test;
int Add(int x, int y)
{
return x+y;
}
int(*pf3)(int, int) = Add;
int(*pf3)(int x, int y) = &Add;
int (*pa) (int x,int y)
(*pa)是函数指针变量名 ,(int x,int y)是pa指向函数的函数类型和个数交代,int是pa指向函数的返回值。
#include <stdio.h>
int Add(int x, int y)
{
return x+y;
}
int main()
{
int(*pf3)(int, int) = Add;
}
printf("%d\n", (*pf3)(2, 3));
printf("%d\n", pf3(3, 5));
return 0;
上面这个代码是通过函数指针调用指针指向的函数。
typedef关键字
typedef 是⽤来类型重命名的,可以将复杂的类型,简单化。
⽐如,你觉得 unsigned int 写起来不⽅便,如果能写成 uint 就⽅便多了,那么我们可以使⽤:
typedef unsigned int uint;
//将unsigned int 重命名为uint
五、 函数指针数组
数组是⼀个存放相同类型数据的存储空间,我们已经学习了指针数组,那要把函数的地址存放到一个数组中,那这个数组就叫函数指针数组。
int(*parr[3])();
parr先和 [] 结合,说明parr是数组,数组的内容是什么呢? 是 i nt (*)() 类型的函数指针。
六、 转移表
一般计算器的实现
int add(int a, int b)
{
return a + b;
}
int sub(int a, int b)
{
return a - b;
}
int mul(int a, int b)
{
return a * b;
}
int div(int a, int b)
{
return a / b;
}
void menu()
{
printf("******************************\n");
printf("********1.add 2.sub******\n");
printf("********3.mut 4.div******\n");
printf("******** 0.exit ******\n");
printf("******************************\n");
printf("******************************\n");
}
int main()
{
int input = 0;
int x = 0;
int y = 0;
int ret = 0;
do
{
menu();
printf("请选择");
scanf("%d", &input);
switch (input)
{
case 1:
printf("请输入操作数");
scanf("%d %d", &x, &y);
ret =add(x, y);
printf("%d\n", ret);
break;
case 2:
printf("请输入操作数");
scanf("%d %d", &x, &y);
ret = sub(x, y);
printf("%d\n", ret);
break;
case 3:
printf("请输入操作数");
scanf("%d %d", &x, &y);
ret = mul(x, y);
printf("%d\n", ret);
break;
case 4:
printf("请输入操作数");
scanf("%d %d", &x, &y);
ret = div(x, y);
printf("%d\n", ret);
break;
case 0:
printf("退出程序\n");
break;
default:
printf("选择错误\n");
break;
}
} while (input);
return 0;
}
函数指针数组实现
#include <stdio.h>
int add(int a, int b)
{
return a + b;
}
int sub(int a, int b)
{
return a - b;
}
int mul(int a, int b)
{
return a*b;
}
int div(int a, int b)
{
return a / b;
}
int main()
{
int x, y;
int input = 1;
int ret = 0;
int(*p[5])(int x, int y) = { 0, add, sub, mul, div };
do
{
printf("*************************\n");
printf(" 1:add 2:sub \n");
printf(" 3:mul 4:div \n");
printf(" 0:exit \n");
printf("*************************\n");
printf( "请选择:" );
scanf("%d", &input);
if ((input <= 4 && input >= 1))
{
printf( "输⼊操作数:" );
scanf( "%d %d", &x, &y);
ret = (*p[input])(x, y);
printf( "ret = %d\n", ret);
}
else if(input == 0)
{
printf("退出计算器\n");
}
else
{
printf( "输⼊有误\n" );
}
}while (input);
return 0;
}