1.函数的参数
函数的参数部分可以有两类:
- 有参函数:
- 无参函数
有参函数又分为两类:
- 有返回值;
- 无返回值
无参函数分为两类
- 有返回值;
- 无返回值
如下四个程序检查用户输入整数是否是质数。
下面所有这些程序的输出都是相同的,并且我们在每个示例中都创建了一个用户定义的函数。但是,我们在每个示例中采用的方法是不同的。
例1.1 没有参数没有返回值
#include <stdio.h> void checkPrimeNumber(); int main() { checkPrimeNumber(); // argument is not passed return 0; } // return type is void meaning doesn't return any value void checkPrimeNumber() { int n, i, flag = 0; printf("Enter a positive integer: "); scanf("%d",&n); for(i=2; i <= n/2; ++i) { if(n%i == 0) { flag = 1; } } if (flag == 1) printf("%d is not a prime number.", n); else printf("%d is a prime number.", n); }
checkPrimeNumber() 函数从用户那里获取输入,检查它是否是素数并将其显示在屏幕上。checkPrimeNumber() 中的空括号; main() 函数中的语句表示没有参数传递给函数。
函数的返回类型为 void。因此,该函数不返回任何值。
例1.2 没有参数但有返回值
#include <stdio.h> int getInteger(); int main() { int n, i, flag = 0; // no argument is passed n = getInteger(); for(i=2; i<=n/2; ++i) { if(n%i==0){ flag = 1; break; } } if (flag == 1) printf("%d is not a prime number.", n); else printf("%d is a prime number.", n); return 0; } // returns integer entered by the user int getInteger() { int n; printf("Enter a positive integer: "); scanf("%d",&n); return n; }
函数 getInteger(); 中的空括号语句表示没有参数传递给函数。但是,函数返回的值被分配给main函数的 n。
在这里,getInteger() 函数从用户那里获取输入并返回给调用函数。然后在 main() 函数中检查数字是否为素数并打印出。
例1.3 有传递参数但无返回值
int main() { int n; printf("Enter a positive integer: "); scanf("%d",&n); // n is passed to the function checkPrimeAndDisplay(n); return 0; } // return type is void meaning doesnot return any value void checkPrimeAndDisplay(int n) { int i, flag = 0; for(i=2; i <= n/2; ++i) { if(n%i == 0){ flag = 1; break; } } if(flag == 1) printf("%d is not a prime number.",n); else printf("%d is a prime number.", n); }
用户输入的整数值被传递给 checkPrimeAndDisplay() 函数。
在这里, checkPrimeAndDisplay() 函数检查传递的参数是否为质数并显示出来。
例1.4 传递参数并返回值
#include <stdio.h> int checkPrimeNumber(int n); int main() { int n, flag; printf("Enter a positive integer: "); scanf("%d",&n); // n is passed to the checkPrimeNumber() function // the returned value is assigned to the flag variable flag = checkPrimeNumber(n); if(flag == 1) printf("%d is not a prime number",n); else printf("%d is a prime number",n); return 0; } // int is returned from the function int checkPrimeNumber(int n) { int i; for(i=2; i <= n/2; ++i) { if(n%i == 0) return 1; } return 0; }
- 来自用户的输入被传递给 checkPrimeNumber() 函数;
- checkPrimeNumber() 函数检查传递的参数是否为素数;
- 如果传递的参数是素数,则函数返回 0。如果传递的参数是非素数,函数返回 1。返回值分配给标志变量;
- 根据 flag 是 0 还是 1,从 main() 函数打印出适当的消息。
以上哪种方法更好?
好吧,这取决于您要解决的问题。在这种情况下,传递参数并从函数返回一个值(示例 4)会更好。
一个函数应该执行一个特定的任务。 checkPrimeNumber() 函数不接受用户的输入,也不显示适当的消息。它只检查一个数字是否是素数。
2.形式参数(形参)和实际参数(实参)
前面已经介绍过,函数的参数分为形参和实参两种。在本小节中,进一步介绍形参、实参的特点和两者的关系。形参出现在函数定义中,在整个函数体内都可以使用,离开该函数则不能使用。
实参出现在主调函数中,进入被调函数后,实参变量也不能使用。形参和实参的功能是作数据传送。发生函数调用时,主调函数把实参的值传送给被调函数的形参从而实现主调函数向被调函数的数据传送。
函数的形参和实参具有以下特点:
- 形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只有在函数内部有效。函数调用结束返回主调函数后则不能再使用该形参变量;
- 实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须具有确定的值,以便把这些值传送给形参。因此应预先用赋值,输入等办法使实参获得确定值;
- 实参和形参在数量上,类型上,顺序上应严格一致,否则会发生类型不匹配”的错误;
- 函数调用中发生的数据传送是单向的。即只能把实参的值传送给形参,而不能把形参的值反向地传送给实参。 因此在函数调用过程中,形参的值发生改变,而实参中的值不会变化。
例2.1.用函数计算出1到用户输入整数的和
int s (int );
main()
{
int n;
printf("input number\n");
scanf("%d",&n);
s(n);
printf("main function n=%d\n",n);
}
int s(int n) //该函数计算出1到n之和
{
int i;
for(i=n-1;i>=1;i--)
n=n+i;
printf("n=%d\n",n);
}
本程序中定义了一个函数s,该函数的功能是求1到n之和。在主函数中输入n值,并作为实参,在调用时传送给s 函数的形参量n( 注意,本例的形参变量和实参变量的标识符都为n,但这是两个不同的量,各自的作用域不同)。
在主函数中用printf 语句输出一次n值,这个n值是实参n的值。在函数s中也用printf 语句输出了一次n值,这个n值是形参最后取得的n值 0。从运行情况看,输入n值为 100。即实参n的值为 100。
把此值传给函数s时,形参n的初值也为 100,在执行函数过程中,形参n的值变为 5050。返回主函数之后,输出实参n的值仍为 100。可见实参的值不随形参的变化而变化。