## 字符指针
字符指针初始化以及使用和之前提到的差不多,规则含义也相同
#include<stdio.h>
int main()
{
char ch = 'a';
char* p1 = &ch;
printf("%c\n", *p1);
char* str = "abcdef";
printf("%s\n", str);
printf("%c\n", *str);
return 0;
}
# 从含有abcdef的那一行代码看起,我们发现,一个字符指针可以存放一个字符串,在这里解释如下:首先可以把它想成一个字符数组,str存放的是首元素的地址(&a),而bcdef的地址依次升高,又因为数组的地址是连续存放的,所以当打印%s时后面用str就表示从str这个地址开始,往后打印这个地址之后代表的内容,所以要用%s格式化打印;同时要注意的是“abcdef”是常量字符串,不能被修改;而之后的代码打印*str,str是首元素的地址,解引用那么就是打印 'a' 了。
## 二维数组传参
在碰到二维数组的时候,常常可以把二维数组看作一维数组来思考处理,这样去想,现在这个二维数组我把它看成一维数组,那么原来二维数组里面的一个个一维数组就看成我们假象的一维数组里面一个个int型或是什么型的简单类型的元素,如此思考可以解决很多问题。
//形参写成数组
#include <stdio.h>
void test(int a[3][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 ", a[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;
}
//形参写成数组指针
#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;
}
这两种形参的写法最终的效果都相同,二维数组传参的本质是传的一维数组的地址。数组形式的就不必多说;关键是数组指针形式的,我们把二维数组看成一维数组的时候,那么二维数组里面的元素类型就是假象的一维数组里面的元素的类型,然而一维数组的类型用指针去接收时,我们把一维数组当成简单元素般的整体,它的类型就是数组指针,就如同用指针接收int型的实参的地址,形参就要用int*,这里接收一维数组的地址就要用数组指针。
# 二维指针虽然我们说的时几行几列,但实际上它在内存里面存储方式和一维数组一样,都是依次连续存放的(一排,而不是几行几列)
## 函数指针
什么是函数指针,依据前面的指针类型可以归纳:函数指针就是一个指向函数地址的指针,可以用这个函数指针变量来存放函数的地址。
对于函数来说,函数名就是函数地址,&函数名也可以表示函数的地址
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;//x和y写上或者省略都是可以的
解释:首先得是一个指针,()的结合性比*高,想要它是一个指针就要用括号把*和指针名先括起来;至于函数指针最前面的类型,表示的是这个函数指针指向的那个函数的返回类型,后面的一些形参是指向函数的形参,形参名称可以省略,类型不能省略,这些都是和指向的那个函数一一对应的;
# 函数指针的使用
#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;
}
在这里使用函数指针的时候 ,用*pf3和pf3都是可以的,*pr3好理解,就是解引用;但是对于pf3可以这样想,假设你不使用函数指针调用函数,就直接用调用函数,那你使用的时候是不是这样的:add(2,3),而又因为add是函数名,可以代表函数的地址,而当你使用函数指针pf3的时候,pf3不就是add这个函数的地址吗,这样想pf3是不是和add在使用的时候一样呢?
## 函数指针数组
函数指针数组就是一个存放函数指针的数组,使用函数指针数组,我们可以用数组的形式来简单化的调用多个函数
# 初始化:int (*p[3]) (int ,int)={p1,p2,p3};
解释:p先和[3]结合,确保它是数组;这个数组里面的元素是函数地址,调用的时候就写成p[1](x,y),代表调用p1这个函数,其他的部分按照之前的函数指针解释去看;去掉名称就是类型(都是这个规律),那么函数指针数组类型写法就是 int (*[3]) (int ,int)
示例展现帮助理解函数指针数组
#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 input = 0;
int (*p[5])(int, int) = { 0,add,sub,mul,div };
do
{
printf("输入选择数:");
scanf("%d", &input);
int x = 0, y = 0;
printf("输入两个操作数:");
scanf("%d%d", &x, &y);
if (input >= 1 && input <= 4)
{
printf("%d\n", p[input](x, y));
}
else if (input == 0)
printf("退出\n");
else
printf("输入错误,重新输入选择数:");
} while (input);
return 0;
}