(注:本课内容较多,请适当做好记录)
C++版:
附:为了防止程序在运行后瞬间退出而无法看到结果,可以#include
例:
1 |
|
变量
变量是在程序的运行过程中,可以根据你的意愿改变的量。在程序设计中,为了避免过多的牵扯到底层,我们通常把它假想成在电脑中的一个空间(比方说一个箱子),并占用电脑的一定空间(内存)。需要时,将数据放进去,必要时可以取出来看一眼。电脑的内存显然是有上限的,因此正确估算自己编写的程序需要占用的运行内存也是需要培养的能力之一。
有了变量的概念,就可以大大扩展编程能干的事了。
变量的定义方法格式如下:
1 | <数据类型a> 变量名1; |
第一行:定义了一个类型为数据类型a,变量名1的变量。
第二行:定义了两个变量,类型为数据类型b。
第三行:定义了两个变量,类型为数据类型c,并给其中的4赋了初值。
这里牵涉到赋值语句,即把数据放入箱子的过程,用=表示,但不是等号,称为赋值号(真正的等号在下一章介绍)。
赋值方法如下:
1 | int a,b,c; |
猜想运行后c的值为多少?
第一行:定义了三个整型变量a,b,c,都是空箱子(没有初值)。
第二行:将a赋值为1,此时a中的内容为1,b,c还是空的。
第三行:将b赋值为2,此时a为1,b为2,c还是空的。
第四行:将b赋值为a的值,此时a为1,b也为1,c还是空的。
第五行:将c赋值为b+1的值,此时a为1,b也为1,c为2。
由此我们可以发现,对变量值的修改是一次性的,修改后将不会记忆之前的状态,之前的数据也就消失了。
cin输入
我们总是希望程序可以按照自己的意愿完成某种工作,甚至一个程序就可以一劳永逸,只需将不同的数据输入,它就能给出需要的答案。
1 | int a; |
这就是C++的一个输入语句cin,我们可以看到与cout格式类似。
第一行:int a;表示声明一个整型变量a(具体请见下一节“数据类型”),表示在电脑这个大仓库中放一个空箱子取名为a。
第二行:cin与cout类似,使用操作符>>与cout相反,>>后的是要输入的目标。这里>>a即表示“在键盘输入一个数后,把这个数放入名叫a的箱子”。
1 | int a; |
现在运行程序,在黑屏幕上输入一个数,回车,看看是不是被正常输出了?
由此我们也可以发现,cout<<后也可以加变量,换句话说:一个变量、一个值、一个表达式是等价的。
C++语言数据类型
计算机能储存、处理数据。然而由于现代计算机的工作原理限制,计算机似乎更擅长处理离散的数据,而对连续数据则有些捉襟见肘(这也是计算机科学更重视离散数学的原因之一)。计算机数据的另外一个特征是它在空间上有限,每个数据都是有范围的,不能无限制增大(或减小),一旦过大(或过小)就会溢出。好在,C++语言已经为我们提供了一定的数据类型,可以基本上覆盖现实编程的使用。(对于自定义类型将在以后的章节介绍)
整型
1 | int a; |
(不是整形~)顾名思义是记录整数的类型,其范围为-2^31~2^31-1(即-2147483648~2147483647)占4个字节(4个字节,32位,一位表示符号,剩下31位对应2^31)。
似乎没有什么好说的了,不过不妨做一下这个实验:
1 | int a=2147483647; |
是2147483648吗?不是,竟然是-2147483648,就想吃豆人一样,在屏幕的右边消失后从左边出现了!这就是数据溢出(这里不作介绍,可自行百度原码、反码、补码),在编程时为了防止出现这样的意外,我们要估算使用场景会不会出现超大的数。
long long(长长整型???)
1 | long long a; |
因此,这里介绍一种更大的整型,操作方法与整型一致,区别就是大,所以占用的空间也大。范围大致在19位十进制数,占64位,8字节。
实型
然而现实应用中不可能只有整数,实型就是计算机处理小数的方法。
1、单精度浮点
1 | float a; |
占32位,范围-3.4*10^38-3.4*10^38
从它的范围我们可以发现,它比整型大很多,不禁疑问:能不能就都用实型数来表示呢?
答案是否定的,实型数和整型数在计算机中的表示是完全不同的,实型除了能表示小数外,在其他任何功能上都不能代替整型。正如之前所说,计算机对连续量的处理能力很弱,它对离散量(整型)可以精确记录,永远准确;而对于连续量(实型)的储存实际上是不精确的,因此两个实型数间也一般不比较是否相等,因为有时会出现明明你认为应该相等时计算机却不认为它们相等的情况。
这个编码方式就比整型复杂一些了,我们暂时也不需纠结什么是“浮点”,什么是“单、双精度”,只要会使用即可:
1 | float a=3.14; |
2、双精度浮点
1 | double a=3.14; |
占64位,范围在±1.79*10^308之间,比float精度更高。
字符型
1 | char a; |
为了解决对字符的处理问题,C++提供了字符型变量,8位(1字节)。但要理解字符型可能需要下些工夫:
我们知道,计算机只可以储存整数,幸好,字符的个数也是有限的,因此,人们想到做一张表,把字符和整数一一映射,不就可以用一个整数表示某一个字符了吗?认真听高一信息课的同学可能已经发现了,它就是ASCII码表。C++语言就是支持ASCII码表编码的一种语言。
所以,C++语言的字符型,其实也是整型的一种,因为字符的数量显然没有2^31个,它相当于是为了节约空间而只涵盖字符范围的整型。
请看下例:
1 | char a; |
输出:
A
66
66
67
第三行:将字符型变量a赋值为A,由此我们发现C++中的单个字符用单引号’ ‘表示;
第四行:将整型变量b赋值为字符a的值;
此时:b的值为65,a的值也为65
接着看这4行输出,请自行寻找规律。
我们发现,cout是类型安全的,程序具体输出什么取决于要输出的量的类型:a是字符型,故输出字符;a+1将字符型变量a转换为整型数65并+1输出;b为整型数,故直接输出整数。另外C++也可以使用C风格的printf进行自定义格式的输出,将字符型作为整型输出,详见C版的教程。
数据类型的转换
不同数据类型的变量之间能否自由的计算、赋值呢? 答案是否定的。一般的,对于数据类型的转换是否会造成数据的丢失(或错误),我们分为安全类型转换和不安全类型转换
安全类型转换
我们发现,如果把一个小箱子里装的东西放进大箱子,将肯定放得下。安全类型转换就是小放大的过程:
1 | char a='A'; |
在赋值前,赋值号将把赋值号右侧的变量的值(右值)转换成与左边的变量(左值)相同,再进行赋值。
对于上面的例子,我们都认为他们的转换是安全的(不会有意外发生)。
不安全类型转换
相反的,大箱子里的东西如果大小超过了小箱子,就有可能出现信息丢失。则为不安全类型转换。
1 | int a=1300; |
对于上面的例子,我们都认为他们的转换是不安全的(没人能保证程序会按照你的意思进行,即使编译器不会告诉你出错)。有兴趣可以试验一下上面的值都变成了什么。
强制类型转换
在我们需要时,也可以强制类型转换,方法如下:
1 | int a=65; |
输出:
A
这里char(a),即将整型变量a强制转成字符型。
标识符、保留字
标识符是指只由字母或下划线(_)开头,字母、数字和下划线组成的字串。(不能用汉字)
1 | 是标识符: |
在C++语言中,只有标识符才可以作为变量/函数/类型名
保留字(也称关键字)是在C++语言中已经有用途的标识符,它们也不能作为变量名。
1 | int if; |
以上都是非法的。
C版:
附:为了防止程序在运行后瞬间退出而无法看到结果,可以#include<stdlib.h>并在需要暂停的地方写system(“pause”);一句。
例:
1 |
|
变量
变量是在程序的运行过程中,可以根据你的意愿改变的量。在程序设计中,为了避免过多的牵扯到底层,我们通常把它假想成在电脑中的一个空间(比方说一个箱子),并占用电脑的一定空间(内存)。需要时,将数据放进去,必要时可以取出来看一眼。电脑的内存显然是有上限的,因此正确估算自己编写的程序需要占用的运行内存也是需要培养的能力之一。
有了变量的概念,就可以大大扩展编程能干的事了。
变量的定义方法格式如下:
1 | <数据类型a> 变量名1; |
第一行:定义了一个类型为数据类型a,变量名1的变量。
第二行:定义了两个变量,类型为数据类型b。
第三行:定义了两个变量,类型为数据类型c,并给其中的4赋了初值。
这里牵涉到赋值语句,即把数据放入箱子的过程,用=表示,但不是等号,称为赋值号(真正的等号在下一章介绍)。
赋值方法如下:
1 | int a,b,c; |
猜想运行后c的值为多少?
第一行:定义了三个整型变量a,b,c,都是空箱子(没有初值)。
第二行:将a赋值为1,此时a中的内容为1,b,c还是空的。
第三行:将b赋值为2,此时a为1,b为2,c还是空的。
第四行:将b赋值为a的值,此时a为1,b也为1,c还是空的。
第五行:将c赋值为b+1的值,此时a为1,b也为1,c为2。
由此我们可以发现,对变量值的修改是一次性的,修改后将不会记忆之前的状态,之前的数据也就消失了。
scanf输入
我们总是希望程序可以按照自己的意愿完成某种工作,甚至一个程序就可以一劳永逸,只需将不同的数据输入,它就能给出需要的答案。
1 | int a; |
这就是C语言的一个输入语句scanf,我们可以看到与printf格式类似。
第一行:int a;表示声明一个整型变量a(具体请见下一节“数据类型”),表示在电脑这个大仓库中放一个空箱子取名为a。
第二行:scanf与printf类似,双引号“”中的是输入格式,逗号后的是要输入的目标。这里&a即表示“在键盘输入一个数后,把这个数放入名叫a的箱子”。
1 | int a; |
现在运行程序,在黑屏幕上输入一个数,回车,看看是不是被正常输出了?
由此我们也可以发现,printf逗号后也可以加变量,换句话说:一个变量、一个值、一个表达式是等价的。
仔细的同学会发现,printf中没有&符号而scanf中需要这个符号。通常对于初学者的要求是“当做规律背下来”。虽然在接下来的课程中还会详细介绍,但在这里还是做一个简单说明(不明白就跳过):
我们现在有一个a箱子,a箱子里有一个数,假设是1。
通常情况下在C语言中,a表示名字叫a的箱子中的内容,也就是1。所以print(a)就是输出a里面的数(a变量的值)。&在C语言中是取地址运算符,&a就不表示a里面的数了,而是a盒子本身。scanf(&a)就可以让计算机在内存中找a这个箱子,往里面输入;而如果scanf(a)就表示寻找a变量的值作为某个箱子的名称(姑且这么认为),而显然没有“1箱子”(而且这也不是我们的目的)。
那printf(&a)会怎样呢?是的,会输出a的地址,不过这也不是没有意义的,具体会在“指针”一章中讲到。
C语言数据类型
计算机能储存、处理数据。然而由于现代计算机的工作原理限制,计算机似乎更擅长处理离散的数据,而对连续数据则有些捉襟见肘(这也是计算机科学更重视离散数学的原因之一)。计算机数据的另外一个特征是它在空间上有限,每个数据都是有范围的,不能无限制增大(或减小),一旦过大(或过小)就会溢出。好在,C语言已经为我们提供了一定的数据类型,可以基本上覆盖现实编程的使用。(对于自定义类型将在以后的章节介绍)
整型
1 | int a; |
(不是整形~)顾名思义是记录整数的类型,其范围为-2^312^31-1(即-21474836482147483647)占4个字节(4个字节,32位,一位表示符号,剩下31位对应2^31)。
似乎没有什么好说的了,不过不妨做一下这个实验:
1 | int a=2147483647; |
是2147483648吗?不是,竟然是-2147483648,就想吃豆人一样,在屏幕的右边消失后从左边出现了!这就是数据溢出(这里不作介绍,可自行百度原码、反码、补码),在编程时为了防止出现这样的意外,我们要估算使用场景会不会出现超大的数。
long long(长长整型???)
1 | long long a; |
因此,这里介绍一种更大的整型,操作方法与整型一致,区别就是大,所以占用的空间也大。范围大致在19位十进制数,占64位,8字节。
另外,占位符为%lld
1 | long long a; |
即可。
实型
然而现实应用中不可能只有整数,实型就是计算机处理小数的方法。
1、单精度浮点
1 | float a; |
占32位,范围-3.4*10^38-3.4*10^38,占位符为%f
从它的范围我们可以发现,它比整型大很多,不禁疑问:能不能就都用实型数来表示呢?
答案是否定的,实型数和整型数在计算机中的表示是完全不同的,实型除了能表示小数外,在其他任何功能上都不能代替整型。正如之前所说,计算机对连续量的处理能力很弱,它对离散量(整型)可以精确记录,永远准确;而对于连续量(实型)的储存实际上是不精确的,因此两个实型数间也一般不比较是否相等,因为有时会出现明明你认为应该相等时计算机却不认为它们相等的情况。
这个编码方式就比整型复杂一些了,我们暂时也不需纠结什么是“浮点”,什么是“单、双精度”,只要会使用即可:
1 | float a=3.14; |
2、双精度浮点
1 | double a=3.14; |
占64位,范围在±1.79*10^308之间,比float精度更高。
字符型
1 | char a; |
为了解决对字符的处理问题,C语言提供了字符型变量,8位(1字节),占位符为%c。但要理解字符型可能需要下些工夫:
我们知道,计算机只可以储存整数,幸好,字符的个数也是有限的,因此,人们想到做一张表,把字符和整数一一映射,不就可以用一个整数表示某一个字符了吗?认真听高一信息课的同学可能已经发现了,它就是ASCII码表。C语言就是支持ASCII码表编码的一种语言。
所以,C语言的字符型,其实也是整型的一种,因为字符的数量显然没有2^31个,它相当于是为了节约空间而只涵盖字符范围的整型。
请看下例:
1 | char a; |
输出:
A
65
A
65
B
66
第三行:将字符型变量a赋值为A,由此我们发现C语言中的单个字符用单引号’ ‘表示;
第四行:将整型b赋值为字符a的值;
此时:b的值为65,a的值也为65
接着看这6行输出,请自行寻找规律。
我们发现,程序具体输出什么只取决于占位符是什么,我们可以说,在0~128内,字符型和整型是可以混用的。
数据类型的转换
不同数据类型的变量之间能否自由的计算、赋值呢? 答案是否定的。一般的,对于数据类型的转换是否会造成数据的丢失(或错误),我们分为安全类型转换和不安全类型转换
安全类型转换
我们发现,如果把一个小箱子里装的东西放进大箱子,将肯定放得下。安全类型转换就是小放大的过程:
1 | char a='A'; |
在赋值前,赋值号将把赋值号右侧的变量的值(右值)转换成与左边的变量(左值)相同,再进行赋值。
对于上面的例子,我们都认为他们的转换是安全的(不会有意外发生)。
不安全类型转换
相反的,大箱子里的东西如果大小超过了小箱子,就有可能出现信息丢失。则为不安全类型转换。
1 | int a=1300; |
对于上面的例子,我们都认为他们的转换是不安全的(没人能保证程序会按照你的意思进行,即使编译器不会告诉你出错)。有兴趣可以试验一下上面的值都变成了什么。
强制类型转换
在我们需要时,也可以强制类型转换,方法如下:
1 | int a=1; |
这里(float)a,即将整型变量a强制转成实型。
标识符、保留字
标识符是指只由字母或下划线(_)开头,字母、数字和下划线组成的字串。(不能用汉字)
1 | 是标识符: |
在C语言中,只有标识符才可以作为变量/函数/类型名
保留字(也称关键字)是在C语言中已经有用途的标识符,它们也不能作为变量名。
1 | int if; |
以上都是非法的。
输出格式控制
在格式符的%后,可以改变输出的格式
以float举例,其他同:
1 | %0.1f 小数保留一位,整数部分不限 |
可以自行试验验证
作业:
思考:
1、什么是变量?什么是赋值语句?赋值后原来的数据还在吗?去哪里了?
2、编写程序是为了什么?与自己手动解题的思维过程有什么区别?
3、什么是数据类型?为什么要区分数据类型?数据的大小为什么有范围?
4、C/C++语言字符型数据的本质是什么?在C/C++语言程序中如何区分整型与字符型?
5、为什么数据类型转换会出现不安全情况?
6、什么是标识符、保留字?为什么一种编程语言中要区分出这些特殊的标识符作为保留字?
习题:
1、输入两个正整数a,b(a,b<10000),输出a+b的值
2、输入一个圆的半径r(r<100),输出圆的面积和周长,输出格式:s=……,c=……。
*3、输入实系数a,b,c,解一元二次方程ax^2+bx+c,数据保证有实根,输出格式:x1=……,x2=……。
提示:include头文件math.h,即可使用函数sqrt(x),表示x的平方根(算术)