C语言---程序设计练习题目及学习方法2

想要在C语言和编程这条路上

走的更远,

需要三个东西,

多看、多敲、多分析逻辑

当然,

这三个东西还不够

还需要保持热爱和PASSION(激情)

这样,

有朝一日,

终会,

成为更好的自己,

看到更好的世界。

篇幅较长万字左右,请耐心阅读学习哦

相信你一定会有所收获!

Let's start!

  1. 计算一个学生的数学和英语成绩的平均分
c 复制代码
	int math,english;
	float avg;
	math = 80;
	english = 90;
	avg = math+english/2.0;   //错误1:没有把数学和英语成绩用括号表示出来 
	avg = (math+english)/2.0; //修改后 
	printf("avg = %f",avg);

数据的格式化输出和输入

  • printf(格式控制,[输出列表]);
  • scanf(格式控制,&地址列表);
  1. 计算一个学生3门课的成绩(自行编码,并成功运行)
c 复制代码
	float sum,avg;
	int Chinese,math,eng;
	printf("请输入学生成绩:");
	scanf("%d %d %d",&Chinese,&math,&eng);
	sum = Chinese+math+eng;
	avg = sum/3.0;
	printf("Sum = %f,avg = %f",sum,avg);
	//记住这种基础框架,以后可以用来求周长或者面积等等 
  1. 执行下面程序之后,a的值为( )
c 复制代码
#include <stdio.h>
int main(){
    int a,b;
    for(a=1,b=1;a<=100;a++){
        if(b>=20)
            break;
        if(b%3==1){
            b+=3;
            continue;
        }
        b-=5;
    }
    return 0;
}
  • 注意:break和continue的使用及作用
  1. 以下程序的输出结果是( )
c 复制代码
#include <stdio.h>
int main() {
	inta,b;
	for(a=1,b=1;a<=100;a++){
		if(b>10) break;
		if(b%3==1)
		{ b+=3;continue; }
	}
	printf("%d\n",a);
	return 0;
}
  • 只能在循环体和swtich语句体内使用break语句
  1. 分析以下程序段:
c 复制代码
char str[]="xyz",*ps = str;
	while(*ps)
		ps++;
	for(ps--;ps-str>=0;ps--)
	puts(ps);
  • 指针指向字符串xyz的第一个地址
  • 利用双循环对其进行操作
  1. 分析程序,读出结果
c 复制代码
#include <stdio.h>
long Func(int n);
int main() {
  int i,n;
  printf("Input n:");
  scanf("%d",&n);
  for(i=1;i<n;i++){
      printf("%d!=%ld\n",i,Func(i));     
  }
  return 0;
}
long Func(int n){
  static long p=1;
  p=p*n;
  return p;
}
  • 静态变量static,从程序开始运行到程序结束,
  1. 读程序,分析结果( )
c 复制代码
#include<stdio.h>
int f(int a){
	int b=0;
	static c=3;   //静态变量 
	b+=1;
	c+=1;
	return(a+b+c);
} 
void main(){
	int a=2,i;
	for(i=0;i<=2;i++){
		printf("%3d",f(a));
	}
} 
  1. 计算数据类型所占内存空间
c 复制代码
	union StateMachine
	{
	char character;
	int number;
	char *str;
	double exp;
	};
	printf("Size of union StateMachine: %zu bytes\n", sizeof(union StateMachine));
  • 共用体与结构体的区别要清楚,下一章节会详细说明
  1. 大小写转换
c 复制代码
    char ch;
    printf("输出一个字符:"); 
    scanf("%c",&ch);  //两种方式,ch = getchar(); 表示接受一个字符到变量ch中 
    ch = ch - 32;
    printf("%c",ch);  //或者putchar() 
  1. 输出一个三位数,求该数个位十位百位上的数的和
c 复制代码
	int num;
	int a1,a2,a3,sum;
	printf("输入一个三位数:");
	scanf("%d",&num);
	//下面的这三行一定要记住!!! 
	a1 = num%10;	//个位数 
  	a2 = num/10%10; //十位数
	a3 = num/100;	//百位数  
	sum = a1 + a2 + a3 ;
	printf("sum = %d",sum);
  • 运算符
  1. 输入一个值,求它的绝对值
