NDK开发--C语言指针(数组指针,函数指针)

上一节 C语言基础部分我们了解了C语言中的指针知识,这一节我们开始深入指针的学习,重点是数组指针,函数指针。

第一、自定义函数传递地址和传递值得理解

为什么在main函数中的变量 i 作为形参传递给自定义函数update后,形参i的内存地址和main函数中的变量i的内存地址不一样?

#include <stdio.h>
void TranslateValue(int i) {
    //传递的是值,不是内存地址
    printf("自定义函数TranslateValue形参i的内存地址:%p\n", &i);
    printf("自定义函数TranslateValue形参i的内存地址:%d\n", i);
}

void TranslateAddr(int *i) {
    //传递的是内存地址
    printf("自定义函数TranslateAddr形参i的内存地址:%p\n", i);
}

int main(){
    int i = 100;
    printf("main函数中的变量i的内存地址是:%p\n", &i);
    printf("main函数中的变量i的内存地址是:%d\n\n", i);
    TranslateValue(i);
    TranslateAddr(&i);
    return 0;
}

输出结果:

自定义函数的使用.png

说明:

1、形参在函数进栈时,有自己的内存地址;

2、作为参数传递的仅仅是内存中的值;

3、如果传递的变量i的内存地址时,这是就是相同的内存地址;

第二、了解多级指针

#include <stdio.h>
int main(){
 
    int number = 100;

    int *number_p = &number;//一级指针:指向变量的内存地址

    int **number_p_p = &number_p;//二级指针:指向一级指针的内存地址

    int ***number_p_p_p = &number_p_p;//三级指针:指向二级指针的内存地址

    printf("一级指针number_p的本身的地址是:%p  所指向的内存地址是:%p    所指向的内存值是:%d\n", &number_p, number_p, *number_p);
    printf("二级指针number_p_p的本身的地址是:%p  所指向的内存地址是:%p    所指向的内存值是:%d\n", &number_p_p, number_p_p, *number_p_p);
    printf("三级指针number_p_p_p的本身的地址是:%p  所指向的内存地址是:%p    所指向的内存值是:%d\n\n", &number_p_p_p, number_p_p_p, *number_p_p_p);
    
    return 0;
}

输出结果:

多级指针.png

说明:

多级指针可以理解成成是指向指针地址的指针;

第三、数组和数组指针

#include <stdio.h>
int main(){
    
    int array[] = {1, 2, 7, 4, 5, 6};
    printf("数组的地址是:%p\n", array);
    printf("数组首元素地址是:%p\n", &(array[0]));
    printf("取数组的第三个元素的值是:%d\n\n", *(array + 2));

    printf("此时的*array+2 为什么没有取第三个元素的值呢?:%d----%d\n\n", *array,*array+2);

    for (int i = 0; i < 6; i++) {
        //由此可以看到内存地址的大小是4个字节,其实就是int类型在内存中的size
        printf("通过数组指针来输出数组的第  %d  的元素的内存地址是: %p   值是: %d \n", i, array + i, *(array + i));
    }

    return 0;
}

输出结果:

数组和数组指针.png

说明

1)数组的内存地址就是数组首元素的内存地址;

2)数组名,可以理解为指向数组首元素的指针;

3)数组取值:3.1 可以通过数组下标的方式来获取,

                    **3.2 可以通过:数据名(即数组的首元素地址)+ 元素的偏移量 == 取值元素的地址 ,然后通过*来获取内存中的值;**

4)由于数组名就是数组的首地址,那么就可以直接将数组名赋值给一个指针,无需使用&来取地址;

5) 数组在内存中是一片连续的内存地址;

6) 数组在取值和偏移量操作的时候,取值的运算符的优先级是优于偏移量操作的+ -操作符的;*

**例如:*(array+2)  与 *array +2 是不一样的,需要使用括号来限定运算符的顺序**

第四、函数指针

#include <stdio.h>
//将函数指针传递给一个函数
int  operate(int (*method)(int ,int),int number ,int number2){
    printf("函数指针的内存地址:%p\n",method);
    return method(number,number2);
}

//两数相减的结果
int reduce(int number, int number2) {
    return number - number2;
}

int main(){
 int num = 100;
     int num2=45;
     printf("获取reduce函数的地址是:%p\n",&reduce);
     printf("reduce函数的函数名地址是:%p\n",reduce);
     printf("通过函数指针来调用函数执行后的结果是:%d  \n",operate(reduce,num,num2));
    return 0;
}

输出结果:

函数指针.png

说明:

1)函数名其实就是函数在内存中的地址,所有可以不使用&来获取函数地址;

2)函数指针的格式 : 例如:int (method)(int ,char) ------- int 返回值类型 (method)函数指针名, (int ,char) 形参;**

3)使用场景:类似于java中的回调函数;或者kotlin中的block

下节预告:C语言动态静态开辟内存

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容