传智播客C语言入门6_第1页
传智播客C语言入门6_第2页
传智播客C语言入门6_第3页
传智播客C语言入门6_第4页
传智播客C语言入门6_第5页
已阅读5页,还剩179页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、讲师:尹成QQ:77025077博客:http:/ 传智播客传智播客http:/高薪就业高薪就业传智播客传智播客 2.不仅仅局限于内存不仅仅局限于内存文件文件 3.灵活却难以理解灵活却难以理解指针进阶指针进阶 4.更深入的理解更深入的理解函数进阶函数进阶 5. 生存期、作用域与可见域生存期、作用域与可见域.传智播客C语言入门教程(6)大纲 1.穷人时代如何节约内存穷人时代如何节约内存位运算位运算6.初学者的疑难解答初学者的疑难解答传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客假设某个时刻,灯1和灯2亮,而其他灯都灭,此时控制字为11000000,想变换下状态,让灯1和灯3亮,

2、 其他灯灭,目标控制字为10100000,只要赋值给该单元即可。问题又来了,如果原来不知道哪几盏灯亮哪几盏灯灭,现在还是想让第3盏灯亮起来,赋值操作看来是行不通了,要如何做呢?在这个背景下,位运算的概念被提出,即能否只改变控制第3盏灯的那一位的状态?本章的剩余章节将结合开灯关灯这一场景讲述位运算的内容。总体来说,C语言中的位运算符有以下两类:位逻辑运算符:&(位“与”)、(位“异或”)、|(位“或”)、(位“取反”)。移位运算符:(右移)传智播客传智播客传智播客传智播客假设不知道哪几盏灯亮着哪几盏灯灭着,但想进行一个操作:让亮着的灯灭掉,让灭着的灯亮起来,这时就要用到位取反操作。位取反

3、的操作符为“”,如果A为10101010,那么A返回的结果为01010101,即每位都取反,0变成1,1变成0,需要注意的是,位取反运算并不改变操作数的值。假设字节A控制着8盏灯的亮灭,那么下述操作可实现预想的功能:A=A:重申,位取反运算并不改变操作数的值,是赋值运算改变了A的值。传智播客传智播客位与运算的操作符为&,将对两个操作数的每一位进行与运算,位“与”运算的准则如下:1 & 1=1 1 & 0=0 0 & 1=0 0 & 0=0不知道哪几盏灯亮着哪几盏灯灭着,想让第3盏灯灭掉,使用位与就能实现,想想看,要如何来做呢?只要在当前状态的基础上位与“

4、11011111”即可,和1位与并不会改变原来位的状态,而和0位与,无论原来是0还是1,都会变成0,灯灭。传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客#include /*使用printf要包含的头文件*/#include void main(void)/*主函数*/short czs=19889;/*声明操作数czs,初始化*/short ls=0,rs=0;/*声明两个结果变量,保存左移右移的结果*/rs=czs4;/*左移操作*/ls=czs4;/*右移操作*/printf(19889左移4位结果是%dn,ls);/*输出ls*/pri

5、ntf(19889右移4位结果是%d,rs);/*输出rs*/getch();/*等待,按任意键继续*/输出结果为:19889左移4位结果是-945619889右移4位结果是1243传智播客传智播客传智播客传智播客用最小的代码完成统计用最小的代码完成统计32位位int数据中数据中1的个数,的个数,并在此基础上实现一个位运算计算器并在此基础上实现一个位运算计算器1输入输入int类型的数据,在内存里面改变二进制,将类型的数据,在内存里面改变二进制,将上半部分全部变为上半部分全部变为0,下半部分变为,下半部分变为1,打印输出,打印输出2把一个32位的数按位反转,就是第32位转到第1位,第31位转到第

6、2位3求函数返回值,输入x=9999;intfunc(x)intcountx=0;while(x)countx+; x=x&(x-1);returncountx;4传智播客传智播客传智播客传智播客传智播客传智播客文件分类v按文件的逻辑结构:l 记录文件:由具有一定结构的记录组成(定长和不定长)l 流式文件:由一个个字符(字节)数据顺序组成v按存储介质:l 普通文件:存储介质文件(磁盘、磁带等)l 设备文件:非存储介质(键盘、显示器、打印机等)v按数据的组织形式:l 文本文件: ASCII文件,每个字节存放一个字符的ASCII码l 二进制文件:数据按其在内存中的存储形式原样存放使用数据文

