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;
}