C语言学习笔记——指针的进阶

1.数组指针

▶数组指针的定义

指向整个数组的指针

int arr1[10] = {1,2,3,4,5,6,7,8,9,10};  //每个元素的类型是int
int (*p)[10] = &arr1;  //数组指针,(*p)代表p是指针,p指向的类型是 int [10]

//arr2,arr3与arr1同样定义
int *d[3] = {arr1,arr2,arr3};  //指针数组,d[3]优先结合,代表是个数组,每个元素的类型是int*

int* (*pd)[3] = &d;  //数组指针,指向的类型是 int* [3]

通俗讲,数组指针就是个指针,指针数组就是个数组。

存放指针的数组叫指针数组,那么存放数组指针的数组呢,怎样定义呢。

//与上面代码衔接

int (*m[3])[10] = {&arr1,&arr2,&arr3};
//m[3]表示是个数组,存放3个元素。
//拿掉m[3]后就是每个元素的类型int (* )[10],即每个元素是个数组指针。
▶数组指针的使用

数组指针p指向整个数组(p的类型为int (*)[10] ),解引用*p后等价为数组名arr1(arr1的类型为int [10] ),值为首元素地址,但是代表的是这个数组(*p与arr1等价)。

int arr1[10] = {1,2,3,4,5,6,7,8,9,10};
int (*p)[10] = &arr1;

for(i=0; i<10; i++)
{
    pritnf("%d ", *((*p)+i));  //与(*p)[i]等价
}
printf("\n");

printf("%d\n", sizeof(*p));  //*p等价于名字arr1,值为首元素地址,但是代表整个数组,所以为40
printf("%d\n", sizeof(p[0]); //同上

一维数组的数组名指向的是→第一个元素。

二维数组的数组名指向的是→整个第一行数组,数组名=第一行数组的地址。

数组指针也是指向→整个数组,所以二维数组也可以当做数组指针去使用。

int arr[2][3] = { 1,2,3,7,8,9 };  //二维数组名arr指向的对象及类型是 int [3]
printf("%d\n", *(*(arr + 1)+1));  //8

int (*p)[3] = arr;                //指针p指向的类型是 int [3],与上等价(p和arr等价)
printf("%d\n", *(*(p+1)+1));

2.函数指针

void test()

printf("%p\n", test);
printf("%p\n", &test);

void (*p1)() = test;  //函数指针
void (*p2)() = &test;  //与上等价

//通过指针调用函数
(*p1)();  //不能写成*p1()
p1();  //不用解引用*也可,因为函数名本身就是指针

//所以解引用多少层都一样
(*test)();
(**p1)();

例,函数返回类型为函数指针:

void (*signal(int, void(*)(int)))(int);
//含义为void(*)(int) signal(int, void(*)(int)) 但是语法不允许这样写
//返回类型为void(*)(int)

typedef void(*pfun_t)(int);
//含义为typedef void(*)(int) pfun_t
//将这个函数指针类型重命名为pfun_t

pfun_t signal(int, void(*)(int))

存放函数指针的数组——函数指针数组

int Add(int x, int y);
int Sub(int x, int y);

int (*p[2])(int, int) = {Add, Sub};  //数组内元素类型必须相同

//通过数组使用函数
p[1](x, y);

3.回调函数

int add(int x, int y)
{   return x+y; }

int cal(int (*p)(int, int)) {
    int x,y;
    printf("输入两个数:");
    scanf("%d %d", &x, &y);
    //其他通用代码
    return p(x,y);  //这里就定义为回调函数
}

int main() {
    int ret;
    ret = cal(add);   
    return 0;
}

4.关于void类型指针

void类型指针可理解为无具体类型,可以存放任意类型指针,但是不能解引用和运算,除非强制类型转换。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值