第一篇:[新]C语言期末复习,经典练习题+知识点总结+模拟考题。三位一体,完胜c语言!!!!{考期必备神器}
C语言期末复习(平时练习答案)
[特别适用于千千万北航学子] 考试重点:(编程题)排序,选择与冒泡排序,各种进制转换。。]
第二次大作业— 前驱、后继字符
1.【问题描述】 从键盘输入一个字符,求出它的前驱和后继字符(按照ASCII码值排序),并按照从小到大的顺序输出这三个字符和对应的ASCII值。【输入形式】 从键盘输入一个字符 【输出形式】 按两行输出: 第一行按照从小到大的顺序输出这三个字符,并以一个空格隔开; 第二行按照从小到大的顺序输出三个字符对应的ASCII值,并以一个空格隔开。【输入样例】 b 【输出样例】 a b c 97 98 99 【样例说明】 输入字符b,b的前驱字符是a,后继字符是c,第一行按照从小到大的顺序输出a b c;第二行输出对应的ASCII值97 98 99 【评分标准】结果完全正确得20分,每个测试点4分。提交程序名为:c0103.c。
//*从键盘输入一个字符,求出它的前驱和后继字符(按照ASCII码值排序),并按照从小到大的顺序输出这三个字符和对应的ASCII值。*// #include
printf(“Input a number:”);scanf(“%c”,&c);
//*从键盘输入一个字符*// printf(“ %c %c %cn”,c-1,c,c+1);//*第一行按照从小到大的顺序输出这三个字符,并以一个空格隔开*// printf(“ %d %d %d”, c-1,c,c+1);//*第二行按照从小到大的顺序输出三个字符对应的ASCII值,并以一个空格隔开。*// return 0;}
当前编程题:第二次大作业---数值变换
2.【问题描述】编写一程序,从键盘输入输入一个三位正整数,然后反向输出对应的数,如果输入的数不是三位正整数,则输出-1。【输入形式】从键盘输入三位的正整数。【输出形式】输出交换后的正整数值。【输入样例】 356 【输出样例】 653 【样例说明】从键盘输入的正整数值为356,将该数的个位与百位互换,所得结果为653.如果输入的正整数为300,则输出为3。【评分标准】结果完全正确得20分,每个测试点4分。提交程序名为:c0102.c。
//*编写一程序,从键盘输入输入一个三位正整数,然后反向输出对应的数,如果输入的数不是三位正整数,则输出-1。*// #include
int a,d,e,f,sum;//*定义变量*// printf(“请输入一个三位正整数,n”);scanf(“%d”,&a);
//* 输入一个数*//
if(a>0)//*对输入的值的正负做判断*// {
d=a/100;
e=(a-d*100)/10;
f=a%10;
sum=100*f+10*e+d;
printf(“%dn”,sum);
//*输出交换后的正整数值。*//
} 当前编程题:第二次大作业---正整数的打印
else 4.【问题描述】给出一个不多于5位的正
printf(“-1n”);
整数,要求:
1.求出它是几位数。
//*如果输入的数不是三位正整数,则输出2.分别打印出每一位数字。
3.按照逆序-1*// 打印出每一位数字。【输入形式】控制台输}
入该正整数。【输出形式】控制台分行输出 输出结果。【样例输入】1234 【样例输出】 当前编程题:第二次大作业---计算平均值
1234 4321 【样例说明】1234位数为4,3.【问题描述】从键盘输入三个整数,分别存入x,y,z三个整型变量中,计算并输出三个数的和以及平均值。【输入形式】从键盘输入三个整数,整数之间以空格隔开。【输出形式】在屏幕上分两行显示结果:第一行为三个数的和,整数形式输出;第二行为三个数的平均值,浮点数形式输出,小数点后保留两位小数。【输入样例】 3 2 3 【输出样例】 8 2.67 【样例说明】 3、2、3的和为8,所以第一行输出8;第二行输出3、2、3的平均值2.67(保留两位小数)。【评分标准】结果完全正确得20分,每个测试点4分。提交程序名为:c0101.c。
//*从键盘输入三个整数,分别存入x,y,z三个整型变量中,计算并输出三个数的和以及平均值*// #include
int x,y,z,sum;//*定义变量*// float average;scanf(“%d%d%d”,&x,&y,&z);
//*从键盘输入三个整数,整数之间以空格隔开*// sum=x+y+z;
average =(float)sum/3;//*第一行为三个数的和,整数形式输出;*// printf(“%dn”,sum);
printf(“%.2fn”,average);
//* 第二行为三个数的平均值,浮点数形式输出,小数点后保留两位小数*// return 0;}
/ 30
分别为1,2,3,4,逆序为4321 【评分标准】该题共有三个输出整数,完全正确得10分,每答错一个扣掉4分,直至得分为0。本题要求上传程序的源文件。所采用语言可以是C(.c)。主文件名设定为intprint.c
//*给出一个不多于5位的正整数,要求:
1.求出它是几位数。
2.分别打印出每一位数字。
3.按照逆序打印出每一位数字。
*// #include
long int a;int n,b,c,d,e,f;printf(“n请输入一个整数(0~99999):”);scanf(“%d”,&a);if(a>9999)
n=5;
else
if(a>999)
n=4;
else
if(a>99)
n=3;
else
if(a>9)
n=2;
else
n=1;
printf(“n这个数的位数
=%dn”,n);
f=a/10000;
e=a%10000/1000;
d=a%10000%1000/100;
c=a%10000%1000%100/10;
b=a%10000%1000%100%10;
switch(n)
{
case 5:
printf(“%d%d%d%d%dn”,f,e,d,c,b);
printf(“%d%d%d%d%dn”,b,c,d,e,f);break;
case 4:
printf(“%d%d%d%dn”,e,d,c,b);
printf(“%d%d%d%dn”,b,c,d,e);break;
case 3:
printf(“%d%d%dn”,d,c,b);
printf(“%d%d%dn”,b,c,d);break;
case 2:
printf(“%d%dn”,c,b);
printf(“%d%dn”,b,c);
case 1:
printf(“%dn”,b);
printf(“%dn”,b);
} }
当前编程题:第二次大作业---简易计算器5.【问题描述】编程实现简易的计算器:读入两个整数运算数(data1和data2)及一个运算符(op),计算表达式data1 op data2的值,其中op可以是+,-,*,/。【输入形式】控制台输入运算数和运算符: 1.首先输入以空格分隔的两个整数,分别是data1和data2;2.3 / 30
输入一个字符作为运算符op,op可以是’+’,’-’,’*’,’/’。输入时,data1、data2、op之间各留有一个空格。具体格式见样例输入。【输出形式】控制台输出运算结果。作除法运算时,若能够整除,则输出为整数,否则输出结果小数点后应保留两位有效数字。【样例输入】5 * 【样例输出】
【样例说明】输入中先后输入第一个运算数23,第二个运算数5,运算符’*’,要求对23和5进行乘法运算。计算结果为115。【评分标准】该题共20分,每个测试点4分。本题要求上传程序的源文件。所采用语言可以是C(.c).即所上传的文件名为calculator.c
//*编程实现简易的计算器:读入两个整数运算数(data1和data2)及一个运算符(op),计算表达式data1 op data2的值,其中op可以是+,-,*,/。*// #include
int data1,data2,c;//定义变量// double d;char op;scanf(“%d%d %c”,&data1,&data2,&op);//输入运算数和运算符// if(op=='+')
//进行判断// {
c=data1+data2;
printf(“%d”,c);}
else
if(op=='-')
{
c=data1-data2;
printf(“%d”,c);
} else
if(op=='*')
{
c=data1*data2;
printf(“%d”,c);
}
else if(op=='/'){
d=(double)data1/data2;printf(“%.2f”,d);} return 0;}
找最大最小整数
1.【问题描述】编写一个程序,用户输入若干整数,试找出其中的最大数和最小数。【输入形式】用户在第一行待输入数据个数,在第二行输入数据。
【输出形式】程序在下一行输出数据的最大值和最小值 【样例输入】 89 62 96 74 52
【样例输出】96 52 【样例说明】用户第一次输入的为数据个数,在下一行依次输入数据。输出为5个数中的最大值和最小值,输出时候两个数之间用空格分隔。
【评分标准】结果完全正确得20分,每个测试点4分。提交程序名为:getmaxandmin.c 矩形相交 2.【问题描述】 / 30
平面上有两个矩形A和B,其位置是任意的。
编程求出其相交部分(如图中阴影部分)的面积。(0≤a,b≤1000)
【输
入形式】
从标准输入读取两行以空格分隔的整数,格式如下: Ax1 Ay1 Ax2 Ay2 Bx1 By1 Bx2 By2
其中(x1,y1)和(x2,y2)为矩形对角线上端点的坐标。各坐标值均为整数,取值在0至1000之间。
【输出形式】
向标准输出打印一个整数,是两矩形相交部分的面积(可能为0)。在输出末尾要有一个回车符。【输入样例】 0 0 2 2 1 1 3 4
【输出样例】 1
【评分标准】
结果完全正确得20分,每个测试点4分,提交程序文件名为area.c。[红色为采用答案
#include
struct point { int x;int y;}A1,A2,B1,B2;
struct rect { struct point p1;struct point p2;}R1,R2;
struct point makepoint(int x,int y);struct rect makerect(struct point p1,struct point p2);struct rect guifanrect(struct rect R);
#define max(A,B)((A)>(B)?(A):(B))#define min(A,B)((A)>(B)?(B):(A))main(){ 5 / 30
int i,num1[4],num2[4],area;
for(i=0;i<4;i++)
scanf(“%d”,&num1[i]);for(i=0;i<4;i++)
scanf(“%d”,&num2[i]);
R1 = makerect(A1 =
makepoint(num1[0],num1[1]),A2 = makepoint(num1[2],num1[3]));
R2 = makerect(B1 =
makepoint(num2[0],num2[1]),B2 = makepoint(num2[2],num2[3]));
R1 = guifanrect(R1);R2 = guifanrect(R2);
if(R1.p2.x <= R2.p1.x || R1.p2.y <= R2.p1.y ||
R1.p1.x >= R2.p2.x || R1.p1.y >= R2.p2.y)
area = 0;else
area = abs(max(R1.p1.x, R2.p1.x)min(R1.p2.y, R2.p2.y));
printf(“%dn”,area);}
struct point makepoint(int x,int y){ struct point temp;temp.x = x;temp.y = y;return temp;} struct rect makerect(struct point p1,struct point p2){ struct rect temp;temp.p1 = p1;temp.p2 = p2;return temp;}
struct rect guifanrect(struct rect r){ struct rect temp;temp.p1.x = min(r.p1.x, r.p2.x);temp.p1.y = min(r.p1.y, r.p2.y);temp.p2.x = max(r.p1.x, r.p2.x);temp.p2.y = max(r.p1.y, r.p2.y);return temp;} 6 / 30
3.【问题描述】编写一个程序,当在一个字符串中出现子串时就删除它。
【输入形式】用户在第一行输入一个字符串,用户在第二行输入一个子串。
【输出形式】程序在下一行输出删除其中所有子串后的字符串。如果字符串不包含子串则输出原字符串本身。【样例输入】
I am a boy!a
【样例输出】
I m boy!
【样例说明】用户首先输入字符串I am a boy!,然后输出子串a,程序会寻找字符串中的子串删除它,最后将删除后的结果输出:I#m##boy!
#表示空格。
【评分标准】结果完全正确得20分,每个测试点4分。提交程序名为:delsubstring.c。#include
int main(void){
char *pdest;
int result;
fgets(source_str, 1024, stdin);
fgets(del_str, 1024, stdin);
source_str[strlen(source_str)-1] = ' ';
del_str[strlen(del_str)-1] = ' ';
pdest = strstr(source_str, del_str);
result = 0;
while(pdest!= NULL){
strncat(dest_str, &source_str[result],(int)(pdest&source_str[result])+ strlen(del_str);
pdest = strstr(&source_str[result], del_str);
}
if(result < strlen(source_str)){
strncat(dest_str, &source_str[result], strlen(source_str)9, test the input, rescan if get the result.*/ int main(){
char integer[250], result[250];
int start = 0, strlength, n, i = 0, j, temp, k = 0;
fgets(integer, 249, stdin);
strlength = strlen(integer)1;i>=0;i--)
printf(“%c”,s[i]);
return 0;}
第八次 填空题 # 题目
1.写出程序的运行结果1,2,3,3,5,4 #include
int a[] = {1,2,3,4,5,6};int *p;p=a;
printf(“%d,”,*p);printf(“%d,”,*(++p));printf(“%d,”,*++p);printf(“%d,”,*(p--));p+=3;
printf(“%d,%d”,*p, *(a+3));}
2.以下程序的运行结果是10 x #include
int x;
char c;};void func(struct n b){
b.x = 20;
b.c= ’y’;} main(){
struct n a = ,10, ’x’-;
func(a);
printf(“%d,%c”, a.x,a.c);}
3.以下程序的运行结果是6,9
#include
int i;
for(i=4;i<=10;i++)
{
if(i%3==0)
continue;
printf(“%d”,i);
} }
选择题
# 题目
1.若有以下程序段 struct dent { int n;int *m;};int a=1, b=2, c=3;struct dent s[3]={{101,&a},{102,&b},{103,&c}};strcut dent *p =s;则以下表达式值为2的是A A.(p++)->m B.*(p++)->m 14 / 30
C.(*p).m D.*(++p)->m
2.下面程序是求数组中的最小的元素,请选择填空。D
findmin(int *s, int t, int *k){
int p;
for(p = 0;p if(s[p] _________;} } main(){ int a[10],i,*k=&i;for(i=0;i<10;i++){ scanf(“%d”,&a[i]);} i=0; findmin(a, 10,k); printf(“%d, %d”, *k,a[*k]);} A.k=p B.*k=p-s C.k=p-s D.*k=p 3.有如下定义: struct { int x; char *y; } tab[2] = {{1, “ab”}, {2, “cd”}}, *p = tab; 语句 printf(“%c”, *(++p)->y);的输出结果是b 4.已知学生记录的定义为: struct student { int no;char name[20];char sex;struct { int year; int month; int day;}birth;};struct student s;假设变量s中的“生日”应是“1988年5月10日”,对“生日”的正确赋值语句是D(A)year=1988;month=5;day=10;(B)brith.year=1988;birth.month=5;birth.day=10;(C)s.year=1988;s.month=5;s.day=10;(D)s.birth.year=1988;s.birth.month=5;s.birth.day=10; 5.若有以下说明和语句,则下面表达式中值为1002的是D struct student { int age; int num;};struct student stu[3] = {{1001, 20}, {1002, 19}, {1003, 21}};struct student *p;p = stu; (A)(p++)->num(B)(p++)->age(C)(*p).num(D)(*++p).age 当前编程题:实验八---统计整数 / 30 1.【问题描述】 输入若干个整数,统计出现次数最多的那个整数。如果出现最多的整数有两个以上,打印最早输入的那个整数。【输入形式】 从标准输入读取输入。第一行只有一个数字N(1≤N≤10000),代表整数的个数。以后的N行每行有一个整数。【输出形式】 向标准输出打印出现次数最多的那个数字。【输入样例】 6 11 0-1 20 0 300 【输出样例】 0 【样例说明】 输入6个整数,其中出现次数最多的是0,共出现两次。【评分标准】 本题不准使用数学库函数。运行时限1秒,正确得20分,每个测试点4分,提交程序名为count.c。{{建电脑桌面}} C 语言总复习C六月,奋战CC语言,大家一起加油啦~~~~~~~~~~~!总体上必须清楚的:¬ 1)程序结构是三种: 顺序结构 , 循环结构(三个循环结构), 选择结构(if 和 switch)¬ 2)读程序都要从main()入口, 然后从最上面顺序往下读(碰到循环做循环,碰到选择做选 择)。¬ 3)计算机的数据在电脑中保存是以二进制的形式.数据存放的位置就是他的地址.¬ 4)bit是位是指为0 或者1。byte 是指字节, 一个字节 = 八个位.¬ 5)一定要记住二进制如何划成十进制。¬ 概念常考到的:¬ 1、编译预处理不是C语言的一部分,不再运行时间。C语言编译的程序称为源程序,它以ASCII数值存放在文本文件中。¬ 2、每个C语言程序中main函数是有且只有一个。¬ 3、在函数中不可以再定义函数。¬ 4、算法的是一定要有输出的,他可以没有输入。¬ 5、break可用于循环结构和switch语句。¬ 6、逗号运算符的级别最低。¬ 第一章¬ 1)合法的用户标识符考查:¬ 合法的要求是由字母,数字,下划线组成。有其它元素就错了。¬ 并且第一个必须为字母或则是下划线。第一个为数字就错了。¬ 关键字不可以作为用户标识符号。main define scanf printf 都不是关键字。迷惑你的地方If是可以做为用户标识符。因为If中的第一个字母大写了,所以不是关键字。¬ 2)实型数据的合法形式:¬ 2.333e-1 就是合法的,且数据是2.333×10-1。¬ 考试口诀:e前e后必有数,e后必为整数。.¬ 3)字符数据的合法形式::¬ '1' 是字符占一个字节,“1”是字符串占两个字节(含有一个结束符号)。¬ '0' 的ASCII数值表示为48,'a' 的ASCII数值是97,'A'的ASCII数值是65。¬ 4)整型一般是两个字节, 字符型是一个字节,双精度一般是4个字节:¬ 考试时候一般会说,在16位编译系统,或者是32位系统。碰到这种情况,不要去管,一样做题。掌握整型一般是两个字节, 字符型是一个字节,双精度一般是4个字节就可以了。¬ 5)转义字符的考查:¬ 16 / 30 在程序中 int a = 0x6d,是把一个十六进制的数给变量a 注意这里的0x必须存在。¬ 在程序中 int a = 06d, 是一个八进制的形式。¬ 在转义字符中,’x6d’才是合法的,0不能写,并且x是小写。¬ ‘141’是合法的,0是不能写的。¬ ‘108’是非法的,因为不可以出现8。¬ 6)算术运算符号的优先级别:¬ 同级别的有的是从左到右,有的是从右到左。¬ 7)强制类型转换:¬ 一定是(int)a 不是 int(a),注意类型上一定有括号的。¬ 注意(int)(a+b)和(int)a+b 的区别。前是把a+b转型,后是把a转型再加b。¬ 8)表达式的考查:¬ 是表达式就一定有数值。¬ 赋值表达式:表达式数值是最左边的数值,a=b=5;该表达式为5,常量不可以赋值。¬ 自加、自减表达式:假设a=5,++a(是为6),a++(为5);¬ 运行的机理:++a 是先把变量的数值加上1,然后把得到的数值放到变量a中,然后再用这¬ 个++a表达式的数值为6,而a++是先用该表达式的数值为5,然后再把a的数值加上1为6,¬ 再放到变量a中。进行了++a和a++后在下面的程序中再用到a的话都是变量a中的6了。¬ 考试口诀:++在前先加后用,++在后先用后加。¬ 逗号表达式:优先级别最低;表达式的数值逗号最右边的那个表达式的数值。¬(2,3,4)的表达式的数值就是4。¬ 9)位运算的考查:¬ 会有一到二题考试题目。¬ 总的处理方法:几乎所有的位运算的题目都要按这个流程来处理(先把十进制变成二进制再变成十进制)。¬ 例1: char a = 6, b;¬ b = a<<2;这种题目的计算是先要把a的十进制6化成二进制,再做位运算。¬ 例2: 一定要记住,¬ 例3: 在没有舍去数据的时候,<<左移一位表示乘以2;>>右移一位表示除以2。¬ 10)018的数值是非法的,八进制是没有8的,逢8进1。¬ 11)%符号两边要求是整数。不是整数就错了。¬ 12)三种取整丢小数的情况:¬ 1、int a =1.6;¬ 2、(int)a; ¬ 3、¬ ¬ 第二章¬ 1)printf函数的格式考查:¬ %d对应整型;%c对应字符;%f对应单精度等等。宽度的,左对齐等修饰。¬ %ld对应 long int;%lf 对应double。¬ 2)scanf函数的格式考察:¬ 注意该函数的第二个部分是&a 这样的地址,不是a; ¬ Scanf(“%d%d%*d%d”,&a,&b,&c);跳过输入的第三个数据。¬ 3)putchar ,getchar 函数的考查:¬ char a = getchar()是没有参数的,从键盘得到你输入的一个字符给变量a。-putchar(‘y’)把字符y输出到屏幕中。¬ 4)如何实现两个变量x,y中数值的互换(要求背下来)¬ 不可以把 x=y ,y=x;要用中间变量 t=x;x=y;y=t。¬ 5)如何实现保留三位小数,第四位四舍五入的程序,(要求背下来)¬ 这个有推广的意义,注意 x =(int)x 这样是把小数部分去掉。¬ ¬ 第三章¬ 特别要注意:c语言中是用非0表示逻辑真的,用0表示逻辑假的。¬ 1)关系表达式:¬ 表达式的数值只能为1(表示为真),或0(表示假)¬ 当关系的表达是为真的时候得到1。如 9>8这个是真的,所以表达式的数值就是1;¬ 17 / 30 2)逻辑表达式:¬ 只能为1(表示为真),或0(表示假)¬ a)共有&& ||!三种逻辑运算符号。¬ b)!>&&>|| 优先的级别。¬ c)注意短路现象。考试比较喜欢考到。¬ d)要表示 x 是比0大,比10小的方法。0 else 是与最接近的if且没有else的相组合的。¬ 4)条件表达式:¬ 表达式1 ?表达式2 :表达式3¬ 注意是当非0时候是表达式2的数值,当为0是就是表达式2的数值。¬ 考试口诀:真前假后。¬ 5)switch语句:¬ a)一定要注意有break 和没有break的差别,书上(34页)的两个例子,没有break时候,只要有一个case匹配了,剩下的都要执行,有break则是直接跳出了swiche语句。¬ b)switch只可以和break一起用,不可以和continue用。¬ ¬ 第四章¬ 1)三种循环结构:¬ a)for(); while();do-while()三种。¬ b)for循环当中必须是两个分号,千万不要忘记。¬ c)写程序的时候一定要注意,循环一定要有结束的条件,否则成了死循环。- d)do-while()循环的最后一个while();的分号一定不能够丢。(当心上机改错)¬ 2)break 和 continue的差别¬ 记忆方法:¬ break:是打破的意思,(破了整个循环)所以看见break就退出真个一层循环。¬ continue:是继续的意思,(继续循环运算),但是要结束本次循环,就是循环体内剩下的语句不再执行,跳到循环开始,然后判断循环条件,进行新一轮的循环。¬ 3)嵌套循环¬ 就是有循环里面还有循环,这种比较复杂,要一层一层一步一步耐心的计算,一般记住两层是处理二维数组的。¬ 4)while((c=getchar())!=’n’)和 while(c=getchar()!=’n’)的差别¬ 先看a = 3!= 2 和(a=3)!=2 的区别:¬(!=号的级别高于=号所以第一个先计算 3!=2)第一个a的数值是得到的1;第二个a的数值是3。¬ 考试注意点: 括号在这里的重要性。¬ ¬ 第五章¬ 函数:是具有一定功能的一个程序块;¬ 1)函数的参数,返回数值(示意图):¬ main()¬ {¬ int a = 5,b=6,c;¬ c = add(a,b);¬ printf(“%d”,c);¬ }¬ ¬ 调用函数¬ a,b是实参¬ 整个函数得到一个数值就是¬ Add函数的返回数值。¬ int add(int x, int y)¬ {¬ int z;¬ z=x+y;¬ return z;¬ }¬ 被调用函数¬ x,y是形式参数¬ 函数返回数值是整型¬ ¬ z就是这个add函数计算后得到的结果,就是函数返回给主程序的返回数值。-程序是在从上往下顺序执行,当碰到了函数add后,把a,b的数值穿给调用函数,程序暂时中断等待返回数值。当得到了返回数值后,再顺序的往下执行¬ 2)一定要注意参数之间的传递¬ 实参和形参之间传数值,和传地址的差别。18 / 30 (考试的重点)¬ 传数值的话,形参的变化不会改变实参的变化。¬ 传地址的话,形参的变化就会有可能改变实参的变化。¬ 3)函数声明的考查:¬ 一定要有:函数名,函数的返回类型,函数的参数类型。¬ 不一定要有:形参的名称。¬ ¬ 第六章¬ 指针变量的本质是用来放地址,而一般的变量是放数值的。¬ int *p 中 *p和p的差别:¬ *p可以当做变量来用;*的作用是取后面地址p里面的数值¬ p是当作地址来使用。¬ *p++ 和(*p)++的之间的差别:改错题目中很重要¬ *p++是地址会变化。¬ (*p)++ 是数值会要变化。¬ 三名主义:(考试的重点)¬ 数组名:表示第一个元素的地址。数组名不可以自加,他是地址常量名。(考了很多次)¬ 函数名:表示该函数的入口地址。¬ 字符串常量名:表示第一个字符的地址。¬ ¬ 第七章¬ 1一维数组的重要概念:¬ 对a[10]这个数组的讨论。¬ 1、a表示数组名,是第一个元素的地址,也就是元素a[10]的地址。¬ 2、a是地址常量,所以只要出现a++,或者是a=a+2赋值的都是错误的。¬ 3、a是一维数组名,所以它是列指针,也就是说a+1是跳一列。¬ 对a[3][3]的讨论。¬ 1、a表示数组名,是第一个元素的地址,也就是元素a[10]的地址。¬ 2、a是地址常量,所以只要出现a++,或者是a=a+2赋值的都是错误的。¬ 3、a是二维数组名,所以它是行指针,也就是说a+1是跳一行。¬ 4、a[0]、a[1]、a[2]也都是地址常量,不可以对它进行赋值操作,同时它们都是列指针,a[0]+1,a[1]+1,a[2]+1都是跳一列。¬ 5、注意a和a[0]、a[1]、a[2]是不同的,它们的基类型是不同的。前者是一行元素,后三者是一列元素。¬ 二维数组做题目的技巧:¬ 如果有a[3][3]={1,2,3,4,5,6,7,8,9}这样的题目。¬ 步骤一:把他们写成: 第一列 第二列 第三列 ¬ a[0]à ->第一行¬ a[1]à 4 —>第二行¬ a[2]à 7 ->第三行¬ 步骤二:这样作题目间很简单: ¬ *(a[0]+1)我们就知道是第一行的第一个元素往后面跳一列,那么这里就是a[0][1]元素,所以是1。¬ *(a[1]+2)我们就知道是第二行的第一个元素往后面跳二列。那么这里就是a[1][2]元素,所以是6。¬ 一定记住:只要是二维数组的题目,一定是写成如上的格式,再去做题目,这样会比较简单。¬ 数组的初始化,一维和二维的,一维可以不写,二维第二个一定要写¬ int a[]={1,2} 合法。int a[][4]={2,3,4}合法。但int a[4][]={2,3,4}非法。¬ 二维数组中的行指针¬ int a[1][2]; ¬ 其中a现在就是一个行指针,a+1跳一行数组元素。搭配(*)p[2]指针¬ a[0],a[1]现在就是一个列指针。a[0]+1 跳一个数组元素。搭配*p[2]指针数组使用¬ 还有记住脱衣服法则:¬ a[2] 变成 *(a+2)a[2][3]变成 *(a+2)[3]再可以变成 *(*(a+2)+3)-这个思想很重要!¬ 学习 模拟试题:::: 一、选择题 1、字符串“'efg'”的长度是:().19 / 30 A、3 B、11 C、7 D、5 2、设变量a是整型,f是实型,i是双精度型,则表达式10+'a'+i*f值的 数据类型为()。A、double B、不确定 C、int D、float 3、下列语句的结果是()。main(){ int j; j=3; printf(“%d,”,++j);printf(“%d”,j++);} A、3,3 B、4,4 C、3,4 D、4,3 4、逻辑表达式!(2-1)&&x||0的值是()A、1 B、0 C、3 D、2 5、int a=1,b=2,c=3;if(a>b)a=b;if(a>c)a=c;则a的值为()。A、3 B、2 C、1 D、不一定 6、执行语句 for(i=1;i++<4;);后变量 i 的值是()。A、3 B、5 C、4 D、不定 7、以下正确的描述是().A、只能用continue语句来终止本次循环 B、switch语句中不能出现continue语句 C、在循环中break语句不能独立出现 D、goto语句只能用于退出多层循环 8、下面合法的语句定义是().A、char a[ ]={'0','1','2','3','4','5'};B、int a[ ]=“string”;C、int a[5]={0,1,2,3,4,5};D、char a=“string”; 9、char a[10];不能将字符串“abc”存储在数组中的是()。 A、int i;for(i=0;i<3;i++)a[i]=i+97;a[i]=0;B、a=“abc”;C、strcpy(a,“abc”);D、a[0]=0;strcat(a,“abc”); 10、在C语言中,一维数组的定义方式为:类型说明符数组名()。 A、[整型常量]或[整型表达式] B、[正整型常量表达式] C、[整型表达式] D、[常量表达式] 11、在定义全局变量和局部静态变量的同时赋值,变量的初始化在()时确定的.A、运行 B、编辑 C、编译 D、调试 12、关于建立函数的目的,以下正确的说法是()。 A、提高程序的可读性 B、减少程序文件所占内存 C、减少程序的篇幅 D、提高程序的执行效率 13、以下函数调用语句中实参的个数是()。func((e1,e2),(e3,e4,e5));A、3 B、5 C、语法错误 D、2 14、设有宏定义#define SUB(x,y)(x)*y,且a=3,b=4,则 SUB(a++,b++)的值为().A、13 B、16 C、20 D、12 15、变量p为指针变量,若p=&a,下列写法不正确的是()。A、*(p++)==a++ 20 / 30 B、&*p==&a C、(*p)++==a++ D、*&a==a 16、下列程序正确的运行结果为().#include union u {char *name;int age;int income;} s; s.name=“WANGLING”;s.age=28; s.income=1000; printf(“%dn”, s.age);} A、8 B、28 C、1000 D、不确定 17、定义my_file 为文件型指针变量,使用fopen只读方式打开一个已存在的二进制文件,以下正 确的调用形式为().A、my_file=fopen(“my.dat”, “r”);B、my_file=fopen(“my.dat”, “rb+”);C、my_file=fopen(“my.dat”, “rb”);D、my_file=fopen(“my.dat”, “r+”); 答案:CABBC BAABB CADDA CC 二、判断 1、若i =3,则printf(“%d”,-i++);输出的值为-4。 2、格式字符%x用来以八进制形式输出整数.3、设u=1,v=2,w=3,则逻辑表达式u||v-w&&v+w的值为0.4、已知a=4,b=2,c=3,d=5,表达式a>b?a:c int a[3][3]={{3,5},{8,9},{12,35}},i,sum=0; for(i=0;i<3;i++)sum+=a[i][2-i];则sum=21.8、二维数组在内存中存贮时,是按行的顺序进行存储的。 9、C语言中引用数组元素的方括号可以用花括号代替.10、每次调用函数时,都要对静态局部变量重新进行初始化.11、在程序中的第二个函数之后定义了某全局变量,则该程序的所有函数均可使用它.12、在C程序中 , 函数既可以嵌套定义 , 也可以嵌套调用 13、在定义宏时,在宏名与带参数的括弧之间不应加空格.14、数组名与指针变量是相互等价的.15、两个类型相同的结构体变量,可以互相赋值.16、C语言中,在打开文件时,必须说明文件的使用方式,“r+”用于打开一个不存在的文件.答案:错错错错错对对对错错错错对错对错 三、填空 1、设x和y均为int型变量,且x=1,y=2,则表达式1.0+x/y的值为____1.0_.2、在C语言中,long类型数据占___4__个字节, short类型数据占_2____个字节.3、int x=2,y=3,z=4;则表达式x+y>z&&y==z的值为 0_____.4、int x=2,y=3,z=4;则表达式x+y&&(x=y)的值为____1_.5、C语言中,二维数组在内存中的存放方式为按___行__优先存放.6、函数调用时的实参和形参之间的数据是单向的_值____传递.7、结构体是不同数据类型的数据集合,作为数据类型, 必须先说明结构体___类型__,再说明结构体变量.8、调用 fopen 函数打开一文本文件,在“使用方式”这一项中, 为输入而打开需填入_r____.答案:(1)1 1.0 1.(2)4(3)0 (4)(5)行(6)值(7)类型(8)21 / 30 r+ r 四、程序设计 1、功能:求出二维数组外围元素之和,作为函数值返回。二 维数组的值在主函数中赋予。------#define M 4 #define N 5 #include “stdio.h” int fun(int a[M][N]){ /*********Begin**********/ /********** End **********/ } main(){ int a[M][N]={{1,3,5,7,9},{2,4,6,8,10},{2,3,4,5,6},{4,5,6,7,8}}; void TestFunc(); int y; y=fun(a); printf(“s=%dn”,y); TestFunc();} void TestFunc(){ FILE *IN,*OUT;int iIN[M][N],iOUT;int i,j,k; IN=fopen(“14.in”,“r”);if(IN==NULL) {printf(“Please Verify The Currernt Dir..It May Be Changed”);} OUT=fopen(“14.out”,“w”);if(OUT==NULL){printf(“Please Verify The Current Dir..It May Be Changed”);} for(k=0;k<10;k++){ for(i=0;i for(j=0;j fscanf(IN,“%d”,&iIN[i][j]); iOUT=fun(iIN);fprintf(OUT,“%dn”,iOUT);} fclose(IN);fclose(OUT);} 【参考代码】 int s=0; int i,j; for(i=0;i s=s+a[i][0]+a[i][N-1]; for(j=1;j s=s+a[0][j]+a[M-1][j]; return s;=============== 2、功能:找出一个大于给定整数且紧随这个整数的素数,并 作为函数值返回。 -----------------*/ #include “stdio.h” #include“conio.h” int fun(int n){ /*********Begin**********/ /********** End **********/ } void TestFunc(){ FILE *IN,*OUT; int s; int t;22 / 30 int o; IN=fopen(“in.dat”,“r”); if(IN==NULL) { printf(“Read File Error”); } OUT=fopen(“out.dat”,“w”); if(OUT==NULL) { printf(“Write File Error”); } for(s=1;s<=5;s++) { fscanf(IN,“%d”,&t); o=fun(t); fprintf(OUT,“%dn”,o); } fclose(IN); fclose(OUT);} main() { int m; printf(“Enter m: ”); scanf(“%d”, &m); printf(“nThe result is %dn”, fun(m)); TestFunc();} 【参考代码】 int i,k; for(i=n+1;;i++){ for(k=2;k 五、程序改错 1、功能:一个5位数,判断它是不是回文数。即12321是回文数,个 位与万位相同,十位与千位相同。------#include “stdio.h” main(){ /**********ERROR**********/ long ge,shi,qian;wan,x; scanf(“%ld”,&x); /**********ERROR**********/ wan=x%10000; qian=x%10000/1000; shi=x%100/10; ge=x%10; /**********ERROR**********/ if(ge==wan||shi==qian) printf(“this number is a huiwenn”); else printf(“this number is not a huiwenn”);} 【改错1】 【参考答案】 long ge,shi,qian,wan,x;=========================================== 【改错2】 【参考答案】 wan=x/10000;=========================================== 【改错3】 【参考答案】 if(ge==wan&&shi==qian)if(shi==qian&&ge==wan)=========================================== 2、功能:一个5位数,判断它是不是回文数。即12321是回文数,个 位与万位相同,十位与千位相同。------#include “stdio.h” main(){ /**********ERROR**********/ long ge,shi,qian;wan,x; scanf(“%ld”,&x); /**********ERROR**********/ 23 / 30 wan=x%10000; qian=x%10000/1000; shi=x%100/10; ge=x%10; /**********ERROR**********/ if(ge==wan||shi==qian) printf(“this number is a huiwenn”); else printf(“this number is not a huiwenn”);} 【参考答案】 #include “math.h” #include ===========================================【参考答案】 float s=0,t=1,p=1;float s=0,p=1,t=1;float p=1,s=0,t=1;float p=1,t=1,s=0;float t=1,p=1,s=0;float t=1,s=0,p=1;double s=0,t=1,p=1;float s=0.0,t=1.0,p=1.0;double s=0.0,t=1.0,p=1.0; =========================================== 【参考答案】 while(fabs(t)>1e-4)while(0.0001 =========================================== 【参考答案】 printf(“pi=%fn”,s*4);printf(“pi=%lfn”,s*4); =========================================== 六、程序填空 1、功能:计算并输出500以内最大的10个能被13或17整除的自然数之和。------#include “stdio.h” /***********FILL***********/ int fun(_____){ int m=0, mc=0, j, n; /***********FILL***********/ while(k >= 2 && _____) { /***********FILL***********/ if(k%13 == 0 || _____) { m=m+k; mc++; } k--; } /***********FILL***********/ _____;} main(){ printf(“%dn”, fun(500));} 【空1】 【参考答案】 int k =========================================== 【空2】 【参考答案】 mc < 10 10 > mc mc <= 9 9 >= mc ===========================================【空3】 【参考答案】 k%17 == 0!(k%17)k/17*17==k =========================================== 【空4】 【参考答案】 return m return(m)24 / 30 =========================================== 2、功能:以下程序中,函数fun的功能是计算x^2-2x+6,主函数中将调用fun函数计算: y1=(x+8)^2-2(x+8)+6 y2=(sin(x))^2-2sin(x)+6 请填空。 ------#include #include return(x*x-2*x+6);} main(){ /***********FILL***********/ double x, __________; printf(“Enter x:”); scanf(“%lf”,&x); /***********FILL***********/ y1=fun(_________); /***********FILL***********/ y2=fun(_________); printf(“y1=%lf,y2=%lfn”, y1, y2);} 【空1】 【参考答案】 y1,y2 y2,y1 =========================================== 【空2】 【参考答案】(x+8)(8+x)x+8 8+x =========================================== 【空3】 【参考答案】 sin(x) C语言必背18个经典程序 1、/*输出9*9口诀。共9行9列,i控制行,j控制列。*/ #include “stdio.h” main(){int i,j,result;for(i=1;i<10;i++) { for(j=1;j<10;j++) { result=i*j; printf(“%d*%d=%-3d”,i,j,result);/*-3d表示左对齐,占3位*/ } printf(“n”);/*每一行后换行*/ } } 2、/*古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 兔子的规律为数列1,1,2,3,5,8,13,21....*/ main(){ long f1,f2;int i;f1=f2=1;for(i=1;i<=20;i++) { printf(“%12ld %12ld”,f1,f2); if(i%2==0)printf(“n”);/*控制输出,每行四个*/ f1=f1+f2;/*前两个月加起来赋值给第三个月*/ f2=f1+f2;/*前两个月加起来赋值给第三个月*/ } } 3、/*判断101-200之间有多少个素数,并输出所有素数及素数的个数。 程序分析:判断素数的方法:用一个数分别去除2到sqrt(这个数),如果能被整除,则表明此数不是素数,反之是素25 / 30 数。*/ #include “math.h” main(){ int m,i,k,h=0,leap=1; printf(“n”); for(m=101;m<=200;m++) { k=sqrt(m+1); for(i=2;i<=k;i++) if(m%i==0) {leap=0;break;} if(leap) /*内循环结束后,leap依然为1,则m是素数*/ {printf(“%-4d”,m);h++; if(h%10==0) printf(“n”); } leap=1; } printf(“nThe total is %d”,h);} 4、/*一个数如果恰好等于它的因子之和,这个数就称为“完数”。例如6=1+2+3.编程 找出1000以内的所有完数。*/ main(){ static int k[10]; int i,j,n,s; for(j=2;j<1000;j++) { n=-1; s=j; for(i=1;i {if((j%i)==0) { n++; s=s-i; k[n]=i; } } if(s==0) {printf(“%d is a wanshu: ”,j); for(i=0;i printf(“%d,”,k[i]); printf(“%dn”,k[n]); } } } 5、/*下面程序的功能是将一个4×4的数组进行逆时针旋转90度后输出,要求原始数组的数据随机输入,新数组以4行4列的方式输出,请在空白处完善程序。*/ main(){ int a[4][4],b[4][4],i,j; /*a存放原始数组数据,b存放旋转后数组数据*/ printf(“input 16 numbers: ”);/*输入一组数据存放到数组a中,然后旋转存放到b数组中*/ for(i=0;i<4;i++) for(j=0;j<4;j++) { scanf(“%d”,&a[i][j]); b[3-j][i]=a[i][j]; } printf(“array b:n”); for(i=0;i<4;i++) { for(j=0;j<4;j++) printf(“%6d”,b[i][j]); printf(“n”); } } 6、/*编程打印直角杨辉三角形*/ main(){int i,j,a[6][6];for(i=0;i<=5;i++) {a[i][i]=1;a[i][0]=1;} for(i=2;i<=5;i++) for(j=1;j<=i-1;j++) a[i][j]=a[i-1][j]+a[i-1][j-1];for(i=0;i<=5;i++) {for(j=0;j<=i;j++) printf(“%4d”,a[i][j]); printf(“n”);} } 7、/*通过键盘输入3名学生4门课程的成绩,分别求每个学生的平均成绩和每门课程的平均成绩。/ 30 要求所有成绩均放入一个4行5列的数组中,输入时同一人数据间用空格,不同人用回车 其中最后一列和最后一行分别放每个学生的平均成绩、每门课程的平均成绩及班级总平均分。*/ #include { float a[4][5],sum1,sum2; int i,j; for(i=0;i<3;i++) for(j=0;j<4;j++) scanf(“%f”,&a[i][j]); for(i=0;i<3;i++) { sum1=0; for(j=0;j<4;j++) sum1+=a[i][j]; a[i][4]=sum1/4; } for(j=0;j<5;j++) { sum2=0; for(i=0;i<3;i++) sum2+=a[i][j]; a[3][j]=sum2/3; } for(i=0;i<4;i++) { for(j=0;j<5;j++) printf(“%6.2f”,a[i][j]); printf(“n”); } } 8、/*完善程序,实现将输入的字符串反序输出,如输入windows 输出swodniw。*/ #include { char c[200],c1; int i,j,k; printf(“Enter a string: ”); scanf(“%s”,c); k=strlen(c); for(i=0,j=k-1;i { c1=c[i];c[i]=c[j];c[j]=c1;} printf(“%sn”,c); } 指针法: void invert(char *s){int i,j,k;char t;k=strlen(s);for(i=0,j=k-1;i { printf(“cannot open the filen”); exit(0); } printf(“input str:n”);gets(str); printf(“n%s”,str);fprintf(fp,“%s”,str);invert(str); printf(“n%s”,str);fprintf(fp,“n%s”,str); fclose(fp);} 9、/*下面程序的功能是从字符数组s中删除存放在c中的字符。*/ #include int j,k; printf(“nEnter a string: ”); gets(s); printf(“nEnter a character: ”); c=getchar(); for(j=k=0;s[j]!= ' ';j++) if(s[j]!=c) s[k++]=s[j]; s[k]= ' '; printf(“n%s”,s);} 10、/*编写一个void sort(int *x,int n)实现将27 / 30 x数组中的n个数据从大到小 排序。n及数组元素在主函数中输入。将结果显示在屏幕上并输出到文件p9_1.out中*/ #include int i,j,k,t; for(i=0;i for(j=i+1;j if(x[j]>x[k])k=j; if(k!=i) { t=x[i]; x[i]=x[k]; x[k]=t; } } } void main(){FILE *fp; int *p,i,a[10]; fp=fopen(“p9_1.out”,“w”); p=a; printf(“Input 10 numbers:”);for(i=0;i<10;i++) scanf(“%d”,p++);p=a; sort(p,10); for(;p fprintf(fp,“%d ”,*p);} system(“pause”); fclose(fp);} 11、已知数组a中的元素已按由小到大顺序排列,以下程序的功能是将输入的一个数插入数组a中,插入后,数组a中的元素仍然由小到大顺序排列*/ main() { int a[10]={0,12,17,20,25,28,30};/*a[0]为工作单元,从a[1]开始存放数据*/ int j=6; fprintf(fp,“The new string is----%sn”,str); fclose(fp);/*j为元素个数*/ printf(“Enter a number: ”); } scanf(“%d”,&x); 13、/*在一个字串s1中查找一子串s2,若 a[0]=x;存在则返回子串在主串中的起始位置 i=j;,不存在则返回-1。*/ x , i, /*从最后一个单元开始*/ while(a[i]>x) { a[i+1]=a[i];i--; } /*将比x大的数往后移动一个位置*/ a[++i]=x; j++; /*插入x后元素总个数增加*/ for(i=1;i<=j;i++)printf(“%8d”,a[i]); printf(“n”);} 12、/*编写函数replace(char *s,char c1,char c2)实现将s所指向的字符串中所有字符c1用c2替换,字符串、字符c1和c2均在主函数中输入,将原始字符串和替换后的字符串显示在屏幕上,并输出到文件p10_2.out中*/ #include { if(*s==c1) *s=c2; s++; } } main(){ FILE *fp; char str[100],a,b; if((fp=fopen(“p10_2.out”,“w”))==NULL) { printf(“cannot open the filen”); exit(0); } printf(“Enter a string:n”); gets(str); printf(“Enter a&&b:n”); scanf(“%c,%c”,&a,&b);printf(“%sn”,str);fprintf(fp,“%sn”,str);replace(str,a,b);printf(“The new string is----%sn”,str);28 / 30 main(){char s1[6]=“thisis”;char s2[5]=“is”; printf(“%dn”,search(s1,s2));system(“pause”);} int search(char s1[],char s2[]){int i=0,j,len=strlen(s2);while(s1[i]){ for(j=0;j if(j>=len)return i;else i++;} return-1;} 14、/*用指针变量输出结构体数组元素。*/ struct student { int num;char *name;char sex;int age;}stu[5]={{1001,“lihua”,'F',18},{1002,“liuxing”,'M',19},{1003,“huangke”,'F',19},{1004,“fengshou”,'F',19},{1005,“Wangming”,'M',18}};main(){int i;struct student *ps;printf(“Num tNametttSextAgetn”); /*用指针变量输出结构体数组元素。*/ for(ps=stu;ps 15、/*建立一个有三个结点的简单链表:*/ #define NULL 0 struct student { int num;char *name;int age;struct student *next;};void main(){ struct student a,b,c,*head,*p;a.num=1001;a.name=“lihua”;a.age=18;/* 对结点成员进行赋值 */ b.num=1002;b.name=“liuxing”;b.age=19;c.num=1003;c.name=“huangke”;c.age=18;head=&a; /* 建立链表,a为头结点 */ a.next=&b;b.next=&c;c.next=NULL;p=head; /* 输出链表 */ do{ printf(“%5d,%s,%3dn”,p->num,p->name,p->age);p=p->next;}while(p!=NULL);} 16、/*输入一个字符串,判断其是否为回文。回文字符串是指从左到右读和从右到左读完全相同的字符串。*/ #include int i,j,n; printf(“输入字符串:n”); gets(s); n=strlen(s); for(i=0,j=n-1;i if(s[i]!=s[j]) break; if(i>=j)printf(“是回文串n”);29 / 30 else printf(“不是回文串n”);} 17、/*冒泡排序,从小到大,排序后结果输出到屏幕及文件myf2.out*/ #include for(i=0;i<=n-1;i++) for(j=0;j if(a[j]>a[j+1]){t=a[j];a[j]=a[j+1];a[j+1]=t;} } main() {int a[10]={12,45,7,8,96,4,10,48,2,46},n=10,i;FILE *f; if((f=fopen(“myf2.out”,“w”))==NULL) printf(“open file myf2.out failed!n”);fun(a,10); for(i=0;i<10;i++) {printf(“%4d”,a[i]); fprintf(f,“%4d”,a[i]); } fclose(f);} 18、编写函数countpi,利用公式 计算π的近似值,当某一项的值小于10-5时,认为达到精度要求,请完善函数。将结果显示在屏幕上并输出到文件p7_3.out中。#include { int m=1; double temp=1.0,s=0; while(temp>=eps) { s+=temp; temp=temp*m/(2*m+1); m++; } return(2*s); } main(){FILE *fp; double eps=1e-5,pi; if((fp=fopen(“p7_3.out”,“w”))==NULL) { printf(“cannot open the filen”); exit(0); } pi= countpi(eps); printf(“pi=%lfn”,pi);fprintf(fp,“pi=%lfn”,pi);fclose(fp);} 30 / 30 谁能出线 电视台举办“超级学生”才艺大赛,由于报名人数狂多,所以要先进行分组预赛。按规定,每10名学生为一个预赛小组,评委打出分数(0~100分),各小组第一名可以进入下一轮;如果有多名学生得分相同都是第一名,则可同时进入下一轮。 1.#include 求出 2 到 m 之间(含 m,m<=1000)所有素数并放在数组 a 中。输入:正整数m 输出:从小到大的所有素数,及个数(素数输出的时候用%4d来控制) 1.#include 9.i=i+1;10.} 11.cnt=0; 12.for(i=0;i 14.j=2; 15.while(a[i]%j!=0)16.{ 17.j++;18.} 19.if(j==a[i])20.{ 21.printf(“%4d”,j);22.cnt=cnt+1;23.} 24.25.}printf(“n”);26.printf(“%d”,cnt);27.printf(“n”);28.return 0;29.} 1.#include 4.int a[10],i,j,n;5.for(i=0;i<10;i++)6.{ 7.scanf(“%d”,&a[i]);8.} 9.for(j=0;j<10;j++)10.{ 11.12.for(i=0;i<9;i++)13.{ 14.if(a[i+1] 16.n=a[i+1];17.a[i+1]=a[i];18.a[i]=n;19.} 20.} 21.} 22.23.for(i=0;i<10;i++)24.{ 25.printf(“ %d”,a[i]); 冒泡法排序26.} 27.printf(“n”);28.return 0;29.} 插入法排序 1.#include 1.#include 7.do 8.{ 9.a[i]=n%10;10.n=n/10;11.i++;12.k++; 13.}while(n!=0); 14.for(j=0;j 16.for(i=0;i 18.if(a[i+1]>a[i])19.{ 20.m=a[i+1];21.a[i+1]=a[i];22.a[i]=m;23.} 24.} 25.} 26.for(i=0;i 28.printf(“%d”,a[i]);29.} 30.printf(“n”);31.return 0;32.} 数组逆序输出 1.#include 4.int a[10],i,j,t;5.for(i=0;i<10;i++)6.{ 7.scanf(“%d”,&a[i]);8.} 9.i=0;10.j=9; 11.while(i 13.t=a[i];14.a[i]=a[j];15.a[j]=t;16.i++;17.j--;18.} 19.for(i=0;i<10;i++)20.{ 21.printf(“%d ”,a[i]);22.} 23.printf(“n”);24.return 0;25.} 求最大值 1.#include 程序定义了 4× 4 的二维数组,请编写程序,给二维数组赋值,并使数组下半三角元素中的值乘以n。例如: 数组中的值为 假设n为10,则输出结果如下:(输出的数按照4位宽度来输出,即%4d) 1.#include 4.int a[4][4],i,j,n;5.for(i=0;i<4;i++)6.{ 7.for(j=0;j<4;j++)8.{ 9.scanf(“%d”,&a[i][j]);10.} 11.} 12.scanf(“%d”,&n);13.for(i=0;i<4;i++)14.{ 15.for(j=0;j<=i;j++)16.{ 17.a[i][j]=n*(a[i][j]);18.} 19.} 20.for(i=0;i<4;i++)21.{ 22.for(j=0;j<4;j++)23.{ 24.printf(“%4d”,a[i][j]);25.} 26.printf(“n”);27.} 28.return 0;29.} 在屏幕上显示杨辉三角形 1.#include 6.int a[N][M],i,j,n;7.scanf(“%d”,&n);8.for(i=0;i 10.j=i; 11.a[i][0]=1;12.a[i][j]=1;13.} 14.for(i=2;i 1.#include 28.printf(“ %d”,a[i][j]); 29.} printf(“n”);30.} 31.return 0;32.} 给数组中的元素按顺序编号 对数组 a[10] 中的十个整数从小到大进行连续编号,输出各个元素的编号。要求不能改变数组 a 中元素的顺序,且相同的整数要具有相同的编号。例如数组是: A=(5,3,4,7,3,5,6,8,9,10)则输出为:(4,1,3,7,1,4,6,8,9,10) 1.#include 4.int a[10],b[10],i,j,t;5.for(i=0;i<10;i++)6.{ 7.scanf(“%d”,&a[i]);8.} 9.for(i=0;i<10;i++)10.{ 11.b[i]=a[i];12.} 13.for(i=0;i<9;i++)14.{ 15.for(j=i+1;j<10;j++)16.{ 17.if(a[i]>a[j])18.{ 19.t=a[i];20.a[i]=a[j];21.a[j]=t;22.} 23.} 24.} 25.for(j=0;j<10;j++)26.{ 27.for(i=0;i<10;i++)28.{ 29.if(b[j]==a[i])30.{ 31.printf(“%3d”,i+1);brea k; 32.} 33.} 34.}printf(“n”);35.return 0;36.} 字符转换 描述 提取一个字符串中的所有数字字符(‘0’...‘9’)将其转换为一个整数输出。输入 一个以回车符为结束标志的字符串(少于80个字符)。输出 把字符串中的所有数字字符(‘0’...‘9’)转换为一个整数并输出。 1.#include 11.{ 12.printf(“%c”,a[j]);13.} 14.} 15.printf(“n”);16.return 0;17.} 合并字符串 输入: 两个已经排好顺序(升序)的字符串 输出: 一个合并在一起的有序(升序)的字符串 要求: 设计一个效率尽量高的算法,对每个字符串只扫描一遍就可以了。 如果采用先进行串连接,然后再进行排序的算法,则效率太低了。 1.#include 7.char a[N],b[M];8.int i,j,t,n;9.gets(a);10.gets(b);11.strcat(a,b);12.n=strlen(a); 13.for(i=0;i 15.for(j=i+1;j 17.if(a[i]>=a[j])18.{ 19.t=a[i];20.a[i]=a[j];21.a[j]=t;22.} 23.} 24.} 25.puts(a);26.return 0;27.} 删除重复字符 1.#include 4.char a[100],b[100];5.int i,j,n=0;6.gets(a);7.b[0]=a[0]; 8.for(i=0;a[i]!=' ';i++)9.{ 10.j=0;11.for(j=0;j<=n;j++)12.{ 13.if(a[i]==b[j])14.{ 15.break;16.} 17.} 18.if(a[i]!=b[j])19.{ 20.n++;21.b[n]=a[i];22.} 23.} 24.b[n+1]=' ';25.puts(b);26.return 0;27.} 删除字符串中指定字符 1.#include 在指定位置插入字符串 1.#include 5.char a[20],b[5],ch,c[10];6.int i,j,k,n; 7.gets(a);gets(b);8.scanf(“%c”,&ch);9.n=strlen(b); 10.for(i=0;a[i]!=' ';i++)11.{ 12.if(ch==a[i])break;13.} 14.k=0; 15.for(j=i;a[j]!=' ';j++)16.{ 17.c[k]=a[j];18.k++;19.} 20.c[k]=' '; 21.for(j=0;j 23.printf(“%c”,a[j]);24.} 25.printf(“%s”,b);26.printf(“%sn”,c);27.return 0;28.} 数的合并 1.int fun(int a,int b)2.{ 3.int c; 4.c=a/10*10+a%10*1000+b/10+b%10*100 ; 5.return c;6.} 7.int main()8.{ 9.int a,b,c; 10.scanf(“%d%d”,&a,&b);11.c=fun(a,b); 12.printf(“c=%dn”,c);13.return 0;14.} 素数的判断 1.int fun(int a)2.{ 3.int i;4.for(i=2;i 请编写函数fun,它的功能是计算下列级数和,值由函数值返回。 例如,当n=10,x=0.3时,函数值为1.349859。请勿改动主函数main,仅在函数fun的花括号中填入所编写的若干语句。 1.#include 10.S=S+z/m;11.} 12.return S;13.} 14.int main()15.{ 16.double x;17.int n; 18.scanf(“%lf%d”,&x,&n);19.printf(“%lfn”,fun(x,n));20.return 0;21.} 求大于m且紧靠m的k个素数 1.int fun(int m,int n,int zz[1000])2.{ 3.int i,j,cnt=0,k=0;4.for(i=m+1;i<1000;i++)5.{ 6.for(j=2;j 8.if(i%j==0)9.break;10.} 11.if(j==m+1)12.{ 13.cnt++;14.zz[k]=i;15.k++; 16.if(cnt==n)17.{ 18.return zz[m];19.} 20.} 21.} 22.} 23.int main()24.{ 25.int m,n,zz[1000];26.scanf(“%d%d”,&m,&n);27.fun(m,n,zz); 28.for(m=0;m 29.printf(“%6d”,zz[m]);30.printf(“n”);31.return 0;32.} 删除指定字符 请编写函数fun,其功能是:从字符串中删除指定的字符。同一字母的大、小写按照不同的字符处理。1.#include 求整数 n 到 m 区间的累加和,其中n<=m。输入: 区间的起始点n 区间的终止点m 输出: 累加和 1.int fun(int a,int b)2.{ 3.int h;4.h=a;5.if(a==b)6.{ 7.h=a;8.} 9.else if(a 11.h=b+fun(a,b-1);12.} 13.14.return h;15.} 16.int main()17.{ 18.int m,n,s; 19.scanf(“%d%d”,&n,&m);20.s=fun(n,m); 21.printf(“%dn”,s);22.return 0;23.} 求最大公约数——递归 请使用递归算法计算正整数n和m的最大公约数GCD(n,m)。 1.#include 4.if((m<=n)&&(n%m==0))5.{ 6.return m;7.} 8.else if(n 10.return GCD(m,n);11.} 12.else 13.{ 14.return GCD(m,n%m);15.} 16.} 17.int main()18.{ 19.int a,b; 20.scanf(“%d%d”,&a,&b);21.printf(“%dn”,GCD(a,b));22.return 0;23.} 求数列的第N项 已知整数数列第一项和第二项是1,该数列从第三项开始,如果该项是奇数项,则它是前两项之和,如果该项是偶数项,则它是前两项之差,即: f(n)= 1 当 n = 1 或 2 时, f(n)= f(n-1)-f(n-2)当n是偶数时, f(n)= f(n-1)+ f(n-2)当n是奇数时,编写一个递归函数,求数列的第N项。 1.#include 14.} 15.else 16.{ 17.return m=f(n-1)+f(n-2); 18.} 19.} 20.} 21.int main()22.{ 23.int n;24.scanf(“%d”,&n);25.printf(“%dn”,f(n));26.return 0;27.} 偶数分解 编写程序,输入若干个大于2的正整数,如果是偶数,则将其分解为两个素数并输出;如果输入的奇 数,则输出“××× is odd number!” ;输入为0时程序结束。只有1和它本身这两个因数的自然数叫做素数,0和1既不是素数也不是和数。实现分解的过程用函数实现。输入:整数序列,0 输出:偶数1 = 素数A + 素数B(当输入是偶数时)奇数1 is odd number!(当输入是奇数时)1.#include 4.int i; 5.for(i=2;i 7.if(n%i==0)8.return 0;9.} 10.if(i==n)11.{ 12.return 1;13.} 14.} 15.void fun(int n)16.{ 17.int i; 18.for(i=2;i 20.if(s(n)==1)21.{ 22.printf(“%d is odd number! n”,n);23.} 24.else if((s(i)==1)&&(s(n-i)= =1)) 25.{ 26.printf(“%d=%d+%dn”,n,i,n -i);break;27.} 28.} 29.} 30.int main()31.{ 32.int n;33.do 34.{ 35.scanf(“%d”,&n);36.fun(n);37.}while(n!=0);38.return 0;39.} 浮点数四舍五入 1.#include 6.} int main()7.{ double a;8.scanf(“%lf”, &a);9.printf(“%lfn”, fun(a));10.return 0;11.} 长整型截短 1.#include 21.return 0;22.} 长整型截短 编写一个函数fun,其功能是:将形参n中,各位上为偶数的数取出,并按原来从高位到低位的顺序组成一个新的数,并作为函数值返回。 1.#include 2.int fun(int n) 3.{ 4.int a,i=0,b=0;5.do 6.{ 7.a=n%10;8.n=n/10;9.if(a%2==0)10.{ 11.b=b+a*pow(10,i);12.i++;13.} 14.}while(n!=0);15.return b;16.} 17.int main()18.{ int n; 19.scanf(“%ld”,&n); 20.printf(“The result is: %ldn”,fun(n)); 21.return 0;22.} 公式求解 1.double fun(int n)2.{ 3.int i; 4.double a=1,s=1;5.for(i=1;i<=n;i++)6.{ 7.a=a/i;8.s=s+a;9.} 10.return s;11.} 12.int main()13.{ int n;14.double s;15.16.scanf(“%d”,&n);17.s=fun(n);18.printf(“s=%fn”,s);19.return 0;20.} 数的合并 请编写函数fun,其功能是:将两个两位数的正整数a、b合并形成一个整数放在c中。合并的方式是:将a的十位和个位依次存放在c数的十位和千位上,b的十位和个位依次存放在c数的个位和百位上。 1.int fun(int a,int b,int *p)2.{ 3.*p=a/10*10+a%10*1000+b%10*100+b/10;4.return p;5.} 6.int main()7.{ 8.int a,b,c;9.scanf(“%d%d”,&a,&b);10.fun(a,b,&c);11.printf(“%dn”,c);12.return 0;13} 数组中奇偶数 请编一个函数 fun,函数的功能是分别求出数组中所有奇数之和以及所有偶数之和。形参 n 给了数组中数据的个数:利用指针 odd 返回奇数之和,利用指针 even 返回偶数之和。 例如:数组中的值依次为: 1,8,2,3,11,6 ;则利用指针 odd 返回奇数之和 15 ;利用指针 even 返回偶数之和 16。 void fun(int x[],int y,int *odd,int *even) { int i; *odd=0; *even=0; for(i=0;i if(x[i]%2!=0) { *odd=*odd+x[i]; } else { *even=*even+x[i]; } } } int main() { int a[N],i,n,odd,even; scanf(“%d”,&n); for(i=0;i printf(“The sum of even numbers:%dn”,even); return 0; } #include #define N 20 浮点数四舍五入 请编一个函数 void fun(double a,double *h),函数的功能是对变量 h 中的值保留 2 位小数,并对第三位进行四舍五入(规定 h 中的值为正数)。 例如: h 值为 8.32433,则函数返回 8.32 ; h 值为 8.32533,则函数返回 8.33。 #include void fun(double a,double *h) { *h=(floor)(a*100+0.5)/100; } int main() { double a,h; scanf(“%lf”,&a); fun(a,&h); printf(“The result:%lfn”,h); return 0; } 字符移动 请编一个函数void fun(char *s),函数的功能是把字符串中所有的字符前移一个位置,串中的第一个字符移到最后。 例如:原有的字符串为: Mn.123xyZ,则调用该函数后,串中的内容为: n.123xyZM。 void fun(char *s) { int i=0,j,k; char ch,a[N]; do { a[i++]=*(s++); }while(*s!=' '); ch=a[0]; for(j=0;j a[j]=a[j+1]; } a[i-1]=ch; a[i]=' '; for(k=i-1;k>=0;k--) { *(--s)=a[k]; } } int main() { char a[N]; gets(a); fun(a); printf(“%sn”,a); return 0; } 生成新数 给定程序中,函数fun的功能是:将形参n所指变量中,各位上为偶数的数去除,剩余的数按原来从高位到低位的顺序组成一个新的数,并通过形参指针n传回所指变量。 例如,输入一个数:27638496,新的数:为739。 #include int a[10],b[10]; int i=0,j=0,k; do { a[i++]=*p%10; *p=*p/10; }while(*p!=0); for(k=0;k if(a[k]%2!=0) { b[j++]=a[k]; } } for(k=0;k *p=*p+b[k]*pow(10,k); } } int main() { int n=-1; while(n>99999999||n<0) { scanf(“%d”,&n);} fun(&n); printf(“%dn”,n); return 0; } 字符串转换成整数 请编写一个函数fun,它的功能是:将一个数字字符串转换为一个整数。例如,若输入字符串“-1234”,则函数把它转换为整数值-123 4 #include int fun(char *p) { char a[10]; int q=0,i=0,j=0; do { a[j++]=*(p++); }while(*p!=' '); if(a[0]=='-') { for(i=1;i q=q+(a[i]-'0')*pow(10,j-1-i); } q=-1*q; } else { for(i=0;i q=q+(a[i]-'0')*pow(10,j-1-i); } } return q; } int main()/* 主函数 */ { char s[10]; int n; gets(s); n = fun(s); printf(“%dn”,n); return 0; } 二维数组按列优先存放 请编写函数fun, 函数的功能是: 将M行N列的二维数组中的字符数据, 按列的顺序依次放到一个字符串中。 例如, 二维数组中的数据为: W W W W S S S S H HHH 则字符串中的内容应是: WSHWSHWSHWSH。 void fun(char w[M][N],char *q) { int j,i; for(j=0;j for(i=0;i *(q++)=w[i][j]; } } *q=' '; } int main() { char a[100],w[M][N]={{'W','W','W','W'},{'S','S','S','S'},{'H','H','H','H'}}; fun(w,a); puts(a); return 0; } #include #define M 3 #define N 4 删除字符串中指定的星号 假定输入的字符串中只包含字母和 * 号。请编写函数 fun,它的功能是:除了尾部的 * 号之外 , 将字符串中其它 * 号全部删除。在编写函数时,不得使用 C 语言提供的字符串函数 void fun(char *p,char *t) { char a[30],b[30],ch; int i=0,j,k=0; do { a[i++]=*(p++); }while(*p!=' '); a[i]=' '; for(j=0;;j++) { if(a[j]!='*') { b[k++]=a[j]; if(a[j]==*t)break; } } for(j=k;j b[j]=*(++t); } for(k=j;k>=0;k--) { *(p--)=b[k]; } } int main() { char s[81],*t; gets(s); t=s; while(*t)t++; t--; while(*t=='*')t--; fun(s , t); puts(s); return 0; } 统计数字字符 请编写函数 fun,它的功能是: 统计形参 s 所指字符串中数字字符出现的次数,并存放在形参 t void fun(char *p,int *q) { int i=0; for(;*p!=' ';p++) { if((*p>='0')&&(*p<='9')) { i++; } } *q=i; } int main() { char s[80]; int t; gets(s); fun(s,&t); printf(“%dn”,t); return 0; } 将两个串按要求形成一个新串 给定程序的函数 fun 的功能是:逐个比较 p、q 所指两个字符串对应位置中的字符,把 ASCII 值大或相等的字符依次存放到 c 所指数组中,形成一个新的字符串。 void fun(char *p,char *q,char *c) { int i,j; for(i=0;*(p+i)!=' '&&*(q+i)!=' ';i++) { if(*(p+i)>=*(q+i)) { *(c+i)=*(p+i); } else { *(c+i)=*(q+i); } } j=i; if(*(p+j)!=' ') { for(j=i;*(p+j)!=' ';j++) { *(c+j)=*(p+j); } } else { for(j=i;*(q+j)!=' ';j++) { *(c+j)=*(q+j); } } *(c+j)=' '; } int main() { char a[10], b[10], c[80]; gets(a);gets(b); fun(a,b,c); puts(c); return 0; } #include #include 统计子串的个数 请编写函数 fun,它的功能是: 统计 substr 所指子字符串在 str 所指字符串中出现的次数。 void fun(char *p,char *q,int *c) { int i,j,cnt; *c=0; for(;*p!=' ';p++) { cnt=1; if(*p==*q) { for(j=0;*(q+j)!=' ';j++) { if(*(p+j)!=*(q+j)) { cnt=0; break; } } } else cnt=0; if(cnt) { (*c)++; } } } int main() { char str[80],substr[80]; int count; gets(str); gets(substr); fun(str,substr,&count); printf(“%dn”,count); return 0; } 函数 fun 的功能是: 将 s 所指字符串中除了下标为奇数、同时 ASCII 值也为奇数的字符之外,其余的所有字符都删除 , 串中剩余字符所形成的一个新串放在 t 所指的数组中。 void fun(char *p,char *q) { int i; for(i=0;*(p+i)!=' ';i++) { if(i%2==1&&*(p+i)%2==1) { *(q++)=*(p+i); } } *(q++)=' '; } int main() { char s[100], t[100]; scanf(“%s”, s); fun(s, t); printf(“%sn”, t); return 0; } 求非偶数的除数 请编写函数 fun,它的功能是:求出能整除形参 x 且不是偶数的各整数 , 并按从小到大的顺序放在 pp 所指的数组中 , 这些除数的个数通过形参 n 返回。 void fun(int x,int *p,int *q) { int i; *q=0; for(i=1;i<=x;i=i+2) { if(x%i==0) { *(p++)=i;(*q)++; } } } int main() { int x, aa[1000], n, i; scanf(“%d”, &x); fun(x, aa, &n); for(i = 0;i < n;i++) printf(“ %d”, aa[i]); printf(“n”); return 0; } 求最大值及其下标 请编写函数 fun,其功能是求出数组的最大元素在数组中的下标并存放在 k 所指的存储单元中 void fun(int *p,int n,int *q) { int i,max; max=0; for(i=0;i if(*(p+i)>max) { max=*(p+i); *q=i; } } } void main() { int a[10], k ,i; for(i=0;i<10;i++) scanf(“%d”,&a[i]); fun(a, 10, &k); printf(“%d,%dn”, k, a[k]); } 结构体填空 给定程序通过定义并赋初值的方式,利用结构体变量存储了一名学生的学号、姓名和3门课的成绩。函数modify的功能是将该学生的各科成绩都乘以一个系数a。请在程序的下划线处填入正确的内容并把下划线删除,使程序得出正确的结果。 #include typedef struct { int num; char name[9]; float score[3]; } STU; void show(STU tt) { int i; printf(“%d %s : ”,tt.num,tt.name); for(i=0;i<3;i++) printf(“%5.1f”,tt.score[i]); printf(“n”); } void modify(STU *ss,float a) { int i; for(i=0;i<3;i++) ss->score[i]*=a; } int main() { STU std= { 1,“Zhanghua”,76.5,78.0,82.0 }; float a; scanf(“%f”,&a); modify(&std,a); show(std); return 0; } 程序通过定义学生结构体变量,存储了学生的学号、姓名和 3 门课的成绩。函数 fun 的功能是对形参 b 所指结构体变量中的数据进行修改 , 最后在主函数中输出修改后的数据。 #include #include struct student { long sno; char name[10]; float score[3]; }; void fun(struct student *b) { b->sno= 10004; strcpy(b->name, “LiJie”); } int main() { struct student t={10002,“ZhangQi”, {93, 85, 87}}; int i; fun(&t); printf(“No: %ld Name: %snScores:”,t.sno, t.name); for(i=0;i<3;i++)printf(“%6.2f”, t.score[i]); printf(“n”); return 0; } 程序通过定义学生结构体数组,存储了若干名学生的学号、姓名和 3 门课的成绩。函数 fun 的功能是将存放学生数据的结构体数组,按照姓名的字典序(从小到大)排序。 #include #include struct student { long sno; char name[10]; float score[3]; }; void fun(struct student a[], int n) { struct student t; int i, j; for(i=0;i for(j=i+1;j if(strcmp(a[i].name,a[j].name)> 0) { t = a[i];a[i] = a[j];a[j] = t;} } int main() { struct student s[4]={{10001,“ZhangSan”, {95, 80, 88}},{10002,“LiSi”, {85, 70, 78}}, {10003,“CaoKai”, {75, 60, 88}},{10004,“FangFang”, {90, 82, 87}}}; int i, j; fun(s, 4); printf(“The data after sorting :n”); for(j=0;j<4;j++) { printf(“nNo: %ld Name: %-8s Scores:”,s[j].sno, s[j].name); for(i=0;i<3;i++) printf(“%6.2f”, s[j].score[i]); } printf(“n”); return 0; } C语言知识点总结资料I 总体上必须清楚的: 程序结构是三种:顺序结构,循环结构(三个循环结构),选择结构(if和switch)读程序都要从main()入口,然后从最上面顺序往下读(碰到循环做循环,碰到选择做选择)。 计算机的数据在电脑中保存是以二进制的形式。数据存放的位置就是它的地址。bit是位是指为0或者1。byte是指字节。一个字节=八个位。—定要记住二进制如何转换成十进制。概念常考到的: 1、编译预处理不是C语言的一部分,不占运行时间,不要加分号。C语言编译的程序称 为源程序,它以ASCII数值存放在文本文件中。 2、每个C语言程序中main函数是有且只有一个。 3、在函数定义中不可以再定义函数。 4、算法的是一定要有输出的,他可以没输入。 5、break可用于循环结构和switch语句。 6、逗号运算符的级别最低。 第3章 1)合法的用户标识符考查: 合法的要求是由字母,数字,下划线组成。有其它元素就错了。并且第一个必须为字母或则是下划线。第一个为数字就错了。 关键字不可以作为用户标识符号。main define scanf printf都不是关键字。迷惑你 的地方If是可以做为用户标识符。因为If中的第一个字母大写了,所以不是关键字。2)实型数据的合法形式: 2.333e-1就是合法的,且数据是2.333X10' 考试口诀:e前e后必有数,e后必为整数。3)字符数据的合法形式:: '1'是字符占一个字节,“1”是字符串占两个字节(含有一个结束符号)。'0'的ASCII数值表示为48,'a'的ASCII数值是97,'A'的ASCII数值是65。一般考试表示单个字符错误的形式:' 65' 字符是可以进行算术运算的,记住:'0'-0=48 大写字母和小写字母转换的方法:' A'+32='a'相互之间一般是相差32。4)int型TC中是2个字节,VC中是4个字节。字符型是1个字节。5)转义字符的考查: 在程序中int a = 0x6d,是把一个十六进制的数给变量a注意这里的0x必须存在。在程序中int a = 06d 是一个八进制的形式。 在转义字符中,‟x6d‟才是合法的,0不能写,并且x是小写。‟141‟是合法的,0是不能写的。‟108‟是非法的,因为不可以出现8。6)强制类型转换: 一定是(int)a不是int(a),注意类型上一定有括号的。 “1” 注意(int)(a+b)和(int)a+b的区别。前是把a+b转型,后是把a转型再加b。7)表达式的考查: 是表达式就一定有数值。 赋值表达式:表达式数值是最左边的数值,a=b=5;该表达式为5,常量不可以赋值。自加、自减表达式:假设a=5,++a(是为6),a++(为5); 运行的机理:++a是先把变量的数值加上1,然后把得到的数值放到变量a中,然后再用这 个++a表达式的数值为6,而a++是先用该表达式的数值为5,然后再把a的数值加上1为6,再放到变量a中。进行了++a和a++后在下面的程序中再用到a的话都是变量a中的6 了。 考试口诀:++在前先加后用,++在后先用后加。 逗号表达式:优先级别最低;表达式的数值逗号最右边的那个表达式的数值。(2,3,4)的表达式的数值就是4。 8)018的数值是非法的,八进制是没有8的,逢8进1。9)%符号两边要求是整数。不是整数就错了。10)三种取整丢小数的情况: 1、int 2、(int)a;3、1/2;3/2;11)字符型和整数是近亲: char a = 65;printf(“%c”, a);得到的输出结果:a prmtf(“%d”, a);得到的输出结果:65 12)printf函数的格式考查: %d对应整型;%c对应字符;%f对应单精度等等。宽度的,左对齐等修饰。%ld 对应 long int;%lf 对应 double。13)scanf函数的格式考察: 注意该函数的第二个部分是&a这样的地址,不是a;scanf(“%d%d%*d%d”,&a,&b,&c);跳过输入的第三个数据。14)putchar ,getchar 函数的考查: char a = getchar()是没有参数的,从键盘得到你输入的一个字符给变量a。putchar(„y‟)把字符y输出到屏幕中。 15)如何实现两个变量x,y中数值的互换(要求背下来) 不可以把x=y ,y=x;要用中间变量t=x;x=y; y=t。 16)如何实现保留三位小数,第四位四舍五入的程序,(要求背下来) 这个有推广的意义,注意x =(int)x这样是把小数部分去掉。 第4章 特别要注意:e语言中是用非0表示逻辑真的,用0表示逻辑假的。1)关系表达式: 表达式的数值只能为1(表示为真),或0(表示假) 当关系的表达是为真的时候得到1。如9>8这个是真的,所以表达式的数值就是1;2)逻辑表达式: a =1.6;只能为1(表示为真),或0(表示假)a)共有&& ||!三种逻辑运算符号。 b)!>&&>||优先的级别。 c)注意短路现象。考试比较喜欢考到。 d)要表示x是比0大,比10小的方法。0 else是与最接近的if且没有else的相组合的。4)条件表达式: 表达式1 ?表达式2 :表达式3 注意是当非0时候是表达式2的数值,当为0是就是表达式2的数值。考试口诀:真前假后。5)switch 语句: a)—定要注意有break和没有break的差别,书上(34页)的两个例子,没有break 时候,只要有一个case匹配了,剩下的都要执行,有break则是直接跳出了 switch语句。b)switch只可以和break —起用,不可以和continue用。C)switch(x)x:是整型常量,字符型常量,枚举型数据。{case 1:....不可以是变量。case 2:...} 第5章 1)三种循环结构: a)for(); while();do-while()三种。 b)for循环当中必须是两个分号,千万不要忘记。 c)写程序的时候一定要注意,循环一定要有结束的条件,否则成了死循环。 d)do-while()循环的最后一个while();的分号一定不能够丢。(当心上机改错),do—while 循环是至少执行一次循环。2)break 和 continue 的差别 记忆方法: break:是打破的意思,(破了整个循环)所以看见break就退出真个一层循环。continue:是继续的意思,(继续循环运算),但是要结束本次循环,就是循环体内剩下 的语句不再执行,跳到循环开始,然后判断循环条件,进行新一轮的循环。3)嵌套循环 就是有循环里面还有循环,这种比较复杂,要一层一层一步一步耐心的计算,一般记住 两层是处理二维数组的。 while((c=getchar())!=‟n‟)和 while(c=getchar()!=‟n‟)的差别 先看a = 3!= 2和(a=3)=2的区别: (!=号的级别髙于=号所以第一个先计算3!=2)第一个a的数值是得到的1;第二个a的数值是3。考试注意点:括号在这里的重要性。 第6章 1)一维数组的重要概念: 对a[10]这个数组的讨论。 1、a表示数组名,是第一个元素的地址,也就是元素a[0]的地址。 2、a是地址常量,所以只要出现a++,或者是a=a+2赋值的都是错误的。 3、a是一维数组名,所以它是列指针,也就是说a+1是跳一列。对a[3][3]的讨论。 1、a表示数组名,是第一个元素的地址,也就是元素a[0]的地址。 2、a是地址常量,所以只要出现a++,或者是a=a+2赋值的都是错误的。 3、a是二维数组名,所以它是行指针,也就是说a+1是跳一行。 4、a[0]、a[1]、a[2]也都是地址常量,不可以对它进行赋值操作,同时它们都是列指针,a[0]+1,a[1]+1,a[2]+1 都是跳一列。 5、注意a和a[0]、a[1]、a[2]是不同的,它们的基类型是不同的。前者是一行元素,后 三者是一列元素。 2)两种重要的数组长度: char a={„a‟,‟b‟,‟c‟};数组长度为3,字符串长度不定。sizeof(a)为3。char a[5]={ „a‟,‟b‟,‟c‟} 数组长度为 5,字符串长度 3。sizeof(a)为 5。3)scanf 和 gets 的数据 如果输入的是 good good study!那么scanf(“%s”,a);只会接收good.考点:不可以接收空格。gets(a);会接收good good study!考点:可以接收空格。 4)字符串的strlen()和strcat()和strcmp()和strcpy()的使用方法一定要记住。他 们的参数都是地址。其中strcat()和strcmp()有两个参数。5)二维数组做题目的技巧: 如果有 a[3][3]={1,2,3,4,5,6,7,8,9}这样的题目。步骤一:把他们写成: 第0列 第1列 第2列 a[0]—> 1 2 3 —> 第0行 a[1]—> 4 5 6 —> 第1行 a[2]—> 7 8 9 —> 第2行 步骤二:这样作题目间很简单: *(a[0]+1)我们就知道是第一行的第一个元素往后面跳一列,那么这里就是a[0][1]元素,所以是1。 *(a[1]+2)我们就知道是第二行的第一个元素往后面跳二列。那么这里就是a[1][2]元素,所以是 6。 一定记住:只要是二维数组的题目,一定是写成如上的格式,再去做题目,这样会比较简单。6)数组的初始化,一维和二维的,一维可以不写,二维第二个一定要写 int a[]={1,2}合法。int a[][4]={2,3,4}合法。但 int a[4][]={2,3,4}非法。7)二维数组中的行指针 int a[1][2];其中a现在就是一个行指针,a+1跳一行数组元素。搭配(*)p[2]指针。 a[0],a[1]现在就是一个列指针。a[0]+1跳一个数组元素。搭配*p[2]指针数组使用。8)还有记住脱帽子法则: a[2]变成 *(a+2)a[2][3]变成 *(a+2)[3],再可以变成 *(*(a+2)+3)这个思想很重要! 第7章 函数:是具有一定功能的一个程序块;是c语言的基本组成单位。,/ 1)函数的参数,返回数值(示意图): 2)—定要注意参数之间的传递 实参和形参之间传数值,和传地址的差别。(考试的重点)传数值的话,形参的变化不会改变实参的变化。传地址的话,形参的变化就会有可能改变实参的变化。3)函数声明的考查: 一定要有:函数名,函数的返回类型,函数的参数类型。不一定要有:形参的名称。4)要求掌握的库函数: sqrt()fabs()pow()sin()其中 pow(a,b)是重点。23 是由 pow(2,3)表示的。5)“文件包含”的考查点: no1.c #include”no2.c” main(){ add(29, 33)} no2.c int add(int a,int b){ return a+b;} 这里一个C语言程序是有两个文件组成,分别是no1.c,no2.c。那么no1.c中最开始有 个#include”no2.c‟‟他表示把第二个文件的内容给包含过来,那么no1.c中调用add()函数的时 候就可以了把数值传到no2.c中的被调用函数add()了。 一个文件必须要有main函数。这句话错了。例如:no2.c就没有。 头文件一定是以.h结束的。这句话错了。例如:no1.c中就是#mclude”no2.c”以.c结尾的。 第8章 1)指针变量的本质是用来放地址,而一般的变量是放数值的。2)int *p中 *p和p的差别: *p可以当做变量来用;*的作用是取后面地址p里面的数值 p是当作地址来使用。 3)*p++和(*p)++的之间的差别——改错题目中很重要 *p++是地址会变化。 (*p)++是数值会要变化。(考试的重点)4)三名主义: 数组名:表示第一个元素的地址。|数组名不可以自加,他是地址常量名。(考了很多次)函数名:表示该函数的入口地址。字符串常量名:表示第一个字符的地址。5)考试重要的话语: 指针变量是存放地址的。并且指向哪个就等价哪个,所有出现*p的地方都可以用它等价的代替。 例如:int a=2,*p=&a; *p=*p+2;(由于*p指向变量a,所以指向哪个就等价哪个,这里*p等价于a,可以相当于是a=a+2)指针变量两种初始化 方法一:int a=2,*p=&a;(定义的同时初始化)..方法二:int a=2,*p;(定义之后初始化p=&a; 文件的复习方法: 把上课时候讲的文件这一章的题目要做一i strlen和sizeof的区别也是考试的重点; 上考试的都会在练习当中。 define f(x)(x*x)和define f(x)x*x之间的差别。一定要好好的注意这写 容易错的地方,替换的时候有括号和没有括号是很大的区别。int *p;p =(int *)malloc(2);p =(int *)malloc(sizeof(int));以上两个等价 当心填空题目,malloc的返回类型是void * 还有main(int argc,char **argv){}这种含有参数的题目,是很呆板的题目。第 一个参数是表示输入的字符串的数目,第二个参数是指向存放的字符串。 函数的递归调用一定要记得有结束的条件,并且要会算简单的递归题目。要会作递归的 题目 结构体和共用体以及链表要掌握最简单的。typedef考的很多,而且一定要知道如何引用 结构体中的各个变量,链表中如何填加和删除节点,以及何如构成一个简单的链表,一定记 住链表中的节点是有两个域,一个放数值,一个放指针。函数指针的用法(*f)()记住一个例子: int add(int x, int y){ } main(){ int(*f)()f=add;} 赋值之后:合法的调用形式为 1、add(2,3); 2、f(2,3); 3、(*f)(2,3)9) 11)共用体的考查: union TT { int a;char ch[2];} 考点一:sizeof(struct TT)= 2;考点二: TT t1;t1=0x1234;那么 ch[0]=0x 34;ch[1]=0x12 C语言总结 第一章 概述 1. C语言的特点 ①语言简洁、紧凑,使用方便、灵活。共有32个关键字,9种控制语句。②运算符丰富,公有34种运算符。 ③数据结构丰富,数据类型有:整型、实型、字符型、数组、指针、结构体、共用体等。④具有结构化的控制语句(如if…else、while、do…while、switch、for)⑤语法限制不太严格,程序设计自由度大。 ⑥允许直接访问物理地址,能进行位(bit)操作,可以直接对硬件操作。⑦生成目标代码质量高,程序执行效率高。⑧可移植性好。2. C语言的用途 C虽不擅长科学计算和管理领域,但对操作系统和系统实用程序以及对硬件进行操作方面,C有明显的优势。现在很多大型应用软件也用C编写。 第二章 数据类型、运算符与表达式 1. C的数据类型 C的数据类型包括:整型、字符型、实型或浮点型(单精度和双精度)、枚举类型、数组类型、结构体类型、共用体类型、指针类型和空类型。2. 常量与变量 常量其值不可改变,符号常量名通常用大写。变量其值可以改变,变量名只能由字母、数字和下划线组成,且第一个字符必须为字母或下划线。否则为不合法的变量名。变量在编译时为其分配相应存储单元。3. 整型数据 整型常量的表示方法:十进制不用说了,八进制以0开头,如0123,十六进制以0x开头,如0x1e。 整型变量分为:基本型(int)、短整型(short int)、长整型(long int)和无符号型。不同机器上各类数据所占内存字节数不同,一般int型为2个字节,long型为4个字节。4. 实型数据 实型常量表示形式:十进制形式由数字和小数点组成(必须有小数点),如:0.12、.123、123.、0.0等。指数形式如123e3代表123×10的三次方。 实型变量分为单精度(float)和双精度(double)两类。在一般系统中float型占4字节,7位有效数字,double型占8字节,15~16位有效数字。5. 字符型数据 字符变量用单引号括起来,如'a','b'等。还有一些是特殊的字符常量,如'n','t'等。分别代表换行和横向跳格。 字符变量以char 来定义,一个变量只能存放一个字符常量。 字符串常量是由双引号括起来的字符序列。这里一定要注意'a'和“a”的不同,前者为字符常量,后者为字符串常量,c规定:每个字符串的结尾加一个结束标志' ',实际上“a”包含两个字符:'a'和' '。 6. 数值型数据间的混合运算 整型、字符型、实型数据间可以混合运算,运算时不同类型数据要转换成同一类型再运算,转换规则: char,short-> int-> unsigned-> long-> double <-float 7. 运算符和表达式 c运算符包括: 算数运算符(+-* / %)关系运算符(> < == >= <=!=)逻辑运算符(!&& ||) 位运算符(<< >> ~ | ^ &)赋值运算符(=)条件运算符(? :)逗号运算符(,)指针运算符(* &)求字节数(sizeof)强制类型转换(类型)分量运算符(.->)下标运算符([ ]) 其它运算符(如函数调用运算符())自增自减运算符(++--)注意:++i和i++的不同之处,++i使用i之前先使i加1,i++使用i之后,使i加1。 逗号表达式的求解过程:先求解表达式1,再求解表达式2,整个表达式的值是表达式2的值。 第三章 最简单的c程序设计 1.c的9种控制语句: if()~ else~ for()~ while()~ do~while()continue break switch goto return 程序的三种基本结构:顺序结构,选择结构,循环结构 2.数据输出 c语言不提供输入输出语句,输入输出操作是由c的库函数完成。但要包含头文件stdio.h。putchar()向终端输出一个字符 printf()的格式字符: ① d格式符 用来输出十进制整数 %d 按整型数据的实际长度输出 %md 使输出长度为m,如果数据长度小于m,则左补空格,如果大于m,则输出实际长度 %ld 输出长整型数据 ② o格式符 以八进制形式输出整数 ③ x格式符 以十六进制形式输出整数 ④ u格式符 用来输出unsigned型数据,以十进制形式输出 ⑤ c格式符 用来输出一个字符 ⑥ s格式符 输出一个字符串 %s 输出实际长度字符串 %ms 输出的串占m列,如果串长度小于m,左补空格,如果大于m,实际输出 %-ms输出的串占m列,如果串长度小于m,右补空格,%m.ns 输出占m列,但只取字符串中左端n个字符并靠右对齐 %-m.ns m、n含义同上,靠左对齐,如果n>m,则m自动取n值 ⑦ f格式符 以小数形式输出实数 %f 整数部分全部输出,小数部分输出6位 %m.nf 输出数据共占m列,其中有n位小数。如果数值长度小于m,左补空格 %-m.nf 同上,右补空格 ⑧ e格式符 以指数形式输出实数 %e 系统指定6位小数,5位指数(e+002)⑨ g格式符 输出实数,根据数值大小,自动选f格式或e格式 3.数据输入 getchar()从终端输入一个字符 scanf(格式控制,地址列表)标准C scanf中不使用%u,对于unsigned型数据,以%d或%o或%x输入。%后的*,用来跳过它相应的数据。输入数据时不能规定精度如scanf(“%7.2f”, &a);是不合法的。 第四章逻辑运算和判断选取控制 1. 关系运算符: c提供6种关系运算符(> < <= >= ==!=)前四种优先级高于后两种。2. If语句 C提供了三种形式的if语句 If(表达式)语句 If(表达式)语句1 else 语句2 If(表达式1)语句1 Else if(表达式2)语句2 … else 语句n 3. 条件运算符 (a>b)?a:b 条件为真,表达式取值a,否则取值b 4. Switch语句 Switch(表达式){ case 常量表达式1:语句1;break;case 常量表达式2:语句2;break; … case 常量表达式n:语句n;break; default :语句n+1;} 第五章 循环控制 1. 几种循环语句 goto语句(现已很少使用) while语句 先判断表达式后执行语句 do-while语句 先执行语句后判断表达式 for语句 2. Break语句和continue语句 Break语句用于跳出循环,continue用于结束本次循环。 第六章 数组 1. 一维数组 c规定只有静态存储(static)和外部存储(extern)数组才能初始化。给数组初始化时可以不指定数组长度。2. 二维数组 3. 字符数组 部分字符串处理函数 puts(字符数组)将一个字符串输出到终端。 gets(字符数组)从终端输入一个字符串到字符数组,并且得到一个函数值,为该字符数组的首地址 strcat(字符数组1,字符数组2)连接两个字符数组中的字符串,数组1必须足够大。Strcpy(字符数组1,字符串2) 将字符串2拷贝到字符数组1中。 Strcmp(字符串1,字符串2)比较字符串,相等返回0,字符串1>字符串2,返回正数,小于返回负数。 Strlen(字符数组)求字符串长度。 Strlwr(字符串)将字符串中的大写字母转换成小写 Strupr(字符串)将字符串中的小写字母转换成大写 以上是一些比较常用的字符串处理函数。 第七章 函数 1. 关于形参和实参的说明 ① 在函数被调用之前,形参不占内存 ② 实参可以是常量、变量或表达式 ③ 必须指定形参的类型 ④ 实参与形参类型应一致 ⑤ 实参对形参的数据传递是“值传递”,即单向传递 2. 函数返回值 如果想让函数返回一个值,在函数中就要用return语句来获得,在定义函数时也要对函数值指定类型,如果不指定,默认返回整型。3. 函数调用 1)注意在函数调用时实参和形参的个数、类型应一一对应。对实参表求值的顺序是不确定的,有的系统按自左至右,有的系统则按自右至左的顺序。这一点要注意。2)函数调用的方式:函数语句,函数表达式,函数参数 3)如果主调函数和被调函数在同一文件中,并且主调函数在前,那么一般要在主调函数中对被调函数进行说明。除非:(1)被调函数的返回值类型为整型或字符型(2)被调函数出现在主调函数之前。 4)对函数的说明和定义是不同的,定义是指对函数功能的确立,包括指定函数名,函数值类型,形参及其类型、函数体等。说明则只是对已定义的函数返回值类型进行说明,只包括函数名、函数类型以及一个空的括弧,不包括形参和函数体。 5)c语言允许函数的递归调用(在调用一个函数的过程中又出现直接或间接的调用该函数本身)。4. 数组作为函数参数 1)数组元素作为函数参数 和一般变量相同 2)数组名作参数应该在主调和被调函数分别定义数组,形参数组的大小可以不定义。注意:数组名作参数,不是单向传递。3)多维数组作参数,在被调函数中对形参数组定义时可以省略第一维的大小说明,但不能省略第二维或更高维的说明。5. 局部变量和全局变量 从变量作用域角度分,变量可分为局部变量和全局变量。1)内部变量(局部变量) 在一个函数内定义,只在函数范围内有效的变量。 2)外部变量(全局变量) 在函数外定义,可以为本文件其它函数所共用,有效范围从定义变量的位置开始 到本文件结束。建议尽量少使用全局变量,因为它在程序全部执行过程中都占用 资源,而且使函数的通用性降低了。如果在定义外部变量之前的函数要想使用该 外部变量,则应在该函数中用extern作外部变量说明。6. 动态存储变量与静态存储变量 从变量值存在的时间(生存期)角度来分,可分为静态存储变量和动态存储变量。静态存储指在程序运行期间给变量分配固定的存储空间,动态存储指程序运行期间根据需要动态的给变量分配存储空间。C语言中,变量的存储方法分为两大类:静态存储类和动态存储类,具体包括:自动的(auto),静态的(static),寄存器的(register),外部的(extern)。1)局部变量的存储方式 函数中的局部变量如不作专门说明,都之auto的,即动态存储的,auto可以省略。局部变量也可以定义为static的,这时它在函数内值是不变的。静态局部变量如不赋初值,编译时系统自动赋值为0,动态局部变量如不赋初值,则它的值是个不确定的值。C规定,只有在定义全局变量和局部静态变量时才能对数组赋初值。为提高执行效率,c允许将局部变量值放在寄存器中,这种变量叫register变量,要用register说明。但只有局部动态变量和形式参数可以作为register变量,其它不行。2)全局变量的存储方式 全局变量在函数外部定义,编译时分配在静态存储区,可以在程序中各个函数所引用。多个文件的情况如何引用全局变量呢?假如在一个文件定义全局变量,在别的文件引用,就要在此文件中用extern对全局变量说明,但如果全局变量定义时用static的话,此全局变量就只能在本文件中引用了,而不能被其它文件引用。3)存储类别小结 从作用域角度分,有局部变量和全局变量 局部变量:自动变量,即动态局部变量(离开函数,值就消失) 静态局部变量(离开函数,值仍保留) 寄存器变量(离开函数,值就消失) (形参可定义为自动变量和寄存器变量)全局变量:静态全局变量(只限本文件引用) 全局变量(允许其它文件引用) 从存在的时间分,有静态存储和动态存储 动态存储:自动变量(本函数内有效) 寄存器变量(本函数内有效) 形参 静态存储:静态局部变量(函数内有效)静态全局变量(本文件内有效) 全局变量(其它文件可引用)从变量值存放的位置分 静态存储区:静态局部变量 静态全局变量 全局变量 动态存储区:自动变量和形参 寄存器内:寄存器变量 7. 内部函数和外部函数 内部函数:只能被本文件中的其它函数调用,定义时前加static,内部函数又称静态函数。外部函数:可以被其它文件调用,定义时前加extern,如果省略,则隐含为外部函数,在需要调用此函数的文件中,一般要用extern说明。 第八章 预编译处理 c编译系统在对程序进行通常的编译之前,先进行预处理。c提供的预处理功能主要有以下三种:1)宏定义 2)文件包含 3)条件编译 1. 宏定义 不带参数的宏定义 用一个指定的标识符来代表一个字符串,形式:#define 标识符 字符串 几点说明: 1)宏名一般用大写 2)宏定义不作语法检查,只有在编译被宏展开后的源程序时才会报错 3)宏定义不是c语句,不在行末加分号 4)宏名有效范围为定义到本源文件结束 5)可以用#undef命令终止宏定义的作用域 6)在宏定义时,可以引用已定义的宏名 带参数的宏定义 定义形式:#define 宏名(参数表)字符串 这和函数有些类似,但他们是不同的: 1)函数调用时,先求实参表达式值,再代入形参,而宏只是简单替换,并不求值 2)函数调用是在程序运行时分配内存的,而宏展开时并不分配内存,也没有返回值的概念 3)对函数中的实参和形参都要定义类型,而且要求一致,宏名无类型,其参数也没有类型。4)函数只有一个返回值,而宏可以得到几个结果 5)宏替换不占运行时间,只占编译时间,而函数调用占运行时间 2. 文件包含处理 #include “文件1” 就是将文件1的全部内容复制插入到#include位置,作为一个源文件进行编译。在#include 命令中,文件名可以用“ ”也可以用< >,假如现在file1.c中包含file2.h文件,“ ”表示系统先在file1.c所在目录中找file2.h,如果找不到,再按系统指定的标准方式检索目录,< >表示系统直接按指定的标准方式检索目录。所以用“ ”保险一点。3. 条件编译 条件编译指不对整个程序都编译,而是编译满足条件的那部分。条件编译有以下几种形式: 1)#ifdef 标识符 程序段1 #else 程序段2 #endif 它的作用:当标识符在前面已经被定义过(一般用#define),则对程序段1编译,否则对程序段2编译。 2)#ifndef 标识符 程序段1 #else 程序段2 #endif 它的作用和#ifdef相反,当标识符没被定义过,对程序段1编译,否则对程序段2编译。3)#if 表达式 程序段1 #else 程序段2 #endif 它的作用:当表达式值为真(非0)时,对程序段1编译,否则对程序段2编译。 Top of Page 第九章 指针 指针说白了就是地址。指针变量就是用来存放指针(地址)的变量。1. 变量的指针和指向变量的指针变量 读起来很拗口,说白了就是变量的地址和用来存放变量地址的地址变量。因为一个变量在编译的时候系统要为它分配一个地址,假如再用一个变量来存放这个地址,那么这个变量就叫做指向变量的指针变量,也就是用来存放变量地址的这么一个变量。所谓“指向”就是指存放××的地址,如指向变量的指针变量,“指向”就是指用来存放变量的地址,再如指向数组的指针变量,“指向”就是指存放数组的地址。只要理解了这个,指针也就不难了。另外,还有指向字符串的指针变量,指向函数的指针变量,指向指针的指针变量等。 1)指针变量的定义 形式:类型标识符 *标识符 如:int *pointer;要注意两点:*表示pointer是个指针变量,在用这个变量的时候不能写成*pointer,*pointer是pointer指向的变量。一个指针变量只能指向同一个类型的变量。如上面 pointer只能指向int型变量。2)指针变量的引用 两个有关的运算符: & 取地址运算符 &a 就代表变量a的地址 * 指针运算符 *a 就代表变量a的值 2. 数组的指针和指向数组的指针变量 数组的指针指数组的起始地址,数组元素的指针指数组元素的地址。1)指向数组元素的指针变量的定义与赋值 定义和指向变量的指针变量定义相同,c规定数组名代表数组的首地址,即第一个数组元素地址。 2)通过指针引用数组元素 我们通常引用数组元素的形式是a[i],如果用指针可以这样引用,*(a+i),或定义一个指针变量p,将数组a的首地址赋给p,p=a;然后用*(p+i)引用。 注意:指针变量p指向数组a首地址,则p++指向数组a的下一元素地址,即a[1]的地址。3)数组名作函数参数 形参数组和实参数组之间并不是值传递,而是共用同一段地址,所以在函数调用过程中如果形参的值发生变化,则实参的值也跟着变化。4)指向多维数组的指针和指针变量 以二维数组为居多。假设定义了一个二维数组a[3][4],那么 a代表整个二维数组的首地址,也代表第0行的首地址,同时也是第0行第0列的元素的首地址。a +0和a[0]代表第0行首地址,a+1和a[1]代表第一行的首地址。 假设a是一个数组的首地址,那么如果a是一维的,a+I代表第I个元素的地址,如果a是二维的,则a+I代表第I行的首地址。 那么第一行第二列的元素地址如何表示呢?a[1]+2或&a[1][2]或*(a+1)+2。 我们只要记住:在二维数组中a代表整个数组的首地址,a[I]代表第I行的首地址,a[I]与*(a+I)等价就行了。只要运用熟练了就没什么复杂的了。5)指向由m个整数组成的一维数组的指针变量 如:int(*p)[4],p是一个指向包含4个元素的一维数组,如果p先指向a[0],则p+1指向a[1],即p的增值是以一维数组的长度为单位的,这里是4,举个例子: 假设a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23},p先指向a[0]也就是数组a的首地址,那么p+1就是a[1] 的首地址即元素9的地址,因为在定义p时int(*p)[4],定义一维数组长度为4,所以p+1就等于加了一个一维数组的长度4。3. 字符串的指针和指向字符串的指针变量 1)字符串的表示形式 c中字符串有两种表示形式:一种是数组,一种是字符指针 char string[]=“I love c!”;char *str=“I love c!”;其实指针形式也是在内存中开辟了一个数组,只不过数组的首地址存放在字符指针变量str中,千万不要认为str是一个字符串变量。2)字符串指针作函数参数 实际上字符串指针就是数组的首地址。3)字符指针变量与字符数组的区别 ① 字符数组由若干元素组成,每个元素存放一个字符,而字符指针变量只存放字符串的首地址,不是整个字符串 ② 对数组初始化要用static,对指针变量不用。 ③ 对字符数组赋值,只能对各个元素赋值,不能象下面这样: char str[14];str=“I love c!”;对指针变量可以,char *str;str=“I love c!”;注意:此时赋给str的不是字符,而是字符串首地址。 ④ 数组在定义和编译时分配内存单元,而指针变量定义后最好将其初始化,否则指针变量的值会指向一个不确定的内存段,将会破坏程序。如: char *a;scanf(“%s”, a);这种方法是很危险的,应该这样: char *a, str[10];a = str;scanf(“%s”, a);这样字符指针就指向了一个确定的内存段。 ⑤ 指针变量的值是可以改变的,而字符数组名所代表的字符串首地址却是不能改变的。4. 函数的指针和指向函数的指针变量 一个函数在编译时被分配一个入口地址,这个入口地址就称为函数的指针。函数名代表函数的入口地址,这一点和数组一样。我们可以用一个指针变量来存放这个入口地址,然后通过该指针变量调用函数。如:假设有一个求两者较大的函数如下:int max(int x, int y);当我们调用这个函数时可以这样: int c;c=max(a, b);这是通常调用方法,其实我们可以定义一个函数指针,通过指针来调用,如: int(*p)();//注意指向函数指针变量的定义形式 p=max;//此句就是将函数的入口地址赋给函数指针变量p c=(*p)(a, b);有些朋友可能对(*p)()不大理解,其实它的意思就是定义一个指向函数的指针变量p,p不是固定指向哪个函数的,而是专门用来存放函数入口地址的变量。在程序中把哪个函数的入口地址赋给它,它就指向哪个函数。但要注意,p不能象指向变量的指针变量一样进行p++,p-等无意义的操作。 既然p是一个指针变量,那么就可以作为函数的参数进行传递。其实函数的指针变量最常用的用途之一就是作为函数参数传递到其它函数。这也是c语言中应用的比较深入的部分了。 5. 返回指针值的函数 我们知道,一个函数可以带回一个整型值、字符值、实型值等,函数还可以带回一个指针型的数据,即地址。这种函数的定义形式如下: 类型标识符 *函数名(参数表)如:int *a(x,y)返回一个指向整型的指针 使用这种函数的时候要注意:在调用时要先定义一个适当的指针来接收函数的返回值。这个适当的指针其类型应为函数返回指针所指向的类型。这样的函数比较难于理解,其实只要把它当做一般的函数来处理就容易了。当我们觉得指针难于理解的时候,就把它暂时当做整型来看,就好理解多了。6. 指针数组 指针数组无疑就是数组元素为指针,定义形式为:类型标识 *数组名[数组长度] 如:int *p[4],千万不要写成int(*p)[4],这是指向一维数组的指针变量。指针数组多用于存放若干个字符串的首地址,注意一点,在定义指针数组时初始化,如下: static char *name[]={“Li jing”,“Wang mi”,“Xu shang”};不要以为数组中存放的是字符串,它存放的是字符串首地址,这一点一定要注意。7. 指向指针的指针 说的明白一点,将一个指针再用一个变量来存放,那么这个变量就是指向指针的指针。定义如:char * *p;8. 指针数组作main()函数的参数 函数形式为 main(int argc, char *argv[]){} main函数的参数是从命令行得到的,argc指命令行参数个数,注意命令名也算一个参数,命令行参数都是字符串,他们的首地址构成一个指针数组argv。Main函数的形参用argc和argv只是一个习惯,也可以定义成别的名字。9. 指针小结 1)有关指针的数据类型 定 义 含 义 Int I;定义一个整型变量I Int *p;P为指向整型数据的指针变量 Int a[n];定义整型数组a,它有n个元素 Int *p[n];定义指针数组p,它有n个指向整型的指针元素 Int(*p)[n];P为指向含有n个元素的一维数组的指针变量 Int f();F为返回整型值的函数 Int *p();P为返回值为指针的函数,该指针指向整型数据 Int(*p)();P为指向函数的指针,该函数返回一个整型值 Int **p;定义一个指向指针的指针变量 2)ANSI新增了一种void *指针类型,即定义一个指针变量,但不指向任何数据类型,等用到的时候再强制转换类型。如: char *p1;void *p2;p1 =(char *)p2;也可以将一个函数定义成void *型,如: void *fun(ch1, ch2)表示函数fun返回一个地址,它指向空类型,如果需要用到此地址,也要对其强制转换。如(假设p1为char型): p1=(char *)fun(c1,c2);指针应该说是c语言中比较重要的概念,也是c语言的精华,它有很多优点,但用不好也会带来严重性的错误,这就需要我们多用,多练,慢慢的积累经验。 第十章结构体与共用体 1. 定义 结构体定义的一般形式: struct 结构体名{ 成员列表 };定义一个结构体变量可以这样定义:struct 结构体名结构体变量名;2. 结构体变量的引用 在引用结构体变量时应注意以下规则: 1)不能将结构体变量作为一个整体输入输出,只能对变量当中的各个成员输入输出。新标准C允许将一个结构体变量直接赋值给另一个具有相同结构的结构体变量。3. 结构体变量的初始化 如: struct student {long int num;char name[20];char sex;char addr[20];}a={89031,“Li Lin”,'M',“123 Beijing Road” };4. 结构体数组 struct student stu[4];定义了一个数组stu,其元素为struct student类型,数组有4个元素。注意数组各元素在内存中是连续存放的。 在定义结构体数组时,数组元素个数可以不指定。编译时,系统会根据给出初值的结构体常量的个数来确定数组元素的个数。5. 指向结构体变量的指针 因为结构体变量在内存中是连续存放各成员的,因此我们可以将结构体变量在内存中的起始地址存放到一个变量中,那么这个变量就是指向结构体变量的指针。注意将结构体变量的首地址赋给指针变量的形式: struct student stu_1;struct student *p;p=&stu_1;//要加取地址符 而指向函数和指向字符串的指针不用 在对引用结构体变量中的成员时,有三种方式: 以上面的结构体为例:设p为指向此结构体变量的指针,即p=&a;1)a.num 2)(*p).num 3)p->num 6. 指向结构体数组的指针 struct student *p;struct student stu[4];p=stu;则p为指向结构体数组的指针变量。这里应注意p++,p指向stu[0],p++则指向stu[1]。P指向的是数组中一个元素的首地址,而不能让p指向元素中的某一成员,如p=&stu[I].name是不对的。 7. 用指向结构体的指针作函数参数 虽然ANSI C允许用整个结构体作为函数参数,但要将全部成员值一个一个传递,开销大。所以用指针作参数,能提高运行效率。Struct student stu;用整个结构体作为参数调用形式: fun(stu);而且被调函数fun中也要定义成结构体变量,struct student stu;用指针作参数调用形式: fun(&stu);被调函数fun中定义成指针变量,struct student *p;8. 用指针处理链表 链表是一种重要的数据结构,原因就在于它可以动态的进行存储分配。链表都有一个头指针,用来存放整个链表的首地址。链表的定义形式如下: struct node{ int num;… struct node *next;};next用来存放下一节点的地址。 如何进行动态的开辟和释放存储单元呢?c提供了以下有关函数: 1)malloc(size)在内存的动态存储区开辟一个长度为size的连续空间。成功返回空间首地址,失败返回0;2)calloc(n,size)在内存的动态存储区开辟n个长度为size的连续空间。成功返回空间首地址,失败返回0;3)free(ptr)释放由ptr指向的内存区。Ptr是最近调用一次调用malloc和calloc时返回的值。上面函数中,n和size为整型,ptr为字符指针。 9. 共用体 定义形式: union 共用体名 { 成员列表 }变量列表;共用体和结构体类似,只是有一点不同,结构体中个成员的起始地址不同,结构体变量在内存中的长度为各成员长度之和;而共用体中个成员的起始地址相同,共用体变量所占的内存长度为最长的成员的长度。共用体类型数据的特点: 1)同一个内存段可以存放几种不同类型的成员 2)共用体变量中起作用的成员是最后一次存放的成员 3)不能对共用体变量名赋值,不能在定义时初始化。4)不能把共用体变量作为函数参数 5)共用体类型可以出现在结构体定义中,反之也可,也可以定义共用体数组。另外,结构体名可以作为参数,而共用体名不可以。这两中数据结构在不同场合中各有所用。10. 枚举类型 定义形式如下:举个例子 enum weekday{sun,mon,tue,wed,thu,fri,sat};enum weekday workday,week_end;//定义枚举变量 workday和week_end被定义成枚举类型,他们的值只能为sun到sat之一。也可以直接定义枚举变量,这一点与结构体相同 enum weekday{sun,mon,tue,wed,thu,fri,sat}wordday,week_end;注意:枚举元素是作为常量存在的,他们是有值的,c在编译时使他们的值按顺序为0,1,2… 如:上面的定义中,sun的值为0,mon的值为1 另外:虽然枚举元素有值,但不能将一个整数直接赋给一个枚举变量。应进行强制类型转换,如: workday=(enum weekday)2;它相当于把tue赋给了workday。11. 用typedef定义类型 typedef的作用就是能够让你定义一个自己喜欢的数据类型名来代替已有的数据类型名。如: typedef int INT;那么我就可以用INT来定义整型变量了。作用和int一样。Typedef用于结构体定义,如: Typedef struct{ Int day;Int month;Int year;}DATE;DATE birthday;DATE *p;等等 用typedef有利于程序的通用与移植。 第十一章 位运算 1)概述 所谓位运算是指进行二进制位的运算。在系统软件中,常要处理二进制位的问题。c提供的位运算符有: & 按位与 | 按位或 ^ 按位异或 ~ 取反 << 左移 >> 右移 &对于将一个单元清零、取一个数中的某些指定位以及保留指定位有很大用途。|常被用来将一个数的某些位置1。 ^判断两个位值,不同为1,相同为0。常用来使特定位翻转等。~常用来配合其它位运算符使用的,常用来设置屏蔽字。 <<将一个数的各二进制位全部左移,高位左移后溢出,舍弃不起作用。左移一位相当于该数乘2,左移n位相当于乘2n。左移比乘法运算要快的多。 >>右移时,要注意符号问题。对无符号数,右移时左边高位移入0,对于有符号数,如果原来符号位为0(正数),则左边移入0;如果符号位为1(负数),则左边移入0还是1要取决于系统。移入0的称为“逻辑右移”,移入1的称为“算数右移”。2)位段 将一个字节分为几段来存放几个信息。所谓位段是以位为单位定义长度的结构体类型中的成员。如: struct packed-data{ unsigned a:2;unsigned b:6;unsigned c:4;unsigned d:4;int I;}data;其中a,b,c,d分别占2位,6位,4位,4位。I为整型,占4 个字节。对于位段成员的引用如下: data.a = 2;等,但要注意赋值时,不要超出位段定义的范围。如位段成员a定义为2位,最大值为3,即(11)2,所以data.a=5;就会取5的两个低位进行赋值,就得不到想要的值了。关于位段的定义和引用,有几点重要说明: ①若某一个段要从另一个字开始存放,可以定义: unsigned a:1;unsigned b:2;unsigned :0;unsigned c:3;(另一单元)使用长度为0的位段,作用就是使下一个位段从下一个存储单元开始存放。②一个位段必须存放在用一个存储单元中,不能跨两个单元。③可以定义无名位段。如: unsigned a:1;unsigned :2;(这两位空间不用)unsigned b:3;④位段的长度不能大于存储单元的长度,也不能定义位段数组。 第十二章 文件 1)概述 c语言将文件看成一个字符的序列,分为ASCII文件(文本文件)和二进制文件。即一个c文件就是一个字节流或二进制流。 ASCII 文件每一个字节放一个ASCII码,代表一个字符,输出与字符一一对应,便于逐个处理字符,但占用空间较多。二进制文件按内存中的存储形式原样输出到磁盘上,节省空间,由于输出与字符不对应,不能直接输出字符形式,一般用于保存中间结果。目前c对文件的处理只有缓冲文件系统一种方法,即无论是从程序到磁盘文件还是从磁盘文件到程序,数据都要先经过缓冲区,待缓冲区充满后,才集中发送。2)文件夹类型指针 在缓冲文件系统中,关键的概念是文件指针。因为每个被使用的文件都在内存中开辟一个缓冲区,来存放文件有关信息。这些信息保存在一个结构体变量中,该结构体类型是由系统定义的,取名为FILE,在stdio.h中定义。 FILE *fp;定义了一个文件指针变量fp,以后对文件的操作都是通过fp进行的。3)文件的打开与关闭 在对文件读写之前,要先打开文件。 打开文件的函数为:fopen(),调用方式为: FILE *fp;fp=fopen(filename,使用文件方式);fopen()失败返回一个空指针NULL,成功则返回一个指向“filename”的文件指针,赋给fp,这样fp就和打开的文件联系在一起了。或者说,fp指向了“filename”。 文件使用方式:r,w,a,rb,wb,ab,r+,w+,a+,rb+,wb+,ab+,具体含义要记住。4)文件的关闭 为了防止数据丢失,程序结束前,务必将打开的文件关闭,即将文件指针与文件脱钩。用fclose(文件指针)函数关闭文件,执行函数后,先将缓冲区中的数据送到磁盘文件,然后释放文件指针。成功返回0,失败返回非0。5)文件的读写 文件打开后,就可以对其读写了,常用的文件读写函数有: ①fputc和fgetc fputc将一个字符写到文件,形式为fputc(ch, fp);将字符ch写入fp所指向的文件。成功返回该字符,失败返回EOF,EOF在stdio.h中定义为符号常量-1。 fgetc 从指定文件读入一个字符,该文件必须是以读或读写方式打开的。调用形式为ch=fgetc(fp);从fp指向的文件读入一个字符赋给ch,当文件结束时,fgetc返回一个EOF,我们可以用函数feof(fp)来判断是否已到文件尾,返回1表示已到文件尾,否则返回0。这个函数适用于文本文件和二进制文件。②fread和fwrite函数 可以读写一组数据。调用形式如下: fread(buffer, size, count, fp);fwrite(buffer, size, count, fp);buffer为一个指针,对fread来讲,是指从文件读出数据的存放地址,对fwrite来讲,是要写入文件的数据的地址。size 要读写的字节数 count 要进行读写多少个size字节的数据项(书上这么说)其实就是读写的次数 fp 文件指针 这两个函数返回值成功为1,失败为非1,一般用于二进制文件的读写。注意:有些c编译系统不具备这两个函数。③fprintf()和fscanf()函数 格式化输出和输入函数,与printf()和scanf()作用相似,只有一点不同,fprintf()和fscanf()的读写对象不是终端而是磁盘文件。调用方式: fprintf(文件指针,格式字符串,输出列表);fscanf(文件指针,格式字符串,输出列表);④fgets()和fputs()函数 作用是读写一个字符串,如: fgets(str,n,fp);意为从fp指向的文件读出n-1个字符,存放到str中,成功返回str的首地址。fputs(“China”, fp);把字符串China写入fp指向的文件。成功返回0,失败为非0。6)文件的定位 文件中有一个位置指针,指向当前读写的位置,如果要强制改变位置指针的位置,可以用有关函数: ①rewind 使位置指针重新返回文件的开头 ②fseek()fseek()函数可以任意改变位置指针的位置,以实现随机读写文件。调用形式: fseek(文件指针类型,位移量,起始点);起始点有以下三个值: SEEK_SET或0 文件开始 SEEK_CUR或1 文件当前位置 SEEK_END或2 文件末尾 位移量指以起始点为基点,移动的字节数(正数向文件尾移动,负数向文件头移动),一般位移量用long型数据,以避免大于64K的文件出错。Fseek()函数一般用于二进制文件,因为文本文件要进行字符转换,计算时会发生混乱。 Fseek(fp, 100L, 0);将位置指针从文件头向文件尾移动100个字节处。Fseek(fp, 50L, 1);将指针从当前位置向文件尾移动50个字节处。Fseek(fp,-10L, 2);将指针从文件尾向文件头移动10个字节处。③ftell()到流式文件位置指针的当前位置,成功返回相对于文件头的位移量,失败返回-1L。 结构体 例10.4 指向结构体数组的指针的应用 #include printf(″No.Name sex agen″); for(p=stu;p<stu+3;p++) printf(″%5d %-20s %2c %4dn″,p->num,p->name,p->sex,p->age); } 运行结果: No.Name sex age 10101 LiLin M 1010Zhang Fun M 10104 WangMing F 例10.5 有一个结构体变量stu,内含学生学号、姓名和3门课程的成绩。要求在main函数中赋予值,在另一函数print中将它们输出。今用结构体变量作函数参数。#include char name[20]; float score[3];}; #include char name[20]; float score[3];}; void main(){ void print(struct student); struct student stu; stu.num=12345; strcpy(stu.name,″LiLin″); stu.score[0]=67.5; stu.score[1]=89; stu.score[2]=78.6; print(stu);} void print(struct student stu){ printf(FORMAT,stu.num,stu.name,stu.score[0],stu.score[1],stu.score[2]); printf(″n″);} 运行结果: 12345 Li Li 67.500000 89.000000 78.599998 例10.6 将上题改用指向结构体变量的指针作参数。#include char name[20]; float score[3];}stu={12345, ″LiLi″,67.5,89,78.6};void main(){ void print(struct student *); print(&stu);} void print(struct student *p){ printf(FORMAT,p->num,p->name,p->score[0],p->score[1],p->score[2]); printf(″\n″); } 运行结果: 12345 Li Li 67.500000 89.000000 78.599998 有10个学生,每个学生的数据包括学号、姓名、3门课的成绩,从键盘输入10个学生数据,要求输出3门课程总平均成绩,以及最高分的学生的数据(包括学号、姓名、3门课程总成绩、平均分数)。 10.1:# include struct student { char num[6]; char name[8]; int score[3]; float avr; }stu[10]; main() { int i,j,max=0,maxi=0,sum=0; float average=0; for(i=0;i<10;i++) { scanf(“%s%s”,stu[i].num,stu[i].name); for(j=0;j<3;j++) scanf(“%d”,&stu[i].score[j]); } for(i=0;i<10;i++) { sum=0; for(j=0;j<3;j++) sum+=stu[i].score[j]; stu[i].avr=sum/3.0; average+=stu[i].avr; if(sum>max){ max=sum;maxi=i;} } average/=10; printf(“average=%6.2fn”,average); printf(“The highest is:%s,%s,%d,%f”,stu[maxi].num,stu[maxi].name,max,stu[maxi].avr); } 指针 例9.4 输入a、b、c3个整数,按大小顺序输出。#include {void exchange(int *q1,int *q2,int *q3);int a,b,c,*p1,*p2,*p3; scanf(″%d,%d,%d″,&a, &b, &c); p1=&a;p2=&b;p3=&c; exchange(p1,p2,p3); printf(″%d,%d,%d\n″,a,b,c); } void exchange(int *q1,int *q2,int *q3){ void swap(int *pt1,int *pt2); if(*q1<*q2)swap(q1,q2); if(*q1<*q3)swap(q1,q3); if(*q2<*q3)swap(q2,q3); } void swap(int *pt1,int *pt2) {int temp; temp=*pt1; *pt1=*pt2; *pt2=temp; score 3 } 运行情况如下: 9,0,10↙ 10,9,0 例9.10:有一个班,3个学生,各学4门课,计算总平均分数以及第n个学生的成绩。这个题目是很简单的。只是为了说明用指向数组的指针作函数参数而举的例子。用函数average求总平均成绩,用函数search找出并输出第i个学生的成绩。#include { void average(float *p,int n); void search(float(*p)[4],int n); float score[3][4]={{65,67,70,60},average(*score,12); /*求12个分数的平均分*/ search(score,2); /*求序号为2的学生的成绩*/ } void average(float *p,int n){ float*p_end; float sum=0,aver; p_end=p+n-1; for(;p<=p_end;p++) sum=sum+(*p); aver=sum/n; printf(″average=%5.2f\n″,aver); } void search(float(*p)[4],int n) / * p是指向具有4个元素的一维数组的指针 */ {int i; printf(″the score of No.%d are:n″,n); for(i=0;i<4;i++) printf(″%5.2f″,*(*(p+n)+i));} 程序运行结果如下: average=82.25 The score of No.2 are: 90.00 99.00 100.00 98.00 例9.11: 在上题基础上,查找有一门以上课程不及格的学生,打印出他们的全部课程的成绩。 #include {void search(float(*p)[4],int n); float score[3][4]={{65,57,70,60},{58,87,90,81},{90,99,100,98}}; {80,87,90,81},{90,99,100,98}}; search(score,3); } void search(float(*p)[4],int n){int i,j,flag; for(j=0;j<n;j++) {flag=0; for(i=0;i<4;i++) if(*(*(p+j)+i)<60)flag=1; if(flag==1) { printf(“No.%d fails,his scores are: \n”,j+1); for(i=0;i<4;i++) printf(″%5.1f″,*(*(p+j)+i)); printf(″\n″); } } } 程序运行结果如下: No.1 fails, his scores are: 65.0 57.0 70.0 60.0 No.2 fails, his scores are: 58.0 87.0 90.0 81.0 例9.17:求a和b中的最大者。#include {int max(int,int);int a,b,c; scanf(″%d,%d″,&a,&b); c=max(a,b);printf(″a=%d,b=%d,max=%dn″,a,b,c); } int max(int x,int y){ int z; if(x>y)z=x; else z=y; return(z); } 例9.18:有若干个学生的成绩(每个学生有4门课程),要求在用户输入学生序号以后,能输出该学生的全部成绩。用指针函数来实现。 #include {float score[][4]={{60,70,80,90},{56,89,67,88},{34,78,90,66}}; float *search(float(*pointer)[4],int n); float*p; int i,m; printf(″enter the number of student:″); scanf(″%d″,&m); printf(″The scores of No.%d are:n″,m); p=search(score,m); for(i=0;i<4;i++)printf(″%5.2ft″,*(p+i)); } float *search(float(*pointer)[4],int n){ float *pt; pt=*(pointer+n); return(pt); } 运行情况如下: enter the number of student:1↙ The scores of No.1 are: 56.00 89.00 67.00 88.00 例9.19: 对上例中的学生,找出其中有不及格课程的学生及其学生号。#include { float score[][4]={{60,70,80,90},{56,89,67,88},{34,78,90,66}}; float search(float(*pointer)[4]); float*p; int i,j; for(i=0;i<3;i++) {p=search(score+i); if(p==*(score+i)) { printf(″No.%d scores:″,i); for(j=0;j<4;j++) printf(″%5.2f″,*(p+j)); printf(″n″);} } } float *search(float(*pointer)[4]){ int i; float *pt; pt=*(pointer+1); for(i=0;i<4;i++) if(*(*pointer+i)<60)pt=*pointer; return(pt); } 运行情况如下: No.1 scores:56.00 89.00 67.00 88.00 No.2 scores:34.00 78.00 90.00 66.00 例9.20:将若干字符串按字母顺序(由小到大)输出。#include {void sort(char *name[ ],int n); void print(char *name[ ],int n); char *name[ ]={“Follow me”,“BASIC”,“Great Wall″,”FORTRAN“,”Computer design“};int n=5; sort(name,n); print(name,n); } void sort(char *name[ ],int n){char *temp; int i,j,k; for(i=0;i<n-1;i++){k=i; for(j=i+1;j<n;j++) if(strcmp(name[k],name[j])>0)k=j; if(k!=i) { temp=name[i]; name[i]=name[k]; name[k]=temp;} } } void print(char *name[ ],int n){ int i; for(i=0;i<n;i++) printf(″%sn″,name[i]); } 运行结果为: BASIC Computer design FORTRAN Follow me Great Wall 作业:(提交上机报告)输入10个整数,将其中最小的数与第一个数对换,把最大的数与最后一个数对换。写3个函数:①输入10个数;②进行处理;③输出10个数。# include { void input(int number[10]); void max_min_value(int array[10]); void output(int array[10]); int number[10];input(number);max_min_value(number);output(number); } void input(int number[10]) { int i; for(i=0;i<=9;i++) scanf(“%d”,&number[i]);} void max_min_value(int array[10]) { int *max,*min,*p,*array_end; array_end=array+10; max=min=array; for(p=array+1;p if(*p>*max)max=p; else if(*p<*min)min=p; *p=array[0];array[0]=*min;*min=*p; *p=array[9];array[9]=*max;*max=*p; } void output(int array[10]) { int *p; for(p=array;p<=array+9;p++) printf(“%4d”,*p); } 数组和函数的组合 例8.12 有一个一维数组,内放10个学生成绩,写一个函数,求出平均分、最高分和最低分。#include /*全局变量*/ void main() {float average(float array[ ],int n); float ave,score[10]; int i; for(i=0;i<10;i++) scanf(″%f″,&score[i]); ave= average(score,10); printf(″max=%6.2f\nmin=%6.2f\n average=%6.2f\n″,Max,Min,ave); } float average(float array[ ],int n) /*定义函数,形参为数组*/ { int i; float aver,sum=array[0]; Max=Min=array[0]; for(i=1;i<n;i++) {if(array[i]>Max)Max=array[i]; else if(array[i] sum=sum+array[i]; } aver=sum/n; return(aver); } 例8.18 有一个含若干字符的字符串,今输入一个字符,要求程序将字符串中该字符删去。用外部函数实现。file1.c(文件1)#include { extern void enter_string(char str[]); extern void detele_string(char str[],char ch); extern void print_string(char str[]); char c; char str[80];enter_string(str); scanf(”%c“,&c); detele_string(str,c); print_string(str); } file2.c(文件2)#include gets(str);} file3.c(文件3) void delete_string(char str[],char ch){ int i,j; for(i=j=0;str[i]!=' ';i++) if(str[i]!=ch) str[j++]=str[i]; str[i]=' ';} file4.c(文件4)#include printf(”%sn",str);} 运行情况如下: abcdefgc↙ (输入str) c↙ (输入要删去的字符)abdefg (输出已删去指定字符的字符串) 8.1:判断m是否是素数。(用函数实现)#include { int f(int m); int m,n; scanf(“%d”,&m); n=f(m); if(n)printf(“%d is a prime numbern”,m); else printf(“%d is not a prime numbern”,m); } int f(int m) { int i,k,p; k=sqrt(m); for(i=2;i<=k;i++) if(m%i==0)break; if(i>=k+1)p=1; else p=0; return p; } 8.2:用起泡法对10个数排序。(用函数实现) #include { void sort(int array[],int n); int a[10],i; for(i=0;i<10;i++) scanf(“%d”,&a[i]); sort(a,10); for(i=0;i<10;i++) printf(“%4d”,a[i]);} void sort(int array[],int n) { int i,j,t; for(i=0;i for(j=0;j<9-i;j++) if(a[j]>a[j+1]) { t=a[j];a[j]=a[j+1];a[j+1]=t;} } 8.3:用选择法对10个数排序。(用函数实现)#include { void sort(int array[],int n); int a[10],i; for(i=0;i<10;i++) scanf(“%d”,&a[i]); sort(a,10); for(i=0;i<10;i++) printf(“%4d”,a[i]);} void sort(int array[],int n) { int i,j,k,t; for(i=0;i { k=i; for(j=i+1;j if(array[j] t=array[k];array[k]=array[i];array[i]=t; } }第二篇:c语言期末复习
第三篇:C语言知识点总结
第四篇:C语言知识点总结
第五篇:C语言期末总结