*c语言学习笔记(十一)*
一、关于形参和实参的含义问题
1、实参:真实传递给函数的参数,实参可以是常量,变量,表达式,函数等。无论实参是何种类型的值,在进行函数调用时,他们都必须具有确定的值,以便把这些值传递给形参;
2、形参:形式参数是指函数名后括号中的变量,因为形式参数只有在函数被调用的过程中才会实现实例化(分配内存单元),所以叫形式参数。形式参数当函数调用完成后就自动销毁了,因此形式参数只在函数中有效。
例:创建一个自定义函数
int MAX(int x,int y);
这里的x,y就是形式参数,当在主函数中调用函数时
int main()
{
MAX(2.3);
},
此时2,3被当做实参传递给函数MAX;形式参数在函数不被调用时,系统不会为形参分配具体内存空间;
二、函数的调用
1、传值调用
函数的实参和形参分别占有不同内存块,对形参的修改不会影响实参;上面的函数调用例子就是传值调用;
2、传地址调用
把函数外部创建变量的内存地址传递给函数参数的一种调用方式;
这种传参方式可以让形参与函数外部变量建立起关系,即可以实现函数内部直接操作函数外部变量;
例:
首先创建自定义函数
void MAX(int*pa,int*pb)
pa,pb为指针变量,形参,类型为整形;
接着再主函数中:
int main
{
int a=1;
int b=2;
MAX(&a,&b);
return 0 ;
}
这里将变量a,b的地址传递给MAX函数中的两个指针变量,则在MAX函数内部,通过对指针变量修改,即可控制变量a,b;假设MAX函数内部存在语句:
*pa=10;
*pb=20;
则当函数调用完成后,a,b的值变为10.,20;
三、练习:创建自定义函数可以实现,输出100-200之间的素数;
本人写出的一段代码,我的思路是再给出一个数判断他是不是素数时,将这个数和数字1中间所有的数全部取余数操作一遍,如果出现了余数为零的情况,则这个数不是素数,由于只选择了余数为零一种情况,故编译器会爆出一个警告信息,并不是所有的结果都有返回值;
int f_judge(int x)
{
int j = 1;
for (j = 2; j < x; j++)
{
int k =x%j;
if (k == 0)
return 0;
}
}
int main()
{
int i = 0;
for (i = 100; i <= 200; i++)
{
if (f_judge(i) != 0 )
printf("%d ", i);
}
return 0;
}
程序运行结果如图
下面给出老师写的代码:
int f_judge(int x)
{
int j = 0;
for (j = 2; j < x; j++)
{
if (x % j == 0)
return 0;
}
return 1;
}
int main()
{
int i = 0;
for (i = 100; i <= 200; i++)
{
if (f_judge(i) == 1 )
printf("%d ", i);
}
return 0;
}
老师的代码所有情况都得到了处理,这里解释一下这段代码的含义,首先也是对得到的i进行一个取余数处理,若得到了结果为零的余数,那么这个数必然不是素数(从for循环中2开始循环到小于i本身,此处避开了素数本身和1) ,此时返回值 0,程序结束;若for循环结束,还没有发现余数为零情况,那么return 1,函数会返回一个值 1;
程序运行结果同上,这里创建的自定义函数,用到的是传值调用,将变量i传递给函数形参;
对代码进行优化,添加一个math.h的头文件之后,将for循环改为
for (j = 2; j <= sqrt(x); j++)
作用与源代码相同。sqrt函数为求出一个非负实数的平方根,这样写可以减少机器的无效运行,提高代码效率;
至于为什么可以这样写,在听课之后得出,假如一个数为两个数的乘积,那么平方根可以为一个界限,在平方根前后如果有因数,那么必定有一个数在平方根之后匹配,是成对出现的,故只要查询平方根之前包括平方根这一半的数字即可;