c 复制代码
	int x,y;
	scanf("%d",&x); 
	if(x<0){
		y=-x;
	}
	else
		y=x;   //或者直接y=x也可以 
	printf("绝对值是:%d",y);
  1. 从键盘输入两个数,输出较大者
c 复制代码
int x,y,max;
	scanf("%d %d",&x,&y);
	max = x>y?x:y;
	printf("max = %d",max);
	千万注意,不能忘记分号 
  1. 分段函数
c 复制代码
int x,y;
	scanf("%d",&x);
	if(x>5){
		y=x+3; 
	}
	else if(x>=0&&x<5){  //这里应该使用else if 不应该使用if的 
		y=0;
	}
	else
		y=2*x+30;  //这里犯了一个错误把2*x写成了2x,注意在C语言中要使用运算符的 
	printf("最大值是:%d",y);
  1. 计算快递公司资费 if语句知道,知道如何用switch去搞
c 复制代码
float weight,cost;
	scanf("%f",&weight);  //这里犯了一个低级错误,变量类型是float,格式控制符应该是%f 
	int weightrange = (int)(weight / 5);  //这也是不可少的一步 
	switch(weightrange){
		case 0: // 重量 <= 5kg
            cost = 3 * weight;
            break;
    	case 1: // 5kg < 重量 <= 10kg
            cost = 5 * 3 + (weight - 5) * 3.5;
            break;
      case 2: // 10kg < 重量 <= 15kg
            cost = 10 * 3.5 + (weight - 10) * 4;
            break;
      case 3: // 15kg < 重量 <= 20kg
            cost = 15 * 3.5 + 5 * 4;
            cost += (weight - 20) * 4;
            break;
      case 4: // 20kg < 重量 <= 25kg
            cost = 20 * 4 + (weight - 20) * 4.5;
            break;
      case 5: // 25kg < 重量 <= 30kg
            cost = 25 * 4.5 + (weight - 25) * 5;
            break;
      case 6: // 30kg < 重量 <= 50kg
            cost = 30 * 4.5 + 20 * 5;
            cost += (weight - 50) * 5;
            break;
      default: // 重量 > 50kg,拒收
            printf("货物重量超过50kg,我们不提供快递服务。\n");
            return 1;
    }

    printf("快递费用为:%.2f 元\n", cost);
  • 1.由于switch语句的case标签是整数常量,
    而这里的重量是一个范围,
    不能直接使用switch语句来处理范围。
    需要调整一下逻辑,
    将重量转换为一个整数来代表不同的重量范围,
    然后使用switch语句
  • 2.分段计价快递分=费,要理清楚逻辑
  1. 从键盘出入一个年份,判断其是否是闰年(ok)
c 复制代码
int year;
	scanf("%d",&year);
	if(year/4==0&&year/100!=0||year%100==0){
		printf("是闰年!",year);
	} else
		printf("不是闰年!",year);
  1. 从键盘输入三个数比较大小,按照从小到大的顺序输出(此类题目掌握还是不熟练)若是还是不理解,那就背住!
c 复制代码
int a,b,c,t;
	scanf("%d %d %d",&a,&b,&c);
//	确保a是最小的 
	if(b>a)
		t = a;
		b = a;
		a = t;
//	确保b是第二小 
	if(c>b)
		t = b;
		b = c;
		b = t;