7、件的目的1、数据文件的改动不引起程序的改动程序与数据分离2、不同程序可以访问同一数据文件中的数据数据共享3、能保存程序运行的中间数据或结果数据传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客磁盘文件输出文件缓冲区输入文件缓冲区程序数据区a缓冲文件系统:缓冲区指令区程序用户数据区磁盘非缓冲文件系统:传智播客传智播客传智播客传智播客传智播客传智播客typedef struct int _fd; /文件号 int _cleft; /缓冲区中剩下的字符数 int _mode; /文件操作方式 char *_next; /文件当前读写位置 char *_buff; /文件缓冲区位置FIL

8、E;传智播客传智播客文件名文件使用方式文件类型指针C程序操作系统磁盘传智播客传智播客传智播客传智播客传智播客传智播客v功能:按指定方式打开文件v返值:正常打开,为指向文件结构体的指针;打开失败,为NULL要打开的文件名使用文件方式例 文件打开与测试 FILE *fp; fp=fopen(“aa.c”,“w”); if(fp=NULL) printf(“File open error!n”); exit(0); 例 FILE *fp; fp= fopen (“c:fengyibkctest.dat”,”r”); 例 FILE *fp; char *filename=“c:fengyibkctes

9、t.dat” fp= fopen(filename,”r”); “r+/rb+” (读写)“a/ab” (追加)“w/wb” (只写)“r/rb” (只读)“w+/wb+” (读写)“a+/ab+” (读写)为输入打开一个文本/二进制文件为输出打开或建立一个文本/二进制文件为读/写打开一个文本/二进制文件为读/写建立一个文本/二进制文件为读/写打开或建立一个文本/二进制文件向文本/二进制文件尾追加数据文件使用方式含义传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客v功能:关闭fp指向的文件v返值:正常关闭为0;出错时,非0文件打开时返回的文件类型指针磁盘文件输出文件缓冲区输入文

10、件缓冲区程序数据区a缓冲文件系统:fclose不关闭文件可能会丢失数据传智播客传智播客 文件I/O与终端I/O#define putc(ch,fp) fputc(ch,fp)#define getc(fp) fgetc(fp)#define putchar( c ) fputc(c,stdout)#define getchar( ) fgetc(stdin)字符I/O:fputc与fgetcfputc函数原型:int fputc(int c, FILE *fp)功能:把一字节代码c写入fp指向的文件中返值:正常,返回c;出错,为EOFfgetc函数原型:int fgetc(FILE *fp)功

