封面书写
实践名称:课程设计
指导教师:申燕萍
班级:
姓名:
学号:
学期:2011~2012 学年 第2学期
报告日期:2012 年 6 月 11 日 ~ 6 月 21日
实训项目(一)学生管理系统分析与设计
实训目的:
分析确定学生管理系统的功能和设计界面
了解C语言在图形设计中的应用;
了解几个简单的图形设计函数。
实训内容:
一、图形函数:
1.画点函数
void far putpixel(int x, int y, int color); 有指定的象元画一个按color所确定颜色的点。
int far getmaxx(void); 返回x轴的最大值。
int far getmaxy(void); 返回y轴的最大值。
int far getx(void); 返回游标在x轴的位置。
void far gety(void); 返回游标有y轴的位置。
void far moveto(int x, int y); 移动游标到(x, y)点, 不是画点, 在移动过程中亦画点。
2.画线函数
void far line(int x0, int y0, int x1, int y1); 画一条从点(x0, y0)到(x1, y1)的直线。
void far lineto(int x, int y); 画一作从现行游标到点(x, y)的直线。
二、编写界面代码,实现界面如下
参考程序:main()
{
int i;
STUDENT *head; /*链表定义头指针*/
head=init(); /*初始化链表*/
clrscr(); /*清屏*/
for(;;) /*无限循环*/
{ switch(menu_select()) /*调用主菜单函数,返回值整数作开关语句的条件*/
{ /*值不同,执行的函数不同,break 不能省略*/
case 0:head=create();break; /*执行初始化*/
case 1:head=insert(head);;break; /*创建链表*/
case 2:head=delete(head);break; /*删除记录*/
case 3:print(head);break; /*显示全部记录*/
case 4:search(head);break; /*查找记录*/
case 5:exit(0);break; /*保存文件*/
}
}
}
/*菜单函数,返回值为整数*/
menu_select()
{
char *menu[]={"***************MENU***************", /*定义菜单字符串数组*/
" 0. input list", /*初始化*/
" 1. insert a record", /*输入记录*/
" 2. Delete a record from list", /*从表中删除记录*/
" 3. print list ", /*显示单链表中所有记录*/
" 4. Search record on name", /*按照姓名查找记录*/
" 5. Quit"}; /*将单链表中记录保存到文件中*/
char s[3]; /*以字符形式保存选择号*/
int c,i; /*定义整形变量*/
gotoxy(1,25); /*移动光标*/
printf("press any key enter menu......\n"); /*压任一键进入主菜单*/
getch(); /*输入任一键*/
clrscr(); /*清屏幕*/
gotoxy(1,1); /*移动光标*/
textcolor(YELLOW); /*设置文本显示颜色为黄色*/
textbackground(BLUE); /*设置背景颜色为蓝色*/
gotoxy(10,2); /*移动光标*/
putch(0xc9); /*输出左上角边框┏*/
for(i=1;i<44;i++)
putch(0xcd); /*输出上边框水平线*/
putch(0xbb); /*输出右上角边框 ┓*/
for(i=3;i<20;i++)
{ gotoxy(10,i);putch(0xba); /*输出左垂直线*/
gotoxy(54,i);putch(0xba);
} /*输出右垂直线*/
gotoxy(10,20);putch(0xc8); /*输出左上角边框┗*/
for(i=1;i<44;i++)
putch(0xcd); /*输出下边框水平线*/
putch(0xbc); /*输出右下角边框┛*/
window(11,3,53,19); /* 制作显示菜单的窗口,大小根据菜单条数设计*/
clrscr(); /*清屏*/
for(i=0;i<7;i++) /*输出主菜单数组*/
{ gotoxy(10,i+1);
cprintf("%s",menu[i]);
}
textbackground(BLACK); /*设置背景颜色为黑色*/
window(1,1,80,25); /*恢复原窗口大小*/
gotoxy(10,21); /*移动光标*/
do{printf("\n Enter you choice(0~14):"); /*在菜单窗口外显示提示信息*/
scanf("%s",s); /*输入选择项*/
c=atoi(s); /*将输入的字符串转化为整形数*/
}while(c<0||c>5); /*选择项不在0~14之间重输*/
return c; /*返回选择项,主程序根据该数调用相应的函数*/
}
实训项目(二)学生链表的建立、信息插入
实训目的:
掌握链表的存储结构;明确链表和顺序存储结构的不同
熟悉链表的基本运算:插入、删除、查找;
完成系统输入记录、插入记录部分的代码编写
实训内容:
一、链表复习
给定程序中已建立一个带有头结点的单向链表,链表中的各结点按结点数据域中的数据从小到大顺序链接。函数fun的功能是:把形参x的值放入一个新结点并插入到链表中,插入后各结点仍保持从小到大顺序排列。
#include <stdio.h>
#include <stdlib.h>
#define N 8
typedef struct list
{ int data;
struct list *next;
} SLIST;
void fun( SLIST *h, int x)
{ SLIST *p, *q, *s;
s=(SLIST *)malloc(sizeof(SLIST));
/**********found**********/
s->data=___x___;
q=h;
p=h->next;
while(p!=NULL && x>p->data) {
/**********found**********/
q=___p___;
p=p->next; }
s->next=p;
/**********found**********/
q->next=___s___; }
SLIST *creatlist(int *a)
{ SLIST *h,*p,*q; int i;
h=p=(SLIST *)malloc(sizeof(SLIST));
for(i=0; i<N; i++)
{ q=(SLIST *)malloc(sizeof(SLIST));
q->data=a[i]; p->next=q; p=q; }
p->next=0;
return h; }
void outlist(SLIST *h)
{ SLIST *p;
p=h->next;
if (p==NULL) printf("\nThe list is NULL!\n");
else { printf("\nHead");
do { printf("->%d",p->data); p=p->next; } while(p!=NULL);
printf("->End\n"); } }
main()
{ SLIST *head; int x;
int a[N]={11,12,15,18,19,22,25,29};
head=creatlist(a);
printf("\nThe list before inserting:\n"); outlist(head);
printf("\nEnter a number : "); scanf("%d",&x);
fun(head,x);
printf("\nThe list after inserting:\n"); outlist(head); }
二、参考程序:
/*创建链表*/
STUDENT *create()
{ int i; int s;
STUDENT *h=NULL,*info; /* STUDENT指向结构体的指针*/
for(;;)
{ info=(STUDENT *)malloc(sizeof(STUDENT)); /*申请空间*/
if(!info) /*如果指针info为空*/
{ printf("\nout of memory"); /*输出内存溢出*/
return NULL; /*返回空指针*/
}
inputs("enter no:",info->no,11); /*输入学号并校验*/
if(info->no[0]=='@') break; /*如果学号首字符为@则结束输入*/
inputs("enter name:",info->name,15); /*输入姓名,并进行校验*/
printf("please input %d score \n",N); /*提示开始输入成绩*/
s=0; /*计算每个学生的总分,初值为0*/
for(i=0;i<N;i++) /*N门课程循环N次*/
{ do{
printf("score%d:",i+1); /*提示输入第几门课程*/
scanf("%d",&info->score[i]); /*输入成绩*/
if(info->score[i]>100||info->score[i]<0) /*确保成绩在0~100之间*/
printf("bad data,repeat input\n"); /*出错提示信息*/
}while(info->score[i]>100||info->score[i]<0);
s=s+info->score[i]; /*累加各门课程成绩*/
}
info->sum=s; /*将总分保存*/
info->average=(float)s/N; /*求出平均值*/
info->order=0; /*未排序前此值为0*/
info->next=h; /*将头结点做为新输入结点的后继结点*/
h=info; /*新输入结点为新的头结点*/
}
return(h); /*返回头指针*/
}
/*输入字符串,并进行长度验证*/
inputs(char *prompt, char *s, int count)
{ char p[255];
do{
printf(prompt); /*显示提示信息*/
scanf("%s",p); /*输入字符串*/
if(strlen(p)>count)printf("\n too long! \n"); /*进行长度校验,超过count值重输入*/
}while(strlen(p)>count);
strcpy(s,p); /*将输入的字符串拷贝到字符串s中*/
}
实训项目(三)信息删除与查询
实训目的:
掌握C#中选择程序结构、循环程序结构、类和函数的基本语法
完成系统插入、删除、查找部分代码的编写
实训内容:
参考程序
/*输出链表中结点信息*/
void print(STUDENT *h)
{ int i=0; /* 统计记录条数*/
STUDENT *p; /*移动指针*/
clrscr(); /*清屏*/
p=h; /*初值为头指针*/
printf("\n\n\n****************************STUDENT*******************************\n");
printf("|rec|nO | name | sc1| sc2| sc3| sum | ave |order|\n");
printf("|---|----------|---------------|----|----|----|--------|-------|-----|\n");
while(p!=NULL)
{ i++;
printf("|%3d |%-10s|%-15s|%4d|%4d|%4d| %4.2f | %4.2f | %3d |\n", i, p->no,p->name,p->score[0],p->score[1],
p->score[2],p->sum,p->average,p->order);
p=p->next;
}
printf("**********************************end*********************************\n");
}
/*删除记录*/
STUDENT *delete(STUDENT *h)
{ STUDENT *p,*q; /*p为查找到要删除的结点指针,q为其前驱指针*/
char s[11]; /*存放学号*/
clrscr(); /*清屏*/
printf("please deleted no\n"); /*显示提示信息*/
scanf("%s",s); /*输入要删除记录的学号*/
q=p=h; /*给q和p赋初值头指针*/
while(strcmp(p->no,s)&&p!=NULL) /*当记录的学号不是要找的,或指针不为空时*/
{ q=p; /*将p指针值赋给q作为p的前驱指针*/
p=p->next; /*将p指针指向下一条记录*/
}
if(p==NULL) /*如果p为空,说明链表中没有该结点*/
printf("\nlist no %s student\n",s);
else /*p不为空,显示找到的记录信息*/
{
printf("*****************************have found***************************\n");
printf("|no | name | sc1| sc2| sc3| sum | ave |order|\n");
printf("|----------|---------------|----|----|----|--------|-------|-----|\n");
printf("|%-10s|%-15s|%4d|%4d|%4d| %4.2f | %4.2f | %3d |\n", p->no,
p->name,p->score[0],p->score[1],p->score[2],p->sum,
p->average,p->order);
printf("********************************end*******************************\n");
getch(); /*压任一键后,开始删除*/
if(p==h) /*如果p==h,说明被删结点是头结点*/
h=p->next; /*修改头指针指向下一条记录*/
else
q->next=p->next; /*不是头指针,将p的后继结点作为q的后继结点*/
free(p); /*释放p所指结点空间*/
printf("\n have deleted No %s student\n",s);
printf("Don't forget save\n");/*提示删除后不要忘记保存文件*/
}
return(h); /*返回头指针*/
}
/*查找记录*/
void search(STUDENT *h)
{
STUDENT *p; /* 移动指针*/
char s[15]; /*存放姓名的字符数组*/
clrscr(); /*清屏幕*/
printf("please enter name for search\n");
scanf("%s",s); /*输入姓名*/
p=h; /*将头指针赋给p*/
while(strcmp(p->name,s)&&p!=NULL) /*当记录的姓名不是要找的,或指针不为空时*/
p=p->next; /*移动指针,指向下一结点*/
if(p==NULL) /*如果指针为空*/
printf("\nlist no %s student\n",s); /*显示没有该学生*/
else /*显示找到的记录信息*/
{
printf("\n\n*****************************havefound***************************\n");
printf("|nO | name | sc1| sc2| sc3| sum | ave |order|\n");
printf("|----------|---------------|----|----|----|--------|-------|-----|\n");
printf("|%-10s|%-15s|%4d|%4d|%4d| %4.2f | %4.2f | %3d |\n", p->no,
p->name,p->score[0],p->score[1],p->score[2],p->sum,p->average,p->order);
printf("********************************end*******************************\n");
}
}
/*插入记录*/
STUDENT *insert(STUDENT *h)
{
STUDENT *p,*q,*info; /*p指向插入位置,q是其前驱,info指新插入记录*/
char s[11]; /*保存插入点位置的学号*/
int s1,i;
printf("please enter location before the no\n");
scanf("%s",s); /*输入插入点学号*/
printf("\nplease new record\n"); /*提示输入记录信息*/
info=(STUDENT *)malloc(sizeof(STUDENT)); /*申请空间*/
if(!info)
{
printf("\nout of memory"); /*如没有申请到,内存溢出*/
return NULL; /*返回空指针*/
}
inputs("enter no:",info->no,11); /*输入学号*/
inputs("enter name:",info->name,15); /*输入姓名*/
printf("please input %d score \n",N); /*提示输入分数*/
s1=0; /*保存新记录的总分,初值为0*/
for(i=0;i<N;i++) /*N门课程循环N次输入成绩*/
{
do{ /*对数据进行验证,保证在0~100之间*/
printf("score%d:",i+1);
scanf("%d",&info->score[i]);
if(info->score[i]>100||info->score[i]<0)
printf("bad data,repeat input\n");
}while(info->score[i]>100||info->score[i]<0);
s1=s1+info->score[i]; /*计算总分*/
}
info->sum=s1; /*将总分存入新记录中*/
info->average=(float)s1/N; /*计算均分*/
info->order=0; /*名次赋值0*/
info->next=NULL; /*设后继指针为空*/
p=h; /*将指针赋值给p*/
q=h; /*将指针赋值给q*/
while(strcmp(p->no,s)&&p!=NULL) /*查找插入位置*/
{ q=p; /*保存指针p,作为下一个p的前驱*/
p=p->next; /*将指针p后移*/
}
if(p==NULL) /*如果p指针为空,说明没有指定结点*/
if(p==h) /*同时p等于h,说明链表为空*/
h=info; /*新记录则为头结点*/
else
q->next=info; /*p为空,但p不等于h,将新结点插在表尾*/
else
if(p==h) /*p不为空,则找到了指定结点*/
{
info->next=p; /*如果p等于h,则新结点插入在第一个结点之前*/
h=info; /*新结点为新的头结点*/
}
else
{
info->next=p; /*不是头结点,则是中间某个位置,新结点的后继为p*/
q->next=info; /*新结点作为q的后继结点*/
}
printf("\n ----have inserted %s student----\n",info->name); printf("---Don't forget save---\n"); /*提示存盘*/
return(h); /*返回头指针*/
}
实训项目(四)二级C综合笔试练习
实训目的:
了解计算机公共基础知识
熟悉数据结构的基本概念
复习选择、循环结构
实训内容:
一、基本理论知识:
1. 算法:
(1) 算法是指解题方案的准确而完整的描述;
(2) 特性:可行性、确定性、有穷性、拥有足够的情报;
(3) 算法复杂度:时间、空间。
2. 数据结构的基本概念:
(1) 数据结构:反映数据元素间关系的数据元素集合的表示(元素、关系);
(2) 逻辑结构:数据元素间前后件的关系
(3) 存储结构(物理结构):数据的逻辑结构在计算机存储空间中的存放形式;
3.线性表及其顺序存储结构
(1)线性表的特征
(2)顺序存储的特点
(3)主要运算(指定位置插入、删除指定元素、查找、排序、分解、合并、复制、逆转)
4.栈和队列
(1)栈:仅在表尾进行插入和删除操作的线性表(后进先出)
(2)队列:允许在一端进行插入,另一端进行删除的线性表(先进先出)
(3)循环队列
5.线性链表
(1)线性链表:线性表的链式存储结构
(2)基本运算(查找、插入、删除)
6.树与二叉树
(1)树:非线性结构
(2)二叉树:每个结点最多有两棵子树,有左右之分
(3)二叉树基本性质:第k层,最多有2k-1个结点;
深度为m的二叉树最多有2m-1个结点
度为0的结点比度为2的结点多一个
(4) 满二叉树:除最后一层外,每一层上所有结点都有两个子结点
(5) 完全二叉树:除最后一层外,每一层结点数都达到最大值,最后一层上只缺少右边若干结点
(6) 遍历:不重复访问二叉树中所有结点
7.查找技术
(1)顺序查找
(2)二分查找
8.排序技术
(1)冒泡排序(2)快速排序
(3)简单插入排序
(4)简单选择
(5)堆排序
二、 C语言复习
(一)C语言的字符集:
由字母、数字、空格、标点和特殊字符构成。
(二)标识符
标识符只能由字母、数字、下划线组成,且第一个字符必须是字母或下划线。
1、标准C不限制标识符的长度,但它受C语言编译系统的限制,Turbo C中标识符的最大长度为32个字符
2、标识符中大小写是有区别的
3、标识符虽然可以由程序员随意定义,但不能与关键字同名.
(三)关键字
(1)数据类型关键字(12个):char, double, enum, float, int, long, short, signed, struct, union, unsigned, void
(2)控制语句关键字(12个):break, case, continue, default, do, else, for, goto, if, return, switch, while
(3)存储类型关键字(4个):auto, extern, register, static
(4)其它关键字(4个):const, sizeof, typedef, volatile
(四)C程序结构特点:
1)一个C语言源程序可以由一个或多个源文件组成,源文件以.c为扩展名。每个源文件可由一个或多个函数组成。
2)一个源程序有且只有一个main函数,是程序的入口。总是从main()函数开始执行,而不论其在程序中的位置。当主函数执行完毕时,亦即程序执行完毕。
3)函数是C语言程序的基本单位
4)源程序中可以有预处理命令,通常放在最前面。
5)以分号作为语句结束的标志。
c程序对大小写敏感,大小写字母代表不同的字符
(五)数据转换
1、自动转换
发生在不同类型的数据混合运算时,由编译系统自动完成。自动转换遵循以下规则:
2、强制转换
一般格式为:
(要转换成的数据类型)(被转换的表达式)
当被转换的表达式是一个简单表达式时,外面的一对圆括号可以缺省。
三、二级C笔试模拟试卷讲评
实训项目(五)二级C综合笔试练习
实训目的:
了解计算机公共基础知识;熟悉软件工程的基本概念;
熟悉二级C笔试的基本情况;复习数组、函数的基本概念。
实训内容:
一、基本理论知识:
1.程序设计基础
(1)结构化程序设计:自顶向下,逐步求精,模块化
(2)程序设计风格;
(3)结构:顺序、选择、循环
(4)面向对象程序设计(对象、属性、类、实例、继承、消息、多态性)
2.软件工程基础
(1)软件工程:应用于计算机软件的定义、开发和维护的一整套方法、工具、文档、实践标准和工序。
(2)软件生命周期:
可行性分析、需求分析、软件设计、软件实现、软件测试、运行、维护
(3)软件工程的原则:
抽象、信息屏蔽(封装技术)、模块化(高内聚低偶合)、局部化、确定性、一致性、完备性、可验证性
(4)CASE(计算机辅助软件工程)
3.结构化分析工具:DFD(数据流图:变换型、事务型)、DD(数据字典)
4.详细设计方法:程序流图、N-S图、PAD图、PDL图
5.软件测试:
(1)目的:发现并改正错误
(2)方法:静态、动态
白盒:逻辑覆盖(语句、路径、判定、条件、判断-条件覆盖)、基本路径测试
黑盒:等价类划分、边界值划分、错误推测、
(3)实施:单元测试(对模块)、
集成测试(测试和组装软件的过程)
确认测试(验证软件功能)
系统测试(真实环境下测试)
6.软件调试
二、C语言复习
一)结构化程序设计的程序结构
顺序结构、分支结构/选择结构、循环结构
二)格式化输出--printf()函数
三)格式化输入--scanf()函数
四)单个字符输入输出--getchar()和putchar()函数
五)关系运算符和关系表达式
1、C语言提供了6种关系运算符:
< <= > >= == !=
说明:
六)逻辑运算和逻辑表达式
1、 C语言提供了3种逻辑运算符
&& 逻辑"与" || 逻辑"或" !逻辑"非"
说明:
七)if语句和if语句构成的选择结构
1、 不含else子句的if语句 形式:if(表达式) 语句
2、 含else子句的if语句 形式:if(表达式) 语句1
else 语句2
3、 if语句的嵌套的形式:
1)、if(条件1)
if(条件2) 语句1;
else 语句2;
else 语句3;
2)、if(条件1)语句1;
else
if(条件2)语句2;
else 语句3;
3)、if(条件1)
if(条件2) 语句1;
else 语句2;
else
if(条件3)语句3;
else 语句4;
注意:在if的嵌套中else总是与最靠近的if配对,如果需要和前面的配对应加大括号实现。
九)、 条件运算符
一般形式:表达式1?表达式2:表达式3
执行过程(略) 优先级别 结合性
条件运算符可以表示简单的if结构的程序
十)、 switch语句和程序
一般格式:switch(表达式)
{case 值1:语句1;
case 值2:语句2;
.
.
case 值N:语句N;
[default: 语句N+1;]
}
三、二级C笔试模拟试卷讲评
实训项目(六)二级C综合笔试练习
实训目的:
了解计算机公共基础知识;熟悉数据库的基本概念;
熟悉二级C笔试的基本情况;C语言程序设计综合复习。
实训内容:
一、基本理论知识:
1.数据库系统的基本概念
(1)数据:描述事物的符号记录
(2)数据库:数据的集成、共享
(3)数据库管理系统(DBMS):属系统软件,
(4)数据语言:数据定义语言(DDL)、数据操纵语言(DML)、数据控制语言(DCL)
(5)数据库系统:数据库(DB)、数据库管理系统(DBMS)、数据库管理员(DBA)、软硬件平台
(6)数据库系统的特点:集成、高共享低冗余、数据独立、数据统一管理与控制
(7)内部体系:二级模式(概念、内部)、三级模式(概念、内部、外部)
2.数据模型:
(1)内容:数据结构、数据操作、数据约束
(2)E-R模型(实体、属性、操作)
实体间关系:1:1、1:M或M:1、M:N或N:M
(3)层次模型
(4)网状模型
(5)关系模型(二维表):主键、外键
3.关系运算
(1)插入、删除、修改、查询
(2)查询:投影
选择:σF(R)
笛卡儿积R×S
自然连接:R|×|S
二C语言复习
一)、while语句和用while语句实现循环结构
while语句的形式:while(表达式) 语句
说明:1特点:先判断后执行,如果第一次表达式的值为假,则循环体一次也不会执行。
2 while语句如果不是一条简单语句,则必须用花括号括起来,组成一条复合语句。
二)、do-while语句和用do-while语句实现循环
do-while语句形式:do{
循环体
}while(表达式);
说明:1特点:先执行后判断
2 while后的圆括号外面一定要有;作为do-while语句的结束标记
三)、while语句和do-while语句的区别
当第一次表达式就不成立的情况下,while语句一次都不执行循环体,do-while语句执行一次。分析输入1和11两种情况
四)、for语句和用for语句实现循环
(一)for语句的形式:
for(表达式1;表达式2;表达式3)语句
五)、循环结构的嵌套
在一个循环体内又完整地包含了另一个循环,称为循环的嵌套。循环的嵌套可以多层,但每一层循环在逻辑上必须是完整的。
六)、break语句
可以使流程跳出switch语句体,也可以在循环结构中,应用break语句使流程跳出本层循环体,提前结束本层循环
七)、continue语句
用以结束本次循环,即跳过本次循环中尚未执行的语句,再一次进行循环条件的判断。所以执行continue语句并未使整个循环终止。
八)、一维数组的定义、数组元素的引用、数组的初始化
1. 用数组来处理求Fibonacci数列问题
2. 用冒泡法对10个数从小到大排序
3. 用选择法对10个数从下到大排序
九)、二维数组的定义、二维数组的引用、初始化
类型说明符 数组名[常量表达式1][常量表达式2];
例如:int a[2][3] 定义一个2行3列的整型数组a
可以看成一种特殊的一维数组,每个元素是一个一维数组
三、应用举例
1. 输入一行字符,统计其中有多少个单词,单词之间用空格分隔开
2. 有3个字符串,要求找出其中最大的字符串
3. 有一个一排好序的数组,今输入一个数,要求按原来排序的规律将它插入数组中
4. 一个数组中的值按逆序重新存放,
5. 打印杨辉三角形,要求打印10行
6. 找出一个二维数组中的鞍点,即该位置上的元素在该行上最大,在该列上最小,也可能没有鞍点
四、二级C笔试模拟试卷讲评
实训项目(七)二级C机试练习
实训目的:
熟悉二级C机试环境;
了解二级C机试的注意事项。
实训内容:
一、二级C机试介绍
1.二级C机试环境熟悉;
2.注意/***********found********/的下一行;
3.程序结束要保存。
一、C语言复习
内容复习
一)、C函数概述及一般形式
一个c程序可由一个主函数和若干个其它函数构成,由主函数调用其他函数,其他函数也可以互相调用,但主函数不能被其他函数调用。
说明:
1、以源程序为单位进行编译,而不是以函数为单位进行编译
2、c程序执行从main开始,调用其他函数后流程回到main,main执行完毕程序结束
3、所有函数是平行的,定义函数时是互相独立的,不能在一个函数内部再定义另外的函数。
二)、函数分类
标准函数(库函数) 无参函数 主调函数
用户自定义函数 有参函数 被调函数
三)、函数定义的一般形式
函数头 类型标识符 函数名( )
函数体 {声明部分
语句}
四)、函数参数和函数值
(一)形参和实参
定义函数时函数名后括弧中变量名为形参
主调函数调用一个函数时,函数名后括弧中的参数称为实参
函数调用时会发生数据传递,按传递方式可分为:
1、值传递
a) 形参为变量,实参可以是已赋值的变量、常量或有确定结果的表达式
b) 实参与形参的类型应相同或兼容
c) 实参与形参有不同的存储空间
d) 在调用函数时才给形参分配内存单元,并将实参对应的值传递给形参,调用结束后,形参单元被释放,实参单元仍保留并维持原值。形参的值发生改变,并不会改变实参。
2、地址传递
形参通常是数组或指针变量,实参可以是变量地址、数组名、指针变量。实参和形参的内存空间是相同的。可以改变实参的值。
(二)、函数返回值
每个函数具有一定的功能,通常希望通过函数调用使主调函数能得到一个确定的值,即函数返回值
一个函数利用return语句只能返回一个值
格式:return(表达式);
括号可以省略,表达式的类型应与函数类型说明一致,不一致时,以函数类型为准,系统会自动转换。
五)、 函数的调用
1、形式:
函数名(实参表列);
函数名( );
实参间用逗号隔开,实参与形参的个数应相等,类型应一致,一一对应。
2、函数声明和函数原型
作用:向c编译系统提供有关信息,如函数值的类型、函数名及函数的参数个数、参数类型等,以便核查。不匹配的编译出错,属语法错误
函数定义在主调函数之前则无需函数原型说明。此外,若函数类型为整型,可以不作声明,不过建议声明为好。
3、函数调用的几种形式;
(1)以语句的形式进行函数调用
ex:puts(str);
Swap(x1,x2);
(2)以表达式的形式进行函数调用
ex:if(strcmp(s1,s2)>0)
n_max=max(x,y,z)
for(j=strlen(str)-1;j>0;j--)
(3)以函数的参数形式进行函数调用
ex:printf("%d",max(x,y,z))
fun1(fun2(t))
4、函数调用时参数间的传递
1)、变量、常量、数组元素作为函数实参
实参与形参之间的参数传递属于值单向传递方式
2)、数组名作函数实参
数组名并不是把数组中所有学生成绩传送给形参数组,而是把实参数组的首地址传给形参数组,使形参数组和实参数组共占同一段内存
5、函数的嵌套调用
c语言函数的定义都是互相平行的,独立的,也就是说不能在一个函数的内部再定义一个函数。即不能嵌套定义函数,但可以嵌套调用函数。也就是说在调用一个函数的过程中又调用另一个函数。
6、函数的递归调用
在调用一个函数的过程中又直接或间接地调用该函数本身,称为函数的递归调用。
7、局部变量和全局变量
(一)局部变量
在一个函数内部定义的变量是内部变量,它只在本函数范围内有效,也就是说只有在本函数内才能使用它们。这样的变量称为"局部变量"。
(二)全局变量
在函数外面定义的变量称为外部变量,外部变量是全局变量。全局变量可以为本文件中其他函数所共用。它的有效范围为从定义变量的位置开始,到本源文件结束
8、静态变量和动态变量
静态局部变量在编译时赋初值,即只赋初值一次,以后每次调用函数不再重新赋值,而只是保留上次函数调用结束时的值。而对自动变量不是在编译时赋初值,而是在函数调用时进行,每调用一次重新给一次初值。
二、例题分析:
给定程序中,函数fun的功能是:将自然数1~10以及它们的平方根写到名为myfile3.txt的文本文件中,然后再顺序读出显示在屏幕上。
#include <math.h>
#include <stdio.h>
int fun(char *fname )
{ FILE *fp; int i,n; float x;
if((fp=fopen(fname, "w"))==NULL) return 0;
for(i=1;i<=10;i++)
/**********found**********/
fprintf(___1___,"%d %f\n",i,sqrt((double)i)); /*应填fp*/
printf("\nSucceed!\n");
/**********found**********/
___2___; /*应填fclose(fp);*/
printf("\nThe data in file :\n");
/**********found**********/
if((fp=fopen(___3___,"r"))==NULL) /*应填fname*/
return 0;
fscanf(fp,"%d%f",&n,&x);
while(!feof(fp))
{ printf("%d %f\n",n,x); fscanf(fp,"%d%f",&n,&x); }
fclose(fp);
return 1; }
main()
{ char fname[]="myfile3.txt";
fun(fname); }
三、二级C 模拟环境机试相关练习
实训项目(八)二级C机试练习
实训目的:
熟悉二级C机试环境;
了解二级C机试的注意事项。
实训内容:
一、二级C机试分类:
1. 程序填空:字母转换、结构体操作、数组操作、文件操作、算法实现、公式计算、字符串操作
2. 程序修改题:字母转换、运算符、格式、变量初始化、数据类型匹配、限定条件、数组元素引用、指针使用、逻辑关系、算法实现、函数类型说明、关键字
3. 程序设计题:统计字符串中个数、字母转换、元素修改、字符串处理、素数计算、方程求根、级数与多项式、数字重组、一维数组运算、二维数组和矩阵运算、排序与查找、结构体数据处理
二、例题分析:
给定程序modi.c中,函数fun的功能是:求出a所指数组中最大数和次最大数(规定最大数和次最大数不在a[0]和a[1]中,依次和a[0]、a[1]中的数对调。
例如数组中原有的数为:7、10、12、0、3、6、9、11、5、8,
输出的结果为:12、11、7、0、3、6、9、10、5、8。
#include <conio.h>
#include <stdio.h>
#define N 20
int fun(int *a,int n)
{int k,m1,m2,max1,max2,t;
max1=max2=-32768;m1=m2=0;
for (k=0;k<n;k++)
if(a[k]>max1)
{ max2=max1;m2=m1;
max1=a[k];m1=k; }
else if (a[k]>max2)
{ max2=a[k];m2=k;}
/************found************/
t=a[0];a[m1]=a[0];a[m1]=t; /*改为t=a[0];a[0]=a[m1];a[m1]=t;*/
/************found************/
t=a[1];a[m2]=a[1];a[m2]=t;} /*改为t=a[1];a[1]=a[m2];a[m2]=t;*/
main()
{ int x,b[N]={7,10,12,0,3,6,9,11,5,8},n=10,i;
clrscr();
for (i=0;i<n;i++) printf("%d ",b[i]);printf("\n");
fun(b,n);
for(i=0;i<n;i++) printf("%d ",b[i]);printf("\n");}
三、二级C 模拟环境机试相关练习
实训项目(九)二级C机试练习
实训目的:
熟悉基本的公式计算算法;
能够根据题目所提供的公式编写程序。
实训内容:
一、例题分析.编写函数fun,它的功能是:根据以下公式计算s,计算结果通过形指针sn传回;s通过形参传入。
1 1 1 1 (-1)^n
sn = ── - ── + ── - ── + …… ────
1 3 5 7 2n+1
例如:若n的值为11时,输出的结果是:S=0.764601 N=11。
#include <conio.h>
#include <stdio.h>
void fun(float *sn,int n)
{ int i;
float s=1;
*sn=0;
for (i=0;i<=n;i++)
{ *sn=*sn+s*(1.0/(2*i+1)); /*累加每一分式*/
s=-s; /*用来控制分式是加还是减*/
}
}
main()
{ int n=11;float s; clrscr();
fun(&s,n);
printf("S=%f N=%d\n",s,n);}
2.给定程序的功能是根据公式计算S,计算结果通过形参指针sn传回;n通过形参传入。
1 1 1 1 1
Sn = ─ - ─ + ─ - ─ + … ───
1 3 5 7 2n+1
例如:若n的值为15时,输出的结果是:S=0.769788 N=15。
#include <stdio.h>
void fun(float *sn, int n)
{/**************found**************/
int i,j=___1___; /* int i,j=1;*/
float s=0.0;
for(i=0;i<=n;i++) {
s=s+j*1.0/(2*i+1);
j*=-1; }/**************found**************/
___2___=s;} /**sn=s;*/
main()
{ int n=15; float s;
/**************found**************/
fun(___3___); /* fun(&s, n);*/
printf("S=%f N=%d\n", s, n);}
二、二级C 模拟环境机试相关练习
实训总结