变量
概念
- 表面:程序运行过程中取值可以改变的数据
- 实质:变量其实代表了一块内存区域/单元/空间。变量名可视为该区域的标识。
整个变量分为三部分:
- 变量名:这个只是变量的一个标识,我们借助变量名来存取数据。
- 变量空间/内存单元:这个就是内存中分配的一块用来存储数据的空间/区域。
- 数据/变量值:这个就是存放在变量空间中的数据
语法
[修饰符] 数据类型 变量列表;
命名规范
1.
变量名可以由数字、字母(区分大小写)、下划线
_
、
$
组成,不能以数字开头。
2.
不建议使用中文,也不建议使用拼音。
3.
变量名不能与系统中已有的标识符重名。(比如关键字、保留字
...
,举例:
int,signed,if,break...
)
案例
// 方式1:先声明,后赋值,注意:赋值操作顺序:从右往左
int num1;
num1 = 21; // 赋值操作,顺序,从右往左,这个句代码的意思是:将21赋值给num1(num1对应的内存单元)
printf("%d",num1);// 将num1对应的数据输出到控制台,需要指明输出数据的格式:int 使用 占位符%d表示
// 方式2:声明并赋初值
int num2 = 21; // 这句代码执行的时候做了两件事:① 向内存申请了一块存储单元(分配内存),② 将21赋值给num2对应的存储单元
printf("%d",num2);
// 方式2:覆盖初始值
int num3 = 21;
num3 = 22;
printf("%d",num3);
// 方式3:变量列表。逗号在C语言中可以作为分隔符和运算符使用
int x = 12, y = 13;
说明:
1. 变量定义是,利用同一个类型标识符可同时定义多个变量,各个变量之间使用
,
(英文逗号)分割。
2. 定义变量后,如果未对变量进行初值的赋予,则变量所代表的内存空间中的数据是随机安排的。
3. 可以在变量定义的同时给变量赋值,这个操作称为变量的初始化,
C
语言允许对变量进行初始化。
4. 初始化变量是,尽量做到类型相同,例子:
long l = 567L
5. 整型数据在内存中的存放方式:
按照补码方法存放:
类型
|
符号位
|
符号位
|
尾数位
/
部分(小数)
|
float(4
个字节
)
| 1 | 8 | 23 |
类型
|
符号位
|
符号位
|
尾数位
/
部分(小数)
|
double(8
个字节
)
| 1 | 11 | 52 |
例子:
需求:将
27.5
以
float
类型存放:
解析:
- 27.5的二级制为11011.1,指数表示法:1.10111 * 2 4
- 指数:4,加上127,就是131,二进制1000 0011
- 尾数(小数点后的数)10111,补够23位 1011 1000 0000 0000 0000 000用二进制表示就是 (符号数位1位)0 (指数位8位)1000 0011 (尾数位23位)1011 1000 0000 0000 0000 000
- 所以 单精度浮点型数据27.5 在内存中的存储方式如下
0 1000 0011 1011 1000 0000 0000 0000 000
注意:浮点型数据在内存中存放的是一个近似值。
7.
字符数据在内存中的存放方式:
以
ASCII
码存放
字符的存在分为两种形式,
ASCII
码(编号,从
0
开始的正整数)和
ASCII
码值(数据,包括英文字母 大小写、数字、特殊符号)
注意:
ASCII
码是可以和整数进行数学运算的。
举例:
// 写法一
char c1 = 'A';
// 写法二
char c2 = 60;
数据类型转换
规则:不同的数据类型参与运算,需要转换为同一类型后运算
数值比较由小到大简单排序:
- 隐式类型转换
说明:编译系统自动完成,一般是低优先级类型向高优先级类型转换,这种被称作自动类型转换
(由小到大)。
语法:
大数据类型 变量名 = 小数据类型变量;
举例:
// 案例1
char c = 'A';// 65
int num = c;
printf("%d",num); // 65
// 案例2
char c2 = 'A';// 65
int num2 = c2 + 22;
printf("%d",num2);// 87
- 强制类型转换
说明:程序员自己实现,一般是高优先级类型向低优先级类型转换,这种被称作强制类型转换(由
大到小)
语法:
小数据类型 变量名 = (小数据类型)大数据类型变量;
举例:
// 案例1
int num1 = 65;
char c1 = (char)num1;
printf("%c",c1); // A
// 案例2
int num2 = 65;
char c2 = (char)(num2 + 32)
printf("%c",c2); // a
注意:强制类型转换过程中,可能会出现精度丢失的问题。如果大类型数据范围
<=
小类型数据范
围,此时数据不会丢失,正常转换;如果大类型数据范围
>
小类型数据范围,此时丢失超出部分的
数据,精度会缺失!
原则:类型转换并不会改变原变量的类型。
运算符
算术运算符
单目运算符
说明:
++ -- +(
正
) -(
负
) *(
解引用运算符,后面讲
)
++a
与
a++
的区别
int a = 1,int x = ++a;
:
++
在前,先自加
1
,后运算
int a = 1,int x = a++;
:
++
在后,先运算,后自加
1
案例:
![](https://i-blog.csdnimg.cn/direct/e63bdafb53bc4015b550c0bd566584d7.png)
总结:
分析上面的案例,我们发现,不管是
++
在前,还是
++
在后,计算数自身都会
+1
。区别在于运算的结果不一样。
++
在前,先自加
1
,后运算;
++
在后,先运算,后自加
1
。
练习1:
int i = 3;
如果 int ret1 = i+++i++; // 求ret1和i的值?7
如果 int ret2 = i+++(++i); // 求ret2和i的值?12
// 上面两道题的做法,先不写代码,猜结果;然后编写代码,验证猜测的正确性。
// int ret1 = (i++)+(i++);
// int ret2 = (i++)+(++i);
--a
与
a--
的区别
- int a = 1,int x = --a; : -- 在前,先自减1,后运算
- int a = 1,int x = a--; : ++ 在后,先运算,后自减1
双目运算符
说明:
+ - * / %
举例:
#include <stdio.h>
int main()
{
printf(3/2); // 1,为什么不是1.5,因为是整型的运算,会直接舍弃掉小数部分
printf(3*1.0/2); // 1.5 为什么是1.5? 3*1.0:转换为double
printf(10%3);// 1 求模运算
printf(10.0%3);// error 求模运算是针对整数进行的
int a = 10;
printf(a*1.0);
return 0;
}
注意:
1.
两个整数相除的结果是整数,小数部分被舍弃。要想其结果是实数,可在分子
*1.0(
隐式类型转换
)
2.
求模运算(取余运算)左右两边的操作数都必须是整型。如果是类似于
3.0
这样的数,是错误的。
关系运算符
说明:
> < >= <= != ==
案例:
![](https://i-blog.csdnimg.cn/direct/d328f19bb348471eb47b92bfc875efe0.png)
什么是表达式?
表达式就是表达某种意思的式子。在
C
语言中,表达式指的是
运算符
连接
操作数
(变量
|
常量
...
)的式子。
注意:
由关系运算符构成的表达式称为关系表达式,关系表达式的值为 boolean( 布尔值 )非 0 :关系成立,为真0 :关系不成立,为假
逻辑运算符
说明:
&&(
与
) ||(
或
) !(
非
)
- && :逻辑与(且),符号两边的操作数都为真,结果才为真。举例: ((5>4)&&(5-4)>1) ,结果 0
- || :逻辑或(或),符号两边的操作数只有有一个为真,结果就为真。举例: ((5>4)||(5- 4)>1) ,结果 1
- ! :逻辑反(取反),取反,非0为真,举例: !(!(5>4)) ,结果 1
惰性运算
所谓的惰性运算,就是减少运算次数。
- 短路与: && 两边的操作数,只要左边不成立 0 ,直接返回假,不再校验右边。
- 短路或: || 两边的操作数,只要左边成立 1 ,直接返回真,不再校验右边。
扩展
ISO-8859-1
:西欧编码,一般遇到直接改编码。针对文件内容。
GBK
:国标,中国标准编码
/
字符库,收录了大量的汉字
+
中文符号。针对文件内容。
UTF-8
:全球标准,几乎收录了全球的各种字符集,包括
GBK
包含的常用汉字以及中文符号。针对文件内容。
ASCII
:字符集,
C
语言字符就是以
ASCII
码进行存储。针对程序内部数据。