甚么!!你这麽传参是吧,好好
在使用自定义函数时,会用到函数传参,今天给大家分享一下函数的传参是设计的呢??
#include
void test(int arr[])//ok?
{}
void test(int arr[10])//ok?
{}
void test(int *arr)//ok?
{}
void test2(int *arr[20])//ok?
{}
void test2(int **arr)//ok?
{}
int main()
{
int arr[10] = {0};//数组
int *arr2[20] = {0};//指针数组,数组里每个元素存放的是地址
test(arr);//传入该数组的首地址
test2(arr2);//传入指针数组的首地址
}
void test(int arr[])
{}
这个应该是容易理解的,用一个同类型的数组接收,数组名表示首元素地址,相当于把地址传过去,对该地址的元素进行处理,可以验证一下,我们可以通过test函数传参过去,对主函数中的arr[]进行修改,然后在主函数中打印出arr[]函数,如果被修改,则是传地址过去,因为test函数也没有返回值,只能是通过传过去地址修改了主函数中的arr[]函数
#include
void test(int arr[])//ok?
{int i;
for(i=0;i<10;i++)
{arr[i]=10-i;
}
}
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10};//数组,
test(arr);//传入该数组的首地址
for(i=0;i<10;i++)
{printf("%d",arr[i]);
}
}
void test(int arr[10])//ok?->ok的
{}
这个情况与第一个一样不管接受的数组元素是多少个,都是传地址过去
void test(int *arr)//ok?------>OK的
{}
这个也容易理解,一级指针可以接收数组的首地址,然后通过对arr+i,就是后面的地址,加1,int类型指针一次访问4个字节,对(arr+i)进行解引用操作,得到的就是对应该地址下主函数arr[]数组对应地址的那个元素,并且可以修改。
那如果是下面这个函数,阁下又应该如何对付勒??
void test2(int *arr[20])//ok?------>ok的
{}
int main()
{
int *arr2[20] = {0};//指针数组,数组里每个元素存放的是地址
test2(arr2);//传入指针数组的首地址
}
你传过去的还是地址,用指针可以接收,可是为什么不用一级指针p呢?是因为这个是一级指针数组,数组元素的元素是int呀,这个数组里存放的都是地址,你要存放一级指针数组的地址应该用个二级指针接收啊! *p只能访问到arr2[]里面的元素(地址),而不能访问到arr2[]里面的地址解引用得到的值,因为还要解引用一次,所以可以用二级指针接收。
用一级指针只能访问&b,不能得到b,如果不用二级指针的话,用一级指针数组的话是可以访问到b的。传参过去拿到的是主函数数组首地址,并没有创造一个真的数组,在test2函数里面arr[1]等于主函数arr2[1],&arr[1]等于&arr2[1],这里不要看他的类型,就把他当一个数组一样,要访问b的话解引用就行
void test(int arr[3][5])//ok?------>ok的
{}
void test(int arr[][])//ok?------->不行
{}
void test(int arr[][5])//ok?------->ok的
{}
//总结:二维数组传参,函数形参的设计只能省略第一个[]的数字。
//因为对一个二维数组,可以不知道有多少行,但是必须知道一行多少元素。
//这样才方便运算。
void test(int *arr)//ok?
{}
void test(int* arr[5])//ok?------>不行
{}
void test(int (*arr)[5])//ok?------>可以的
{}
void test(int **arr)//ok?------>不行
{}
int main()
{
int arr[3][5] = {0};
test(arr);
}
void test(int *arr)//ok?------->可以
{}
二维数组连续存放可以把arr[3][5]当成arr[15];
void test(int* arr)//ok?------->可以
{
int i = 0;
for (i = 0; i < 15; i++)
{
*(arr + i) = i;
}
}
int main()
{
int arr[3][5] = { 0 };
test(arr);
int i = 0;
for (i = 0; i < 3; i++)
{
int j = 0;
for (j = 0; j < 5; j++)
{
printf("%d ", arr[i][j]);
}
}
}
void test(int* arr[5])//ok?------>不行
传地址过去,对于形参arr[0]对应的地址就是主函数arr[0][0]的地址,但是形参是int*类型的,和主函数的arr数组类型int不对应的
void test(int (*arr)[5])//ok?------>可以的
用数组指针接收二维数组在我之前的文章里面讲过
数组指针
void test(int **arr)//ok?------>不行
二级指针接收一级指针的地址,怎么能接收二维数组的地址呢?头给你打破咯哈哈哈哈哈哈哈哈哈
昨天写的很晚了,今天续上
|
|
|
#include
void print(int *p, int sz)
{
int i = 0;
for(i=0; i<sz; i++)
{
printf("%d\n", *(p+i));
}
}
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9};
int *p = arr;
int sz = sizeof(arr)/sizeof(arr[0]);
//一级指针p,传给函数
print(p, sz);
return 0;
}
#include
void test(int** ptr)//二级指针接收一级指针的地址
{
printf("num = %d\n", **ptr);
}
int main()
{
int n = 10;
int*p = &n;
int **pp = &p;
test(pp);
test(&p);
return 0;
}
ptr存放一级指针p的地址,一次解引用得到p指针的内容,也就是n的地址,再解引用一次得到n.
现在有一个疑问,有指向单个类型的指针,有指向数组的指针,有指向指针的指针,有没有指向函数的指针呢????????
看一下这个代码
#include
void test()
{
printf("hehe\n");
}
int main()
{
printf("%p\n", test);
printf("%p\n", &test);
return 0;
}
这两个都是函数的地址,那要怎么将函数的地址存起来呢??
指针
函数指针
定义一个指针*p,这个指针的类型应该和函数的类型一样,也就是同样的参数,同样的返回类型
void (*p)();
这个就是
void test()
的函数指针,满足上面的要求。
我们可以用这个函数指针调用这个函数
#include
void test()
{
printf("hehe\n");
}
int main()
{
void (*p)()=test;//声明函数指针并初始化
(*p)();//p存放test的地址,*p就是该函数,调用该函数一般test();所以(*p)();就可以调用这个函数
return 0;
}
果然写不下,动动发财的小手往右滑滑呗
数组是存放相同类型数据的存储空间,指针数组存放的是地址,把好多函数的地址能存在什么数组里面呢???当然是函数指针数组,这个应该怎么定义呢,我们看一下函数指针 void (*p)(),这个可以存放一个数组的地址,我们把变量p换成数组的话 void (*arr[5])(),这样就可以存放5个函数的地址了。
#include
void test()
{
printf("hehe\n");
}
void test1()
{
printf("haha\n");
}
int main()
{
void (*arr[2])() = { &test1,&test };
(*arr[0])();
(*arr[1])();
return 0;
}
本文分享了数组传参,指针传参,函数指针,函数指针数组,如果哪里不对的话,求大佬多多指教,谢谢大家了,点赞的大佬offer多多!!!