C语言典例.docx
《C语言典例.docx》由会员分享,可在线阅读,更多相关《C语言典例.docx(24页珍藏版)》请在冰豆网上搜索。
C语言典例
C语言必会典例
一:
for循环与break语句if语句的应用
例子1:
/*
从键盘输入一个大于1的正整数,判断其是否是素数
(素数是指仅能被1和自身整除,且大于2的整数)
*/
#include
voidmain()
{
inti,x;
intflag=1;
printf("请输入一个正整数x=");
scanf("%d",&x);
for(i=2;i{
if(x%i==0)//注意是x%i,这个数是被除数
{
flag=0;
break;
}
}
if(flag==0)//如果不定义flag,就是if(x==i);则是素数,否则不是
{
printf("%d不是素数\n",x);
}
else
printf("%d是素数\n",x);
}
/*
总结:
如果是素数,i就一直加i=x(此时x%i!
=0)从而不满足i如果不是素数,i会加到总有一个值满足if语句中的条件后执行break而跳出
*/
例子2:
/*输出100以内的素数*/
#include
voidmain()
{
inti,j;
intflag;//第5行
for(i=2;i<=100;i++)
{
flag=1;//注意只能在此地初始化保证每判断一次重新给flag置1,千万不能在第5行初始化
for(j=2;j
{
if(i%j==0)
{
flag=0;
break;//跳出的是隔它最近的循环,而不是if语句,只不过常与if连用
}
}
if(flag==1)//如果是素数就输出,进而再进入大for语句寻在下一个素数
printf("%-3d",i);
}
printf("\n");//换行
}
例子3
/*输出500以内的最大的10个素数及其和*/
#include
voidmain()
{
inti,j,flag,counter=0,sum=0;//counter一定要给初值
for(i=500;i>=2;i--)//注意倒过来输出
{
flag=1;//注意只能在此地初始化保证每判断一次重新给flag置1,千万不能在第
5行初始化
for(j=2;j
{
if(i%j==0)
{
flag=0;//不是素数flag一定记0
break;
}
}
if(flag==1)
{
counter++;//如果是素数,进来counter加一次
if(counter<=10)//判断输出前十个
{
sum=sum+i;
printf("%-4d",i);
}
}
}
printf("\n");//换行
printf("sum=%4d\n",sum);
}
例子4
参考上机实验第二题
/*
分析:
其实程序把500以内的每个数都判断了一遍,但在屏幕上置只输出后10个,这与上机实验的方法二思维方式不同,具体的几种方法请参考它。
*/
二:
(1)for循环与一维数组的应用
例子1
/*从键盘输入10(适用人数不确定)个同学的成绩,输出高于平均成绩的人数*/
#include
#defineLEN100
voidmain()
{
intdata[LEN],i,len;//定义一个长度为LEN的数组
intsum=0,counter=0;//两者一定要给初始化,因为不是静态变量默认值不是0,而是
垃圾值
floatave;
printf("请输入学生人数:
");//这两句可以不要,成绩个数直接用LEN表示和改
scanf("%d\n",&len);//取地址符千万不能掉
for(i=0;i{
scanf("%d",&data[i]);//取地址符千万不能掉
sum=sum+data[i];//有时在输入数据时就对数据进行相关的处理较好
}
//ave=sum*1.0/len;//可以把平均成绩输出来检查结果
//printf("%.2f\n",ave);
for(i=0;i{
if(data[i]>ave)
{
counter++;
}
}
printf("高于平均成绩的人数为:
%d个\n",counter);
}
例子2
/*
从键盘输入若干个学生成绩,当输入负数时结
束,计平均成绩,并输出低于平均分的学生成绩
*/
#include
#defineLEN1000
voidmain()
{
inti,len,score[LEN];
floataverage=0,sum=0;//一定要初始化
printf("请输入学生的人数:
");
scanf("%d",&len);//&符号不要掉
for(i=0;i{
scanf("%d",&score[i]);//&符号不要掉
sum=sum+score[i];
}
average=sum/len;
for(i=0;i{
if(score[i]<0)
{
printf("有无效成绩,程序结束,请重新输入\n");
break;//巧妙之处
}
if(score[i]printf("低于平均分学生的成绩为:
%d\n",score[i]);
}
}
(2)for循环与二维数组的应用
例子1
/*将一个二维数组的行和列的元素互换,存到另一个二维数组中(求转置矩阵)*/
#include
voidmain()
{
inta[2][3]={{1,2,3},{4,5,6}};
intb[3][2],i,j;
printf("arraya:
\n");
for(i=0;i<2;i++)//输出数组a
{
for(j=0;j<3;j++)
{
printf("%3d",a[i][j]);
}
printf("\n");//每输出一行就换行
}
for(i=0;i<2;i++)//转置
{
for(j=0;j<3;j++)
{
b[j][i]=a[i][j];
}
}
printf("arrayb:
\n");
for(j=0;j<3;j++)//输出转置后的数组b
{
for(i=0;i<2;i++)//注意这里可以用别的变量如j上面用i,也可以用其他定义除
a,b的变量
{
printf("%3d",b[j][i]);
}
printf("\n");
}
}
例子2
/*从键盘输入5个学生的3门课程的成绩,并计算出学生3门课程的平均成绩*/
#include
voidmain()
{
intdata[5][4],i,j;
intsum;
floatave[5];
for(i=0;i<5;i++)
{
sum=0;
printf("请输入第%d个同学的三门课程的成绩:
",i+1);//注意是i+1,不能在外面
for(j=0;j<3;j++)
{
scanf("%d",&data[i][j]);//注意“&”
sum=sum+data[i][j];//本例是在输入数据时就对数据进行相关的处理,包括
下一句
}
ave[i]=sum*1.0/3;//注意是float型
}
for(i=0;i<5;i++)
{
printf("第%d个同学的平均成绩为%.2f\n",i+1,ave[i]);
}
}
例子3
/*从键盘输入5个学生的3门课程的成绩,并计算出学生3门课程的平均成绩*/
#include
voidmain()
{
intdata[5][4],i,j;
floatave[5]={0};//初始化,全给0
for(i=0;i<5;i++)
{
printf("请输入第%d个同学的三门课程的成绩:
",i+1);//注意i+1,不能在外面
for(j=0;j<3;j++)
{
scanf("%d",&data[i][j]);//注意"&"
}
}
for(i=0;i<5;i++)//输出时专门用于计算的双重循环
{
for(j=0;j<3;j++)
{
ave[i]=ave[i]+data[i][j];
}
ave[i]=ave[i]/3;//不能在大for语句的外面
}
for(i=0;i<5;i++)//专门的输出循环
{
printf("第%d个同学的平均成绩为%.2f\n",i+1,ave[i]);
}
}
例子4
参考上机实验的第二题
/*
总结:
与上例1相比显然要复杂些,但我们应该注意以下3点:
(1)有时在输入数据时就对数据进行相关的处理的话要方便。
(2)有时要在输出数据才对数据进行相关的处理就比较好。
(3)具体考虑那种,要视情况而定,一种不行就换另一种。
*/
三:
(1)数组的越界问题—未考虑下标的变化范围
例子1
/*从键盘输入10个成绩,并将最低分存放到最后一个数组元素中*/
#include
voidmain()
{
intdata[10],i,t;//定义一个中间变量t,相当于一个空箱子
printf("请输入10个成绩:
");
for(i=0;i<10;i++)
{
scanf("%d",&data[i]);
}
for(i=0;i<9;i++)//千万注意:
i<9;千万不能是i<10;因为当i=9时,data[i+1]的
下标是10,,超出了数组data的允许下标范围。
{
if(data[i]{
t=data[i];
data[i]=data[i+1];
data[i+1]=t;
}
}
printf("%d\n",data[9]);
}
附注:
还有输入数据错误而造成数组的越界问题处理叫较简单,只是在输出或输入数据时用if语句判断一下,如果不符合数据要求常采用break跳出循环。
(2)数组数据的排序问题—冒泡法(用得较多)
冒泡
法是假如有n个数,则需要进行n-1轮的冒泡,在第一轮冒泡的比较中要进行n-1次两两比较,在第i轮冒泡中要进行n-i次两两比较。
例1中的10个数进行9轮比较,所以a<9,不能取等号,因为从0开始,而每结束一轮冒泡后就减少一个数的比较,从而得到一个新的冒泡范围。
所以在第a轮冒中则要进行10-a次两两比较,所以j<9-a,注意不能取等号,也不是10-i,因为j是从0开始。
例子1
/*从键盘输入10个成绩,按从小到大的顺序输出成绩(冒泡法)*/
#include
voidmain()
{
inta,i,j,t,data[10];//也可以不定义变量a
printf("请输入10个成绩:
");
for(i=0;i<10;i++)
{
scanf("%d",&data[i]);
}
for(a=0;a<9;a++)//控制冒泡轮数,如果不定义a也可以用i以节省变量但不能用j
{
for(j=0;j<9-a;j++)//控制每轮冒泡所比较的次数,这里的循环条件不能取等号
{
if(data[j+1]{
t=data[j];
data[j]=data[j+1];
data[j+1]=t;
}
}
}
for(i=0;i<10;i++)
{
printf("%-3d",data[i]);
}
printf("\n");
}
例子2
/*输入十个成绩,输出最高分和最低分,如果有无效成绩就把这无效成绩输出来*/
#include
voidmain()
{
intdata1[10],data2[10],i,j,k=0,t;
printf("请输入十个成绩:
");
for(i=0;i<10;i++)
{
scanf("%d",&data1[i]);//在输入数据时不对数据进行任何的处理就显得方便些
}
for(i=0;i<10;i++)//控制冒泡的轮数,这里直接用的变量i作为控制轮数的变量
{
for(j=0;j<9-i;j++)//控制每轮冒泡所需要比较的次数
{
if(data1[j]>data1[j+1])
{
t=data1[j];
data1[j]=data1[j+1];
data1[j+1]=t;
}
}
}
for(i=0;i<10;i++)//在要输出前清查是否有无效成绩,并输出无效成绩
{
if(data1[i]<0)
{
while(k<=10)
{
data2[k]=data1[i];//把无效成绩存到另一个数组data2中
printf("有成绩无效,且无效成绩为%d,请重新输入\n",data2[k]);
k++;
break;//跳出while循环,进行下一个成绩的检查
}
}
}
if(data1[0]>=0&&data1[1]>=0&&data1[2]>=0&&data1[3]>=0&&data1[4]>=0&&data1[5]>=0&&data1[6]>=0&&data1[7]>=0&&data1[8]>=0&&data1[9]>=0)//这里需要优化,想想有什么办法呢?
{
printf("最高分是:
%d\n",data1[9]);
printf("最低分是:
%d\n",data1[0]);
}}(主函数大括号的另一半)
例子3
/*从键盘输入5门课程6个同学的成绩,输出每门课程的最高分*/
#include
voidmain()
{
intdata[5][6],i,j,a,t;
for(i=0;i<5;i++)//5行,对应5门课程
{
printf("请输入第%d门课程对应的六名同学的的成绩:
",i+1);
for(j=0;j<6;j++)//6列,对应6个同学的成绩
{
scanf("%d",&data[i][j]);
}
}
for(a=0;a<5;a++)//控制五门课程,使每门课程都要比较
{
for(i=0;i<5;i++)//控制一门课程所要比较的轮数
{
for(j=0;j<5-i;j++)//控制一门课程一轮所要比较的次数
{
If(data[a][j]>data[a][j+1])//注意前面的a,是代表的第几门课
{
t=data[a][j];
data[a][j]=data[a][j+1];
data[a][j+1]=t;
}
}
}
}
for(a=0;a<5;a++)//这里是a,不是i
{
printf("第%d门课程的最高分:
%d\n",a+1,data[a][5]);
}
}
/*
分析:
例3与例2的逻辑思维较强,特别是例3使用了三重循环,掌握了这种
思想或思维方式,冒泡法与数组(一维和二维)的基本应用就差不多了。
*/
(2)数组数据的排序问题—选择排序法(用得较少)
思路:
对于一个待排列的数列,首先从n个数据中选择一个最小的数据,并将它交换到第一个位置,然后再从剩下的n-1个数据中选择一个最小的数据,并将它交换到第二个位置,以此类推,最后从两个数据中选择一个最小的数据并将它交换到第n-1个位置为止。
若有n个数,则需要进行n-1次选择操作。
例子1
/*从键盘输入10个成绩,按从小到大的顺序输出成绩(选择排序法)*/
#include
voidmain(void)
{
intdata[10],i,j,t,min;
printf("请输入10个成绩:
");
for(i=0;i<10;i++)
{
scanf("%d",&data[i]);
}
for(i=0;i<9;i++)//循环做9次选择
{
min=i;//min作为最小值的下标
for(j=i+1;j<10;j++)//找从i+1开始的最小值的下标
{
if(data[min]>data[j])
{
min=j;
}
}
if(min!
=i)//如果最小值的下标不是i就交换数据
{
t=data[i];data[i]=data[min];data[min]=t;
}
}
printf("排序后的成绩:
\n");
for(i=0;i<10;i++)
{
printf("%-3d",data[i]);
}
printf("\n");
}
(3)数组数据的查找问题—顺序查找法
例子1
/*已知在数组中保存有10个成绩,从键盘输入一个成绩判断它是否存在*/
#include
voidmain()
{
intdata[10]={99,87,65,77,63,96,100,85,92,80};
inti,k,flag=0;
printf("请输入要查找的成绩:
");
scanf("%d",&k);
for(i=0;i<10;i++)
{
if(k==data[i])//注意是等于符"=="不是赋值符"="
{
flag=1;
break;
}
}
if(flag==1)//注意是等于符"=="不是赋值符"="
printf("存在%d\n",k);
else
printf("不存在您要查找的成绩\n");
}
例子2
备注:
因与例子一前面的一样,这里只写不同之处
………略
for(i=0;i<10;i++)
{
if(k==data[i])//注意是等于符"=="不是赋值符"="
{
printf("存在%d\n",data[i]);break;
}
if((i==9)&&(k!
=data[9]))//注意i==9中是等于符"=="不是赋值符"="
{
printf("不存在您要查找的成绩\n");
break;
}
}
分析:
显然例子1的标志变量法要好得多,这种方法的思维用得较多
(4)数组数据的查找问题—折半查找法
前提:
待查找的一组数据是
有序排列的。
思路是首先选取中间位置的数与要查找的数比较,如果两者相等则成功,否则利用数据的有序性可以决定要查找的数在哪一半。
不断重复这样的查找过程直至查到或不存在为止。
例子1
/*已知在数组中保存有10个成绩,从键盘输入一个成绩判断它是否存在*/
#include
voidmain()
{
intdata[10]={63,65,77,80,85,87,92,96,99,100};//有序
intk,lower,high,mid,flag;
printf("请输入要查找的成绩:
");
scanf("%d",&k);//"&"不要忘
lower=0;
high=9;
while(lower<=high)//当范围缩小到同一个数时取等号说明所有的范围都找了一遍,
如果还没有找到就不满足循环条件(如:
high=-1;lower=0)跳出while循环
{
mid=(lower+high)/2;
if(data[mid]lower=mid+1;
elseif(data[mid]>k)
high=mid-1;
else//循环下去直到上面2种情况都不满足则找到了,如果三种情况都不满足
则不存在
{
flag=1;
break;
}
}
if(flag==1)//是"=="不是"="
printf("存在%d\n",k);
else
printf("您要查找的成绩不存在\n");
}
总结:
有序数列用半折法速度快;无序数列用顺序法是唯一可行的方法。
四:
(1)数组作为函数的参数(数组名作为实参)
例子1
/*输入任意个成绩,并输出最高分*/
#include
#defineLEN10//也可以不用宏定义,直接传值和给长度
voidinput(intdata[],intlen);//声明函数,如果写在main函数之后就不用声明
intcal_max(intdata[],intlen);//声明函数
voidmain()
{
intscore[LEN];//如果不用宏定义的话LEN都改为10
input(score,LEN);
printf("最高分为%d\n",cal_max(score,LEN));
}
voidinput(intdata[],intlen)//也可以用*data(指针)后续讲
{
inti;
printf("请输入%d个成绩:
",len);
for(i=0;i{
scanf("%d",&data[i]);//可改为data+i
}
}
intcal_max(intdata[],intlen)
{
inti,max=0;
for(i=0;i{
if(data[i]>max)//data[i]可以改成*(data+i)
{
max=data[i];
}
}
returnmax;//返回最大值,C中return只能返回一个值
}
/*
分析:
将数组名(数组首元素的地址)作为实参,要求函数的形参是
相同类型的数组或指针,这种方式是把实参数组的起始地址
传给形参数组,形参数组的改变也是对实参数组的改变,这种
参数的传递方式为地址传递,而不是值的传递。
data与score