学习笔记---大型程序基础

多文件组织


概念:一个完整的程序被存放在多于一个文件中时,称为程序的多文件组织


意义:在设计一个功能复杂的大程序时,为了便于程序的设计和调试,通常将程序分成若干个文件,把实现一个模块的程序或数据放在一个文件中。


调用外部函数


代码示例:


main.c:

#include <stdio.h>
#include <stdlib.h>
int max(int x,int y);//对max函数进行声明
int main()
{
    int a,b,c;
    printf("输入两数:");
    scanf("%d %d",&a,&b);
    c=max(a,b);//调用另一个文件中的函数
    printf("max=%d\n",c);
    return 0;
}
max.c:

int max(int x,int y)
{
    int z;
    z=x>y?x:y;
    return z;
}
程序结构图:


结果:


解析:

1.这里将main.c中用到的max函数放在max.c文件中。因为两个文件是同一个项目下的。所以程序运行时可以识别并调用max.c中的max函数。并成功运行。

2.程序运行将从main函数开始。在main函数中调用max函数之前,必须在main.c文件中对max函数进行声明!

3.如果max函数中用到了诸如printf之类的需要头文件的函数,必须在max.c文件中进行include进行头文件声明


调用外部头文件

代码示例:

main.c:

/*这个程序用来测试外部头文件*/
#include "head.h"//调用外部头文件

int main()
{
    int a;
    scanf("%d",&a);
    printf("Test Success!\na=%d",a);
    return 0;
}
head.h:

#ifndef HEAD_H_INCLUDED
#define HEAD_H_INCLUDED
/*头文件从此开始*/
#include <stdio.h>
#include <stdlib.h>
/*头文件从此结束*/
#endif // HEAD_H_INCLUDED

程序结构图:


结果:



解析:

1.将函数声明、全局变量定义、库函数引用打包成为.h形式的头文件,并在需要时调用,使代码更简洁。提高可读性

2.main.c中调用头文件注意#include "head.h"要用双引号而非小括号!



程序文件分类:


头文件(.h)

包含:函数声明、全局变量定义、库函数引用


源文件(.c)

包含:主体代码


连编程序:


连编编译源文件,并将其与库函数文件连接(先编译,后连接)


图解:


解析:

源文件先被编译成.o.obj文件(后缀名根据系统不同改变)

保存在项目文件夹中的obj文件夹中,如图:


接着将以编译的.o.obj文件和库函数文件.lib连接,生成.exe的可执行文件

保存在项目文件夹的bin文件夹中,如图:




静态函数与外部函数


外部函数


定义:可供其他文件调用的函数


关键代码:extern


用法:extern 返回值类型 函数名 ([参数表列])


代码示例:

main.c:

#include <stdio.h>
#include <stdlib.h>
extern int max(int x,int y);//对max函数进行声明,用extern表明max函数的本体在其他文件中。
int main()
{
    int a,b,c;
    printf("输入两数:");
    scanf("%d %d",&a,&b);
    c=max(a,b);//调用另一个文件中的函数
    printf("max=%d\n",c);
    return 0;
}
max.c:

extern int max(int x,int y)//用extern使max成为外部函数
{
    int z;
    z=x>y?x:y;
    return z;
}
结果:


解析:

1.在定义函数时,在函数首部的最左端冠以extern使之成为外部函数。
2.在需要调用此函数的文件中,用extern声明所用的函数是外部函数。


注1:extern是默认参数!既函数定义时不加前缀,则默认是外部函数,允许被其他文件调用。而在其他文件中声明调用外部函数时,即使不使用extern前缀,系统也会默认其调用的是外部函数。extern可省略)

注2:在编译中,遇到调用外部函数,编译器会假定这个函数的定义存在,只不过在不在当前文件中,并正常产生目标文件。不会因为外部函数未定义报错。

注3:在连接时,会检查编译器得到的若干目标文件中的函数,以及包括的库文件内提供的函数,如果命名唯一,且外部函数定义正常。产生可执行的目标文件.exe;否则,连接失败。

注4:编写大型程序,需要定义大量函数。对于需要外部调用的函数,应该主动加上extern修饰,以便代码阅读。



静态函数(内部函数)


定义:不可供其他文件调用的函数


关键代码:static


用法:static返回值类型 函数名 ([参数表列])


代码示例:

main.c:

#include <stdio.h>
#include <stdlib.h>
int max(int x,int y);//对max函数进行声明
int main()
{
    int a,b,c;
    printf("输入两数:");
    scanf("%d %d",&a,&b);
    c=max(a,b);//调用另一个文件中的函数
    printf("max=%d\n",c);
    return 0;
}
max.c:

static int max(int x,int y)//使用static将max变成静态函数
{
    int z;
    z=x>y?x:y;
    return z;
}
结果:



解析:如图,连接时报错,无法找到max函数的定义。


注1:编写大型程序时,需要定义大量的函数。如果这些函数出现重名,会在编译中出现错误。而将函数定义为静态,即使其他文件中出现同名静态函数,也不会冲突。

注2:通常把只允许在同一文件中使用的函数和全局变量前面都冠以static使之局部化,从而其他文件都不能引用。


外部全局变量和静态全局变量


外部全局变量


关键代码:extern


扩展同文件全局变量的作用范围


代码示例:

#include <stdio.h>
#include <stdlib.h>
/*这个程序用来测试extern扩展全局变量的作用范围*/

int max(int,int);
int main()
{
    extern int a,b;
    printf("%d\n",max(a,b));
    return 0;
}

int a=15,b=-7;//定义全局变量a,b

int max(int x,int y)
{
    int z;
    z=x>y?x:y;
    return z;
}
结果:


解析:

通过在main函数中对全局变量做提前引用声明,使得全局变量的作用范围提升了。


声明其他文件中定义的外部变量


代码示例:

main.c:

#include <stdio.h>
#include <stdlib.h>
/*这个程序用来测试外部变量*/
extern int a,b;//用extern修饰表示这里定义的a,b是外部变量a,b
int max(int x,int y);
int main()
{
    printf("max=%d\n",max(a,b));
    return 0;
}
max.c:

int a=15,b=-7;//定义全局(外部)变量
extern int max(int x,int y)
{
    int z;
    z=x>y?x:y;
    return z;
}
结果:


解析:

1.通过extern声明,成功在一个文件中调用其他文件中定义的变量。

2.max.c中定义a,b时不能用extern修饰!

3.main.c中的extern可以省略,但为了方便代码阅读,不建议略去。


编译系统对extern的处理

图示:





注1:extern的作用其实是扩展变量的作用范围,声明外部变量也可以说是将外部变量的作用范围扩展到了本文件中。

注2:外部变量将增加程序的耦合性!使得代码变得更加复杂!应当谨慎使用!


静态全局变量


关键代码:static


代码示例:

main.c:

#include <stdio.h>
#include <stdlib.h>
/*这个程序用来测试外部变量*/
int a=100,b=10;//用extern修饰表示这里定义的a,b是外部变量a,b
int max(int x,int y);
int main()
{
    printf("max=%d\n",max(a,b));
    return 0;
}
max.c:

static int a=15,b=-7;//定义静态全局变量
extern int max(int x,int y)
{
    int z;
    z=x>y?x:y;
    return z;
}
结果:



解析:

如果max.c中的a,b不用static定义为静态全局变量,将和main中的a,b冲突!


注:静态与外部变量更多更详细的属性,可参考变量类型篇http://blog.csdn.net/aketoshknight/article/details/53790332






你可能感兴趣的:(静态变量,C语言,外部变量,静态函数,外部函数)