目录
前言
这一系列文章所记录的是大一上学期学的一门名为《C语言程序设计》的实验内容,一共包括了八个实验,由于实验一是安装VC以及打印“hello,world”的基本操作,故没有放在这个系列里面,这些实验的代码部分参考与网上,仅供学习和参考~
知识纲要
注:粗体即为重要部分
1:C语言是大小写敏感的语言,C语言的基本单位是语句,分号是语句结束的标记;C语言具有丰富的数据类型:
2.常量和变量:在程序运行过程中,其值不能改变的量称为常量,其值可以被改变的量称为变量。
3.常量分为字面常量和符号常量:
- A:字面常量的书写格式:
- 整数:0开头为8进制,0X开头为16进制,其余数字开头为10进制
- 实数:只能用10进制,可以用不带指数和带指数两种书写方式,实型常量都是double类型;
- 字符:用单撇号定界,只能是单个字符,单撇号、反斜杠和控制字符要用“转义字符”,如:'A'、'\\'、'\''、'\n'等
- 字符串:用双撇号界定,可以包含0或多个字符,反斜杠、双撇号和控制字符要用“转义字符”,如:"Hello\n"
- 字符:用单撇号定界,只能是单个字符,单撇号、反斜杠和控制字符要用“转义字符”,如:'A'、'\\'、'\''、'\n'等
- 实数:只能用10进制,可以用不带指数和带指数两种书写方式,实型常量都是double类型;
- 整数:0开头为8进制,0X开头为16进制,其余数字开头为10进制
- B:符号常量要用宏定义预处理指令:如:#define PI 3.1415926
- 4.C语言是强类型的语言:变量使用前必须声明其属于哪一个类型,引用变量前必须给变量赋值,否则定义在函数中的自动变量的值是一个随机数;C语言所有变量的定义必须在执行语句前,开始执行语句后就不能再出现定义变量的语句(C++无此限制);
- 变量定义的语法格式为:
- 类型名 变量名[=初始值][,变量名[=初始值],…];
- 5.赋值运算:先计算等号右侧的表达式,将结果存在左侧变量分配的存储空间。一般形式:变量名=表达式;
- 注意:左侧只能是变量名,不能是表达式或常量。
- 6.运算符:学习运算符时应注意以下几点
- 运算符的功能:如加、减、乘、除等。
- 与运算量的关系:运算量的个数和运算量的类型
- 运算的优先级别:C语言运算符的优先级有15级
- 运算符的结合方向:单目、赋值、条件运算符是右结合
注意自加和自减运算符的前缀和后缀形式的差别:
前缀式:先增(或减)值后引用
后缀式:先引用后增(或减)值
如:若a=1;
执行:b = ++a; 后,b=2,a=2;
执行:b = a++; 后,b=1, a=2;
7.表达式:描述了对哪些数据,以什么顺序以及施以什么样的操作。它由运算符与运算量组成。运算量可以是常量、变量或函数。
几点需要注意的地方:
- 分式应写在一行:(a+b)/(c+d)
- 相乘必须用*: 2*a*b 不可以写成:2ab
- 有些运算要用函数:求绝对值、乘方、开方
8.两种特殊的表达式
- 赋值表达式:C语言中把用赋值号连结变量和表达式的式子称为赋值表达式。例如:a=3+5,赋值表达式的值就是被赋值后变量的值。如,表达式a=3+5的值是8。
- 逗号表达式:用逗号作为分隔符把几个表达式组合在一起,形成的复合型表达式称为逗号表达式。逗号表达式的值是这个复合表达式中最后一个表达式的值。如:a=6,a*3,a+3的值是a+3的值9。
9.不同类型数据间的转换:数据类型的转换有如下三种基本情况:
- 同一类型但长度不同的数据间的转换。
- 整型数据与实型数据之间的转换。
- 整型数中有符号格式与无符号格式之间的转换
10.数据提升与降格:
- 由低级的数据转换为高级的数据,称为数据提升。如:由短数据转换为长数据,由整数转换为浮点数。相反方向的转换称为降格。同一长度的整数带符号与不带符号的转换,属于同一级别。
- 11.隐式转换和显式转换(强制类型转换)
- 数据类型的隐式转换有以下情况:
- 运算转换: 在不同类型数据混合运算时,为使表达式中的各运算量具有共同的类型而进行的数据类型转换。char和short先转换为int,float转换为double;当一个运算符两端的运算量类型不一致时,按“向高看齐”的原则对“较低”的类型进行提升。注意:1/3结果是0而不是0.3333…。
- 赋值转换: 把一个表达式的值赋给与其类型不同的变量时。具有一定的强制性,不论表达式结果为何类型,都要转换为变量的类型,若不能转换则编译时会有错误。
- 函数调用转换:函数调用时,若实参与形参类型不一致时,将实参转换为形参的类型。(并不是任何类型间都可以自动转换,一般要求实参与形参类型应一致)。
- 强制类型转换:是将一个类型的变量强制转换为另一种类型,它的一般形式是:(类型标识符)表达式
- 注意:
- 显式转换实际上是一种单元(单目)运算符,必须用圆括号把类型标识符括起来,不要写成:int(3.6+5.5)的形式。
- 强制类型转换运算符的优先级别很高,一般要将需转换类型的表达式放在一对括号中。如:(int)(3.6+5.5) 与 (int)3.6+5.5 不同。
- 对一个变量进行显式转换后,得到一个新的类型的数据,但原来变量的类型和值不变
12.C语言是大小写敏感的语言,C语言的基本单位是语句,分号是语句结束的标记;
13.C语言的语句分为结构控制语句和表达式语句两大类,单独一个分号称为空语句,将多个语句放在一对花括号中构成一个复合语句(也称分程序);
14.C语言是强类型的语言,变量使用前必须声明其属于哪一个类型,引用变量前必须给变量赋值,否则定义在函数中的自动变量的值是一个随机数;C语言所有变量的定义必须在执行语句前,开始执行语句后就不能再出现定义变量的语句(C++无此限制);
15.输入和输出:pintf和scanf函数中的第一个参数是格式字符串。printf函数格式字符串中的普通字符会照样输出“%”开始到格式符结束的部分会用对应参数表达式的值按格式替换,要输出“%”要用“%%”;不要将提示的字符串放在scanf函数格式字符串中,scanf函数的其他参数是变量的地址,不要忘了给变量加取地址运算符“&”, scanf函数的返回值是正确输入数据的项数,不是输入的数值;
实验内容
要求:第1~3题要在源代码的最后,用多行注释给出程序执行的结果,并说明你对结果的理解。
1.输入并运行以下程序,分析程序的运行结果:
#include <stdio.h>
void main( )
{ char c;
int m = 0165, a = 321, b = -10;
c = a; //a的值已超出char类型的取值范围
printf("10进制: m=%d, 16进制: m=%x\n",m,m);
printf("c = %c\n",c);
printf("a: %d, %o, %x, %u\n",a,a,a,a);
printf("b: %d, %u, %x, %u\n",b,b,b,b);
}
2.输入并运行以下程序,分析程序的运行结果。
#include <stdio.h>
void main()
{ int a=14, b=3;
float x, y;
printf("a/b=%d, b/a=%d\n", a/b, b/a);
x=a/b; y=b/a;
printf("x=%f, y=%f\n", x, y);
printf("forced transform: %f, %f\n",(float)a/b,(float)(a/b));
printf("a%%b=%d, b%%a=%d\n", a%b, b%a);
}
说明:
- 注意两个整数相除和求余运算的结果;
- 最后一个printf的格式控制中连续两个%的作用是输出“%”字符本身。
3.输入并运行以下程序,分析程序的运行结果。
#include <stdio.h>
void main()
{ short s1=1,s2=-1;
unsigned short us1=1,us2=-1;
int a,b;
printf("s1 =%04hX(%hd),\ts2 =%04hX(%hd)\n",s1,s1,s2,s2);
printf("us1=%04hX(%hu),\tus2=%04hX(%hu)\n",us1,us1,us2,us2);
printf("有符号类型, 符号位扩展:\n");
a=s1,b=s2;
printf("a=%08X(%d),\tb=%08X(%d)\n",a,a,b,b);
printf("无符号类型,0位扩展:\n");
a=us1,b=us2;
printf("a=%08X(%d),\tb=%08X(%d)\n",a,a,b,b);
}
4.设计一个程序,按“yyyy-m-d”格式输入日期,然后按“yyyy年mm月dd日”格式输出日期的(y指年份,m指月份,d为日)。要求有输入日期的提示。如:程序运行时先输出提示,输入2020-5-1后按回车,程序运行显示界面如下:
5.设计一计算购房贷款还款月数的程序。设贷款额为d,每月还款额为p,月利率为r,计算还款月数的公式为下图:
要求:
d,p,r的值在程序运行时输入(要有提示),输入数据的分隔用默认分隔符,求得月数输出时只保留小数点后1位;
提示:
求以10为底的对数用函数log10,原型在数学函数库“math.h”中声明。输入不恰当的d,p,r的值可能会造成输出结果超出所用数据类型或对数函数参数的取值范围,从而产生错误的结果,可在输入时使d为300000元,p为6000元,r为1%作验证,看结果是否为69.7个月。
实验结果
注:(在代码后的注释中写出来了)
第一个小实验
#include <stdio.h>
void main( )
{ char c;
int m = 0165, a = 321, b = -10;
c = a; //a的值已超出char类型的取值范围
printf("10进制: m=%d, 16进制: m=%x\n",m,m);//结果为“十进制:m=117,十六进制:m=75”。 原因165前面有0,转换成了八进制 117=1*8^2+6*8^1+5*8^0. 117=7*16^1+5*16^0
printf("c = %c\n",c);//c=A char类型的取值范围<321,出现的溢出。%c用来输出一个字符 c存储的最后一个字节的信息是01000001
printf("a: %d, %o, %x, %u\n",a,a,a,a);//a:321,501,141,321 %d为整型输出 %o为以八进制输出 %x为以十六进制输出 %u为以十进制来输出一个unsigned型数据
printf("b: %d, %u, %x, %u\n",b,b,b,b);//b:-10,4294967286,fffffff6,4294967286 %d为整型输出输出-10 但是429...出现的原因是负数的补码与正数相反且加1,而出现ffffff6则可能是数据过大,超出类型可存储的范围,出现的乱码
}
第二个小实验
#include <stdio.h>
void main()
{ int a=14, b=3;
float x, y;
printf("a/b=%d, b/a=%d\n", a/b, b/a);//a/b=4,b/a=0 %d为整形输出,a/b=4.666666...但由于输出的是整形,所以0.666666...被省去 同理b/a=0.215 0.215被省去得出0
x=a/b; y=b/a;
printf("x=%f, y=%f\n", x, y);//x=4.000000,y=0.000000 由于%f输出的是浮点型,精度为6位,但是从int转换到float时丢失了小数点后面的精度
printf("forced transform: %f, %f\n",(float)a/b,(float)(a/b));// forced transform: 4.666667, 4.000000 用(float)强制转变为浮点型小数 其中(float)a/b为先把a转换为小数再除b,而(float)(a/b)为先将a/b的结果转变为整数,再以4.000000的小数输出
printf("a%%b=%d, b%%a=%d\n", a%b, b%a);//a%b=2, b%a=3 %是求余运算符 14/3=4余2 3/14商0余3
}
第三个小实验
#include <stdio.h>
void main()
{ short s1=1,s2=-1;
unsigned short us1=1,us2=-1;
int a,b;
printf("s1 =%04hX(%hd),\ts2 =%04hX(%hd)\n",s1,s1,s2,s2);//s1 =0001(1), 以16进制输出s1,输出宽度为4 hx 代表以16进制的 输出short类型的整数 (%hd为短整形) s2 =FFFF(-1) 同s1一样 宽度为4
printf("us1=%04hX(%hu),\tus2=%04hX(%hu)\n",us1,us1,us2,us2);//us1=0001(1), us2=FFFF(65535) unsighed short 类型的函数中-被省略即第一位为0 i其中/t为换行输出 65535=2^8
printf("有符号类型, 符号位扩展:\n");
a=s1,b=s2;
printf("a=%08X(%d),\tb=%08X(%d)\n",a,a,b,b);//a=00000001(1), b=FFFFFFFF(-1) 以16进制输出a 输出宽度为8 %d代表a的整形 其中无符号的从四位晋升到八位拓展了0000 有符号的从FFFF 又增加了四个F
printf("无符号类型,0位扩展:\n");
a=us1,b=us2;
printf("a=%08X(%d),\tb=%08X(%d)\n",a,a,b,b);//a=00000001(1), b=0000FFFF(65535) 同上三行解释一样。不过这个是一开始就设定了b为无符号,拓展的时候以正数的形式出现,故拓展了四个0 而非F
}
第四个小实验
#include<stdio.h>
int main()
{
int a,b,c;
printf("按yyyy-m-d格式输入日期:");
scanf("%d-%d-%d",&a,&b,&c);
printf("该日期是:%d年%.2d月%.2d日\n",a,b,c);
return 0;
}
第五个小实验
#include<stdio.h>
#include<math.h>
int main()
{
float d,p,r;
float n;
printf("依次输入d,p,r:");
scanf("%f%f%f",&d,&p,&r);
n=log10(p/(p-d*r))/log10(1+r);
printf("m=%.1f\n",n);
return 0;
}
结语
如果有疑问欢迎大家留言讨论,你如果觉得这篇文章对你有帮助可以给我一个免费的赞吗?我们之间的交流是我最大的动力!