C语言指针的应用

多级指针

多级指针就是指向指针的指针,或者说是一个指针链,下面是一个程序示例以及它的运行结果。

#include <stdio.h>
int main() {
    int num = 10;
    int *num_p = &num;
    int **num_p_p = &num_p;

    printf("num的地址:%p\n", &num);
    printf("*num_p的值:%p\n", num_p);
    printf("*num_p的地址:%p\n", &num_p);
    printf("**num_p_p的值:%p\n", num_p_p);

    printf("num的值:%d\n",num);
    printf("*num_p指向内存地址所对应的值:%d\n", *num_p);
    printf("**num_p_p指向内存地址所对应的值:%d\n", **num_p_p);
}
运行结果

通过上面的代码可以看到,首先我们定义了一个 int 类型的变量 num,并为它赋值为10,接着我们定义了一个 int 类型的指针变量 num_p 并将 num 的内存地址赋值给 num_p,再接着定义了一个二级int类型的指针变量 num_p_p并将 num_p 的地址赋值 num_p_p

多级指针示意图

数组指针

#include <stdio.h>
int main() {
    int arr[] = {1, 6, 7, 8};

    printf("&arr = %p\n", &arr);
    printf("&arr[0] = %p\n", &arr[0]);
    return 0;
}
运行结果

通过上面的运行结果可以看出,直接打印数组的内存地址是和其第一个元素的内存地址相同的,那么数组的指针其实就是数组第一个元素的指针,我们通过给指针做位移操作应该就可以拿到数组内的所有元素。

#include <stdio.h>
int main() {
    int arr[] = {1, 6, 7, 8};

    printf("数组的内存地址 = %p\n", &arr);
    printf("数组第一个元素的内存地址 = %p\n", &arr[0]);
    int *arr_p = arr;

    /**
     * sizeof(arr) 数组所占的字节数
     * sizeof(int) int所占的字节数
     * sizeof(arr) / sizeof(int) = arr数组的长度
     */
    int index;
    for (index = 0; index < sizeof(arr) / sizeof(int); ++index) {
        // *(arr_p + index) :先挪动指针,然后再取出地址所对应的值
        printf("位置:%d,值:%d,地址:%p\n", index, *(arr_p + index), arr_p + index);
    }

    return 0;
}
运行结果

通过上面的运行结果可以看出,通过挪动数组指针确实可以拿到数组内所有的元素,细心的小伙伴可以发现,数组 arr 每个元素的内存地址都比其前一个元素大了 4,这个4就是int类型的元素所占的字节数量,所以我们也可以得出:数组是一块连续的内存地址

指针挪动示意图

函数指针

在C语言万物皆指针,所以一个函数也有自己的内存地址,也有指针。

#include <stdio.h>

// C语言不支持函数的重载,所以声明函数时可以不用写形参
void add();
void sub();
void operation();
int main() {
    printf("add函数的内存地址:%p\n",&add);
    printf("sub函数的内存地址:%p\n",&sub);
    operation(&add, 1, 1);
    operation(&sub, 10, 1);
}

void add(int num1, int num2) {
    printf("num1 + num2 = %d\n", (num1 + num2));
}

void sub(int num1, int num2) {
    printf("num1 - num2 = %d\n", (num1 - num2));
}

/**
 *
 * @param method
 *        void 函数的返回值
 *        (*method) 函数的指针
 *        (int,int) 函数的形参类型
 * @param num1
 * @param num2
 */
void operation(void(*method_p)(int, int), int num1, int num2) {
    printf("接收到函数的内存地址:%p\n", method_p);
    method_p(num1, num2);
}
运行结果

这里我们定义了三个函数 addsuboperationoperation函数的一个参数有些特殊,它接收一个 返回值为 void,形参为 int、int 的一个函数指针做参数,operation函数拿到传递的函数指针,进而可以通过函数指针来调用相应的函数。


系统:Windows 10 64位
IDE:CLion

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值