第四章-数据与运算
数据的分类
计算机中存储的数据可以分为两种:静态数据和动态数据。
- 静态数据
- 概念:静态数据是指一些永久性的数据,一般存储在硬盘中。硬盘的存储空间一般都比较大,现在普通计算机的硬盘都有500G左右,因此硬盘中可以存放一些比较大的文件。
- 存储的时长:计算机关闭之后再开启,这些数据依旧还在,只要你不主动删掉或者硬盘没坏,这些数据永远都在。
- 哪些是静态数据:静态数据一般是以文件的形式存储在硬盘上,比如文档、照片、视频等。
- 动态数据(临时数据)
- 概念:动态数据指在程序运行过程中,动态产生的临时数据,一般存储在内存中。内存的存储空间一般都比较小,现在普通计算机的内存只有4G左右,因此要谨慎使用内存,不要占用太多的内存空间。
- 存储的时长:计算机关闭之后,这些临时数据就会被清除。
- 哪些是动态数据:当运行某个程序(软件)时,整个程序就会被加载到内存中,在程序运行过程中,会产生各种各样的临时数据,这些临时数据都是存储在内存中的。当程序停止运行或者计算机被强制关闭时,这个程序产生的所有临时数据都会被清除。
- 既然硬盘的存储空间这么大,为何不把所有的应用程序加载到硬盘中去执行呢?有个主要原因是内存的访问速度比硬盘快N倍。
- 数据的大小
- 不管是静态还是动态数据,都是0和1组成的。也就是说,文档/视频/语音都是有0/1组成的
- 数据越大,包含的0和1就越多
- 那么问题就来了,比如一个视频很大,那么当我们说他的大小时,难道说:他有
n个0/1
组成吗?- 为了表达方便,因此定出了以下单位:
- 一个0/1就叫:比特位(bit)
- 8个0/1就叫:字节(Byte)
- 如果一个视频为30M,那么他就是由:
30*1024*1024*8个0/1组成
- 1 KB = 1024 B,1 MB = 1024 KB,1 GB = 1024 MB,1 TB = 1024 GB
- C语言中的数据类型
转义字符
常量与变量
- 常见的常量有:
- 整型(int): 3;
- 浮点型:双精度(double) 3.4;
- 单精度(float) 3.4f;
- 字符型(char): ‘3’;
- 字符串型(string): “3”;
- 注意: 为了跟double区分开来,float 型数据都是以f结尾的,比如5.43f、-2.3f、0.0f。需要注意的是,绝对不能有10f这样格式的,编译器会直接报错,只有小数才允许加上f。
- 定义常量PI的两种方式:
#define Pai 3.14159;
const float pai 3.14159;
- 区别:
- 第一种方式:是将Pi定义成一种符号,此时Pai只是3.14159的别名,在编译期间用3.14159去取代Pi的值,define相当于替换。
- 第二种方式:是将PI定义成变量,但告诉编译器它的值是固定不变的,如果在程序中试图去修改它的值,在编译时会报错;
- 定义变量:
- 任何变量在使用之前,必须先进行定义。
- 定义变量的目的是:在内存中分配一块存储空间给变量,方便以后存储数据。
- 如果定义了多个变量,就会为这多个变量分别分配不同的存储空间。
- 不同类型的变量占用不同大小的存储空间。内存极其有限,分配适当的存储空间
- 变量什么时间分配内存
- 如果在程序中定义了一个变量,在对程序进行编译时,系统就会个这个变量分配内存单元
- 初始化的两种形式:
- 先定义,后初始化:int a; a = 10;
- 定义的同时进行初始化:int a = 10;
- 自我理解:定义变量就是在分配存储空间,定义一个变量,意思就是分配一块存储空间,用于存储数据.注意: 变量的作用域,决定了这块存储空间什么时间被销毁
- 常量与变量的区别:都分配了一块存储空间用于存储数据,但是常量分配的只能存储那个数据,变量可以改变存储的数据
- 变量的作用域:(这里不包含static)
- 变量在函数中的作用域:从定义变量的那行开始,一直到函数结束
- 变量在代码块中的作用域:
- 代码块:
{//这就是代码块 int a = 10;}
,用于及时回收不在使用的变量内存,为了提升性能 - 代码块中定义变量开始,一直到代码块结束
- 总结:从定义变量的那一行开始,一直到所在的代码块结束
- 代码块:
- 变量的存储
- 所占用的字节数跟类型有关,也跟编译器环境有关(Mac是64位的)
- 变量为什么一定要初始化?
- 如果变量没有初始化,那么这个变量的值就是一个不确定的值。
- 定义完变量,就会在内存中分配一块存储中间,而此时这个内存中存储的内容是随机的垃圾数据。
- 跟java不同,Java会给自定义的变量自动初始化为0;

-
if/switch代码注意事项:
//案例1: //错误 if(10) int a = 10; //正确 if(10){ int a = 10;} //或者 int a ; if(10) a = 10; //案例2: //错误: int a = 10; switch(a){ case 10: int b = 5; b++; break; case 2: … } //正确 int a = 10; switch(a){ case 10: { int b = 5; b++; break; } case 2: … } //或者 int a = 10; int b = 4; switch(a){ case 10: b = 5; b++; break; … } //案例3: //错误:原理同上 for(int i = 0;i<10;i++) int a = 10;
- 原因分析:作用域的问题
- if中,if后面的作用域仅仅是if后面那一句话,然而重新定义了一个变量a,那么理论上a的作用域就是从定义开始到”}”结束,但是其实不是,因此冲突
- switch中,作用域仅仅是满足case后到break之间的内容,但是如果在case中定义了一个变量b,那么默认的作用域就是从定义开始到”}”结束,因此也会冲突
- 解决办法,将if/case中的语句用{}起来即可
- 原因分析:作用域的问题
break与continue区别:
break:
1.使用场合
1> switch语句:退出整个switch语句
2> 循环结构:退出当前循环结构
* while
* do while
* for
2.注意点
只对当前的循环结构有效
continue:
1.使用场合
循环结构:结束当前这次的循环体(不在执行之后的代码),进入下一次循环体
* while
* do while
* for
2.注意点
只对当前的循环结构有效
goto语句无条件转移语句
- 一般形式:
goto 语句标号;
- “语句标号”必须是合法的标识符。不能用整数作标号。
- goto语句作用:调到代码的某一段来执行,必须配合“语句标号”来使用
- 用途:
- 与if语句一起构成循环结构;
- 从多层循环体的内层循环跳到外层循环。
- 注意:
- 结构化程序设计方法主张限制使用goto语句,滥用该语句将使程序流程无规律、可读性差。
-
代码示例:
void test(){ int i = 1, sum = 0; loop: if (i <= 100) { sum = sum + i; i++; goto loop; } printf("Sum=%d", sum); }
C语言中的位运算
- 按位与: &
- 功能
- 只有对应的两个二进位均为1时,结果位才为1,否则为0。
- 举例: 比如9&5,其实就是1001&101=1,因此9&5=1
- 规律:二进制中,与1相&就保持原位,与0相&就为0
- 判断一个数的奇偶:a&1 = 1 (奇数)/ = 0(偶数)
- 功能
- 按位或:
|
- 功能
- 只要对应的二个二进位有一个为1时,结果位就为1,否则为0。
-
举例: 比如 9|5
,其实就是1001101=1101,因此9 5=13
- 功能
- 按位异或:^
- 功能
- 当对应的二进位相异(不相同)时,结果为1,否则为0。
- 举例: 比如9
^
5,其实就是1001^
101=1100,因此9^
5=12 - 规律:相同整数相^的结果是0。比如5
^
5=0 - (重要!!!)多个整数相
^
的结果跟顺序无关。比如5^
6^
7=5^
7^
6 - 因此得出结论:a
^
b^
a = b
举例2: 交换两个变量的值 a = a ^ b; b = a ^ b; <=>a^b^b = a a = a ^ b; <=>a^b^a = b
- 功能
- 取反: ~
- 对整数a的各二进位进行取反,符号位也取反(0变1,1变0)
- 左移:«
- a«n
- 把整数a的各二进位全部左移n位,高位丢弃,低位补0。左移n位其实就是乘以2的n次方
- 由于左移是丢弃最高位,0补最低位,所以符号位也会被丢弃,左移出来的结果值可能会改变正负性
- 规律:每向左移动一位*2
- a * 2的n次方 : a«n
- 右移:»
- a» n
- 把整数a的各二进位全部右移n位,保持符号位不变。右移n位其实就是除以2的n次方
- 为正数时, 符号位为0,最高位补0
- 为负数时,符号位为1,最高位是补0或是补1 取决于编译系统的规定
- 规律:每向右移动一位/2
- a*2的-n次方: a»n