一、字符指针变量
1、指针变量指向字符
字符指针是把字符的地址给一个字符指针变量
字符指针变量是char*的类型
#include<stdio.h>
int main()
{
char ch = 'w';
char* p = &ch;
printf("%c\n", *p);
return 0;
}
通过地址的解引用就能打印对应的值
2、指针变量指向字符串
当一个字符指针指向字符串时,本质指针变量存放的还是字符串的第一元素的地址。
#include<stdio.h>
int main()
{
char ch[] = "abcdefg";
char* p = &ch;
printf("%c\n", *p);
return 0;
}
二、数组指针变量
1、数组指针变量是什么?
指针数组它是一个存放指针的数组
数组指针它是一个指向数组的指针
本质上指针数组是一个数组
而数组指针是一个指针
#include<stdio.h>
int main()
{
int a[5] = { 1,2,3,4,5 };
int* p1[5] = { &a[0],&a[1],&a[2],&a[3],&a[4] };
int(*p2)[5] = &a;
return 0;
}
上面代码中:
int * p1[5] 是一个指针数组,数组有五个元素,每个元素都是int*类型的指针
int(*p2)[5]是一个数组指针,这个指针变量p2的类型是int (*)[5]的指针
数组指针的类型是跟其他指针的类型有很大区别的。
2、二维数组传参的本质
在二维数组传参时,形参可以写成数组的形式,但本质上形参的类型是数组指针。
#include<stdio.h>
void test(int(*p)[5])
{
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 5; j++)
{
printf("%d ", *(*(p + i) + j));
}
printf("\n");
}
}
int main()
{
int a[3][5] = { {1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7} };
test(a);
return 0;
}
在二维数组中传过去的是首元素地址,传过去的是一个一维数组每个数组的元素个数为五。形参接收时用数组指针接收。
三、函数指针
C语言中函数也有对应的地址,是地址就可以用指针变量来指向这个函数,得到地址就可以通过指针来调用函数。
#include<stdio.h>
int Add(int x, int y)
{
return x + y;
}
int main()
{
int a = 20;
int b = 10;
int ret=Add(a, b);
printf("%d\n", ret);
return 0;
}
这是一个求两数相加的函数Add
在调用时用函数名加()里面传参就能完成
函数名就是函数的地址,Add和&Add都是地址没有区别。
#include<stdio.h>
int Add(int x, int y)
{
return x + y;
}
int main()
{
int a = 20;
int b = 10;
int (*p)(int, int) = Add;
int ret = p(a, b);
printf("%d\n", ret);
return 0;
}
把函数用指针来存放,需要确定函数的类型,*p表示的是指针,指针指向的参数(int,int),返回类型int,就是把p去掉,就是函数的类型,Add函数的类型为int (*)(int,int),p是一个变量名可以任意取名
在用指针调用时,使用方式跟函数一样,p变量可以不加解引用操作符,加上也不影响,这是应为Add跟&Add是一样的效果
四、函数指针数组
当我们学会函数数指针的创建和使用时
需要存放多个函数指针使可以创建一个数组
#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;
}
int main()
{
int a = 20;
int b = 10;
int (*p[4])(int, int) = { Add,Sub,Mul,Div };
for (int i = 0; i < 4; i++)
{
printf("%d\n", (*(p + i))(a, b));
}
return 0;
}
上面通过函数指针数组完成了四种函数的调用,分别为加减乘除