指针的进阶-2

int main()
{
    int arr1[10] = { 0 }; //整形数组
    int* p[10]; //指针数组
    int(*p)[10]; // 数组指针,p指向一个数组,由10个元素,每个元素是int类型
    //类似于二维数组
    // (*)表示p[5]是一个数组,有五个元素,每个元素是一个指针(地址),[10]表示每个元素指向一个数组,有
    // 10个元素,int表示表示每个元素是int类型。
    int(*p[5])[10];// p[5]是一个指针数组,由五个元素,每个元素指向一个数组,指向的数组有10个元素,每个元素是int类型

    return 0;
}

//数组参数和指针参数

//一维数组的传参

void test1(int arr[])
{

}
void test2(int arr[10])
{

}
/*
    arr1[10]中存放了10int类型的数据
    int    int    int    int    int    int    int    int    int    int
    ↑ 数组名arr1代表首元素的地址,首元素是int类型,所以其地址是int*类型
*/
void test3(int *arr)
{

}


void test4(int* arr[10])
{

}
/*
    指针数组arr2[10]中存放了10个元素,每个元素是int* 类型,永存存放int类型的地址
    int*    int*    int*    int*    int*    int*    int*    int*    int*    int*
     ↑  数组名代表首元素的地址,首元素是int*类型的,故其地址是int**类型的
    ------
*/
void test1(int** arr)
{

}

int main()
{
    int arr1[10] = {0};
    int* arr2[10] = { 0 };
    return 0;
}
 

//二维数组传参

void test(int arr[3][5])
{

}
//必须有列数,n维数组必须含有n-1维数组的信息
void test(int arr[][5])
{

}
void test(int (*p)[5])
{

}
void test()
{

}
void test()
{

}
void test()
{


}
int main()
{
    int arr[3][5] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 };
    test(arr);
    // 一维数组数组名是首元素的地址,类型为int *
    // 二维数组数组名是首行(n-1维)的地址,类型为 int(*)[]
  // &数组名,取出的是该数组的地址,+1跳过整个数组的大小

    return 0;
}

//一级指针传参

void test(int* p)
{
}
int main()
{
    int arr[10] = { 0 };
    int* p = arr;
    int a = 10;
    test(p);//本质是复制,传值
    test(&a);//本质是传地址,可以改变a的值,传址
    test(arr);//传址
}

//二级指针传参

void test(int **p)
{
}
int main()
{
    int a = 10;
    int* p = &a;
    int** pp = &p;
    int* arr[10];
    test(pp);
    test(&p);
    test(arr);
    return 0;
}

//函数指针


/*
    类比
    数组指针-->指向数组的指针
    函数指针-->指向函数的指针

    函数也是有地址的,每一个函数都有自己的地址
    1.函数名就是函数的地址,&函数名拿到的也是函数的地址,故对于函数来说 数组名和&数组名等价
    2.使用数组名时也一样 加不加*效果都一样   (Add)(4,5)与(*Add)(4,5)效果一样

    作用:
        不仅可以通过函数名来找到函数,也可以通过其地址来找到函数

    对于函数来说:
    &函数名   和   函数名 拿到的都是该函数的地址

    如何存取函数的地址呢?    ↓(表明指针指向的是一个函数,括号里填入参数类型)
        函数返回类型 (*p)(int,int)
                                  ↑(表明是一个指针)
    类似于数组指针
        指向数组类型  (*p)[10]


    函数指针的使用
    int a =    (*p)(4,5);


    函数和全局变量一个道理,在编译器据分配地址了
    共有:栈区,堆区,静态区,还有代码区,常量区等
    函数存在代码区,全局变量在静态区,
    代码区是只读的,不能改

    -------
*/

int Add(int x, int y)
{
    return x + y;
}
int main()
{
    int arr[10] = { 0 };
    int(*p)[10] = &arr;

    //&函数名   和   函数名 拿到的都是该函数的地址
    printf("%p\n", &Add);
    printf("%p\n", Add);

    int (*pf)(int, int) = &Add;
    // 定义完之后pf就和Add一样,解引用是加不加*号都可以
    //但是定义的时候一定要加上

    printf("%p\n", pf);
    printf("%p\n", *pf);
    int (*pff)(int, int) = Add;
    printf("%p\n", pff);
    printf("%p\n", *pff);

    int ret = (pff)(4, 5);
    int ret2 = (*pff)(4, 5);
    printf("%d\n", ret);
    printf("%d\n", ret2);
    printf("%d\n", (Add)(4, 6));
    printf("%d\n", (*Add)(4, 6));
    return 0;
}

//函数指针的应用

int Add(int x, int y)
{
    return x + y;
}
//在函数内调用其它函数
void calc(int (*p)(int, int))
{
    int a = 5;
    int b = 3;
    int ret = p(5, 3);
    printf("%d\n", ret);
}
int main()
{
    calc(Add);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值