大程序结构

大程序结构

它的意思可以说是这样

main()里边的代码长了,适合分成几个函数

一个源代码文件长了,适合分成几个文件


项目

这个需要新建一个项目,然后把相关的文件添加进来

有的IDE有分开的编译和构建按钮,前者是对单个源文件编译,后者是对整个项目做链接


头文件

把函数原型放到一个头文件中,在需要是在相应的.c文件(源文件)中用include包含,这样可以让编译器在编译时知道函数的原型

在使用和定义这个函数的地方都应该#include这个头文件(后缀为.h)

一般的做法就是任何.cmain.c除外)都有对应的同名.h把所有对外公开的函数的原型和全局变量的声明都放进去

只有声明可以放到头文件中,这是规则不是法律,否则会造成一个项目中多个编译单元有重名的实体

某些编译器允许几个编译单元中存在同名的函数或者用week修饰符来强调这种存在


下面举个例子

新建一个C项目,选择控制台应用程序,并给项目起个名字,这时会有一个main.c文件,下面添加一个头文件

1

main.c文件:

# include <stdio.h>
# include "max.h"  
//这里用双引号(半角)代替<>,当然stdio.h也可以用双引号,不过一般自定义的头文件都用双引号包括 

int main(int argc, char *argv[]) {
	int a, b;
	printf("请输入两个整数,中间用空格分开:");
	scanf("%d %d", &a, &b);
	printf("%d\n", max(a, b));
	
	return 0;
}

max.h

int max(int a, int b);  
//这是max函数的原型(声明),自定义函数原型定义在头文件中 

max.c

//这里放的是函数体,即函数的定义 
int max(int a, int b) {
	return a>b ? a : b;  //使用三目运算符返回两个数中的大数 
}

示例输出结果为:


这仅仅是一个简单的程序,平时直接新建一个文件就行了,只有在写较大的程序时才会将程序分成源文件和头文件,这里仅仅是举例

如果此时关闭项目,只打开一个main.c文件,编译时会报错,因为

两个独立的源码文件不能编译形成可执行程序


编译单元

一个.c文件是一个编译单元

编译器每次编译只处理一个编译单元

在编写一些较大的程序时,如果所有文件都已经编译过,而在需要修改哪个源文件时,再进行编译可以只编译被修改文件,而可以不用对其它文件再次编译

 

“”还是< >

“”要求编译器首先在当前目录(.c文件所在目录)寻找这个文件,如果没有,到编译器指定的目录去找

< >让编译器只在指定的目录去找

编译器自己知道自己的标准库的头文件在哪里

环境变量和编译器命令行参数也可以指定寻找头文件的目录


#include的误区

它不是用来引入库的

stdio.h里只有printf等的原型,其代码在另外的地方

某个.libwindows)或.aunix)中

现在的C语言编译器默认会引入所有的标准库

#include<stdio.h>只是为了让编译器知道printf等函数的原型


不对外公开的函数

在函数前面加上static就使得它成为只能在所在的编译单元中被使用的函数,

在全局变量前面加上static就使得它成为只能在所在编译单元中被使用的全局变量


声明和定义

声明是不产生代码的东西

函数原型

变量声明

结构声明

宏声明

枚举声明

类型声明

inline声明

定义是产生代码的东西

int i;是变量的定义

extern int i;是变量的声明

extern用来告知编译器变量在当前范围之外声明过了.被extern语句描述过的变量将分派不到任何空间,因为他们在别的地方被定义过了.extern语句频繁的用于在多个文件之间的跨范围数据传递. 


inline这个关键字请求编译器扩张一个给定的函数。它向这个函数发出一条插入代码的call。函数里面有静态变量,嵌套的,switches,或者是递归的时候不给予内联。当一个函数声明包含在一个类声明里面时,编译器会尝试的自动把函数内联。
关键字inline请求编译器给一个函数扩展空间,它向这个函数发出一条插入代码的call.函数里面有 static 数据, 循环,static 或者是递归的时候不给予内联.当一个函数声明包含在一个类声明里面时,编译器会尝试的自动把函数内联.


