简单笔记(三)

来源:互联网 发布:淘宝二手电脑怎么检测 编辑:程序博客网 时间:2024/05/01 08:00

 10.11.16

1.6 数组
以下程序为统计各个数字、空白字符(空格符、制表符及换行符)以及所有其他字符出现次数的程序。
#include <stdio.h>
 
/*统计各个数字、空白字符及其他字符出现的次数*/
main ()
{
int c,i,nwhite,nother;
int ndigit[10];
 
nwhite=nother=0;
for(i=0;i<10;++i)
 ndigit[i]=0;
 
while((c=getchar())!=EOF)
 if(c>='0'&&c<='9')
++ndigit[c-'0'];
 else if(c==' '||c='/n'||c=='/t')
++nwhite;
 else 
++nother;
 
printf("digits =");
for(i=0;i<10;++i)
 printf(" %d",ndigit[i]);
 printf(",white space = %d,other = %d", nwhite,nother);
}
程序中的说明语句
int ndigit[10];
用于把ndigit说明为由10个整数组成的数组。在C语言中,数组下标总是从0开始。
1.7 函数
定义一个求幂的函数power(m,n)来说明定义函数的方法。
该函数用于计算整数m的正整数次幂n,如power(2,5)的值为32。(在标准库中包含了一个用于计算x的y次幂的函数pow(x,y)。)
下面给出函数power(m,n)的定义及调用它的主程序:
#include <stdio.h>
 
int power(int m,int n);
 
/*测试power函数*/
main()
{
int i;
 
for(i=0;i<10;++i)
 printf("%d %d/n",i,power(2,i),power(-3,i));
return 0;
}
 
/*power: 求底的n次幂;n>=0 */
int powe(int base,int n)
{
int i,p;
 
p=1;
for(i=1;i<=n;++i)
 p=p*base;
return p;
}
函数定义的一般形式为:
返回值类型函数名(可能有的参数说明)
{
说明素列
语句序列
}
power函数本身的第一行
int power(int base,int n)
说明参数的类型与名字以及该函数返回的结果的类型。power的参数名只能在power内部使用,在其它函数中不可见:在其它函数中使用与其相同的参数名而不会发生冲突。
一般而言,把在函数定义中永远括号括住的表中命名的变量称为参数,而把函数调用中与参数对应的值叫变元。为了表示两者的区别,有时也用形式变元与实际变元这两个术语。
power函数计算的的值由return语句返回给main函数。关键词return可以后跟任何表达式:
return 表达式;
1.8 变元--按值调用
在C语言中,所有函数变元都是“按值”传递的。这意味着,被调用函数所得到的变元值放在临时变量中而不是放在原来的变量中。这样它的性质就与诸如FORTRAN等采用“按引用调用”的语言或诸如Pascal等采用var参数的语言有所不同,在这些语言中,被调用函数必须访问原来的变元,而不是采用局部复制的方法。
最主要的区别在于,在C语言中,被调用函数不能直接更改调用函数中变量的值,他只能更改其私有临时拷贝的值。
1.9 字符数组
C语言中最常用的数组类型是字符数组。
下面来编写一段程序,它用于读入一组文本行并把最长的文本行打印出来。对算法描述相当简单:
while(还有没有处理的行)
 if(该行比已处理的最长的行还要长)
保存该行
保存该行的长度
打印最长的行
这一算法描述很清楚,很自然地把所要编写的程序分成了若干部分,分别用于读入新行、测试读入的行、保存该行及控制这一过程。
首先编写一个独立的函数getline来读取输入的下一行。我们想使这个函数在其他地方也能使用。getline函数至少在读到文件末尾是要返回一个信号,而更有用的设计是它能在读入文本行时返回该行的长度,而在遇到文件结束符时返回0.由于0不是有效的行长度,因此是一个可以接受的标记文件结束的返回值。每一行至少要有一个字符,只包含换行符的行的长度为1.
当发现某一个新读入的行比以前读入的最长的行还要长时,就要把该行保存起来。这意味着需要用的二个函数copy来把新行复制到一个安全的位置。
最后,需要用主函数main来控制对getline和copy这两个函数的调用。整个程序如下:
#include <stdio.h>
#defineMAXLINE1000/*最大数入行的大小*/
 
