第五周 函数
标签(空格分隔):程序设计入门—C语言
5.1函数
#include <stdio.h>
void sum ( int begin, int end ){
int i, sum = 0;
for ( i = begin; i <= end; i++ ){
sum += i;
}
printf("从%d到%d的和是%d\n", begin, end, sum);
}
int main()
{
sum(1,10);
sum(20,30);
sum(35,45);
}
- 什么是函数
- 函数是一块代码,接受零个或多个参数,做一件事情并返回零个或一个值
- C语言的函数可以不返回值,如果要返回值,也只能返回一个值
- 函数头:返回类型 函数名 参数表
void sum ( int begin, int end )
{函数体} - 调用函数:函数名(参数值)
- ( )起到了表示函数调用的重要作用,即使没有参数也需要()
- 如果有参数,则需要给出正确的数字和顺序
- 这些值会被按照顺序依次用来初始化函数中的参数
- 函数返回
- 函数知道每一次是哪里来调用它,会返回到正确的地方
int max( int a, int b){
int ret;
if ( a>b ){
ret = a;
}else{
ret = b;
}
return ret;
}
- 从函数中返回值
- return停止函数执行,并送回一个值
- 从函数中返回值:return; 或return 表达式;
- 一个函数里面可以出现多个return语句,但最好单一出口
- 返回值可以赋值给变量,可以再传递给函数,甚至可以丢掉
- 没有返回值的函数
- void 函数名(参数表)
- 不能使用带值的的return,也可以没有return
- 调用的时候不能做返回值的赋值
5.2使用函数
5.2.1函数原型
#include <stdio.h>
void sum ( int begin, int end ); //函数声明
int main()
{
sum(1,10);
sum(20,30);
sum(35,45);
}
void sum ( int begin, int end ){ //函数定义
int i, sum = 0;
for ( i = begin; i <= end; i++ ){
sum += i;
}
printf("从%d到%d的和是%d\n", begin, end, sum);
}
- 函数先后关系
- 把sum()写在上面是因为:
- C编译器自上而下顺序分析你的代码
- 在看到sum(1,10)的时候,它需要知道sum()的样子
- 也就是sum()要几个参数,每个参数的类型如何,返回什么类型
- 这样才能检查你对sum()的调用是否正确
- 函数原型
- 函数头,以分号”;”结尾,就构成了函数的原型
- 函数原型的目的是告诉编译器这个函数长什么样:名称,参数(数量及类型),返回类型
- 函数原型声明可以不写参数名称
- 原型声明一般写在调用它的函数前面
5.2.2参数传递
- 调用函数
- 如果函数有参数,调用函数时必须传递给它数量、类型正确的值
- 可以传递给函数的值是表达式的结果,包括:字面量,变量,函数的返回值,计算的结果
- 类型不匹配?
- 调用函数时给的值与参数的类型不匹配是C语言传统上最大的漏洞
- 编译器总是悄悄的替你把类型转换好,但这很可能不是你所期望的
- 后续的语言,C++/Java在这方面很严格
- 传过去的是什么?
- C语言在调用函数的时候,永远只能传值给函数
- 传值
- 每个函数都有自己的变量空间,参数也位于这个空间中,与其他函数没有关系
- 过去,对于函数参数表中的参数,叫做”形式参数”,调用函数时给的值叫做”实际参数”
- 易让初学者误会实际参数就是实际在函数中进行计算的参数,误会调用函数的时候把变量而不是值传进去了,所以不建议使用该叫法
- 我们认为,它们是参数和值的关系
5.2.3本地变量(局部变量、自动变量)
- 本地变量
- 函数的每次运行,就产生了一个独立的变量空间,在这个空间中的变量,是函数的这次运行所独有的,称作本地变量
- 定义在函数内部的变量就是本地变量
- 参数也是本地变量
- 变量的生存期和作用域
- 生存期:什么时候这个变量开始出现,到什么时候消亡了
- 作用域:在(代码的)什么范围内可以访问这个变量(这个变量可以起什么作用)
- 对于本地变量,这两个问题的答案是统一的,大括号内——块
- 本地变量规则
- 本地变量是定义在块内的
它可以定义在函数的块内,也可以定义在语句的块内,甚至可以随便拉一对大括号来定义变量 - 程序运行进入这个块之前,其中的变量不存在,离开这个块,其中的变量就消失了
- 块外面定义的变量在块里面仍然有效
- 块里面定义了和外面同名的变量,则掩盖外面的
- 不能在一个块内定义同名变量
- 本地变量不会被默认初始化
- 参数在进入函数的时候被初始化了
- 本地变量是定义在块内的
5.2.4函数庶事
- 没有参数时
- void f(void) 表示没有参数
- void f() 表示参数表未知,不表示没有参数,不建议写
- 逗号运算符?
- 调用函数时的圆括号里的逗号是标点符号,不是运算符
- f(a,b) 传两个参数
- f((a,b)) 先做括号里的运算,逗号是运算符,传一个参数
- C语言不允许函数嵌套定义
- 这是什么?
- int i, j, sum(int a, int b);
- 定义int类型变量i,j,声明sum函数要两个int作为参数并且返回一个int,不建议
- return(i);
- 这里的圆括号没有意义,return后面要一个表达式,加括号易让人误解return是一个函数,不建议
- 关于main
- int main()也是一个函数
- int main(void)可以这么写
- main是C语言的入口,return 0;是有意义的
windows: if errorlevel 1…
Unix Bash: echo $?
Csh: echo $status
//素数和
#include<stdio.h>
int isPrime(int i){
int ret =1;
int k;
for (k=2;k<i-1;k++){
if(i%k==0){
ret =0;
break;
}
}
return ret;
}
int main(){
int n,m;
// scanf("%d %d",&n,&m);
m=isPrime(5);
printf("%d",m);
return 0;
}
第五周 小测验
- 以下哪句不是正确的原型?–>D函数定义,有{}
A.int f();
B.int f(int i);
C.int f(int);
D.int f(int) {} - 以下哪个函数的定义是错误的?–>B改为int f(int i) { return i+1; }
A.void f() {}
B.void f(int i) { return i+1; }
C.void f(int i) {}
D.int f() { return 0; } - 对于不返回值而且只有一个int类型的参数的函数,以下哪些函数原型是正确的?–>ABC
A.void f(int x);
B.void f();
C.void f(int);
D.void f(x); - 以下程序的输出是什么?–>5-6
#include <stdio.h>
void swap(int a, int b);
int main()
{
int a = 5;
int b = 6;
swap(a,b);
printf("%d-%d\n", a, b);
return 0;
}
void swap(int a, int b)
{
int t = a;
a = b;
b = t;
}
第五周编程题
1 分解质因数(5分)
- 题目内容:每个非素数(合数)都可以写成几个素数(也可称为质数)相乘的形式,这几个素数就都叫做这个合数的质因数。比如,6可以被分解为2x3,而24可以被分解为2x2x2x3。
- 现在,你的程序要读入一个[2,100000]范围内的整数,然后输出它的质因数分解式;当读到的就是素数时,输出它本身。
- 输入格式:一个整数,范围在[2,100000]内。
- 输出格式:形如: n=axbxcxd 或 n=n有的符号之间都没有空格,x是小写字母x。
- 输入样例: 18
- 输出样例: 18=2x3x3
#include <stdio.h>
int yinshu(int n){
int i=2;
for(;i<=n;i++){
if (n%i==0){
n=n/i;
printf("%d",i);
if(n!=1){
printf("X");
}
break;
}
}
return n;
}
int main(){
int n;
scanf("%d",&n);
printf("%d=",n);
do{
n=yinshu(n);
}while(n!=1);
return 0;
}
> #include<stdio.h>
> int yinshu(int n){
> int a;
> int i;
> for ( i=2; i<=n; i++){
> if( n%i == 0){
> a = i;
> break;
> }
> }
> return a;
> }
> int main(){
> int n;
> scanf("%d", &n);
> printf("%d=", n);
> int x = yinshu(n);
> while ( x != n ){
> printf("%dX", x);
> n=n/x;
> x = yinshu(n);
> }
> printf("%d", x);
> return 0;
> }
2 完数(5分)
- 题目内容:一个正整数的因子是所有可以整除它的正整数。而一个数如果恰好等于除它本身外的因子之和,这个数就称为完数。例如6=1+2+3(6的因子是1,2,3)。
现在,你要写一个程序,读入两个正整数n和m(1<=n<m<1000)
,输出[n,m]范围内所有的完数。 - 提示:可以写一个函数来判断某个数是否是完数。
- 输入格式:两个正整数,以空格分隔。
- 输出格式:其间所有的完数,以空格分隔,最后一个数字后面没有空格。如果没有,则输出一个空行。
- 输入样例:1 10
- 输出样例:6
#include<stdio.h>
int wanshu(int n){
int t=n;//记录N值
int sum=0;
int i;
for(i=1;i<n;i++){
if (n%i==0){
sum+=i;
}
}
if(sum==t){
return 1;
}else{
return 0;
}
}
int main(){
int n,m;
scanf("%d %d",&n,&m);
int i;
int a=1;//第一个输出
for(i=n;i<=m;i++){
if(wanshu(i)==1){
if (a==1){
printf("%d",i);
a=0;
}else{
printf(" %d",i);
}
}
}
if(a==1){
printf("\n") ;
}
return 0;
}