11、能:从fp指向的文件中读取一字节代码返值:正常,返回读到的代码值;读到文件尾或出错,为EOF传智播客传智播客传智播客传智播客传智播客传智播客 判断二进制文件是否结束 while(!feof(fp) c=fgetc(fp); . 例 文件拷贝例 从键盘输入字符,逐个 存到磁盘文件中,直到 输入#“为止#include main() FILE *fp; char ch,*filename=“out.txt”; if(fp=fopen(filename,w)=NULL) printf(cannot open filen);exit(0); printf(Please input string:);

12、ch=getchar(); while(ch!=#) fputc(ch,fp); putchar(ch); ch=getchar(); fclose(fp);例 读文本文件内容, 并显示#include main() FILE *fp; char ch,*filename=“out.txt”; if(fp=fopen(filename,”r)=NULL) printf(cannot open filen); exit(0); while(ch=fgetc(fp)!=EOF) putchar(ch); fclose(fp);判断文本文件是否结束vfeofl 函数原型: int feof(FILE

13、 *fp)l 功能:判断文件是否结束l 返值:文件结束,返回真(非0);文件未结束,返回0#include main() FILE *in, *out; char ch,infile10,outfile10; scanf(%s,infile); scanf(%s,outfile); if (in = fopen(infile, r)= NULL) printf(Cannot open infile.n); exit(0); if (out = fopen(outfile, w)= NULL) printf(Cannot open outfile.n); exit(0); while (!feo

14、f(in) fputc(fgetc(in), out); fclose(in); fclose(out);传智播客传智播客传智播客传智播客size_t fread(void *buffer,size_t size, size_t count,FILE *fp)size_t fwrite(void *buffer,size_t size, size_t count,FILE *fp)v功能:读/写数据块v返值:成功,返回读/写的块数;出错或文件尾,返回0v说明:l typedef unsigned size_t;l buffer: 指向要输入/输出数据块的首地址的指针l size: 每个要读/写

15、的数据块的大小(字节数)l count: 要读/写的数据块的个数l fp: 要读/写的文件指针l fread与fwrite 一般用于二进制文件的输入/输出传智播客传智播客传智播客传智播客例 float f2; FILE *fp; fp=fopen(“aa.dat”,“rb”); fread(f,4,2,fp);for(i=0;i2;i+) fread(&fi,4,1,fp);例 struct student int num; char name20; char sex; int age; float score3; stud10; for(i=0;i10;i+) fread(&

16、studi,sizeof(struct student),1,fp);传智播客传智播客例 从键盘输入4个学生数据,把他们转存到磁盘文件中去#include #define SIZE 2struct student_type char name10; int num; int age; char addr15;studSIZE;main() int i; for(i=0;iSIZE;i+)scanf(%s%d%d%s,,&studi.num, &studi.age,studi.addr); save(); display();void save() FILE

17、*fp; int i; if(fp=fopen(d:fengyiexestu_dat,wb)=NULL) printf(cannot open filen); return; for(i=0;iSIZE;i+) if(fwrite(&studi,sizeof(struct student_type),1,fp)!=1) printf(file write errorn); fclose(fp);void display() FILE *fp; int i; if(fp=fopen(d:fengyiexestu_dat,rb)=NULL) printf(cannot open filen

18、); return; for(i=0;iSIZE;i+) fread(&studi,sizeof(struct student_type),1,fp); printf(%-10s %4d %4d %-15sn,, studi.num,studi.age,studi.addr); fclose(fp);传智播客传智播客传智播客传智播客int fprintf(FILE *fp,const char *format,argument,)int fscanf(FILE *fp,const char *format,address,)v功能:按格式对文件进行I/O操作v返值:

19、成功,返回I/O的个数;出错或文件尾,返回EOF例 fprintf(fp,“%d,%6.2f”,i,t); /将i和t按%d,%6.2f格式输出到fp文件 fscanf(fp,“%d,%f”,&i,&t); /若文件中有3,4.5 ,则将3送入i, 4.5送入t例 从键盘按格式输入数据存到磁盘文件中去#include main() char s80,c80; int a,b; FILE *fp; if(fp=fopen(test,w)=NULL) puts(cant open file); exit() ; fscanf(stdin,%s%d,s,&a);/*read

20、from keaboard*/ fprintf(fp,%s %d,s,a);/*write to file*/ fclose(fp); if(fp=fopen(test,r)=NULL) puts(cant open file); exit(); fscanf(fp,%s%d,c,&b);/*read from file*/ fprintf(stdout,%s %d,c,b);/*print to screen*/ fclose(fp);传智播客传智播客v函数原型:char *fgets(char *s,int n,FILE *fp) int fputs(char *s,FILE *f

21、p)v功能:从fp指向的文件读/写一个字符串v返值:l fgets正常时返回读取字符串的首地址;出错或文件尾,返回NULLl fputs正常时返回写入的最后一个字符;出错为EOF例 从键盘读入字符串存入文件,再从文件读回显示fgets从fp所指文件读n-1个字符送入s指向的内存区,并在最后加一个0(若读入n-1个字符前遇换行符或文件尾(EOF)即结束)fputs把s指向的字符串写入fp指向的文件#includemain() FILE *fp; char string81; if(fp=fopen(file.txt,w)=NULL) printf(cannt open file);exit(0)

22、; while(strlen(gets(string)0) fputs(string,fp); fputs(n,fp); fclose(fp); if(fp=fopen(file.txt,r)=NULL) printf(cannt open file);exit(0); while(fgets(string,81,fp)!=NULL) fputs(string,stdout); fclose(fp);传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客#includeint main() FILE *f

23、p1,*fp2; fp1=fopen(“file1.dat”,“r”); fp2=fopen(“file2.dat”,“w”); while(!feof(fp1) putchar(getc(fp1); putchar(10); rewind(fp1); while(!feof(fp1) putc(getc(fp1),fp2); fclose(fp1); fclose(fp2); return 0;传智播客传智播客随机生成随机生成100000个实数,然后保存入文件,然后个实数,然后保存入文件,然后从文件里面加载,然后求平均值从文件里面加载,然后求平均值1输入输入10个实数,然后写到文件,然后读取

24、,然后个实数,然后写到文件,然后读取,然后打印出最大的,最小的,打印出最大的,最小的,2创建创建10个结构体,然后初始化,写到文件,然后个结构体,然后初始化,写到文件,然后读取出来读取出来3随机生成随机生成100000个数字写到文件,要求写到文件个数字写到文件,要求写到文件有序,然后输入一个值,用二分法查找出来有序,然后输入一个值,用二分法查找出来4传智播客传智播客指针函数变量数组指针结构体地址传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客 char name59=“gain”,“much”,“stronger”, “point”,“bye”;

25、 char *name5=“gain”,“much”,“stronger”, “point”,“bye”;g a i n 0s t r o n g e r 0p o i n t 0m u c h 0name0name1name2name3name4b y e 0g a i n 0s t r o n g e r 0p o i n t 0m u c h 0b y e 06.3.6二维数组与指针数组区别二维数组存储空间固定字符指针数组相当于可变列长的二维数组分配内存单元=数组维数*2+各字符串长度指针数组元素的作用相当于二维数组的行名但指针数组中元素是指针变量二维数组的行名是地址常量传智播客传智播客

26、F o ll o w 0G r e a t 0F O R T R A N 0C o m p u t e r 0传智播客传智播客F o ll o w 0G r e a t 0F O R T R A N 0C o m p u t e r 0name0name1name2name3namep传智播客传智播客F o ll o w 0G r e a t 0F O R T R A N 0C o m p u t e r 0name0name1name2name3namep传智播客传智播客传智播客传智播客&a0&a1&a2&a3&a4p12345传智播客传智播客传智播客

27、传智播客传智播客传智播客#include int main(int argc,char *argv) while(argc1) +argv; printf(“%sn”, *argv); -argc; return 0;传智播客传智播客传智播客传智播客传智播客传智播客就像数组名是指向数组元素首地址的常指针一样,函数名也是指向函数的指针,函数在内存中也有对应的一块存储单元,函数名便是指向该块内存的常指针,换句话说,通过函数名确定要执行的代码块在内存中的位置。为了验证上面的结论,我们来亲自实践一下。传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客用同一个函数指针实现加

28、减乘数运算,并将函数用同一个函数指针实现加减乘数运算,并将函数指针用作参数指针用作参数.1创建一个创建一个5维数组,每组维数组,每组5个元素,设计一个方案个元素,设计一个方案用指针找出最大的数与最小的数用指针找出最大的数与最小的数.(感觉困难的同(感觉困难的同学实现三维数组)学实现三维数组)2创建一个创建一个3维结构体数组,结构体为姓名与分数维结构体数组,结构体为姓名与分数,每组,每组5个元素,设计一个算法,用指针数组找个元素,设计一个算法,用指针数组找出得分最高与得分最低的姓名,分数可能重合。出得分最高与得分最低的姓名,分数可能重合。3用指向指针的指针,实现加减乘除运算用指向指针的指针,实现

29、加减乘除运算4传智播客传智播客本节从更深层次帮助大家理解函数。从和函数关系最密切的调用和返回入手,函数的参数传递有传值,传指针2种方式,从类型的角度上看,参数不仅仅可以是系统内建的数据类型,还可以是数组、结构等。此外,递归编程机制,函数的作用域和可见域,变量的生存期、作用域和可见域等都是本章讨论的重点。传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客(1)把数组的元素作实参 int a=1,2,3 fun1(a2)(2)

30、把数组名作实参 int a=1,2,3 fun2(a)传智播客传智播客数组名作函数参数v数组名作函数参数,是地址传递v数组名作函数参数,实参与形参的对应关系实参形参数组名指针变量数组名指针变量数组名数组名指针变量指针变量传智播客传智播客传智播客传智播客当用数组名作为函数实参时,函数形参会接收到此数组的首地址。这就意味着函数形参数组首地址等于实参数组首地址。在函数中对形参数组的操作直接作用于实参数组。void main() int a3=4,5,6; f(a);/数组名作实参 void f(int b3) b0=8;b1=9; b2=10; 传智播客传智播客99void main() float

31、 s5=80,82,70,90,68; float a1=f1(s0,s1,s2,s3,s4);/数组元素作实参 float a2=f2(s,5); /数组名(数组首地址)作实参 float a1(float a,float b,float c,float d,float e) return (a+b+c+d+e)/5;float a2(float score,int n) float result=0; int i; for (i=0;in;i+) result+=scorei; return result/n;在调用函数时需要传递多个实参,效率低、通用性差在调用函数时只需传递两个实参,效率

32、高、通用性强传智播客传智播客例 将数组a中的n个整数按相反顺序存放 ij 3 7 9 11 0 6 7 5 4 20 1 2 3 4 5 6 7 8 9ijijijji11760594723实参与形参均用数组void inv(int x, int n) int t,i,j,m=(n-1)/2; for(i=0;i=m;i+) j=n-1-i; t=xi; xi=xj; xj=t; main() int i,a10=3,7,9,11,0,6,7,5,4,2; inv(a,10); printf(The array has been reverted:n); for(i=0;i10;i+) pri

33、ntf(%d,ai); printf(n);m=4传智播客传智播客例 将数组a中的n个整数按相反顺序存放 void inv(int *x, int n) int t,*p,*i,*j,m=(n-1)/2; i=x; j=x+n-1; p=x+m; for(;i=p;i+,j-) t=*i; *i=*j; *j=t; main() int i,a10=3,7,9,11,0,6,7,5,4,2; inv(a,10); printf(The array has been reverted:n); for(i=0;i10;i+) printf(%d,ai); printf(n);实参用数组,形参用指针

34、变量37911067542a0a1a2a3a4a5a6a7a8a9xp=x+ma数组60711594723ijijijjiji传智播客传智播客例 将数组a中的n个整数按相反顺序存放 void inv(int *x, int n) int t,*i,*j,*p,m=(n-1)/2; i=x; j=x+n-1; p=x+m; for(;i=p;i+,j-) t=*i; *i=*j; *j=t; main() int i,a10,*p=a; for(i=0;i10;i+,p+) scanf(%d,p); p=a; inv(p,10); printf(The array has been revert

35、ed:n); for(p=a;pa+10;p+) printf(%d,*p);实参与形参均用指针变量传智播客传智播客例 将数组a中的n个整数按相反顺序存放 void inv(int x, int n) int t,i,j,m=(n-1)/2; for(i=0;i=m;i+) j=n-1-i; t=xi; xi=xj; xj=t; main() int i,a10,*p=a; for(i=0;i10;i+,p+) scanf(%d,p); p=a; inv(p,10); printf(The array has been reverted:n); for(p=arr;parr+10;p+) pr

36、intf(%d ,*p);实参用指针变量,形参用数组传智播客传智播客算法图例:算法图例:从数列中查找从数列中查找 二分查找法的执行效率很高二分查找法的执行效率很高传智播客传智播客等价于:int *m, num, key ;传智播客传智播客传智播客传智播客递归是程序设计中的一种算法,或者说是一种编程机制。一个函数直接调用自己本身或者通过调用其他函数来间接地调用自己,称为递归函数,递归在编程时候很有多用途,可以简化问题。传智播客传智播客传智播客传智播客传智播客传智播客ABC传智播客传智播客传智播客传智播客#include int main() void hanoi(int n,char one,

37、char two,char three); int m; printf(“the number of diskes:); scanf(%d,&m); printf(move %d diskes:n,m); hanoi(m,A,B,C);void hanoi(int n,char one,char two, char three) void move(char x,char y); if(n=1) move(one,three); else hanoi(n-1,one,three,two); move(one,three); hanoi(n-1,two,one,three); 传智播客传

38、智播客传智播客传智播客传智播客传智播客实现一个函数,传入数组,对数组进行排序,但实现一个函数,传入数组,对数组进行排序,但是不允许开创新的空间,是不允许开创新的空间,1实现一个函数,修改一个指针变量。实现一个函数,修改一个指针变量。2创建一个函数,进行递归运算实现创建一个函数,进行递归运算实现1 +(12)+(123)+31+2+3+4+n分别用传值与传址,递归与非递归分别用传值与传址,递归与非递归两种函数实现,两种函数实现,4传智播客传智播客传智播客传智播客传智播客传智播客标准C语言支持四种变量存储类型。说明符如下:autostaticexternregister 储存类型储存类型传智播客传

39、智播客一个由C编译的程序占用的内存大致分为以下几部分:栈区(stack):由编译器自动分配释放,存放函数的参数值,局部变量的值等。堆区(heap):一般由程序员分配释放(动态内存申请与释放),若程序员不释放,程序结束时可能由操作系统回收。全局区(静态区)(static):全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域,该区域在程序结束后由操作系统释放。常量区:字符串常量和其他常量的存储位置,程序结束后由操作系统释放。程序代码区:存放函数体的二进制代码。 传智播客传智播客传智播客传智播客传智播客传智播客传智播客

40、传智播客void fun(int x) int y; if (x0) int x; 成对的大括号及内部的语句组成了程序块。函数体、选择和循环结构中都要用大括号表示边界。大括号内定义的变量,必须紧跟在左大括号后面,其作用范围是从定义处直到配对的右大括号之前。若多层大括号中出现重名变量,外层同名变量在内层中被屏蔽不起作用。z作用域x作用域y作用域传智播客传智播客变量可以在程序中三个地方说明:函数的参数定义部分函数的参数定义部分 形式参数形式参数函数内部函数内部 局部变量局部变量函数外部函数外部 全局变量全局变量( (即大括号外的变量即大括号外的变量)传智播客传智播客在函数内定义的变量,其作用范围局

41、限于此函数体内部,这种变量叫局部变量,函数的形参、在main函数中定义的变量也是局部变量。局部变量在函数被调用时由系统分配存储区,在不同的函数中同名的变量实际上在内存中占不同的单元,因此在不同的函数中可以定义相同名字的局部变量。传智播客传智播客#include “stdio.h”void fun(int x, int y) int z=10; x+=10; y+=10; if(z) int z=20; printf(“x=%d y=%d z=%dn”, x, y, z); printf(“x=%d y=%d z=%dn”, x, y, z);int main() int x=10, y=10,

42、 z=10; fun(x, y); printf(“x=%d y=%d z=%d”, x, y, z); return 0; 程序的运行结果是:x=20 y=20 z=20 x=20 y=20 z=10 x=10 y=10 z=10传智播客传智播客在任何大括号外面定义的变量叫全局变量,其作用范围是从定义处直到文件末尾。由于全局变量作用范围很大,若在某个函数中修改了全局变量的值,在其它函数中读出的就是这个新值。建议:用大写字母命名全局变量,便于区分局部变量。传智播客传智播客#include “stdio.h”int x,y;void fun() int a=20, b=10; x=x+a+b;/

43、x=8+20+10 y=y+a-b;/y=2+20-10int main() int a=5, b=3; x=a+b; /x=8 y=a-b;/y=2 fun(); printf(“%d, %d”, x, y);/x=38, y=12 return 0; 传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客 x=1,y=2,z=3;printf(x is %d,y is %d,z is %dn,x,y,z);/*#1*/*此处记为B行,声明的y,作用域和生存期为从B行到#4,屏蔽了A行定义的y*/int y=6;printf(x is %d,y is %d,z is %dn,x,y

44、,z);/*#2*/*此处记为C行,声明的y和z,作用域和生存期为从C行到#3*/*屏蔽了B行定义的y和A行定义的z*/int y=8,z=9;printf(x is %d,y is %d,z is %dn,x,y,z);/*#3*/printf(x is %d,y is %d,z is %dn,x,y,z);传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客编译器会自动优化设置程序运行时变量的存放位置,用户不必做此声明传智播客传智播客register int i=0;register int i=0;/ /* *寄存器变量寄存器变量* */ /double sign=1.0,r

45、es=0,ad=1.0;double sign=1.0,res=0,ad=1.0;for(i=1;i=100000000;i+)for(i=1;i=100000000;i+) res=res+ad;res=res+ad;sign=-sign;sign=-sign;ad=sign/(2ad=sign/(2* *i+1);i+1); res=resres=res* *4;4;printf(pi is %f,res);printf(pi is %f,res);/ /* *输出结果输出结果* */ /传智播客传智播客传智播客传智播客extern int x; /提升全局变量x作用范围至此void ma

46、in() x+; int x=8;void f1() x-;若在全局变量定义处之前想要访问这个变量,可以在相应的地方用“extern”关键字提前声明此变量,从而将在后面定义的全局变量作用范围扩展到前面来。x原来的作用范围x现在的作用范围传智播客传智播客140void num() extern int x,y;/*将全局变量x, y作用域扩展到此处*/ int a=15,b=10; x=a-b; y=a+b;int x,y;/* 全局变量x, y */int main() int a=7,b=5; x=a+b;/* x=7+5 */ y=a-b;/* y=7-5 */ num(); printf

47、(“%d,%d”,x,y); return 0; 程序的运行结果是:5, 25传智播客传智播客全局变量的作用范围还可以扩展至其它C程序文件,只需要在其它C程序文件中使用extern关键字说明一下即可。int A;void printValue();/声明函数int main() A=0; printValue(); return 0; extern int A; /声明外部变量Avoid printValue() printf(“%d”, A); A+;prog1.cprog2.c传智播客传智播客若要禁止某个函数被其他C文件用extern关键字方式扩展过去访问,可以在定义此函数时用static

48、关键字限制。此函数就成了内部函数。extern void secret( );extern void public( );int main() secret( );/错误 public( ); /正确 return 0; static void secret( ) /此函数只能本文件中访用void public( ) /此函数其他文件也能访问prog1.cprog2.c传智播客传智播客C程序一般都由多个源代码文件构成,函数可以被多个文件访问。只需在其他文件中将要访问的函数原型用extern关键字说明即可。extern void public1( );extern void public2( )

49、;int main() public1( ); /正确 public2( ); /正确 return 0; void public1( ) /此函数其他文件也能访问void public2( ) /此函数其他文件也能访问prog1.cprog2.c传智播客传智播客传智播客传智播客传智播客传智播客 int main() int max( ); extern int A,B,C; scanf(“%d %d %d”,&A,&B,&C); printf(max is %dn,max(); return 0;int A ,B ,C;int max( ) int m; m=AB?A

50、:B; if (Cm) m=C; return(m); 传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客file1.cstatic int A;int main ( ) file2.cextern A;void fun (int n) A=A*n; 只能用于本文件只能用于本文件本文件仍然不能用本文件仍然不能用传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客在auto变量一节中提到,内层代码块中声明的变量将屏蔽外层代码块中声明的同名变量,屏蔽准则对全局变量同样适用extern int x=10;/*全局变量x定义,带初始表达式*/d

51、ouble y=30;/*extern可省略,只要定义在外部即可*/void main(void)/*主函数*/extern float z;/*声明全局变量z*/z=5;/*对全局变量的操作*/void print(void);/*print函数声明*/print();/*print函数调用*/printf(x is %d ,y is %f ,z is %fn,x,y,z);/*输出全局变量*/getch();/*等待,按任意键结束*/float z;/*全局变量z定义,默认初始化为0*/void print()/*print函数*/int x=1;/*局部变量屏蔽全局变量*/double

52、y=3;printf(x is %d ,y is %f ,z is %fn,x,y,z);/*输出局部变量*/传智播客传智播客传智播客传智播客在函数中定义的static变量与auto变量的区别: 在函数调用结束时:自动变量会被自动销毁,而静态变量会被始终保留于内存直至整个程序结束后才被销毁。当再次调用该函数时, 将使用上次函数被调用时该静态变量被设置的值。传智播客传智播客传智播客传智播客int fun(int a)/* a是自动变量 */ int b=0;/* b是自动变量,调用后重新赋值 */ static int c=3;/* c是静态变量 *,编译就赋值/ b+; c+; return

53、(a+b+c);int main() int x=2, i; for (i=0; i3; i+) printf(“%dn”, fun(x); return 0; 程序的运行结果是:789传智播客传智播客#include /实现12345int main() int fac(int n); int i; for(i=1;i=5;i+) printf(“%d!=%dn”,i,fac(i); return 0;int fac(int n) static int f=1; f=f*n; return(f); 传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客传智播客静态局部整型变量或静态局部整型变量或静态外部整型变量静态外部整型变量自动变量,在自动变量,在函数内定义函数内定义寄存器变量,寄存器变量,在函数内定义在函数内定义将已定义的外部变量将已定义的外部变量b的作用域扩展至此的作用域扩展至此传智播客传智播客从作用域角度分,有局部变量和全局变从作用域角度分,有局部变量和全局变量。它们采用的存储类别如下:量。它们采用的存储类别如下:按作用域角度分按作用域角度分

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论