1.基于指针的函数传参
通过下面的例子,我们可以发现a和b的地址是不同的,这就是所谓的“传值调用”,a和b不是同一个变量,函数传参的本质是复制一份变量副本
void func(int b)
{
printf("%d",&b);
}
int main(void)
{
int a;
printf("%d",&a);
func(a);
}
- 所以,当我们要实现输出型参数时,一般需要使用指针作为参数,(相当于全局变量,但比全局变量优越)
- 下面的例子有着令人震惊的结果,打印信息都是4,func1的结果可以理解,但是fun2明明传参是整个数组,打印信息应该是40才对呀!?原来,数组作为参数进行传参时会自动退化为一个指针,也就是说,c语言中无法将数组作为整个参数传参!!
void func1(int *b)
{
printf("%d",sizeof(b));
}
void func2(int b[10])
{
printf("%d",sizeof(b));
}
- 但是,结构体和数组不同,把整个结构体传参时,在子函数复制一份副本。说到底,结构体变量和普通变量一模一样,不过说实话,结构体传参还是用指针比较好,这样效率会高一点
2.main函数传参
- main函数传参可以提高程序的灵活性,通过argc和argv作为参数来实现,使用方法如下:
int main(int argc, char *argv[])
int main(int argc, char **argv) //这样使用也可以
- argc是int类型,代表了传给main的参数个数。
argv
是char *[]
类型即字符串数组,里面都是参数 - 如果我们在控制台中输入
./a.out xx yy zz
来执行当前目录下a.out的可执行程序,那么得到的结果为
argc值为4
argv[0]值为./a.out
//之所以要把执行的程序名字也算作参数,目的是为了让一个应用程序支持多个程序功能,比如busybox
argv[1]值为xx
argv[2]值为yy
argv[3]值为zz
3.函数指针与typedef
- 现在有一个简单的函数int func1(int),以该数组作为例子分析
func1是一个int (*)(int)类型的变量,其值为函数入口地址
&func1也是一个int (*)(int)类型的变量,其值为函数入口地址
- 函数指针的使用
int (*pfunc)(int); //定义一个函数指针
pfunc = func1; //为函数指针初始化,这一步使用pfunc = &func1也可以
pfunc(); //调用函数指针
- 利用typedef,简化函数指针的定义
typedef int *(ptype)(int); //创建了一个函数指针类型
ptype pfunc1, pfunc2; //定义了两个ptype类型的函数指针