一、数据类型之(char)
1、字符类型(char):可以表示单个字符(一个数字,字母,符号)。
也可以用单引号('')扩上,直接表示一个字符类型的数据。
注意事项:
在单引号内使用转义符“\“,可以表示特色含义。
多个字符称为字符串,但C语言中使用char数组表示,数组不是基本数据类型,而是构造类型。
2、格式占位符
使用%c表示char类型
3、字符类型本质
- C语言中,char类型本质是一个整数,是ASCII码中对应的数字,存储长度是 1 个字节,char类型也可以进行数学运算。
- 字符型同样分为signed char(有符号)和unsigned char(无符号),其中signed char取值范围-128 ~ 127,unsigned char取值范围0 ~ 255。默认是否带符号取决于当前运行环境。
#include <stdio.h>
int main()
{
// 声明char类型的变量并赋值,字面量数据需要单引号进行包裹
char c1 = 'A';
char c2 = '9';
char c3 = '\t';
printf("c1 = %c, c2 = %c, c3 = %c \n", c1, c2, c3);
// char 类型本质上是整数类型,其范围是0~255之间,是ASCII码的扩展
char c4 = 'A';
char c5 = 97;
printf("c4 = %c, c4 = %d \n", c4, c4);
printf("c5 = %c, c5 = %d \n", c5, c5);
printf("c4+c5= %d \n", c4 + c5);
// char类型的取值范围
signed char c6 = 200; // 有符号的char 取值范围是-128~127之间
unsigned char c7 = 200; // 无符号的char 取值范围是0-255之间,超出范围
char c8 = 200; // 当前系统默认是有符号的char
printf("c6 = %d, c7 = %d, c8 = %d", c6, c7, c8);
return 0;
}
c1 = A, c2 = 9, c3 =
c4 = A, c4 = 65
c5 = a, c5 = 97
c4+c5= 162
c6 = -56, c7 = 200, c8 = -56
200的二进制数是1100 1000
char类型,假如没有unsigned修饰的话,范围是-128~127
+56是0011 1000,反码1100 0111,
-56是+56的补码1100 1000
200超出范围了char数值表达的最大范围。
所以1100 1000的第一个1是它的符号位,为负。表示的数值就是-56
二、布尔类型
1、基本介绍
布尔值用于表示真、假两种状态,通常用于逻辑运算和条件判断。
C99标准还提供了一个头文件 <stdbool.h> 定义了bool代表_Bool,true代表1,false代表0。
#include <stdio.h>
#include <stdbool.h>
int main()
{
bool b1 = false;
bool b2 = true;
printf("b1 = %d, b2 = %d \n", b1, b2);
if (b1)
{
printf("b1 is true");
}
if (b2)
{
printf("b2 is true");
}
return 0;
}
b1 = 0, b2 = 1, b3 = 1
b2 is true
三、获取数据存储大小
使用sizeof
可以获取数据类型或变量、字面量的存储大小,单位是字节。sizeof返回一个size_t类型的无符号整数值,格式占位符是 %zu。
size_t
通常是 unsigned int
或 unsigned long
的别名,具体是哪个类型的别名,由系统和编译器决定。
#include <stdio.h>
int main()
{
// 计算数据类型的字节大小,必须使用小括号将数据类型关键字包裹起来
printf("char占字节大小为:%zu \n", sizeof(char)); // 1
printf("short占字节大小为:%zu \n", sizeof(short)); // 2
printf("int占字节大小为:%zu \n", sizeof(int)); // 4
printf("long占字节大小为:%zu \n", sizeof(long)); // 4
printf("long long占字节大小为:%zu \n", sizeof(long long)); // 8
printf("float占字节大小为:%zu \n", sizeof(float)); // 4
printf("double占字节大小为:%zu \n", sizeof(double)); // 8
printf("long double占字节大小为:%zu \n", sizeof(long double)); // 16
printf("====================\n");
// 计算字面量数据的字节大小,可以省略括号
printf("字符a的字节大小:%zu \n", sizeof 'a'); // 4
printf("整数100的字节大小:%zu \n", sizeof 100); // 4
printf("浮点数3.14的字节大小:%zu \n", sizeof 3.14f); // 4
printf("====================\n");
// 计算变量数据的字节大小,可以省略括号
char a = 'a';
int b = 10;
long long c = 100;
double d = 100.345;
printf("变量a的字节大小为:%zu \n", sizeof a); // 1
printf("变量b的字节大小为:%zu \n", sizeof b); // 4
printf("变量c的字节大小为:%zu \n", sizeof c); // 8
printf("变量d的字节大小为:%zu \n", sizeof d); // 8
return 0;
}
char占字节大小为:1
short占字节大小为:2
int占字节大小为:4
long占字节大小为:4
long long占字节大小为:8
float占字节大小为:4
double占字节大小为:8
long double占字节大小为:16
====================
字符a的字节大小:4
整数100的字节大小:4
浮点数3.14的字节大小:4
====================
变量a的字节大小为:1
变量b的字节大小为:4
变量c的字节大小为:8
变量d的字节大小为:8
字符型常量,不属浮点数常量,而归属于 int 型。所以,字符型 char 常量占四个字节。
四、数据类型的转换
c语言中不同类型的数据在运算和赋值的时候会进行类型转换,分为:隐式转换(自动类型转换)和显示转换(强制类型转换)。
1、隐式转换(自动类型转换)
不同类型的数据进行混合运算,会发生数据类型转换,窄类型会自动转为宽类型,这样不会造成精度损失。
- 不同类型整数进行运算,窄类型整数自动转换为宽类型整数。
- 不同类型浮点数进行运算,精度小的类型自动转换为精度大的类型。
- 整数与浮点数进行运算,整数自动转换为浮点数。
2、显示转换(强制类型转换)
隐式类型转换中的宽类型赋值给窄类型,编译器是会产生警告的,提示程序存在潜在的隐患,如果非常明确地希望转换数据类型,就需要用到强制(或显式)类型转换。
#include <stdio.h>
int main()
{
double d1 = 3.987;
double d2 = 4.235;
int sum1 = d1 + d2; // 先相加,后传int
int sum2 = (int)d1 + (int)d2; // d1转int为3,d2转int为4 结果为:7
int sum3 = (int)(d1 + d2); // 先相加,后传int
int sum4 = (int)(2.5 * 10 + 2 * 1.5);
printf("sum1 = %d \n", sum1);
printf("sum2 = %d \n", sum2);
printf("sum3 = %d \n", sum3);
printf("sum4 = %d \n", sum4);
return 0;
}
sum1 = 8
sum2 = 7
sum3 = 8
sum4 = 28
五、运算符基础
1、什么是运算符
运算符是一种告诉编译器执行特定的数学或逻辑操作的符号。
简述:运算符是一种特殊的符号,用以用于数据的运算、赋值和比较等。
2、算术运算符分类
- 一元运算符(一目运算符):由一个操作数使用的符号(+a)
- 二元运算符(二目运算符):由两个操作数使用的符号(a+b)
- 三元运算符(三目运算符):由三个操作数使用的符号
3、按照功能分类
- 算术运算符
- 关系运算符
- 逻辑运算符
- 位运算符
- 赋值运算符
- 杂项运算符
4、算术运算符
假设变量A为10,变量B为20
- 自增、自减运算符可以写在操作数的前面也可以写在操作数后面,不论前面还是后面,对操作数的副作用是一致的。
- 自增、自减运算符在前在后,对于表达式的值是不同的。 如果运算符在前,表达式的值是操作数自增、自减之后的值;如果运算符在后,表达式的值是操作数自增、自减之前的值。
#include <stdio.h>
int main()
{
{ // 自增(后加)
int x = 10;
int y = x++; // 先参与运算,后加1.(先取出x的值赋值给y,然后x自身再加1)
printf("x = %d, y = %d \n", x, y);
}
{ // 自增(前加)
int x = 10;
int y = ++x; // 先加1,后参与运算.(先自身加1,然后再把结果赋值给y)
printf("x = %d, y = %d \n", x, y);
}
{ // 自减(后减)
int x = 10;
int y = x--;
printf("x = %d, y = %d \n", x, y);
}
{ // 自减(前减)
int x = 10;
int y = --x;
printf("x = %d, y = %d \n", x, y);
}
{ // 例子
int x = 10;
int y = 3;
int z = x-- + ++y; // 先取出x的值为10,放在那里不动,然后计算++y,y的值是4,最后计算 10+4 = 14
printf("x = %d, y = %d, z = %d \n", x, y, z);
}
return 0;
}
x = 11, y = 10
x = 11, y = 11
x = 9, y = 10
x = 9, y = 9
x = 9, y = 4, z = 14
5、关系运算符
#include <stdio.h>
int main(){
// 关系运算符(比较运算符)
int a = 10, b = 5;
printf("a==b是否 相等 的结果: %d \n",a==b); // 0
printf("a!=b是否 不等 的结果: %d \n",a!=b); // 1
printf("a>b 是否 大于 的结果: %d \n",a>b); // 1
printf("a<b 是否 小于 的结果: %d \n",a<b); // 0
printf("a>=b是否 大于等于 的结果: %d \n",a>=b); // 1
printf("a<=b是否 小于等于 的结果: %d \n",a<=b); // 0
return 0;
}
a==b是否 相等 的结果: 0
a!=b是否 不等 的结果: 1
a>b 是否 大于 的结果: 1
a<b 是否 小于 的结果: 0
a>=b是否 大于等于 的结果: 1
a<=b是否 小于等于 的结果: 0
六、逻辑运算符
#include <stdio.h>
int main()
{
{
// 逻辑与 &&
int a = 10, b = 20;
printf("a = %d , b = %d , a > 5 && b > 10 逻辑与 的结果为: %d \n", a, b, a > 5 && b > 10);
// 如果出现短路(第一个操作数为假,第二个没必要计算了),后面的表达式不会执行
printf("a = %d , b = %d , a < 5 && b++ > 10 逻辑与 的结果为: %d \n", a, b, a < 5 && b++ > 10);
}
{
// 逻辑或 ||
int a = 10, b = 20;
printf("a = %d , b = %d , a > 10 || b < 50 逻辑或 的结果为: %d \n", a, b, a > 10 || b < 50);
// 如果出现短路(第一个操作数为真,第二个没必要计算了),后面的表达式不会执行
printf("a = %d , b = %d , a >5 || b++ > 10 逻辑或 的结果为: %d \n", a, b, a > 5 || b++ > 10);
}
{
// 逻辑非 !
printf("!0 逻辑非 的结果为: %d \n",!0);
}
return 0;
}
a = 10 , b = 20 , a > 5 && b > 10 逻辑与 的结果为: 1
a = 10 , b = 20 , a < 5 && b++ > 10 逻辑与 的结果为: 0
a = 10 , b = 20 , a > 10 || b < 50 逻辑或 的结果为: 1
a = 10 , b = 20 , a >5 || b++ > 10 逻辑或 的结果为: 1
!0 逻辑非 的结果为: 1