//	确保c是最大 
	if(c>b)
		t = c;
		c = b;
		c = t;
	printf("%d %d %d",a,b,c);

	// 从小到大排序 
	 首先比较 a 和 b,如果 a 大于 b,则交换它们
    if (a > b) {
        t = a; 	  // 将 a 的值临时存储在 temp 中
        a = b;    // 将 b 的值赋给 a
        b = t;    // 将 temp(原来 a 的值)赋给 b
    }

    // 然后比较 a 和 c,如果 a 大于 c,则交换它们
    if (a > c) {
        t = a; 	  // 将 a 的值临时存储在 temp 中
        a = c;    // 将 c 的值赋给 a
        c = t;    // 将 temp(原来 a 的值)赋给 c
    }

    // 最后比较 b 和 c,如果 b 大于 c,则交换它们
    if (b > c) {
        t = b;    // 将 b 的值临时存储在 temp 中
        b = c;    // 将 c 的值赋给 b
        c = t;    // 将 temp(原来 b 的值)赋给 c
    }
    printf("从小到大的顺序是:%d %d %d\n", a, b, c);
	
	//从大到小排序
    // 首先比较 a 和 b,如果 a 小于 b,则交换它们
    if (a < b) {
        t = a;    // 将 a 的值临时存储在 temp 中
        a = b;    // 将 b 的值赋给 a
        b = t;    // 将 temp(原来 b 的值)赋给 b
    }

    // 然后比较 a 和 c,如果 a 小于 c,则交换它们
    if (a < c) {
        t = a;    // 将 a 的值临时存储在 temp 中
        a = c;    // 将 c 的值赋给 a
        c = t;    // 将 temp(原来 c 的值)赋给 c
    }

    // 比较 b 和 c,如果 b 小于 c,则交换它们
    if (b < c) {
        t = b;    // 将 b 的值临时存储在 temp 中
        b = c;    // 将 c 的值赋给 b
        c = t;    // 将 temp(原来 b 的值)赋给 c
    }

    printf("从大到小的顺序是:%d %d %d\n", a, b, c);
  1. 九九乘法表
c 复制代码
int i,j;
	for(i = 1;i<=10;i++) {
		for(j = 1;j<=i;j++){
			printf("%d*%d = %d\t",j,i,i*j);
		}
		printf("\n");
	}
	反思:为什么输出不了结果?
	int i, j;
     打印九九乘法表
    for(i = 1; i <= 10; i++) { // 外层循环,i 从 1 到 10
        for(j = 1; j <= i; j++) { // 内层循环,j 从 1 到 i
            printf("%d * %d = %d\t", j, i, i * j); // 打印乘法表的一行
        }
        printf("\n"); // 每打印完一行后换行
    }
	for(i=1;i<=10;i++){
		for(j=1;j<=i;j++){
			printf("%d*%d=%d\t",j,i,j*i);
		}
	printf("\n");
	}
  1. 错误分析
c 复制代码
int i;
	while(i<=100);
	if(i/3=0&&i/5=0)
		printf("%d",i);
	i++;

下面请大家进行练习:

习题1:计算正整数1-100中的奇数之和和偶数之和

习题2:输入10个数,统计并输出整数、负数和0的个数

习题3:打印并输出所有的水仙花数

补充知识:

一维数组
	一维数组的定义
	类型标识符 数组名[常量表达式]
	引用:数组名[下标表达式]
	其中 [下标表达式]表示数组中一个元素的顺序号,必须是整型常量、整形变量或整形表达式 
 	
 	用数组来存储、批量处理同类型数据,对于数据录入,求和统计,比较等操作,
 	可以使用循环语句来实现,使得程序简单精炼 
 	
 	数组元素是按照顺序排列的,数组元素的访问是通过下标变量进行的
	数组元素在内存中是连续存放的
  1. 从键盘获取10个学生的成绩,并计算出平均分
c 复制代码
int score[10];	//定义一个数组存放学生成绩 
	float avg;
	int i;
	
	for(i=0;i<10;i++)
		scanf("%d",&score[i]);  //循环输入数组元素 
	for(i=0;i<10;i++)
		avg=avg+score[i];	 //累加数组元素求出总分 
		
	avg=avg/10;
	printf("这10个学生平均分为%f",avg);	 
  • 解题步骤:
    1.定义三个变量,其中分数为数组,并利用for循环,从键盘获取输入
    2.在循环中累加每个元素的值,求出总分
    3.用总分数除以总人数
  1. 求出10个学生成绩最高的序号及其成绩
c 复制代码
int score[10];
	int max=0;
	int i;
	
	for(i=0;i<10;i++)
		scanf("%d",&score[i]); 
	for(i=0;i<10;i++)
		if(score[i]>score[max])
			max=i;	 

	printf("第%d位同学成绩最高,为%d分",max+1,score[max]);
  • 解题步骤:
    1.定义一维数组存放数组
    2.循环输入10个成绩
    3.从第一个数组元素开始逐个比较,将成绩较高者的数组元素的下标存入变量max中
    4.循环比较结束后,max中即是分数最高者的数组下标,加1为其序号,输出结果
  1. 用初始化方法,把10位同学成绩存储在数组中,
    在用键盘输入一个考分,查询该成绩是否在数组中
    如果在,则输出它是第几个学生的成绩