下面举个较大的程序的例子——学生成绩管理系统(有一些简单的操作)

2

main.c文件:

# include <stdio.h> 
# include <stdlib.h> 

int main(void) { 
	system("color 2f"); 
	int flag = 0;  
	menu();  
	do { 
		flag = 1;    
		switch(getch()) {
		case '1' :
			inputscore();
			break;      
		case '2' : 
			lookscore();
			break;    
		case '3' : 
			searchscore();
			break;    
		case '4' :
			statistic();
			break;    
		case '5' : 
			modify();
			break;    
		case '6' : 
			add();
			break;     
		case '7' : 
			delscore();
			break;     
		case '8' : 
			savescore();
			break;    
		case '9' :
			exit(0);   
		default : 
			printf("输入有误\n");    
		}    
		printf("按任意键继续\n");   
		getch();   
		menu(); 
	}while (flag == 1); 
	
	return 0;
}         

studentscore.h文件:

# include <stdio.h> 
# include <string.h>
# include <stdlib.h> 
# define N 30 
# define M 3  

typedef struct student { 
	char number[10];  
	char name[20];   
	float score[M];   
	float aver; 
}STU, * PSTU;

STU stu[N]; 
int n, x = 0;   

void menu(void);          //菜单 
void inputscore(void);    //输入学生信息及成绩 
void avergescore(void);   //求平均 
void lookscore(void);     //查看成绩
void searchscore(void);   //查找成绩
void statistic(void);     //成绩统计
void modify(void);        //修改成绩 
void add(void);           //添加成绩
void delscore(void);      //删除成绩
void savescore(void);     //保存成绩

studentscore.c文件:

# include "studentscore.h" 

/*****************************菜单************************************/ 
void menu(void) {  
	system("cls"); 
	printf("\n");   
	printf("\t\t※※★★★★★欢迎进入学生成绩管理系统★★★★★※※\n");
	printf("\t\t|**************************************************|\n"); 
	printf("\t\t|                       菜单                       |\n"); 
	printf("\t\t|**************************************************|\n");  
	printf("\t\t|录入成绩----------------------------------------1 |\n\t\t|\t\t\t\t\t\t   |\n");  
	printf("\t\t|查看成绩及成绩排序------------------------------2 |\n\t\t|\t\t\t\t\t\t   |\n");  
	printf("\t\t|查询学生成绩------------------------------------3 |\n\t\t|\t\t\t\t\t\t   |\n");  
	printf("\t\t|成绩统计----------------------------------------4 |\n\t\t|\t\t\t\t\t\t   |\n");  
	printf("\t\t|修改成绩----------------------------------------5 |\n\t\t|\t\t\t\t\t\t   |\n");  
	printf("\t\t|添加成绩----------------------------------------6 |\n\t\t|\t\t\t\t\t\t   |\n"); 
	printf("\t\t|删除成绩----------------------------------------7 |\n\t\t|\t\t\t\t\t\t   |\n");  
	printf("\t\t|保存成绩----------------------------------------8 |\n\t\t|\t\t\t\t\t\t   |\n");  
	printf("\t\t|退出系统----------------------------------------9 |\n");  
	printf("\t\t※★★★★★★★★★★★★★★★★★★★★★★★★※\n");
	printf("\t\t请输入您的选择\n");  
}      

/***************输入各个同学的学生信息******************************/
void inputscore(void) { 
	int i, j;    
	system("cls"); 
	printf("请输入学生总数: ");  
	scanf("%d", &n); 
	for(i=0; i<n; i++) { 
		printf("请输入学生 %d 的学号 姓名(中间用空格分隔):\n", i+1); 
		scanf("%s %s", stu[i].number, stu[i].name);  
		printf("请输入学生成绩(中间用空格分隔):\n");  
		printf("数据结构\tjava程序设计\t汇编\n"); 
		for(j=0; j<M; j++) 			
			scanf("%f", &stu[i].score[j]); 	 
		printf("\n");
	}  
	printf("成功输入\n"); 
} 

