函数
- 一个c程序由许多小的函数组成,而不是几个大的函数。
- 一个设计得当的函数,把程序不需要了解的具体细节隐藏起来。
//test_6
//求幂运算 2^5
#include <stdio.h>
int power(int x, int y); //函数原型 也可写成int power(int, int);
//主函数
int main()
{
printf("the result is %d.\n",power(2,5)); //调用幂函数 2 5称为实际参数
return 0;
}
//求幂函数 函数定义
int power(int x, int y) //x y称为形式参数
{
int i;
int p = 1;
for(i=1; i<=y; i++)
p *= x;
return p; //返回p的值给main函数
}
函数定义的一般形式
返回值类型 函数名 (0个或多个函数参数)
{
声明部分
语句序列
}
最简单的函数
dummy(){}
#include <stdio.h>
#include <ctype.h> //isspace() isdigit()...
#define MAXLINE 1000
char string[MAXLINE]="ould";
int getaline(char line[], int lim);
int stringdex(char source[], char target[]);
double atof(char string[]);
int main()
{
char line[MAXLINE]; //因函数之间的数据交流,line设置在函数外部
int found=0;
while(getaline(line,MAXLINE)>0)
{
if(stringdex(line,string)>=0)
{
printf("the line is %s\n", line);
found++;
}
printf("the value of line is %lf\n",atof(line));
}
printf("the value of found is %d\n", found);
return found;
}
//得到一行数据
int getaline(char line[], int lim)
{
char c;
int i;
for(i=0;(c=getchar())!=EOF && c!='\n' && i<lim;i++) //判断一行结束的标志
{
if(c=='!')
return -1; //避免无限循环
line[i]=c;
}
if(c=='\n') //在字符串结尾补上'\n'
line[i++]=c;
line[i]='\0'; //在字符串结尾补上'\0'
return i;
}
//判断一行数据中是否包含指定字符串信息
int stringdex(char source[], char target[])
{
int i,j,k;
for(i=0; source[i]!='\0';i++)
{
for(j=i,k=0;source[j]==target[k] && target[k]!='\0';j++,k++)
;
if(k>0 && target[k]=='\0') //判断两个字符串匹配的依据
return i;
}
return -1;
}
//将字符串类型变换成double类型
double atof(char string[])
{
int i,sign,var;
double pow;
for(i=0;isspace(string[i]);i++) //去除前面的空格
;
sign=((string[i]=='-')?-1:1); //判断符号
if(string[i]=='+'||string[i]=='-') //跳过符号
i++;
for(var=0;isdigit(string[i]);i++) //计算数值
var=10*var+(string[i]-'0');
if(string[i]=='.') //跳过小数点
i++;
for(pow=1;isdigit(string[i]);i++) //计算数值
{
var=10*var+(string[i]-'0');
pow=pow*10; //跟踪小数位数
}
return sign*var/pow;
}
int atoi(char string[])
{
return (int)atof(string);
}
- 函数的参数和内部变量,仅在函数内部有效。对其他函数是不可见的。
- 函数之间的通信是通过函数参数,返回值,外部变量进行的。
- c语言中的函数参数,是通过“值传递”的方式,由函数调用者传递给被调函数的。被调函数接收到的函数参数,并不是原始参数,而是临时本地副本。一方面,可以减少函数中变量声明的个数,另一方面,被调函数内部对参数的操作,不会影响函数调用者中的原始参数值。
- 若需要改变函数调用者中的原始参数的值,则需要把原始参数的地址传递给被调用函数,相应的,在被调用函数的参数部分,需要将对应的参数声明为指针类型(从技术角度看,地址就是指向变量的指针)。
- 若函数的参数是数组名,传递给被调函数的是数组中首元素的地址,并不复制数组本身,被调函数可通过数组下标访问或修改数组元素的值。
- 若函数定义和调用它的函数不在同一源文件中,是单独编译的。若返回值不匹配,是无法检测出的,可能会引起数据丢失错误。
- 若返回值或者参数列表为空,默认类型为int,若为空,最好标记为void,防止错误发生。
return语句
- main()中的return 0 语句,表示程序向其执行环境返回状态,0表示正常终止。
- 一般函数,不带表达式的return语句,不返回有用的值,表示把控制权返回给调用者。
变量
- 局部变量(自动变量)。
- 函数内部定义的变量,其他函数不能访问,生命周期在此函数被调用期间。
- 不会自动被初始化,未初始化时,存储的是无效值。
- static类型,在函数多次被调用之间,保持值不变。
- 外部变量。
- 定义在所有函数之外的变量,只能被定义一次。
- 函数在使用此变量时,需要在前面添加extern关键字,进行声明。
- 函数之间可通过外部变量交换数据,而不用使用参数表。(应尽可能的以参数表的方式,而少使用外部变量)
- 若程序只有一个源文件,若变量定义在函数之前,则可以省略extern。
- 若程序包含多个源文件,变量定义在file1,变量使用在file2,则需要在file2中,用extern声明来建立该变量和定义之间的联系。一般把变量和函数的extern声明放在一个.h文件,并以#include放在file2的开头。
定义和声明
- 定义。创建变量,分配存储单元。
- 声明。说明变量的性质,但不分配存储单元。