前言
🎉欢迎关注🔎点赞👍收藏⭐️留言📝
🎉推荐up主专题文章【C语言编程一百题】
📌QQ:3052645092 有问题可以一起讨论哦
🔎超级好用的刷题网站【牛客网】
🍭作者水平很有限,如果发现错误,请及时告知作者哦!感谢感谢!
⭐️指针传参和数组传参
⭐️一维数组传参
void Show(int a[], int num){
printf("Show: %d\n", sizeof(a));//这个呢???
}
int main(){
int a[10] = { 0 };
printf("main: %d\n", sizeof(a));//求的是整数组的大小
Show(a,10);
return 0;
}
🔎回答一个问题,Show函数中sizeof(a)会是多少?
🔎1.为什么是4呢?
因为数组传参发生了降维,降维成了指针!!!🔎2.为什么降维?
先明确一点,任何函数调用都会形成临时拷贝。因为C是面向过程的语言,在一个程序中就会有很多的函数调用,也会有很多用到数组的场合,数组这么大,每次调用函数都要形成临时拷贝,就会很占用空间,所以C采用降维,降维成指针,这样就避免了数组的临时拷贝,就会大大的提高效率。
🔎3.那么降维成了什么样的指针了呢?
降维成了指向其内部元素类型的指针!!!!🔎4.那为什么就降维成了,指向内部元素类型的指针了呢?
你数组传参是不是每次都传的首元素地址,那用一个和首元素类型一样的指针变量来接收不是理所应当的嘛!🔎5.那么数组降维了,会发生临时拷贝吗?
会的,降维成了指针,指针也是数据呀,是数据就要被拷贝,所以用指针变量来接收!!!
⭐️一级指针传参
#include<stdio.h>
void test(char *p)
{
printf("test: &p = %p\n", &p);
}
int main()
{
char *p = "hello world";
printf("main: &p = %p\n", &p);
test(p);
return 0;
}
🔎结论:在C语言中,只要函数调用,必定发生拷贝。只不过要根据具体情况去决定,拷贝了什么,拷贝了多少!
⭐️一道经典的指针传参相关题目
void GetStr(char **pp)
{
*pp = malloc(sizeof(char)*6);
if (NULL != *pp){
strcpy(*pp, "hello");
}
else{
//do nothing!
}
}
int main()
{
char *p = NULL;
GetStr(&p);
printf("%s\n", p);
system("pause");
return 0;
}
⭐️二维数组传参
#include <stdio.h>
#include <windows.h>
void show(char (*p)[4])//二维数组传参也会发生降维,降维成指向其内部元素类型的指针
{
printf("show: %d\n", sizeof(p));
}
int main()
{
char a[3][4] = { 0 };
printf("main: %d\n", sizeof(a));
show(a);//数组名首元素地址,即一维数组的地址,类型是char (*)[4]
return 0;
}
🔎也会发生临时拷贝哦 那么在传参的时候可以省略数组元素个数嘛
🔎类型不同所以说,数组的元素个数是数组类型的一部分;
🔎总结:任何维度的数组,传参的时候,都要发生降维,降维成指向其内部元素类型的指针 那么,二维数组,内部“元素”是一维数组!那么降维成指向一维数组的指针
🔎降维成指向内部元素类型的指针,a[3][4][5][6][7],a是一个多维数组,有三个元素每个还是多维数组,传参所以用char (*p)[4][5][6][7],这样的指针接收!!!
⭐️函数指针!!!
🔎函数也是有地址的!!!! 有这两种方法都可以打印地址!!!
#include<stdio.h>
void Show(){
printf("you can see me\n");
}
int main(){
Show();
void(*p)() = Show;//函数指针,指向了一个函数返回类型是void
(*p)();//解引用p找到函数的地址,调用这个函数
p();//p是一个指针变量,现在用的是p的右值,即变量的内容,函数的地址数据,故可以调用这个函数
return 0;
}