int getline (char line[],int maxline);
void copy(char to[],char from[]);
 
/*打印最长的输入行*/
main()
{
int  len;/*当前行长度*/
int  max;/*至目前为止所发现的最长行的长度*/
char line[MAXLINE];/*当前出输入的行*/
char longest[MAXLINE];/*用于保存最长的行*/
 
max=0;
while((len=getline(line,MAXLINE))>0)
 if(len>max)
 {
max=len;
copy(longest,line);
 }
if(max>0)/*有一行*/
 printf("%s",longest);
return 0;
}
 
/*getline:将一行读入s中并返回其长度*/
int getline(char s[],int lim)
{
int c,i;
 
for(i=0;i<lim-1&&(c=getchar())!=EOF&&c!='/n';++i)
 s[i]=c;
if(c=='/n')
{
 s[i]=c;
 ++i;
}
s[i]='/n';
return i;
}
 
/*copy:从from拷贝到to;假定to足够大*/
void copy(char to[],char from[])
{
int i;
 
i=0;
while((to[i]=from[i])!='/n')
 ++i;
}
在程序的一开始就对getline和copy这两个函数进行了说明,假定它们都放在同一文件中。
1.10 外部变量与作用域
main函数中的变量(如line、longest等)是main函数私有的或称局部于main函数的。由于它们是在main函数中说明的,其他函数不能直接访问它们。在其他函数中说明的变量也同样如此,例如,getline函数中说明的变量i与copy函数中说明的变量i没有关系。函数中的每一个局部变量值在该函数被调用时存在,在该函数执行完推出时消失。以后我们将用自动变量来之局部变量。
由于自动变量只在函数调用执行期间存在,故在函数的两次调用期间自动变量不保留在前次调用时所赋得值,且在函数的每次调用执行时都要显示给其赋值。如果没有给自动变量赋初值,那么其中所存放那个的是无用数据。
作为对自动变量的替补,可以定义适用于所有函数的外部变量,即可以被所有函数通过变量名访问的变量。由于外部变量可以全局访问,因此可以用外部变量替代变元表用于在函数间交换数据。而且,外部变量在程序执行期间一直存在,而不实在函数调用时产生、在函数执行完时消失,即使从为其赋值的函数返回后仍保留原来的值不变。
外部变量必须在所有函数之外定义,且只能定义一次,定义的目的是为之分配存储单元。在每一个函数中都要对所要访问的外部变量进行说明,说明所使用外部变量的类型。在说明是可以用extern语句显式指明,也可以通过上下文隐式说明。为了更具体的讨论外部变量,我们重写上面用于打印最长行的程序,把line、longest与max说明成外部变量。这需要修改所有这三个函数的调用、说明与函数体。
#include <stdio.h>
 
#define MAXLINE 1000/*最大数入行的大小*/
 
int max;/*至目前为止所发选的最长航的长度*/
char line[MAXLINE];/*当前输入的行*/
char longest[MAXLINE];/*用于保存最长的行*/
 
/*打印最长的输入行;特别版版本*/
main()
{
int len;
extern int max;
extern char longest[ ];
 
max=0;
while((len=getline())>0)
 if(len>max)
 {
max=len;
copy();
 }
if(max>0)/*有一行*/
 printf("%s",longest);
return 0;
}
 
/*getline:特别版本*/
int getline(void)
{
int c,i;
extern char line[];
 
for(i=0;i<MAXLINE-1&&(c=getchar())!=EOF&&c!='/n';++i)
 line[i]=c;
if(c=='/n')
{
 line[i]=c;
 ++i;
}
line[i]='/0';
return i;
}
 
/*copy:特别版本*/
void copy(void)
{
int i;
extern char line[],longest[];
 
i=0;
while((longest[i]=line[i])!='/0')
 ++i;
 
}
在某些情况下,extern说明可以省略。如果外部变量的定义在源文件中出现在使用它的函数之前,那么在该函数中就没有必要使用extern说明。事实上,比较常用的做法是把所有外部变量的定义放在源文件的开始处,这样就可以省略extern说明。
读者应该注意到,这一节我们在说到外部变量时很小心谨慎地使用着两个词定义和说明。“定义”指变量建立或分配存储单元的位置,而“说明”则指明变量性质的位置,但并不分配存储单元。