c 复制代码
int score[10]={50,60,70,80,90,40,20,30,10,80};
	int i;
	int find;
	printf("请输入分数:");
	scanf("%d",&find); 
	
	for(i=0;i<10;i++){
		if(score[i]==find){
			printf("这个学生是第%d个",i+1);
			break;
		}
	}
  • 解题步骤:
    1.定义一维数组存放数组,下标变量i,find存放从键盘输入的成绩
    2.从键盘输入一个考分find
    3.将find与数组的每一个元素对比,如果不同,则再与score的下一个元素比较
    如果相同,则将其下标值加1得到输入考分是第几个学生的成绩,将其输出

核心算法的初步认识:

冒泡排序法

排序的算法还有插入排序,选择排序,归并排序,快速排序等

先来认识一下冒泡排序

  1. 将学生成绩从低分到高分进行排序并输出
c 复制代码
int score[6]={50,60,40,30,20,80};
	int i,k,t;
	for(k=1;k<6-1;k++){ //后面做的多了理解之后就可以直接写k<5 要知道为什么这样去写 
		for(i=6-1;i>=k;i--){ 
			if(score[i]<score[i-1]){
				t=score[i];
				score[i]=score[i-1];
				score[i-1]=t;
			}
		}
	}
	printf("排序后的顺序是:");
	for(i=0;i<6;i++)
		printf("%6d",score[i]);
  • 解题步骤:
    1.定义数组存放成绩,可以从键盘获取,这里就直接初始化了,省时间
    2.定义i,k,t变量
    3.构造双层循环将数组排序
    4.将排序后的数组循环输出
    第3步将数组进行排序的过程:
    将相邻的成绩进行比较。如果前者小于后者,就交换位置,以此类推

简单总结一下:

冒泡排序算法是从最后一个元素开始,两相邻元素进行比较和交换,使最小元素逐渐从底部移到顶部,较大的元素逐渐从顶部移到底部

直到把最小元素交换到最顶部,就像水底的气泡一样逐渐往上冒,这叫一轮冒泡。再对剩下的元素重复上面的过程,直到将所有元素排好序

思考 :通常进行考试成绩排序时,多数是从高到低进行排序,怎么实现呢?

补充知识:

二维数组 
	二维数组定义及初始化与一维类似 
	注意:在初始化数据时,行可以省略,但是列不能省!! 
	这里重点是初始化
	
	两种方式:
		1.按行赋初值
		int tall[3][4] = {{5,4,3,8},{7,8,4,5},{7,6,4,9}};
		2.按二维数组在内存中的排列顺序给元素赋值
		int tall[3][4]={120,150,147,162,153,147,190,177,179,157,148,149};等价于 
		int tall[3][4] = {{120,150,147,162},{153,147,190,177}{179,157,148,149}};
		
	说明:
	1.同一维数组一样可以对部分元素显式赋初值,未显式赋初值的元素将自动设为0,例如:
		int tall[3][4] = {{5},{7},{6}};
		它的作用是只对各行第一列元素进行赋初值,其余元素都是0
	2.赋初值时,行标可以省略,但是列不可省,下面几种方法都是等价的 
		int b[][4] = {{1,2,3,4},{7,8,4,5}};
		int b[2][4] = {1,2,3,4, 7,8,4,5};
		int b[][4] = {1,2,3,4, 7,8,4,5};
  1. 一个学习小组有5个人,每个人有英语数学两项成绩,试着将成绩用二维数组存储,并打印到屏幕上
