20145233韩昊辰第二周实习实验报告
20145233韩昊辰第二周C语言实习
实习内容
- 学习使用新系统中的C语言教学,完成25个课时的学习,在虚拟机中完成C语言代码编写与基础C语言知识理解。
- 因为虚拟机打开不方便,并且使用的是vc6编译的,所以在咨询了老师之后,可以使用自己的电脑完成这次实习,所以我接下来会放上自己25个课时的结果截图,以及程序代码。
实习一 C语言的概述
- c语言的起源和发展
- c语言的特点
优点:代码量小 速度快 功能强大
缺点:危险性高 开发周期长 可移植性不强 - c语言的应用领域
系统软件开发:操作系统 :windows linux unix
驱动程序:主板驱动 显卡驱动 摄像头驱动
数据库:DB2 Oracle Sql server
应用软件开发:办公软件:Wps
图形图像多媒体:ACDSee Photoshop、MediaPlayer
嵌入式软件开发:智能手机、掌上电脑
游戏开发:2D、3D游戏 - c语言的重要性:a.有史以来最重要的语言
b.所有大学工科和理科学生必修课程
c.最重要的系统软件:Windows、Linux、Unix均使用c开发
d.一名合格黑客必须掌握的语言
e.程序设计和开发人员必须掌握的语言
f.学习数据结构、c++、java、c#奠定基础 - Visual C++ 6.0软件的安装
实习程序代码
#include <stdio.h>
#include <math.h>
int main(void)
{
int a = 1;
int b = 2;
int c = 3;
float delta;
float x1;
float x2;
delta = b*b - 4*a*c;
if (delta > 0)
{
x1 = (-b + sqrt(delta)) / (2 * a);
x2= (-b - sqrt(delta)) / (2 * a);
printf("该一元二次方程有两个解,x1=%f,x2=%f\n", x1, x2);
}
else if (delta = 0)
{
x1 = -b / (2 * a);
x2 = x1;
printf("该一元二次方程有唯一一个解,x1=x2=%f\n", x1);
}
else
{
printf("无解\n");
}
return 0;
}
实习一结果
实习二 算法
- 算法
- (1)算法是指解题方案的准确而完整的描述。
A.算法的基本特征:①可行性;②确定性;③有穷性;④拥有足够的情报。
B.算法的基本要素:①算法中对数据的运算和操作:基本的运算和操作包括算术运算、逻辑运算、关系运算和数据传输;②算法的控制结构:基本的控制结构包括顺序结构、选择结构、循环结构。
C.算法设计的基本方法:①列举法;②归纳法;③递推;④递归;⑤减半递推技术;⑥回溯法。 - (2)算法的复杂度
算法的复杂度主要包括时间复杂度和空间复杂度。
A.算法的时间复杂度:是指执行算法所需要的计算工作量。算法的工作量用算法所执行的基本运算次数来度量,而算法所执行的基本运算次数是问题规模的函数。即:算法的工作量=f(n)其中n是问题的规模。
B.算法的空间复杂度:一般是指执行这个算法所需要的内存空间。一个算法所占用的存储空间包括算法程序所占的空间、输入的初始数据所占用的存储空间以及算法执行过程中所需要的额外空间。 - 数据结构的基本概念
数据结构作为计算机的一门学科,主要研究和讨论以下三个方面的问题:
①数据集合中各数据元素之间所固有的逻辑关系,即数据的逻辑结构;
②在对数据进行处理时,各数据元素在计算机中的存储关系,即数据的存储结构;
③对各种数据结构进行的运算。 - (1)数据结构的定义
①数据结构是指相互有关联的数据元素的集合。
②数据处理是指对数据集合中的各元素以各种方式进行运算,包括插入、删除、查找、更改等运算,也包括对数据元素进行分析。
③数据的逻辑结构是指反映数据元素之间逻辑关系的数据结构。
④数据的逻辑结构在计算机存储空间中的存放形式称为数据的存储结构(也称数据的物理结构)。常用的存储结构有顺序、链接、索引等存储结构。 - (2)数据结构的图形表示
在数据结构的图形表示中,对于数据集合D中的每一个数据元素用中间标有元素值的方框表示,一般称之为数据结点,简称结点;为了进一步表示各数据元素之间的前后件关系,对于关系R中的每一个二元组,用一条有向线段从前件结点指向后件结点。 - (3)线性结构与非线性结构
如果一个非空的数据结构满足下列两个条件:
①有且只有一个根结点;
②每一个结点最多有一个前件,也最多有一个后件。
则称该数据结构为线性结构。如果一个数据结构不是线性结构,则称为非线性结构。
图解算法的逻辑结构 - 步骤1:顺序结构。顺序结构是最简单的算法结构,语句与语句之间,框与框之间是按从上到下的顺序进行的。它是由若干个依次执行的处理步骤组成的,它也是任何一个算法都离不开的一种算法结构,如图,其中A和B两个框是依次执行的,只有在执行完A框所指定的 操作后,才能接着执行B框所指定的操作。顺序结构的一个简单的例子是交换变量a和b的值。
- 算法如下:
S1:m=a;
S2:a=b;
S1:b=m. - 程序框图如图:
图 1 逻辑算法图
- 步骤2:条件分支结构。在一个算法中,经常会遇到一些条件的判断、算法的流程根据条件是否成立有不同的流向,这种先根据条件作出判断,再决定执行哪一种操作的结构称为条件分支结构,如右图所示的一个条件分支结构,此结构中包含一个判断框,根据给定的条 件P是否成立而选择执行A框或B框,请注意,无论P条件是否成立,只能执行A框或B框之一,不可能既执行A框又执行B框,也不可能A框和B框都不执行。无论走哪一条路径,在执行完A框或B框之后,脱离本条件分支结构。A框或B框两个框中,可以有一个是空的,即不执行 任何操作
- 例:
- 写出求方程px+q=0(其中p和q为常数)根一个算法,并画出程序框图。
- 分析:此方程的根与p和q取值有关。算法如下:
S1:输入p、q
S2:如果p≠0,则使x=-q/p,并执行S3;否则,执行S4;
S3:输出x;
S4:如果q≠0,则输出“方程无实数根”,否则,输出“方程的解是全体实数”
图 2 逻辑算法图
- 步骤3:循环结构。需要重复执行同一操作的结构称为循环结构,即从某处开始,按照一定条件反复执行某一处理步骤,反复执行的处理步骤称为循环体。循环结构中通常都有一个起循环计数作用的变量,这个变量的取值一般都包含在执行或终止循环的条件中。循环结 构有while型循环(也称当型循环)和until型循环(也称直到型循环)两种,要注意这两种循环的联系和区别。
实习代码
# include <stdio.h>
int main(void)
{
int i,j;
for(i = 100;i <= 300;i++)
{
for(j = 2;j <= i;j++)
if(i%j == 0)
break;
if(j ==i)
printf("%-4d",i);
}
return 0;
}
实习二结果
实习三 C语言预备计算机知识
- 汇编语言是最低级的语言,它可以直接与硬件打交道。高级语言有Pascal、Basic、Fortran等等。高级语言的一条语句对应低级语言的很多条语句,任何高级语言编写的程序都要经过编译程序的编译、连接才能成为可以运行的程序。
- 编译连接的过程也就是把高级语言翻译成机器语言(二进制机器码)的过程,而汇编语言是基本上与机器语言一 一对应的一种语言。这个翻译过程是由编译程序自动完成的。把C语言定为中级语言是有它的道理的,因为C语言既有汇编语言的存取底层硬件的能力,又具有高级语言的许多特点。熟练掌握了C语言,学习其它的各种编程语言应该是很轻松的了。
- C语言的书写格式:
1) 一个C语言编写的源程序,必定有一个主程序(称为main()函数,在C语言中子程序称为“函数”(当然,不要理解成为数学里面的“函数”)。但是决不能有一个以上的main函数(即只能有一个)。
2) 函数语句块用‘{’括号开始, 以‘}’反括号结束。这样的花括号必须成对出现。
3) 表达式写在小括号里面,以‘(’括号开始,以‘)’反括号结束。
4) 函数不能嵌套,即函数里面不能再套函数。(每一个函数是完成一个特定功能的函数模块)
- C语言的组成:
C语言是由许多函数组成的。其中只有一个主函数(main()函数)。C程序执行时总是从main函数的‘{’处开始,至main函数的反大括号'}'处结束。当然还有其它一些规则,这将在以后的学习中去熟悉它。
- C语言的书写规则:
C语言在书写时有它自身的特点:书写格式比较自由,在一行里可以写多条语句,一个语句也可以分写在多行上。虽然如此,在书写源程序时还是要注意哪些可以自由书写,而哪些必须要按照书写规则来书写。 - 几条规则写在下面:
1) 一行内可以写几个语句,建议一行不超过两条语句;
2) 一条语句可以写在多行上;
3) C语句不需要写行标号;
4) 每条语句及数据定义的后面要写上分号以表示该语句结束;
5) C语言中注释用 //来表示;
6) 建议书写时采用缩进格式;
7) 花括号、小括号都是成对出现的。
- 一个最简单的C程序的编写:
/程序代码/ /注释部分/
main() /main是主函数名。紧跟在main后面的括号是放参数的。
括号里面为空说明main函数不需要参数/
{ /正写的大花括号表示main函数从这里开始/
} /反写的大花括号表示main函数到这里结束/
- 说明:由于是一个演示程序,在函数体内并没有任何可以执行的语句,也就是这个程序什么事也不做。
这个程序就是这么简单: 写在一行上就是 main() { }
你在TC的编辑环境下把这段代码输入进去,按F9键编译连接,按CTRL_F5运行,一定很正常。但是什么结果也不会有,因为在main函数里面什么代码也没有。
- 下面再举一个可以向屏幕上输出一条信息的例子:
main()
{
printf("这就是C语言编写的程序!"); /这一条语句的作用是向屏幕输出一条信息
”这就是C语言编写的程序!"/
} - 在这个程序中,main函数只有一条语句:printf("这就是C语言编写的程序!");这个语句的作用是向屏幕输出一个字符串。有关这个语句的知识以后再讲。现在要注意的是一个C语言程序的框架是怎样组成的。
- C语言程序的几种文件格式:
- 1、 源程序---在TC集成环境中输入的程序文本称为源程序。源程序是一种文本文件。它是我们看得见并认识的一种文件。其扩展名为.C。例如你把文件保存为TEST,那么在磁盘上应看得到TEST.C这个文件。这样的文件可以用记事本打开。
- 2、二进制文件---写完了源程序后接着要做的是编译这个文件。在TC集成环境里是按ALT_F9键,编译后生成了一个二进制文件,这个二进制文件名为TEST.OBJ,也就是扩展名为OBJ的目标文件。
- 3、运行文件---最后一步是make(或Link),在TC集成环境里是按F9键Make之后生成了一个可以在DOS下运行的文件,其扩展名为EXE。如TEST.EXE。这个EXE文件是由第2步中的OBJ文件生成的。
- OBJ文件虽然是二进制文件,而电脑又是可以运行二进制文件的,为什么还要把OBJ文件Link为EXE文件才能运行?这里的知识就比较多了,这里不能多讲。
- 但是要明白一点,在DOS下仅仅有了一个二进制文件还不能运行,因为操作系统要把这些二进制文件加以规划,把相应的数据、程序代码放到应该放的内存位置,这样的经过严密规划和组织好了的二进制文件才能运行。而这些只有在生成的EXE文件里面才做完了这些工作。
实习代码
#include <stdio.h>
int main(void)
{
float x=123.45e-2;
printf("%f\n",x);
return 0;
}
实习三结果
实习四 硬件之间的关系
- 1 软硬件协同设计概要
- 1.1传统的设计方法
嵌入式系统由功能模块组成,按实现方法可以分为软件模块和硬件模块两大类。传统的设计方法
采用硬件优先的原则。流程如图1所示。
- 1.2软硬件协同设计方法
- 软硬件协同设计让软件设计和硬件设计作为一个整体,在设计初期对系统进行建模(modeling),在
此基础上实现软硬件的综合优化探索和并行开发。
- 硬件模型可以在一定的抽象层次(相对于RTL层次)实现,通常建的是事务级模型(TransactionLev-el Model),用高级语言C或SystemC来实现。相对于RTL精确到pin和cycle的颗粒度,TLM模型只需要精确到数据传输包的颗粒度,因此模型的设计时间远比RTL设计少,仿真速度远比RTL快。软件设计可以在硬件模型的基 础上就展开验证,系统模型在早期就可以得到验证和评估,减少了每次系统优化迭代的时间。硬件设计完成后的系统集成,由于软件部分已经基本得到验证,所以调试难度也相对较小。
- 基于软硬件协同设计的原理,提出了一种用c语言建模系统的方法,并将它应用于实际产品研发项目中,大大降低了验证复杂度,优化了系统性能,缩短了开发周期。在软件功能函数基础上,用C语言实现硬件模块的所有寄存器读写功能,主要包括:
①参数寄存器配置模块参数。
②命令寄存器触发硬件工作过程。
③状态寄存器储存硬件状态和处理结果。
实习代码
#include <stdio.h>
int main(void)
{
int x=47;
printf("%x\n",x);
printf("%x\n",x);
printf("%#x\n",x);
printf("%#x\n",x);
return 0;
}
实习四结果
实习五 数据类型和变量
%a,%A 读入一个浮点值(仅C99有效)
%c 读入一个字符
%d 读入十进制整数
%i 读入十进制,八进制,十六进制整数
%o 读入八进制整数
%x,%X 读入十六进制整数
%s 读入一个字符串,遇空格、制表符或换行符结束。
%f,%F,%e,%E,%g,%G 用来输入实数,可以用小数形式或指数形式输入。
%p 读入一个指针
%u 读入一个无符号十进制整数
%n 至此已读入值的等价字符数
%[] 扫描字符集合
%% 读%符号
x是1f,X是1F
实习代码
# include <stdio.h>
int main(void)
{
int x = 47;
printf("%x\n",x);
printf("%x\n",x);
printf("%#x\n",x);
printf("%#x\n",x);
return 0;
}
实习五结果
实习六 什么叫进制
- 一)、数制
计算机中采用的是二进制,因为二进制具有运算简单,易实现且可靠,为逻辑设计提供了有利的途径、节省设备等优点,为了便于描述,又常用八、十六进制作为二进制的缩写。
- 一般计数都采用进位计数,其特点是:
(1)逢N进一,N是每种进位计数制表示一位数所需要的符号数目为基数。
(2)采用位置表示法,处在不同位置的数字所代表的值不同,而在固定位置上单位数字表示的值是确定的,这个固定位上的值称为权。
在计算机中:D7 D6 D5 D4 D3 D2 D1 D0 只有两种0和1
8 4 2 1
- 二)、数制转换
- 不同进位计数制之间的转换原则:不同进位计数制之间的转换是根据两个有理数如相等,则两数的整数和分数部分一定分别相等的原则进行的。也就是说,若转换前两数相等,转换后仍必须相等。
有四进制
十进制:有10个基数:0 ~~ 9 ,逢十进一
二进制:有2 个基数:0 ~~ 1 ,逢二进一
八进制:有8个基数:0 ~~ 7 ,逢八进一
十六进制:有16个基数:0 ~~ 9,A,B,C,D,E,F (A=10,B=11,C=12,D=13,E=14,F=15) ,逢十六进一
- 1、数的进位记数法
N=a n-1p n-1+a n-2p n-2+…+a2p2+a1p1+a0*p0 - 2、十进制数与P进制数之间的转换
①十进制转换成二进制:十进制整数转换成二进制整数通常采用除2取余法,小数部分乘2取整法。例如,将(30)10转换成二进制数。
将(30)10转换成二进制数
2| 30 ….0 ----最右位
2 15 ….1
2 7 ….1
2 3 ….1
1 ….1 ----最左位
∴ (30)10=(11110)2
将(30)10转换成八、十六进制数
8| 30 ……6 ------最右位
3 ------最左位
∴ (30)10 =(36)8
16| 30 …14(E)----最右位
1 ----最左位
∴ (30)10 =(1E)16 - 3、将P进制数转换为十进制数
把一个二进制转换成十进制采用方法:把这个二进制的最后一位乘上20,倒数第二位乘上21,……,一直到最高位乘上2n,然后将各项乘积相加的结果就它的十进制表达式。
把二进制11110转换为十进制
(11110)2=124+123+122+121+020=
=16+8+4+2+0
=(30)10
把一个八进制转换成十进制采用方法:把这个八进制的最后一位乘上80,倒数第二位乘上81,……,一直到最高位乘上8n,然后将各项乘积相加的结果就它的十进制表达式。
把八进制36转换为十进制
(36)8=3\81+680=24+6=(30)10
把一个十六进制转换成十进制采用方法:把这个十六进制的最后一位乘上160,倒数第二位乘上161,……,一直到最高位乘上16n,然后将各项乘积相加的结果就它的十进制表达式。
把十六制1E转换为十进制
(1E)16=1161+14*160=16+14=(30)10 - 4、二进制转换成八进制数
(1)二进制数转换成八进制数:对于整数,从低位到高位将二进制数的每三位分为一组,若不够三位时,在高位左面添0,补足三位,然后将每三位二进制数用一位八进制数替换,小数部分从小数点开始,自左向右每三位一组进行转换即可完成。例如:
将二进制数1101001转换成八进制数,则
(001 101 001)2
| | |
( 1 5 1)8
( 1101001)2=(151)8
(2)八进制数转换成二进制数:只要将每位八进制数用三位二进制数替换,即可完成转换,例如,把八进制数(643.503)8,转换成二进制数,则
(6 4 3 . 5 0 3)8
| | | | | |
(110 100 011 . 101 000 011)2
(643.503)8=(110100011.101000011)2 - 5、二进制与十六进制之间的转换
(1)二进制数转换成十六进制数:由于2的4次方=16,所以依照二进制与八进制的转换方法,将二进制数的每四位用一个十六进制数码来表示,整数部分以小数点为界点从右往左每四位一组转换,小数部分从小数点开始自左向右每四位一组进行转换。
(2)十六进制转换成二进制数
如将十六进制数转换成二进制数,只要将每一位十六进制数用四位相应的二进制数表示,即可完成转换。
例如:将(163.5B)16转换成二进制数,则
( 1 6 3 . 5 B )16
| | | | |
(0001 0110 0011. 0101 1011 )2
(163.5B)16=(101100011.01011011)2
实习代码
#include <stdio.h>
int powe(int n)
{
int i;
int s=1;
for(i=1;i<=n;i++)
{
s=s*16;
}
return s;
}
void main()
{
int m;
int n;
int i;
int r;
int a;
printf("请输入一个16进制数");
scanf("%d",&m);
a=m;
n=0,i=0;
while(m)
{
r=m%10;
n=n+r*powe(i);
m=m/10;
i++;
}
printf("16进制数%d对应的10进制数是%d\n",a,n);
}
实习六结果
实习七 代码的规范化
- 1 排版
1-1:程序块要采用缩进风格编写,缩进的TAB键一个.
1-2:相对独立的程序块之间、变量说明之后必须加空行.
1-3:较长的语句(>80字符)要分成多行书写,长表达式要在低优先级操作符处划分新行,操作符放在新行之首,划分出的新行要进行适当的缩进,使排版整齐,语句可读.
1-4:循环、判断等语句中若有较长的表达式或语句,则要进行适应的划分,长表达式要在低优先级操作符处划分新行,操作符放在新行之首.
1-5:若函数或过程中的参数较长,则要进行适当的划分.
1-6:不允许把多个短语句写在一行中,即一行只写一条语句.
1-7:if、while、for、default、do等语句自占一行.
1-8:对齐只使用TAB键,不使用空格键.
1-9:函数或过程的开始、结构的定义及循环、判断等语句中的代码都要采用缩进风格,case语句下的情况处理语句也要遵从语句缩进要求.
1-10:程序块的分界符(如C/C++语言的大括号'{'和'}')应各独占一行并且位于同一列,同时与引用它们的语句左对齐.在函数体的开始、类的定义、结构的定义、枚举的定义以及if、for、do、while0、switch、case语句中的程序都要采用如上的缩进方式.
1-11:在两个以上的关键字、变量、常量进行对等操作时,它们之间的操作符之前、之后或者前后要加空格;进行非对等操作时,如果是关系密切的立即操作符(如->),后不应加空格.
1-12: 程序结构清析,简单易懂,单个函数的程序行数不得超过100行. - 2 注释
2-1:一般情况下,源程序有效注释量必须在20%以上.
2-2:说明性文件(如头文件.h文件、.inc文件、.def文件、编译说明文件.cfg等)头部应进行注释,注释必须列出:版权说明、版本号、生成日期、作者、内容、功能、与其它文件的关系、修改日志等,头文件的注释中还应有函数功能简要说明.
2-3:源文件头部应进行注释,列出:版权说明、版本号、生成日期、作者、模块目的/功能、主要函数及其功能、修改日志等.
2-4:函数头部应进行注释,列出:函数的目的/功能、输入参数、输出参数、返回值、调用关系(函数、表)等.
2-5:边写代码边注释,修改代码同时修改相应的注释,以保证注释与代码的一致性.不再有用的注释要删除.
2-6:注释的内容要清楚、明了,含义准确,防止注释二义性.
2-7:避免在注释中使用缩写,特别是非常用缩写.
2-8:注释应与其描述的代码相近,对代码的注释应放在其上方或右方(对单条语句的注释)相邻位置,不可放在下面,如放于上方则需与其上面的代码用空行隔开.
2-9:对于所有有物理含义的变量、常量,如果其命名不是充分自注释的,在声明时都必须加以注释,说明其物理含义.变量、常量、宏的注释应放在其上方相邻位置或右方.
2-10:数据结构声明(包括数组、结构、类、枚举等),如果其命名不是充分自注释的,必须加以注释.对数据结构的注释应放在其上方相邻位置,不可放在下面;对结构中的每个域的注释放在此域的右方.
2-11:全局变量要有较详细的注释,包括对其功能、取值范围、哪些函数或过程存取它以及存取时注意事项等的说明.
2-12:注释与所描述内容进行同样的缩排.
2-13:将注释与其上面的代码用空行隔开.
2-14:对变量的定义和分支语句(条件分支、循环语句等)必须编写注释.
2-15:对于switch语句下的case语句,如果因为特殊情况需要处理完一个case后进入下一个case处理,必须在该case语句处理完、下一个case语句前加上明确的注释. - 3 标识符命名
3-1:标识符的命名要清晰、明了,有明确含义,同时使用完整的单词或大家基本可以理解的缩写,避免使人产生误解.
3-2:命名中若使用特殊约定或缩写,则要有注释说明.
3-3:自己特有的命名风格,要自始至终保持一致,不可来回变化.
3-4:对于变量命名,禁止取单个字符(如i、j、k...),建议除了要有具体含义外,还能表明其变量类型、数据类型等,但i、j、k作局部循环变量是允许的.
3-5:命名规范必须与所使用的系统风格保持一致,并在同一项目中统一,比如采用UNIX的全小写加下划线的风格或大小写混排的方式,不要使用大小写与下划线混排的方式. - 4 可读性
4-1:注意运算符的优先级,并用括号明确表达式的操作顺序,避免使用默认优先级.
4-2:避免使用不易理解的数字,用有意义的标识来替代.涉及物理状态或者含有物理意义的常量,不应直接使用数字,必须用有意义的枚举或宏来代替. - 5 变量
5-1:去掉没必要的公共变量.
5-2:仔细定义并明确公共变量的含义、作用、取值范围及公共变量间的关系.
5-3:明确公共变量与操作此公共变量的函数或过程的关系,如访问、修改及创建等.
5-4:当向公共变量传递数据时,要十分小心,防止赋与不合理的值或越界等现象发生.
5-5:防止局部变量与公共变量同名.
5-6:严禁使用未经初始化的变量作为右值. - 6 函数、过程
6-1:对所调用函数的错误返回码要仔细、全面地处理.
6-2:明确函数功能,精确(而不是近似)地实现函数设计.
6-3:编写可重入函数时,应注意局部变量的使用(如编写C/C++语言的可重入函数时,应使用auto即缺省态局部变量或寄存器变量).
6-4:编写可重入函数时,若使用全局变量,则应通过关中断、信号量(即P、V操作)等手段对其加以保护。
实习代码
#include<stdio.h>
int main(void)
{
float a,b,c,t;
scanf("%f, %f, %f", &a, &b, &c);
if(a>b)
{
t=a;
a=b;
b=t;
}
if(a>c)
{
t=a;
a=c;
c=t;
}
if(b>c)
{
t=b;
b=c;
c=t;
}
printf("%5.2f, %5.2f, %5.2f\n", a, b, c);
return 0;
}
实习七结果
实习八 不同数据类型之间的赋值问题
-
- 各类数值型数据间混合运算时的类型转换规则
- 整型、实型、字符型数据间可以混合运算。在这种情况下,需要将不一致的数据类型转换成一致的数据类型,然后进行运算。为了保证运算精度,系统在运算时的转换规则是将存储长度较短的运算对象转换成存储长度较长的类型,然后再进行处理。这种转换是系统自动进行的。
1) 纵向箭头表示必定会进行的转换,如float型数据必先转换为double型数据,然后与其他操作数进行运算。与此类似,char型或short型数据必先转换为int型数据,然后进行运算。
2) 横向箭头表示当运算对象为不同类型数据时的转换方向,如int型数据与unsigned型数据进行运算,int型转换为unsigned型后方可进行运算。int型数据与double型数据进行运算,int型直接转换为double型后进行运算,不能理解为先转换为unsigned int型,然后转换为long int型,最后再转换为double型。 - 赋值时的类型转换
- 当赋值运算符两侧的类型不同时,需进行类型转换,这种转换也是系统自动进行的。具体转换原则如下:
1)float、double型赋值给int型:直接截断小数。
例如:int i=f+0.6; f的值4.0,右边算术表达式运算后的结果为一个值为4.6的double型数据,根据上述转换原则,直接舍弃小数,所以i的值为4。
2)int、char型赋值给float、double型:补足有效位以进行数据类型转换。
例如:float f=4; float为7位有效数字,所以f的值为4.000000。
3)char型(1字节)赋值给int型(2字节):数值赋给int的低8位,高8位补0。
4)long int型赋值给int型:long int截断低字节给int型。
5)int 型赋值给long int:赋给long int的低16位,如果int的最高位是0,则long int的高16位全为0;如果int的最高位是1,则long int的高8位全为1(称为“符号扩展”)。
6)unsigned int型赋值给int型:直接传送数值。
7)非unsigned数据型赋值给位数相同的unsigned 数据:直接传送数值 - 强制类型转换
除了以上的两种自动类型转换外,在C语言中,允许强制类型转换,将某一数据的数据类型转换为指定的另一种数据类型。强制转换是用强制转换运算符进行的,强制转换运算符为:(类型名),强制转换运算符组成的运算表达式的一般形式为:
(类型名)(表达式) - 例如:
(int)(x + y) //将x+y的值转换成整型,即取整数部分。
(float)x + y //将x转换成单精度型。
- 强制转换运算符优先级比算术运算符高。同表达式中数据类型的自动转换一样,强制类型转换也是临时转换,对原运算对象的类型没有影响。
- 例如,已知有变量定义:int b=7;float a=2.5,c=4.7;求下面算术表达式的值。
a+(int)(b/3*(int)(a+c)/2.0)%4; - 根据运算符结合性规则,上述表达式要自左之右执行,b/3为2,2*int(a+c)为14,14/2.0为7.0,强制类型转换后为7,7%4为3;a的值2.5与3相加,最终结果为5.5。
实习代码
# include <stdio.h>
# include <stdlib.h>
int main(int argc,char**argv)
{
unsigned int right = 1;
char left = -1;
if(left < right)
printf("%d<%d\n",left,right);
else if(left == right)
printf("%d=%d\n",left,right);
else
printf("%d>%d\n",left,right);
system("PAUSE");
return 0;
}
实习结果
实习九 什么是ASCII码
实习代码
#include <stdio.h>
int main(void)
{
char ch='b';
printf("%d\n",ch);
return 0;
}
实习九结果
实习十 基本的输入与输出
- int scanf(const char *format, arg_list)
- scanf主要从标准输入流中获取参数值,format为指定的参数格式及参数类型,如scanf("%s,%d",str,icount);它要求在标准输入流中输入类似"son of bitch,1000"这样的字符串,同时程序会将"son of bitch"给str,1000给icount.
- scanf函数的返回值为int值,即成功赋值的个数,在上例中如果函数调用成功,则会返回2,所以我们在写程序时,可以通过
- 语句if(scanf("%s,%d",str,icount) != 2){...}来判断用户输入是否正确.
int printf(const char format, arg_list) - printf主要是将格式化字符串输出到标准输出流中,在stdio.h头文件中定义了标准的输入和输出,分别是stdin,stdout.
arg_list可以是变量名,也可以是表达式,但最终都会以值的形式填充进format中.
int getc(FILE \fp) - getc主要是从文件中读出一个字符.常用的判断文件是否读取结束的语句为:(ch = getc(fp)) != EOF.EOF为文件结束标志,定义在stdio.h中,就像EXIT_SUCCESS,EXIT_FAILURE定义在stdlib.h中一样,文件也可以被理解为一种流,所以当fp为stdin时,getc(stdin) 就等同于getchar()了.
- int putc(int ch,FILE *fp)
- putc主要是把字符ch写到文件fp中去.如果fp为stdout,则putc就等同于putchar()了.
- int getchar(void)
- getchar主要是从标准输入流读取一个字符.默认的标准输入流即stdio.h中定义的stdin.但是从输入流中读取字符时又涉及到缓冲的问题,所以并不是在屏幕中敲上一个字符程序就会运行,一般是通过在屏幕上敲上回车键,然后将回车前的字符串放在缓冲区中,getchar就是在 缓冲区中一个一个的读字符.当然也可以在while循环中指定终止字符,如下面的语句:
- while ((c = getchar()) != '#')这是以#来结束的.
int putchar(int ch) - putchar(ch)主要是把字符ch写到标准流stdout中去.
char gets(char \str) - gets主要是从标准输入流读取字符串并回显,读到换行符时退出,并会将换行符省去.
int puts(char *str) - puts主要是把字符串str写到标准流stdout中去,并会在输出到最后时添加一个换行符.
char fgets(char \str, int num, FILE *fp) - str是存放读入的字符数组指针,num是最大允许的读入字符数,fp是文件指针.fgets的功能是读一行字符,该行的字符数不大于num-1.因为fgets函数会在末尾加上一个空字符以构成一个字符串.另外fgets在读取到换行符后不会将其省略.
int fputs(char *str, file fp) - fputs将str写入fp.fputs与puts的不同之处是fputs在打印时并不添加换行符.
int fgetc(FILE \fp) - fgetc从fp的当前位置读取一个字符.
int fputc(int ch, file *fp) - fputc是将ch写入fp当前指定位置.
int fscanf(FILE *fp, char *format,...) - fscanf按照指定格式从文件中出读出数据,并赋值到参数列表中.
int fprintf(FILE *fp, char *format,...) - fprintf将格式化数据写入流式文件中.
实习代码
#include<stdio.h>
int main(void)
{
char a,b,c; //定义字符变量a,b,c
a=getchar(); //从键盘输入一个字符,送给字符变量a
b=getchar(); //从键盘输入一个字符,送给字符变量b
c=getchar(); //从键盘输入一个字符,送给字符变量c
putchar(a); //将变量a的值输出
putchar(b); //将变量b的值输出
putchar(c); //将变量c的值输出
putchar('\n'); //换行
return 0;
}
实习十结果
实习十一 除法与取余运算符
- 除法/的运算结果和运算对象的数据类型有关,两个数都是int,则商就是int,若商有小数,则截取小数部分;被除数和除数中只要有一个或者两个都是浮点型数据,则商也是浮点型,不截取小数部分。
- 如:
16/53 16/5.03.20000 -13/4-4
-13/-34 3/50 5/31 - 最典型的例题就是求s=1+1/2+1/3+4/1+1/5+……+1/100的值
- 取余%的运算符对象必须是整数,结果是整除后的余数,其余数的符号与被除数相同
- 如:
13%3-1 13%-31 -13%3-1
-13%23-13 3%5==3
实习代码
# include <stdio.h>
#include <stdlib.h>
int main(void)
{
int a,b;
float c;
printf("input a integer number a=");
scanf("%d",&a);
printf("\ninput a integer number b=");
scanf("%d",&b);
printf("\ninput a floating number c=");
scanf("%d",&c);
printf("\nthe results: a/b=%d a/c=%f a(mod)b=%d\n",a/b,a/c,a%b);
system("pause");
return 0;
}
实习十一结果
实习十二 流程控制
- 1.什么是流程控制
程序代码的执行顺序 - 2.流程控制的分类
顺序执行
选择执行
定义:
某些代码可能执行,也可能不执行,有选择的执行某些代码
分类: - If
1.if最简单的用法
格式:
if(表达式)
语句
功能:如果表达式为真,执行语句
如果表达式为假,语句不执行
2.if的范围问题
(1) if(表达式)
语句A;
语句B;
解释:if默认的只能控制一个语句的执行
if无法控制语句B的执行或不执行
(2)if(表达式)
{
语句A;
语句B;
}
此时if可以控制语句A和语句B
由此可见:if默认只能控制一个语句的执行或不执行
如果想控制多个语句的执行或不执行就必须把这些语句用{}括气来
3.if..else...的用法
4.if..else if..else...的用法
例子:
if (1)
printf ("A");
else if (2)
printf ("B");
else if (3)
printf ("C");
else
printf("D");
如果写为:
if (1)
printf("A");
printf("H");//在这句出错
else if .. //原因else没有对应的if.
5.c语言对真假的处理
非零是真
零就是假
真用1表示
假用0表示
6.if举例--求分数的等级
7.if的常见问题解析
1.空语句问题
if (3 > 2);
等价于
if (3 > 2)
//这就是空语句 - switch
循环执行
定义:
某些代码会被重复执行
分类 - for
1.格式:
for (1; 2; 3)
语句A;
2.执行的流程
单个for循环的使用
多个for循环的嵌套使用
for(1; 2; 3)
for(4; 5; 6)
A;
B;
3.范围
4.举例:
1+2+3+4+...+100
1+1/2+1/3+...+1/100 - while
do...while
break和continue
实习代码
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a=3,b=2,c=1;
system("cls");
printf("[1]:%d,%d,%d\n",a,b,c);
{
int b=5;
int c=12;
printf("[2]:%d,%d,%d\n",a,b,c);
}
printf("[3]:%d,%d,%d\n",a,b,c);
getchar();
return 0;
}
实习十二结果
实习十三 if概述
- If语句的第一种形式
语法格式为:if(表达式)
语句1;
语句2;
NS图表示如下:
|-----------|
| 表达式 |
|-----|-----|
| 真 | 假 |
|-----|-----|
|语句1| |
|-----------|
| 语句2 |
|-----------|
语句解释:对表达式进行判断,结果为真(非0)时则执行语句1,若为假(为0)则退出if语句,继续执行if后的语句2。
补充:1、表达十可以使用关系表达式,也可以使用逻辑表达式或算术表达式。
2、语句1可以是单个语句,也可以是复合语句。
3、语句1可以跟在表达式后,中间用空格分开。
- If语句的第二种形式
语法格式为:if(表达式)
语句1;
else
语句2;
语句3;
NS图表示如下:
|------------|
| 表达式 |
|------|-----|
| 真 | 假 |
|------|-----|
|语句1 |语句2|
|------------|
| 语句3 |
|------------|
语句解释:对表达式1进行判断,结果为真(非0)时则执行语句1,若为假(为0)则执行语句2,完成执行后退出if并执行if后的语句3。
- If语句的第三种形式
语法格式为:if(表达式1)
语句1;
else if(表达式2)
语句2;
else
语句3;
语句4;
NS图表示如下:
|-----------------|
| 表达式1 |
|-----------------|
|真 | 假 |
|---- |-----------|
|语句1| 表达式2 |
| |-----------|
| |真 | 假 |
| |-----|-----|
| |语句2|语句3|
|-----|-----|-----|
| 语句4 |
|-----------------|
语句解释:对表达式1进行判断,结果为真(非0)时则执行语句1,若为假(为0)则进行表达式2的判断,表达式2判断为真(非0)则执行语句2,若为假(为0)则执行语句3。完成所有表 达式判断并进行最后一次执行后则退出if,执行if后的语句4。
补充:无数的表达式可以继续判断下去,最后执行的语句n可以为空,表示最后一个表达式判断为假时则退出if。 - If语句的嵌套
语法格式为:if (表达式1)
| if(表达式2)
| | 语句1;
| else
| | 语句2;
else
| if(表达式3)
| | 语句3;
| else
| | 语句4;
语句5;
语句解释:对表达式1进行判断,结果为真时则执行嵌套if语句,若为假则执行下一个嵌套的if语句。完成最后一次执行后则退出if,执行if后的语句5。
实习代码
#include<stdio.h>
int main()
{
int iSignal; //定义变量表示信号灯的状态
printf("the Red Light is 0,the Green Light is 1\n");//输出提示信息
scanf("%d",&iSignal); //输入iSignal变量
if(iSignal==1) //使用if语句进行判断
{
printf("the Light is green,cars can run\n"); //判断结果为真是输出
}
return 0;
}
实习十三结果
实习十四 C语言常见误区
- 1.书写标识符时,忽略了大小写字母的区别。
main()
{
int a=5;
printf("%d",A);
}
编译程序把a和A认为是两个不同的变量名,而显示出错信息。C认为大写字母和小写字母是两个不同的字符。习惯上,符号常量名用大写,变量名用小写表示,以增加可读性。 - 2.忽略了变量的类型,进行了不合法的运算。
main()
{
float a,b;
printf("%d",a%b);
}
%是求余运算,得到a/b的整余数。整型变量a和b可以进行求余运算,而实型变量不允许进行“求余”运算。 - 3.将字符常量与字符串常量混淆。
char c;
c="a";
在这里就混淆了字符常量与字符串常量,字符常量是由一对单引号括起来的单个字符,字符串常量是一对双引号括起来的字符序列。C规定以“\”作字符串结束标志,它是由系统自动加上的,所以字符串“a”实际上包含两个字符:‘a'和‘',而把它赋给一个字符变量是不行的。 - 4.忽略了“=”与“”的区别。
在许多高级语言中,用“=”符号作为关系运算符“等于”。如在BASIC程序中可以写if (a=3) then …但C语言中,“=”是赋值运算符,“”是关系运算符。如:
if (a==3) a=b;前者是进行比较,a是否和3相等,后者表示如果a和3相等,把b值赋给a。由于习惯问题,初学者往往会犯这样的错误。 - 5.忘记加分号。
- 6.多加分号。
- 7.输入变量时忘记加地址运算符“&”。
int a,b;
scanf("%d%d",a,b);
这是不合法的。Scanf函数的作用是:按照a、b在内存的地址将a、b的值存进去。“&a”指a在内存中的地址。 - 8.输入数据的方式与要求不符。
①scanf("%d%d",&a,&b);输入时,不能用逗号作两个数据间的分隔符,如下面输入不合法:3,4输入数据时,在两个数据之间以一个或多个空格间隔,也可用回车键,跳格键tab。
②scanf("%d,%d",&a,&b);C规定:如果在“格式控制”字符串中除了格式说明以外还有其它字符,则在输入数据时应输入与这些字符相同的字符。下面输入是合法的:
3,4此时不用逗号而用空格或其它字符是不对的。
3 4 3:4
又如:scanf("a=%d,b=%d",&a,&b);输入应如以下形式:a=3,b=4 - 9.输入字符的格式与要求不一致。
在用“%c”格式输入字符时,“空格字符”和“转义字符”都作为有效字符输入。
scanf("%c%c%c",&c1,&c2,&c3);如输入a b c字符“a”送给c1,字符“ ”送给c2,字符“b”送给c3,因为%c只要求读入一个字符,后面不需要用空格作为两个字符的间隔。 - 10.输入输出的数据类型与所用格式说明符不一致。
例如,a已定义为整型,b定义为实型,a=3;b=4.5;printf("%f%d\n",a,b);编译时不给出出错信息,但运行结果将与原意不符。这种错误尤其需要注意。 - 11.输入数据时,企图规定精度。scanf("%7.2f",&a);这样做是不合法的,输入数据时不能规定精度。
- 12.switch语句中漏写break语句。
例如:根据考试成绩的等级打印出百分制数段。
switch(grade)
{ case 'A':printf("85~100\n");
case 'B':printf("70~84\n");
case 'C':printf("60~69\n");
case 'D':printf("<60\n");
default:printf("error\n");
由于漏写了break语句,case只起标号的作用,而不起判断作用。因此,当grade值为A时,printf函数在执行完第一个语句后接着执行第二、三、四、五个printf函数语句。正确写法应在每个分支后再加上“break;”。例如case 'A':printf("85~100\n");break; - 13.忽视了while和do-while语句在细节上的区别。因为while循环是先判断后执行,而do-while循环是先执行后判断。
- 14.定义数组时误用变量。
int n;
scanf("%d",&n);
int a[n];
数组名后用方括号括起来的是常量表达式,可以包括常量和符号常量。即C不允许对数组的大小作动态定义。 - 15.在定义数组时,将定义的“元素个数”误认为是可使的最大下标值。
main()
{static int a[10]={1,2,3,4,5,6,7,8,9,10};
printf("%d",a[10]);
}
C语言规定:定义时用a[10],表示a数组有10个元素。其下标值由0开始,所以数组元素a[10]是不存在的。 - 16.在不应加地址运算符&的位置加了地址运算符。scanf("%s",&str);C语言编译系统对数组名的处理是:数组名代表该数组的起始地址,且scanf函数中的输入项是字符数组名,不必要再加地址符&。应改为:scanf("%s",str);
- 17.同时定义了形参和函数中的局部变量。
int max(x,y)
int x,y,z;
{
z=x>y?x:y;
return(z);
}
形参应该在函数体外定义,而局部变量应该在函数体内定义。应改为:
int max(x,y)
int x,y;
{
int z;
z=x>y?x:y;
return(z);
}
实习代码
# include<stdio.h>
int main() //主函数main中
{
int iNumber1=1; //在第1个iNumber1定义位置
printf("%d\n",iNumber1); //输出变量值
if(iNumber1>0)
{
int iNumber1=2; //在第2个iNumber1定义位置
printf("%d\n",iNumber1);//输出变量值
if(iNumber1>0)
{
int iNumber1=3; //在第3个iNumber1定义位置
printf("%d\n",iNumber1);//输出变量值
}
printf("%d\n",iNumber1);//输出变量值
}
printf("%d\n",iNumber1); //输出变量值
return 0;
}
实习十四结果
实习十五 循环概述
- C语言循环控制语句提供了 while语句、do-while语句和for语句来实现循环结构。
- while循环语句
一般形式如下:
while(表达式)
语句 - do-while语句
一般形式如下: - do语句while(表达式);
do-while循环是先执行语句,然后对表达式求值。若值为真,则再次执行语句,如此反复执行,否则将结束循环。语句可以是简单语句,也可以是复合语句。 - for语句
for语句是循环控制结构中使用最广泛的一种循环控制语句,特别适合已知循环次数的情况。 - 一般形式如下:
for ( [表达式 1]; [表达式 2 ]; [表达式3] )语句 - 其中:
表达式1:一般为赋值表达式,给控制变量赋初值;
表达式2:关系表达式或逻辑表达式,循环控制条件;
表达式3:一般为赋值表达式,给控制变量增量或减量;
语句:循环体,当有多条语句时,必须使用复合语句。
其执行过程如下:首先计算表达式1,然后计算表达式 2。若表达式2为真,则执行循环体;否则,退for循环,执行for循环后的语句。如果执行了循环体,则循环体每执行一次,都计算表达式3,然后重新计算表达式2,依此循环,直至表达式 2的值为假,退出循环。 - for语句的三个表达式都是可以省略的,但分号“;”绝对不能省略。for语句有以下几种格式:
(1)for(; 😉 语句;
(2)for(;表达式2;表达式3 ) 语句;
(3)for(表达式1;表达式2;) 语句;
(4)for(i=1,j = n; i < j; i ++,j - - ) 语句; - 三种语句比较
同一个问题,往往既可以用 while语句解决,也可以用 do-while或者for语句来解决,但在实际应用中,应根据具体情况来选用不同的循环语句。选用的一般原则是:
(1) 如果循环次数在执行循环体之前就已确定,一般用 for语句。如果循环次数是由循环体的执行情况确定的,一般用 while语句或者do- while语句。
(2) 当循环体至少执行一次时,用 do-while语句,反之,如果循环体可能一次也不执行,则选用while语句。
C++/C循环语句中,for语句使用频率最高,while语句其次,do语句很少用。
三种循环语句for、while、do-while可以互相嵌套自由组合。但要注意的是,各循环必须完整,相互之间绝不允许交叉。
其他循环语句 - 多重循环结构
在多重循环中,如果有可能,应当将最长的循环放在最内层,最短的循环放在最外层,以减少CPU跨越循环层的次数。
一个循环体内又包含另一个完整的循环结构
三种循环可互相嵌套,层数不限
外层循环可包含两个以上内循环,但不能相互交叉
实习代码
#include <stdio.h>
int main()
{
int iSum=0;
int iNumber=1;
while(iNumber<=100)
{
iSum=iSum+iNumber;
iNumber++;
}
printf("the result is: %d\n",iSum);
return 0;
}
实习十五结果
实习十六 while循环
- while循环的一般格式为
- while ( 条件 )
语句1
语句2
...
wend
如果条件为真(即式子的值是对的),就执行while和wend之间的循环体,执行之后返回while顶部,再次检查条件是否为真,如果为真则又继续执行循环体,为假则不执行循环体,跳到wend之后,接着执行wend之后的语句,结束循环。
-
while (a<101) h=h+a a=a+1 wend
-
在while循环中,特别要注意两个地方,一个是while后面的条件,一个是while和wend之间必须要有一个语句改变条件里某个变量的值,以避免出现循环不执行或一直执行不能停止的情况。在上面的例子里,a=a+1每执行一次,a的值增加1,a的值增加到一定的情况,就不会小于101,循环就停止了。如果少了a=a+1这一行,a的值将不会改变,循环将一直执行,不会停止。应注意避免这种情况出现。
实习代码
#include<stdio.h>
int main()
{
int i=1,sum=0; //定义变量i的初始值为1,sum的初始值为0
while(i<=100) //当i>100,条件表达式i<=100的值为假,不执行循环体
{ //循环体开始
sum=sum+i; //第一次累加后,sum的值为1
i++; //加完后,i的值加1,为下次累加做准备
} //循环体结束
printf("sum=%d\n",sum);//输出1+2+3+...+100的累加和
return 0;
}
实习十六结果
实习十七 for 和 while的比较
- int i =0;
for(i=0;i<10;i++)
{
printf("现在循环第"+i+"次");
} - 首先我们设置了一个整型(int)变量 i 这里要注意 变量的设置需要是标识量, 及开始的第一个字母必须是字母后者下划线,整个变量名里只能含有字母、数字、下划线,c语言里的关键字不能为变量名。
C语言32个关键字
auto :声明自动变量 一般不使用
double :声明双精度变量或函数
int: 声明整型变量或函数
struct:声明结构体变量或函数
break:跳出当前循环
else :条件语句否定分支(与 if 连用)
long :声明长整型变量或函数
switch :用于开关语句
case:开关语句分支
enum :声明枚举类型
register:声明积存器变量
typedef:用以给数据类型取别名(当然还有其他作用)
char :声明字符型变量或函数
extern:声明变量是在其他文件正声明(也可以看做是引用变量)
return :子程序返回语句(可以带参数,也看不带参数)
union:声明联合数据类型
const :声明只读变量
float:声明浮点型变量或函数
short :声明短整型变量或函数
unsigned:声明无符号类型变量或函数
continue:结束当前循环,开始下一轮循环
for:一种循环语句(可意会不可言传)
signed:生命有符号类型变量或函数
void :声明函数无返回值或无参数,声明无类型指针(基本上就这三个作用)
default:开关语句中的“其他”分支
goto:无条件跳转语句
sizeof:计算数据类型长度
volatile:说明变量在程序执行中可被隐含地改变
do :循环语句的循环体
while :循环语句的循环条件
static :声明静态变量
if:条件语句 - 然后使用for循环关键字 for循环的基本格式是
for(循环开始;循环结束条件;每次循环的累加)
{
//循环体
}
所以我们的循环就是把i的起始值设置为0; 当i<10的时候就继续循环,每次循环后i加一。那么本循环就执行了10次。printf("现在循环第"+i+"次"); 就是说在屏幕打印出循环的次数,不过我们的i值是0开始的所以第一次就是打印现在是第0次循环.
思考:1、在不改变i值的情况下怎样做才能实现打印出现在是第1次循环。
2、怎样才能实现换行 - while循环
int i=0
while(i<10)
{
printf("现在是第"+(i+1)+次打印\n");
i++;
} - 上面就是while循环,while括号里只填写开始条件,但是需要注意,循环体必须给定结束条件,否则就会进入死循环。
i++不能少
例题:兔子问题
实习代码
#include<stdio.h>
int main()
{
int f1=1,f2=1;
int i;
for (i=1;i<=20;i++) //每个循环中输出2个月的数据,故循环20次即可
{
printf ("%12ld%12ld",f1,f2); //输出已知的两个月的兔子数
if (i%2==0)
printf ("\n");
f1=f1+f2; //计算出下个月的兔子数,并存放在f1中
f2=f2+f1; //计算出下两个月的兔子数,并存放在f2中
}
return 0;
}
实习十七结果
实习十八 Do...while与while和for的比较
- (1)while语句和do...while语句,只在while后面指定循环条件,但是需要在循环体中包括使循环趋于结束的语句,而for语句则可以在迭代语句中包含使循环趋于结束的语句。
(2)用while语句和do...while语句时,对循环变量的初始化操作应该放在while语句和do...while语句之前,而for语句则可以在初始化语句中完成。
(3)while语句和do...while语句实现的功能相同,唯一的区别就是do…while语句先执行后判断,无论表达式的值是否为true,都将执行一次循环;而while语句则是首先判断表达式的值是否为true,如果为true则执行循环语句;否则将不执行循环语句。
(4)for循环语句一般用在对于循环次数已知的情况下,而while语句和do...while语句则一般用在对于循环次数不确定的情况下 - 1、while语句
while关键字的中文意思是“当……的时候”,也就是当条件成立时循环执行对应的代码。while语句是循环语句中基本的结构,语法格式比较简单。 - 2、do-while语句
do-while语句由关键字do和while组成,是循环语句中最典型的“先循环再判断”的流程控制结构,这个和其它2个循环语句都不相同。 - 3、for语句
for关键字的意思是“当…的时候”,是实际开发中比较常用的循环语句,其语法格式相对于前面的循环语句来说稍显复杂,但是在熟悉以后,将会发现其语法安排的比较条理,把循环控制和循环体很清晰的分开
实习代码
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i,sum=0;
printf("please enter i,i=?");
scanf("%d",&i);
do
{
sum=sum+i;
i++;
}
while(i<=100);
printf("sum=%d\n",sum);
system("PAUSE");
return 0;
}
实习十八结果
实习十九 Switch简介
- C语言还提供了另一种用于多分支选择的switch语句, 其一般形式为:
switch(表达式){
case常量表达式1: 语句1;
case常量表达式2: 语句2;
…
case常量表达式n: 语句n;
default:语句n+1;
} - 其语义是:计算表达式的值。 并逐个与其后的常量表达式值相比较,当表达式的值与某个常量表达式的值相等时, 即执行其后的语句,然后不再进行判断,继续执行后面所有case后的语句。如表达式的值与所有case后的常量表达式均不相同时,则执行default后的语句。
main(){
int a;
printf("input integer number: ");
scanf("%d",&a);
switch (a){
case 1:printf("Monday\n");
case 2:printf("Tuesday\n");
case 3:printf("Wednesday\n");
case 4:printf("Thursday\n");
case 5:printf("Friday\n");
case 6:printf("Saturday\n");
case 7:printf("Sunday\n");
default:printf("error\n");
}
} - 本程序是要求输入一个数字,输出一个英文单词。但是当输入3之后,却执行了case3以及以后的所有语句,输出了Wednesday 及以后的所有单词。这当然是不希望的。为什么会出现这种情况呢?这恰恰反应了switch语句的一个特点。在switch语句中,“case 常量表达式”只相当于一个语句标号, 表达式的值和某标号相等则转向该标号执行,但不能在执行完该标号的语句后自动跳出整个switch 语句,所以出现了继续执行所有后面case语句的情况。 这是与前面介绍的if语句完全不同的,应特别注意。
实习代码
#include <stdio.h>
int main ()
{
char grade;
scanf("%c",&grade);
printf("Your corce:");
switch(grade)
{
case 'A':printf("85-100\n");break;
case 'B':printf("70-84\n");break;
case 'C':printf("60-69\n");break;
case 'D':printf("60\n");break;
default:printf("enter data error!\n");
}
return 0;
}
实习十九结果
实习二十 Break用法
- break语句
- break语句通常用在循环语句和开关语句中。当break用于开关语句switch中时,可使程序跳出switch而执行switch以后的语句;如果没有break语句,则将成为一个死循环而无法退出。break在switch 中的用法已在前面介绍开关语句时的例子中碰到,这里不再举例。
- 当break语句用于do-while、for、while循环语句中时,可使程序终止循环而执行循环后面的语句, 通常break语句总是与if语句联在一起。即满足条件时便跳出循环。
- 注意:
1)break语句对if-else的条件语句不起作用。
2)在多层循环中, 一个break语句只向外跳一层。 - break语句通常用在循环语句和开关语句中。当break用于开关语句switch中时,可使程序跳出switch而执行switch以后的语句;如果没有break语句,则将成为一个死循环而无法退出。break在switch 中的用法已在前面介绍开关语句时的例子中碰到,这里不再举例。
- 当break语句用于do-while、for、while循环语句中时,可使程序终止循环而执行循环后面的语句, 通常break语句总是与if语句联在一起。即满足条件时便跳出循环。
main()
{
int i=0;
char c;
while(1) /设置循环/
{
c='\0'; /变量赋初值/
while(c!=13&&c!=27) /键盘接收字符直到按回车或Esc键/
{
c=getch();
printf("%c\n", c);
}
if(c==27)
break; /判断若按Esc键则退出循环/
i++;
printf("The No. is %d\n", i);
}
printf("The end");
} - 注意:
break语句对if-else的条件语句不起作用。
在多层循环中, 一个break语句只向外跳一层。 - 例题:在全系1000学生中,征集慈善募捐,当总数达到10万元时就结束,统计此时捐款的人数,以及平均每人的数目
- 编程思路:
- 显然应该用循环来处理。实际循环的次数事先不能确定,可以设为最大值,即1000,在循环体中累计捐款总数,并用if语句检查是否达到10万元,如果达到就不再继续执行循环,终止累加并计算人均捐款数。在程序中定义变量amount,用来存放捐款数,变量total,用来存放累加后的总捐款数,变量aver,用来存放人均捐款数,以上3个变量均为单精度浮点型。定义整型变量i作为循环变量。定衣符号常量SUM代表100000.
实习代码
#include <stdio.h>
#define SUM 100000
int main()
{
float amount,aver,total;
int i;
for(i=1,total=0;i<=1000;i++)
{
printf("please enter amount:");
scanf("%f",&amount);
total=total+amount;
if(total>=SUM) break;
}
aver=total/i;
printf("num=%ld\n aver=10.2f\n",i,aver);
return 0;
}
实习二十结果
实习二十一 数组
- 1、数组的概念、定义和使用
数组(array)是C语言中用于组合同类型数据对象的机制。一个数组里汇集一批对象(数组元素)。程序中既能从数组出发处理其中的个别元素,也能以统一方式处理数组的一批元素或所有元素。后一处理方式特别重要,是由一批成员构成的数组和一批独立命名的变量间的主要区别。数组机制要解决三个问题:)描述数组的性质,定义数组变量; )使用数组,包括通过数组变量使用元素; )实现数组,即在内存里为数组安排一种存储方式,使程序里可以方便地操作它们。当然,最后一个问题主要与语言的实现有关系,在实现C语言系统时,必须确定如何实现数组变量。了解这方面情况也有利于在编程时正确使用数组。 - 2、数组变量定义
根据数组的性质,在定义数组变量(下面简单说成 “定义数组”)需要说明两个问题: )该数组(变量)的元素是什么类型的; )这个数组里包含多少个元素。C语言规定,每个数组变量的大小是固定的,需要在定义时说明。数组定义的形式与简单变量类似,但需要增加有关元素个数的信息。在被定义变量名之后写一对方括号就是一个数组定义,指定元素个数的方式是在括号里写一个整型表达式。人们常把数组元素类型看作数组的类型,把元素类型为整型的数组说成是整型数组,类似地说双精度数组等。本书下面也采用这种说法。
例如,下面的描述定义了两个数组:
int a[ 0];
double a [ 00];
定义了一个包含有 0个元素的整型数组a和一个 00个元素的双精度数组a 。数组元素个数也称为数组的大小或数组的长度。数组定义可以与其他变量的定义写在一起,例如可以写:
int a [ ], n, a [ ], m;
数组变量也是变量,数组定义可以出现在任何能定义简单变量的地方。数组变量也是变量,在作用域和存在期方面与简单变量没有差别。根据定义位置不同,数组也分为外部数组和函数内的局部数组,包括函数内的静态数组(用关键字static)和普通的自动数组,定义方式(及位置)决定了它们的作用域与存在期。
可以写出数组的外部说明。C语言规定,在写数组变量的外部说明时不必写数组大小,只要在数组变量名后写一对方括号。例如下面是两个数组的外部说明:
extern int a[];
extern double a [];
这两个说明通知本源文件的其他部分,有两个数组(a和a )在其他地方定义,它们的元素类型分别是整型和双精度类型。数组元素个数必须能在编译时静态确定,因此这个表达式必须能静态求值,最简单的情况就是写一个整型字面量(整数)。根据这个规定,下面数组定义不合法
void f(int m, int n) {
int b[n];
....
}
此时局部数组b的大小依赖于函数的参数值,这个值在编译时无法确定。 - 3、数组的使用
使用数组的最基本操作是元素访问,对数组的使用最终都通过对元素的使用而实现。数组元素在数组里顺序排列编号,首元素的编号规定为0,其他元素顺序编号。这样,n个元素的数组的元素编号范围是0到n-1 。如果程序里定义了数组:
int b[ ];
b的元素将依次编号为0、 、 、 。数组元素的编号也称为元素的下标或指标。
数组元素访问通过数组名和表示下标的表达式进行,用下标运算符[]描述。下标运算符[]是C语言里优先级最高的运算符之一,它的两个运算对象的书写形式比较特殊:一个运算对象写在方括号前面,应表示一个数组(简单情况是数组名);另一个应该是整型表达式,写在括号里面表示元素下标。元素访问是一种基本表达式,写在表达式里的b[ ]就是一个下标表达式,表示访问数组b中编号为 的元素,即上面定义的数组b的最后元素。
实习代码
#include <stdio.h>
int main()
{
int a[3][4]={{1,2,3,4},{9,8,7,6},{-10,10,-5,2}};
int i,j,row=0,colum=0,max;
max=a[0][0];
printf("array a:\n");
for(i=0;i<=2;i++)
for(j=0;j<=3;j++)
if(a[i][j]>max)
{
max=a[i][j];
row=i;
colum=j;
}
printf("max=%d\nrow=%d\n",max,row,colum);
return 0;
}
实习二十一结果
实习二十二 函数
- 一、无参函数的定义形式
类型标识符 函数名()
{
声明部分
语句
}
其中类型标识符和函数名称为函数头。类型标识符指明了本函数的类型,函数的类型实际上是函数返回值的类型。该类型标识符与前面介绍的各种说明符相同。函数名是由用户定义的标识符,函数名后有一个空括号,其中无参数,但括号不可少。
{}中的内容称为函数体。在函数体中声明部分,是对函数体内部所用到的变量的类型说明。
在很多情况下都不要求无参函数有返回值,此时函数类型符可以写为void。
我们可以改写一个函数定义:
void Hello()
{
printf ("Hello,world \n");
}
这里,只把main改为Hello作为函数名,其余不变。Hello函数是一个无参函数,当被其它函数调用时,输出Hello world字符串。 - 二、有参函数定义的一般形式
类型标识符 函数名(形式参数表列)
{
声明部分
语句
}
有参函数比无参函数多了一个内容,即形式参数表列。在形参表中给出的参数称为形式参数,它们可以是各种类型的变量,各参数之间用逗号间隔。在进行函数调用时,主调函数将赋予这些形式参数实际的值。形参既然是变量,必须在形参表中给出形参的类型说明。
例如,定义一个函数,用于求两个数中的大数,可写为:
int max(int a, int b)
{
if (a>b) return a;
else return b;
}
第一行说明max函数是一个整型函数,其返回的函数值是一个整数。形参为a,b,均为整型量。a,b的具体值是由主调函数在调用时传送过来的。在{}中的函数体内,除形参外没有使用其它变量,因此只有语句而没有声明部分。在max函数体中的return语句是把a(或b)的值作为函数的值返回给主调函数。有返回值函数中至少应有一个return语句。
在C程序中,一个函数的定义可以放在任意位置,既可放在主函数main之前,也可放在main之后。
实习代码
#include<stdio.h>
int main()
{ void print_star(); //声明print_star 函数
void print_message(); //声明print_message函数
print_star(); //调用print_star 函数
print_message(); //调用print_message函数
print_star(); //调用print_star 函数
return 0;
}
void print_star() //定义print_star函数
{
printf("*************\n"); //输出一行*号
}
void print_message() //定义print_message函数
{
printf("How do you do!\n"); //输出一行文字信息
}
实习二十二结果
实习二十三 指针
- 1.定义方法
形式:
类型标识符变量标识符;
定义存放指定类型数据地址的指针变量。
类型标识符是定义指针的基类型,给出指针数据对应存储单元所存放的数据的类型,一般用“指向”这个词来说明这种关系,即类型标识符给出指针所指向的数据类型,可以是简单类型,也可以是复杂类型。用“”表示定义的是指针变量,不是普通变量。变量标识符给出的是指针变量名。
例如:
(1)Int p1,p2,p3;
定义指向整型数据的指针变量p1、p2、p3。
(2)float q1,q2,q3;
定义指向实型数据的指针变量q1、q2、q3。
(3)charr1,r2,r3;
定义指向字符型数据的指针变量r1、r2、r3。
(4)struct date
{int year;
int month;
int day;
}t1, *t2, *t3;
定义指向struct date类型数据的指针变量t1、t2、t3。 - 2.指针变量所指向的变量特定类型的数据
定义的指针变量用于存放指向类型数据的地址,我们可以通过指针运算“”,引用指针变量所指向的数据。有关内容我们在指针运算中加以介绍。
例如,对指针变量p1、p2、p3,假定已有值,\p1、p2、p3代表指针变量p1、p2、p3所指向的数据,也就是p1、p2、p3的值对应的存储单元里存放的数据,称为指针变量所指向的变量,简称指针指向变量。
指针类型也是一种复杂类型,指针指向变量可以认为是指针数据的分量。指针指向变量相当于基类型变量。
如果指针变量p1、p2、p3分别存放整型变量i、j、k的地址,则p1指向i,p2指向j,p3指向k。
实习代码
#include<stdio.h>
int main()
{ int a=100,b=10; //定义整型变量a,b,并初始化
int * pointer_1,* pointer_2; //定义指向整型数据的指针变量pointer_1,pointer_2
pointer_1=&a; //把变量a的地址赋给指针变量pointer_1
pointer_2=&b; //把变量b的地址赋给指针变量pointer_2
printf("a=%d,b=%d\n",a,b); //输出变量a和b的值
printf("* pointer_1=%d,* pointer_2=%d\n",* pointer_1,* pointer_2); //输出变量a和b的值
return 0;
}
实习二十三结果
实习二十四 文件的输入与输出
- C语言是通过将一个文件类型指针与文件关联起来来对文件进行打开、关闭、输入、输出。
文件类型为FILE(实际上是一个结构体)。定义一个文件指针为FILE fp;就可以将fp和某个文件关联起来进行操作了。例如要打开一个文件:
FILE \fp;fp=fopen("filename",“打开方式”);//fopen的返回值为NULL或指向文件的指针或者直接FILE *fp=("filename","打开方式");如果要重定向只需将指针fp和另一个文件关联。意思是可用一个文件指针操作多个文件。
文件使用完后要及时关闭。这是个好习惯。关闭函数为fclose(fp);这样fp就不在和之前指向的文件关联了。 - 1.判断文件是否打开成功: www.2cto.com
判断文件是否打开成功可用fopen的返回值if((fp=fopen("filename","r"))==NULL)则打开失败。 - 2.判断文件是否结束:
判断ASCII文件是否结束fgetc()会返回结束标志EOF(即-1)由于二进制文件数据会出现-1所以必须用函数feof(fp)判断,feof(fp)==1则已结束。 - 3.单个字符的输入输出:fgetc()和fputc()
ch=fgetc(fp);fp为文件指针,且fgetc()不会忽略空格和回车符,只能用于读入字符。相应的fputc(ch,fp);向文件输出字符时也不会忽略空格,回车符因为fgetc()返回字符所以fgetc()和fputc()通常嵌套使用:fputc(fgetc(in),out)。
fputc()的返回值为输入的字符或EOF(-1)(失败的情况下)
fgetc()的返回值为读入的字符(包括文件结束标志EOF(-1)) - 4.数据块的输入输出:
fread(buff,size,count,fp)和发fwrite(buffer,size,count,fp)buffer是一个指针,对于fread,它是读入数据的存放地址,对于发fwrite它是要输出数据的地址,size是指要读写的字节数,count是要进行读写多少个size字节的数据项。
如果成功fread和fwrite都返回成功输入和读取的数据块个数有可能比count小;
注意:fread参数buffer指向的空间必须大于或等于要读入的数据块大小。
fread和fwrite一般用于二进制文件的输入输出。用于ASCII文件字符发生转换的情况下可能出现与原设想的情况不同。 - 5.putw()和getw()用来对磁盘文件读写一个整数。
例如putw(10,fp);//返回值为输出的数字(int)
int i=getw(fp);//失败则返回-1
但注意putw()和getw()都是按二进制输入输出的。
所以如果你用putw()输入数据到文件后以文本的方式打开看到的将都是乱码。
同样如果你在文本文件中输入了数字并保存,用getw()来读入的话读入的结果并不是你想象的那样。因为它是按二进制读的。
实习代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
FILE * fp;
char str[3][10],temp[10];
int i,j,k,n=3;
printf("Enter strings :\n");
for(i=0;i<n;i++)
gets(str[i]);
for(i=0;i<n-1;i++)
{
k=1;
for(j=i+1;j<n;j++)
if(strcmp(str[k],str[j])>0)
k=j;
if(k!=j)
{
strcpy(temp,str[i]);
strcpy(str[i],str[k]);
strcpy(str[k],temp);
}
if((fp=fopen("D:\\CC\\string.dat","w+"))==NULL)
{
printf("can not open file!\n");
exit(0);
}
printf("\nThe new sequence :\n");
for(i=0;i<n;i++)
{
fputs(str[i],fp);
fputs("\n",fp);
printf("%s\n",str[i]);
}
}
return 0;
}
实习二十四结果
实习二十五 用户自己建立数据类型
- 结构(struct)
结构是由基本数据类型构成的、并用一个标识符来命名的各种变量的组合。
结构中可以使用不同的数据类型。 - 1.结构说明和结构变量定义
在Turbo C中,结构也是一种数据类型,可以使用结构变量,因此,象其它类型的变量一样,在使用结构变量时要先对其定义。
定义结构变量的一般格式为:
struct 结构名
{
类型 变量名;
类型 变量名;
...
} 结构变量;
结构名是结构的标识符不是变量名。类型为第二节中所讲述的五种数据类型(整型、浮点型、字符型、指针型和无值型)。构成结构的每一个类型变量称为结构成员,它象数组的元素一样,但数组中元素是以下标来访问的,而结构是按变量名字来访问成员的。
下面举一个例子来说明怎样定义结构变量。
struct string
{
char name[8];
int age;
char sex[2];
char depart[20];
float wage1, wage2, wage3, wage4, wage5;
} person;
这个例子定义了一个结构名为string的结构变量person, 如果省略变量person, 则变成对结构的说明。用已说明的结构名也可定义结构变量。这样定义时上例变成:
struct string
{
char name[8];
int age;
char sex[2];
char depart[20];
float wage1, wage2, wage3, wage4, wage5;
};
struct string person;
如果需要定义多个具有相同形式的结构变量时用这种方法比较方便, 它先作结构说明, 再用结构名来定义变量。
例如:
struct string Tianyr, Liuqi, ...;
如果省略结构名, 则称之为无名结构, 这种情况常常出现在函数内部, 用这种结构时前面的例子变成:
struct
{
char name[8];
int age;
char sex[2];
char depart[20];
float wage1, wage2, wage3, wage4, wage5;
} Tianyr, Liuqi; - 2.结构变量的使用
结构是一个新的数据类型, 因此结构变量也可以象其它类型的变量一样赋值、运算,不同的是结构变量以成员作为基本变量。
结构成员的表示方式为:结构变量.成员名如果将"结构变量.成员名"看成一个整体, 则这个整体的数据类型与结构中该成员的数据类型相同, 这样就可象前面所讲的变量那样使用。
实习代码
#include<string.h>
#include<stdio.h>
struct Person //声明结构体类型struct Person
{char name[20]; //候选人姓名
int count; //候选人得票数
}leader[3]={"Li",0,"Zhang",0,"Sun",0};//定义结构体数组并初始化
int main ()
{ int i,j;
char leader_name[20]; //定义字符数组
for(i=1;i<=10;i++)
{scanf("%s",leader_name); //输入所选的候选人姓名
for(j=0;j<3;j++)
if(strcmp(leader_name,leader[j].name)==0)leader[j].count++;
}
printf("\nResult:\n");
for(i=0;i<3;i++)
printf("%5s:%d\n",leader[i].name,leader[i].count);
return 0;
}
实习二十五结果
实习感想
- 本次实习内容我选择了之前自己不是很熟悉的C语言部分,通过这25个课时的学习,我对之前不太清楚地C语言知识有了补充,并且通过比较简单的25个代码来强化了这些知识,总体来说,收获蛮多。