/*****************计算各个同学的平均分*****************************/ 
void avergescore(void) { 
	int i, j;     
	for(i=0; i<n; i++) { 
		stu[i].aver = 0;  
		for(j=0; j<M; j++) {    
			stu[i].aver += stu[i].score[j];  
		}    
		stu[i].aver = stu[i].aver / M;   
	}
} 

/************查看学生成绩及根据平均分对学生进行排序*********************/ 
void lookscore(void) { 
	int i, j, k; 
	STU t; 
	avergescore(); 
	system("cls");    
	for(i=0; i<n-1; i++) {
		for(k=i,j=i+1; j<n; j++)  
			if(stu[j].aver > stu[k].aver)   
				k = j;  
			if(k != j) {
				t = stu[k];   
				stu[k] = stu[i];    
				stu[i] = t;  
			} 
	}   
	printf("名次\t学号\t姓名\t数据结构        java程序设计    汇编            平均分\n"); 
	for(i=0; i<n; i++) { 
		printf("%d\t%s\t%s\t",i+1, stu[i].number, stu[i].name); 
		for(j=0; j<M; j++)
			printf("%4.2f\t\t", stu[i].score[j]); 
		printf("%4.2f", stu[i].aver); 
		printf("\n");  
	}
} 

/*****************通过输入学号查找学生成绩***************************/ 
void searchscore(void) { 
	char a[10];
	int i, j; 
	system("cls"); 
	avergescore();
	printf("请输入需查询的学生学号\n"); 
	scanf("%s", a);  
	
	for(i=0; i<=n; i++) { 
		if(strcmp(a, stu[i].number) == 0) {
			printf("名次\t学号\t姓名\t数据结构        java程序设计    汇编            平均分\n"); 
			printf("%d\t%s\t%s\t",i+1, stu[i].number, stu[i].name);   
			for(j=0; j<M; j++)   
				printf("%4.2f\t\t", stu[i].score[j]);   
			printf("%4.2f", stu[i].aver);  
			printf("\n");  
			break;        
		}     
		if(n == i)
			printf("未找到该学生信息\n");
	}
} 

/*******统计学生成绩信息,平均分及格率,优秀率,成绩方差****************/ 
void statistic(void) {
	PSTU p = stu; 
	int i, j;  
	float count = 0.0, sum = 0.0; 
	system("cls"); 
	avergescore();
	for(i=0; i<n; i++) /*平均分计算*/ { 
		sum += (p+i)->aver;
	}  
	printf("该班级平均分为%4.2f\n\n", sum/n); 
	
	for(i=0; i<n; i++) 	/*及格率计算*/ { 
		if((p+i)->aver >= 60) 
			count++; 
	}  
	printf("该班级及格率为%4.2f%%\n\n", count/n*100);
	
	count = 0.0; 	
	for(i=0; i<n; i++)  /*优秀率计算*/ { 
		if((p+i)->aver >= 90)  
			count++;  
	}  
	printf("该班级优秀率为%4.2f%%\n\n", count/n*100); 
	
	for(i=0; i<n; i++)  /*方差计算*/ {
		for(j=0; j<M; j++) {
			sum = ((p+i)->score[j] - (p+i)->aver) * ((p+i)->score[j] - (p+i)->aver); 
		}  
		sum = sum/n;  
		printf("学生%s的成绩方差为%4.2f\n\n", (p+i)->name, sum); 
	}  
	printf("平均分低于60的学生名单:\n"); 
	for(i=0; i<n; i++) {     
		if(stu[i].aver < 60) {
	     	x++;
			printf("%3s\n\n", stu[i].name); 
		}	
	}   
	if(0 == x) {
		printf("所有同学都及格了!!!\n\n");
	} 		    
}  