c 复制代码
	数学	86	100	75	88	65
	英语	78	90	80	65	85
	int score[2][5]={{86,100,75,88,65},{78,90,80,65,85}};
	int i,j;
	for(j=0;j<5;j++){
		printf("%-6d",j+1); //循环5次,输出5个学生的序号 
	}
	for(i=0;i<2;i++){  //循环两次,输出两行数据 
		printf("\n");  //输出一行数据后换行 
		for(j=0;j<5;j++){   //循环5次,输出一行5个成绩 
			printf("%-6d",score[i][j]);   //输出数据占6格,左对齐 
		}
	}
  • 解题步骤:
    1.定义2行5列的二维数组score[2][5]存放成绩表,第1行存放数学成绩,第2行存放英语
    每个同学的两项成绩存储在一列,既可以通过列数表示学生序号
    2.依次输出所有学生的序号
    3.依次输出所有学生的数学成绩
    4.依次输出所有学生的英语成绩
  1. 有12个同学按照3行4列的顺序站在操场上,从里面找到最高的同学身高
c 复制代码
int tall[3][4]={120,150,147,162,153,147,190,177,179,157,148,149};
	int i,j;
	int tallest=0;
	for(i=0;i<3;i++){
		for(j=0;j<4;j++){
			if(tallest<tall[i][j])
				tallest=tall[i][j];
		}
	}
	printf("最高同学身高是:%d",tallest);
  • 解题步骤:
    1.定义
    2.定义变量tallest,用于存放最高身高
    3.构造双重循环将身高数据逐个与tallest比较,
    如果比tallest大,则存入tallest,在进行下一次比较
    4.输出

对于数组问题的解决,
主要重点是其下标变化的规律,
从而构造适当的表达式

同类错误总结:

1.定义或者引用数组时,误用圆括号,正确应该是中括号
	int i,array(10);
	应改为 int i,array[10];
2.对二维数组的定义和引用的方法不对
	int array[5,4]
	printf("%d",array[1+2,2+1]);
	应该为 
	int array[5][4]
	printf("%d",array[1+2][2+1]);
3.给数组变量赋初值时,初值的个数超过了数组的大小
	int array[3]={1,2,3,4};
	应该为
	int array[3]={1,2,3}; 
4.输入变量时忘记添加地址运算符&
5.输入数据时,企图规定精度
	scanf("%7.2f",&a); 
6.if语句中,只要超过一行,就用{}包含起来 
7.switch(),括号中的表达式只能是int型,char型或者枚举类型
8.case后面 常量表达式 ,default可有可无
9.do-while循环,不管条件是否成立,至少执行循环体一次 
	
10.for(初值;条件;增量)
	循环体只包含一条语句时,可以省略{},如果包含两条及以上,那么为复合语句,必须用{}包含起来
	其中,3个表达式都可以省略,但是括号里面的分号不能省 

练习:

习题1:将一个数组中的元素进行逆序存放,9,8,7,6,5,4,3,2,1

习题2:在一个升序数组中插入一个数,使数组仍然保持升序排列

习题3:合并两个降序数组,使合并后的数据仍然保持降序排列

习题4:求一个3x3矩阵主对角线元素之和

习题5:编写程序,打印10行杨辉三角

相关推荐
xiaoshiguang34 分钟前
LeetCode:222.完全二叉树节点的数量
算法·leetcode
爱吃西瓜的小菜鸡5 分钟前
【C语言】判断回文
c语言·学习·算法
别NULL7 分钟前
机试题——疯长的草
数据结构·c++·算法
TT哇11 分钟前
*【每日一题 提高题】[蓝桥杯 2022 国 A] 选素数
java·算法·蓝桥杯
yuanbenshidiaos2 小时前
C++----------函数的调用机制
java·c++·算法
唐叔在学习2 小时前
【唐叔学算法】第21天:超越比较-计数排序、桶排序与基数排序的Java实践及性能剖析
数据结构·算法·排序算法
ALISHENGYA2 小时前
全国青少年信息学奥林匹克竞赛(信奥赛)备考实战之分支结构(switch语句)
数据结构·算法
chengooooooo2 小时前
代码随想录训练营第二十七天| 贪心理论基础 455.分发饼干 376. 摆动序列 53. 最大子序和
算法·leetcode·职场和发展
jackiendsc2 小时前
Java的垃圾回收机制介绍、工作原理、算法及分析调优
java·开发语言·算法
FeboReigns2 小时前
C++简明教程(文章要求学过一点C语言)(1)
c语言·开发语言·c++