想要在C语言和编程这条路上
走的更远,
需要三个东西,
多看、多敲、多分析逻辑
当然,
这三个东西还不够
还需要保持热爱和PASSION(激情)
这样,
有朝一日,
终会,
成为更好的自己,
看到更好的世界。
篇幅较长万字左右,请耐心阅读学习哦
相信你一定会有所收获!
Let's start!
- 计算一个学生的数学和英语成绩的平均分
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(格式控制,&地址列表);
- 计算一个学生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);
//记住这种基础框架,以后可以用来求周长或者面积等等
- 执行下面程序之后,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的使用及作用
- 以下程序的输出结果是( )
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
语句
- 分析以下程序段:
c
char str[]="xyz",*ps = str;
while(*ps)
ps++;
for(ps--;ps-str>=0;ps--)
puts(ps);
- 指针指向字符串xyz的第一个地址
- 利用双循环对其进行操作
- 分析程序,读出结果
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,从程序开始运行到程序结束,
- 读程序,分析结果( )
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));
}
}
- 计算数据类型所占内存空间
c
union StateMachine
{
char character;
int number;
char *str;
double exp;
};
printf("Size of union StateMachine: %zu bytes\n", sizeof(union StateMachine));
- 共用体与结构体的区别要清楚,下一章节会详细说明
- 大小写转换
c
char ch;
printf("输出一个字符:");
scanf("%c",&ch); //两种方式,ch = getchar(); 表示接受一个字符到变量ch中
ch = ch - 32;
printf("%c",ch); //或者putchar()
- 输出一个三位数,求该数个位十位百位上的数的和
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);
- 运算符
- 输入一个值,求它的绝对值
c
int x,y;
scanf("%d",&x);
if(x<0){
y=-x;
}
else
y=x; //或者直接y=x也可以
printf("绝对值是:%d",y);
- 从键盘输入两个数,输出较大者
c
int x,y,max;
scanf("%d %d",&x,&y);
max = x>y?x:y;
printf("max = %d",max);
千万注意,不能忘记分号
- 分段函数
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);
- 计算快递公司资费 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.分段计价快递分=费,要理清楚逻辑
- 从键盘出入一个年份,判断其是否是闰年(ok)
c
int year;
scanf("%d",&year);
if(year/4==0&&year/100!=0||year%100==0){
printf("是闰年!",year);
} else
printf("不是闰年!",year);
- 从键盘输入三个数比较大小,按照从小到大的顺序输出(此类题目掌握还是不熟练)若是还是不理解,那就背住!
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);
- 九九乘法表
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");
}
- 错误分析
c
int i;
while(i<=100);
if(i/3=0&&i/5=0)
printf("%d",i);
i++;
下面请大家进行练习:
习题1:计算正整数1-100中的奇数之和和偶数之和
习题2:输入10个数,统计并输出整数、负数和0的个数
习题3:打印并输出所有的水仙花数
补充知识:
一维数组
一维数组的定义
类型标识符 数组名[常量表达式]
引用:数组名[下标表达式]
其中 [下标表达式]表示数组中一个元素的顺序号,必须是整型常量、整形变量或整形表达式
用数组来存储、批量处理同类型数据,对于数据录入,求和统计,比较等操作,
可以使用循环语句来实现,使得程序简单精炼
数组元素是按照顺序排列的,数组元素的访问是通过下标变量进行的
数组元素在内存中是连续存放的
- 从键盘获取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.用总分数除以总人数
- 求出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为其序号,输出结果
- 用初始化方法,把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得到输入考分是第几个学生的成绩,将其输出
核心算法的初步认识:
冒泡排序法
排序的算法还有插入排序,选择排序,归并排序,快速排序等
先来认识一下冒泡排序
- 将学生成绩从低分到高分进行排序并输出
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};
- 一个学习小组有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.依次输出所有学生的英语成绩
- 有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行杨辉三角