/***************修改学生成绩*********************************************/
void modify(void) { 
	char a[10]; 
	int i, j;  
	system("cls"); 
	avergescore();
	printf("请输入需要修改成绩的学生学号\n");  
	scanf("%s", a); 
	for(i=0; i<=n; i++) { 
		if(strcmp(a, stu[i].number) == 0) { 
			printf("名次\t学号\t姓名\t数据结构        java程序设计    汇编            平均分\n"); 
			printf("%d\t%s\t%s\t",i+1, stu[i].number, stu[i].name);   
			for(j=0; j<M; j++)   
				printf("%4.2f\t\t", stu[i].score[j]);   
			printf("%4.2f", stu[i].aver);  
			printf("\n");   
			printf("请重新输入学生成绩:\n");    
			printf("数据结构\tjava程序设计\t汇编\n");    
			for(j=0; j<M; j++)  
				scanf("%f", &stu[i].score[j]);  
			printf("修改成功\n");    
			break;  
		} 
		if(n == i)
			printf("未找到该学生信息\n");  
	}   
}  

/*****************添加学生成绩********************/
void add(void) { 
	int a, i, j; 
	system("cls"); 
	avergescore();
	printf("请输入新增加的学生人数:\n"); 
	scanf("%d", &a); 
	n +=a;  
	for(i=n-a; i<n; i++) { 
		printf("请输入学生%d的学号 姓名:\n", i+1); 
		scanf("%s %s", stu[i].number, stu[i].name); 
		printf("请输入学生成绩:\n"); 
		printf("数据结构\tjava程序设计\t汇编\n"); 
		for(j=0; j<M; j++)   
			scanf("%f", &stu[i].score[j]); 
		printf("添加成功\n"); 
		
	} 
} 

/*******************删除学生成绩*****************************************/
void delscore(void) {
	int i, j, c; 
	char m, a[10];  
	system("cls"); 
	printf("请输入学生学号\n"); 
	scanf("%s", a); 
	for(i=0; i<=n; i++) { 
		if(strcmp(a, stu[i].number) == 0) {
			printf("名次\t学号\t姓名\t数据结构        java程序设计    汇编            平均分\n"); 
			printf("%d\t%s\t%s\t",i+1, stu[i].number, stu[i].name);   
			for(j=0; j<M; j++)   
				printf("%4.2f\t\t", stu[i].score[j]);   
			printf("%4.2f", stu[i].aver);  
			printf("\n");  
			c = i;  
			break;  
		}   
		if(n == i) {	
			printf("未找到该学生信息\n");
			return; 
		}
	}  
	printf("是否删除该学生成绩(y/n)\n"); 
	scanf("%s", &m);  
	if(m == 'y') {     
		for(i=c; i<=n-1; i++)  
			stu[i] = stu[i+1]; 
		n += 1;                
		printf("删除成功\n");  
	}   
	else  
		printf("删除失败\n"); 
}  

/******************保存学生成绩************************/ 
void savescore(void) {
	FILE * fp; 
	int i, flag = 1; 
	char m; 
	system("cls");  
	avergescore();
	puts("是否保存学生成绩(y/n)");
	scanf("%s", &m);  
	if(m == 'y') { 
		if((fp = fopen("score.dat","wb")) == NULL) {
			printf("文件打开失败\n"); 
			return;   
		}    
		for(i=0; i<n; i++)   
			if(fwrite(&stu[i], sizeof(struct student), 1, fp) != 1) {
				printf("保存失败\n");    
				flag = 0;   
			}  
			if(flag == 1)  
				printf("保存成功!\n"); 
			fclose(fp);  
	}  
	else  
		return; 
}

部分输出操作结果:







【所有代码均在windows系统下dev c++下运行通过】

如有错误,敬请指正

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值