int f(int a,int b)
{
float c;
c=a+b;
return c;
}
关于函数需要说明的是,假如返回变量的类型与函数类型不一致时,返回时系统会自动进行类型转换,以函数返回值的类型为最终结果,即例题中会将变量c的值转换成整型返回,变量c本身的类型不变。
如果函数是缺省的,系统规定默认为int型。
调用语句中出现的参数称为实参,被调函数中的参数称为形参。在函数定义时,系统是不给形参分配内存空间的,只有当函数调用发生时,实参传给形参,这时才给形参分配内存空间。
函数声明
编译一个C语言源文件是从第一行开始扫描到最后的,你调用一个函数,之前必须定义或申明过这个函数。
被调函数的定义如果出现在主调函数的后面,则主调函数中必须在调用之前对被调函数进行声明,否则系统会认为被调函数没有定义就使用。
这样是合法的:
void main(){
float f(float x,float y); //在主调函数中声明被调用函数,格式:函数头+“;”
}
float f(float x,float y){
}
在以下三种情况下,主调函数中不再需要对被调函数进行声明:
(1)当被调函数的返回值类型是整型(int)时,不需要进行函数声明。
void main(){
f(1,2);
}
int f(int x,int y){
}
(2)当被调函数的定义出现在主调函数之前,也无需进行函数声明
float f(float x,float y){
}
void main(){
f(1.2,3.4);
}
(3)如果在所有函数定义之前,在函数的外部进行了函数声明,则在各个主调函数中不必对所定义的函数再做声明。
#include <stdio.h>
float f(float x,float y);
void main(){
f(1.2,3.4);
}
float f(float x,float y){
}
#include <stdio.h>
int f(int a,int b)
{
int max;
max=(a>b)?a:b;
return max;
}
void main()
{
int a,b,max;
scanf("%d,%d",&a,&b);
printf("max=%d",f(a,b));
}
参数的传递
当形参是普通变量时,发生函数调用时,是实参传递值给形参,形参的任何变化不会回传给实参,换言之,实参向形参传递的是值,而且是单向传递。
嵌套调用
函数是由函数头+函数体构成的。各个函数是独立的,个函数内不能包含另一个函数,换言之,函数是不可以嵌套定义的。但是,调用函数是可以数套调用的。也就是说,在调用一个函数的过程中可以调用另一个函数。
上图中表示的是两层嵌套调用。如图所示,整个程序的执行顺序是从main函数开始执行(步骤①,过程中调用A函数,转去(步骤②)执行A函数(步骤③),过程中又调用B函数,转去(步骤④)执行B函数(步骤⑤)返回(步骤⑥)临近的调用点,继续执行A函数中其余程序(步骤⑦),执行完A函数,返回(步骤⑧上一层调用点,继续执行主函数中其余程序(步骤⑨),一直至结束。以此类推,不管嵌套多少层,函数调用的执行方式是不变的。
变量的作用域
分为:局部变量和全局变量
注意:主函数(main函数)虽然是程序的起点,但主函数中定义的变量也只能在主函数中有效,主函数也不能使用其他函数中定义的变量。
#include <stdio.h>
void main(){
int a=2,b=4,c; //a,b,c是局部变量,作用域是main函数
c=a*b;
{
int c=5;
printf("c=%d\n",c);
}
printf("c=%d\n",c);
}
#include <stdio.h>
void main(){
int a,b;
scanf("%d%d",&a,&b);
if(a<b)
{
int t; //其作用域仅在if语句中有效
t=a;
a=b;
b=t;
}
printf("a=%d,b=%d,t=%d\n",a,b,t); //该语句有问题,t
}
全局变量:在函数之外定义的变量。
作用域:从定义变量位置的开始到程序文件结束。
#include <stdio.h>
int x,y; //全局变量x、y,作用域:从此行到程序最后
void fun1()
{
x=1;y=2;
printf("fun1:x=%d,y=%d\n",x,y);
}
float a,b; //全局变量a、b,作用域:从此行开始到最后
void fun2()
{
a=3.5;b=4.6;
printf("fun2:a=%f,b=%f\n",a,b);
printf("fun2:x=%d,y=%d\n",x,y);
}
void main(){
fun1();
fun2();
printf("main:a=%f,b=%f\n",a,b);
printf("main:x=%d,y=%d\n",x,y);
}
从上可以看出只要在变量的作用域内,函数可以直接使用全局变量
#include <stdio.h>
int x,y;
extern float a,b; //利用extern声明变量a和b,扩大它们的作用域
void fun1()
{
x=1;y=2;
a=3.5;b=4.6;
printf("fun1:a=%f,b=%f\n",a,b);
printf("fun1:x=%d,y=%d\n",x,y);
}
float a,b; //全局变量a、b,作用域:从此行开始到最后
void fun2()
{
printf("fun2:a=%f,b=%f\n",a,b);
printf("fun2:x=%d,y=%d\n",x,y);
}
void main(){
fun1();
fun2();
printf("main:a=%f,b=%f\n",a,b);
printf("main:x=%d,y=%d\n",x,y);
}
局部变量和局部变量同名情况
#include <stdio.h>
int x=1,y=2; //定义全局变量x,y
void fun1()
{
x=1;y=2;
printf("fun1:x=%d,y=%d\n",x,y);
}
void main(){
int x=3,y=4; //新定义局部变量x,y
fun1();
printf("main:x=%d,y=%d\n",x,y);
}
变量的存储类型:
变量的存储类型:即变量在内存中的存储方法,不同的存储方法将影响变量在内存中存在的时间(即生存期)
计算机内存提供给触及使用的存储空间分为三部分:程序区,静态存储区和动态存储区。
程序区存放的是可执行程序的机器指令;静态存储区存放的是需要占用固定存储单元的变量:
动态存储区存放的是不需要占用固定存储单元的变量。
4个关键字来声明:auto,register,static,extern
auto类型也称为自动存储类型,定义变量时,如果没有指定其存储类型,那么系统默认为自动存储类型变量。
一般定义格式:auto 数据类型 变量名;
static类型
静态变量具有记忆功能。如果想在函数调用结束后仍然保留函数中定义的局部变量的值,即可使用static。
一般定义格式:static 数据类型 变量名
静态变量分为内部静态变量和外部静态变量。在函数内部定义的静态变量是内部静态变量,在函数之外定义的静态变量是外部静态变量。
#include <stdio.h>
int fun(int a)
{
static int c=2;
a+=c++;
return a;
}
void main()
{
int a=2,i,k;
for(i=0;i<2;i++)
k=fun(a);
printf("%d\n",k); //5
}
编译预处理
文件包含:是在一个文件中,将另一个文件的全部内容包含进来。
两种格式:#include <文件名> 或#include "文件名"
文件名是指要包含进来的文件的名称。两种格式的区别在于找寻被包含文件的范围不同。使用尖括号(<>),表示直接到指定的标准包含文件目录去寻找文件(标准包含文件目录是由用户在设置环境时设置的),不在源文件所在目录中寻找:使用双引号(“”)表示先在当前源文件所在目录中寻找,如果找不到,在到标准包含文件目录寻找。
宏定义
无参宏:不带参数的宏定义 带参宏:带参数的宏定义无
宏替换不占用运行时间
无参宏
定义格式:#define 符号变量名 字符串
符号常量名称为:宏名;大写字母表示,符号常量名与所对应的字符串用空格隔开。凡是遇到符号常量名的地方,经过编译预处理后,都被替换为它所对应的字符串。宏名的有效范围为定义命令之后到本源文件结束。但可以用#undef命令来终止宏定义的作用域
#define PI 3.14
#include <stdio.h>
void fun1()
{
float d,r
r=5.0;
d=PI*r;
#undef PI //终止了PI的宏定义,PI的有效范围到此为止
void main()
{
}
说明:预处理对符号常量的处理只是进行简单的替换工作,不作语法检查,如果程序中使用的预处理语句有错误,只能在真正的编译阶段检查出来。
宏定义允许嵌套
#define PI 3.14
#define D 2*PI
#define M a+b
#include <stdio.h>
void main()
{
int a,b,s;
printf("input a,b;\n");
scanf("a=%d,b=%d",&a,&b);
s=10*M;
printf("s=%d",s);
}
带参宏
一般格式:#define 宏名(参数表) 字符串
#define M(x) x*1o
#define M(x) x*10
#include <stdio.h>
void main()
{
int a,s;
printf("input a;\n");
scanf("a=%d",&a);
s=M(a+1);
printf("s=%d",s);
}
#include <stdio.h>
#define N 2
#define s(x) x*x
#define f(x) (x*x)
void main()
{
int i1,i2;
i1=10/s(N+1);
i2=10/f(N+2);
printf("i1=%d,i2=%d\n",i1,i2); // i1=8,i2=1
}