本章目标
1.数据类型介绍
2.signed与unsigned
3.数据类型的取值
4.变量
5.算术操作符
6。赋值操作符
7.单目操作符
8.强制类型转换
1.数据类型介绍
c语言为我们提供了大量的数据类型供我们使用,数据类型能够为我们描述我们常见的数值,和字符。
例如int 类型(整型)来去描述整数,char(字符型)去描述字符,float类型,去描述浮点数也就是小数。所谓我类型也就是该类数据所具有的共同特征
该小节主要进行对数据类型中的c语言提供的类型去进行介绍,关于自定义类型,结构体,联合体等,我会在后续的文章中进行分享。
我们首先数据类型进行一个大体认知
(1)字符型
char
signed char
unsigned char
(2)整型
//短整型
short
unsigned short
signed short
//整型
int
unsigned int
signed int
//长整型
long
unsigned long
signed long
(3)浮点型
float
double
long double
(4)布尔类型
_Bool
在C99之前的c语言中用0或者非0的数表示真假,0表示假非0表示真,在后续的标准,引入了一个新的类型表示真假,布尔类型,对于布尔类型有两个取值,true或者false
显而易见true 表示真,false 表示假,当你准备使用的该类型的时候,需要包含头文件
<stdbool.h>同时也可以使用l来直接定义变量。以下做出展示
#include<stdio.h>
#include<stdbool.h>
int main()
{
_Bool flag = true;
if(flag)
{
printf("hehehehe");
}
return 0;
}
而在vs2022中你可以直接使用bool来定义,该写法在头文件中已经定义
可以直接使用
(5)数据类型的长度
每一中数据类型都有自己的长度,取值范围,该长度是该类型向操作系统申请的内存空间的大小,而内存空间的单位是字节,一个字节是8个bit位,而bit位是用来存储二进制位的,当二进制当转换为十进制的时候就会出现可以保存数据的取值范围。
其中的进制转换,在后面的文章会单独出一期进行分享。
例如unsigned char 和signed char 是一个字节
signed int 和 unsigned int 是四个字节
float 是四个字节
double是8个字节。
在这里我们介绍一个操作符sizeof
(6)sizeof
sizeof是一个操作符也是一个关键字,它是专门用来算类型长度,单位是字节
sizeof后面可以跟一个类型也可以跟一个表达式
sizeof后面是表达式的时候是可以省略括号的
sizeof是不会进行真实计算的,它只会计算结果的类型大小
sizeof的返回类型是size_t类型的。
#include <stdio.h>
int main()
{
int a = 10;
printf("%zd\n", sizeof(a));
printf("%zd\n", sizeof a);//a是变量的名字,可以省略掉sizeof后边的()
printf("%zd\n", sizeof(int));
printf("%zd\n", sizeof(3 + 3.5));
return 0;
}
类型的返回大小
int main()
{
printf("%zd\n", sizeof(char));
printf("%zd\n", sizeof(_Bool));
printf("%zd\n", sizeof(short));
printf("%zd\n", sizeof(int));
printf("%zd\n", sizeof(long));
printf("%zd\n", sizeof(long long));
printf("%zd\n", sizeof(float));
printf("%zd\n", sizeof(double));
printf("%zd\n", sizeof(long double));
return 0;
}
sizeof的表达式并不真实计算
int main()
{
short s = 2;
int b = 10;
printf("%zd\n", sizeof(s = b + 1));
printf("s = %d\n", s);
return 0;
}
那么什么是size_t类型的呢?
其实在C语言的标准中只规定了sizeof的返回类型是一个无符号整数,并没有具体的返回类型。所以各种IDE的实现也就各有不同,为了统一标准创建了一个size_t类型,用来对用当前环境的sizeof的返回类型。
2.signed和unsigned
在前面的分享中我并没有使用int,char 这种类型给大家去做解释,或者你对前文中的signed 和unsigned 有很多疑惑那么我接下来就对下面进行一一介绍
我们首先从signed 和unsigned两个来进行解释。
从·字面意思来进行理解,signed有符号的
unsigned 无符号的
那么二者有什么区别呢
在前面中我们提到当我们创建变量的时候会去向操作系统去申请空间,就那signed int来进行举例
它会被分配4个字节大小的空间,而一个字节有分为8个比特位,当这32个比特位按顺序排列好的时候,最高位的二进制位会被当做符号位,去用来表示正负,这也是说明对于带有signed 的类型来说它是有正负的。
反正,unsigned 的类型最高位就不会被当做符号位
这其中就引出一个问题
unsigned类型数据要比signed类型的数据能够多储存一倍的数据
在这里我们拿char的两种类型来进行距离
对于unsigned char来说,它会被分配一个字节,当它的比特位全是1的情况下
它的表示数值是最大的,也就是11111111当我们把这个二进制数字转换为10进制的时候就是255.。在这里我们简单的将以下进制转换
其实无论哪一种进制来说,每一位数据都是有它自己的权重的。
在这里我们拿12来距离。对于个位来说它的权重是10的0次方,而对于十位来说它的权重是10的一次方,对于十二这个数字,也就是10^11
+10^01=12.
举一反三对于二进制来说它的每一位2的多少次方,在这里我们拿101距离,我们从右边往左看,也是从低位向高位看,对于第一个数字来说也就是2的0次方,第二个数字也就是2的1次方,第三个数字也就是2的2次方的,当我们按照上面的方法进行计算的时候,这个二进制数字转化为10进制也就是5。
我们回到正题。对于有符号的整数来说它的最高位会被当做符号位也就会使这个类型表示的数字少一倍对于char来说当他的最高位为1其他位为0的时候它表示的是128,而当最高位为0其他位为1的时候它所有位加一起的和表示的数字是127,同理也可以推出其他类型的所保存的数据类型大小了。
那么我们来解释下一个问题。
int 和char究竟是带signed还是unsigned的
对于int来说它默认是signed int
所以我们一般为了表示有符号的整型的时候我们会将signed省略。
而对于char来说,它带signed还是unsigned是由当前环境所决定的。
这也就是说对于char来说,它可能是unsigned类型的也可能是signed类型的。
3.数据类型的取值
上述的数据类型有很多,其中整型类型就有4种,那么为什么有这么多的数据类型呢?
其实是为了适应各种场景的使用如果要去查看当前类型的极限值的时候,可以从以下两个文件去查看
limits.h该文件包含了整型的取值范围
float.h该文件包括了浮点型的取值范围
我们接下来做演示
此为整型的最大最小值
此为浮点型的最大最小值在float.h中的体现。
4.变量
当我们理解了什么是类型,那么类型是用来做什么的,它是为了创建变量的。
那么什么是变量。在c语言中我们把经常变化的量称之为变量,不变的量称之为常量。
关于变量的创建的语法
data_type name;
| |
| |
类型名 变量名
char a;//字符型变量
int b;//浮点型变量
float c;//浮点型变量
当我们创建变量的时候给一个初始值,就叫做变量的初始化。
char a='w';//字符型变量
int b=10;//浮点型变量
float c1.2;//浮点型变量
变量的分类:
全局变量:在大括号外定义的变量,全局变量的使用范围很广,整个项目如果想要使用都可以引用它。
局部变量:在大括号内部使用的变量就是局部变量。它比起全局变量有着更高的优先级。不过它的作用域并不是整个项目它仅局限当前的花括号内。并且当当前花括号结束后它就会销毁。
#include <stdio.h>
int global = 2023;//
全局变量
int main()
{
int local = 2018;//
局部变量
printf("%d\n", local);
printf("%d\n", global);
return 0;
}
在这里提出一个问题
当全局变量和局部变量的名字相同的时候,局部变量会优先使用。
那么局部变量和全局变量储存在哪里呢?
在项目创建的时候·会向操作系统申请一块空间,而这块操作空间又会被细分为,栈区,堆区,静态区等。一般我们在学习c语言的阶段我们会主要关注这三个区域。
我们的局部变量就储存在栈区。
我们的全局变量就会储存在静态区。
那么堆区是用来储存什么的呢?
在后面我们会学子动态内存的分配与管理,而这部分主要存的就是动态申请下来的空间。
5.算数操作符
在写代码的时候我们可能会遇到一些操作涉及到计算。c语言为我们提供一系列的运算符包括±*/,还有%其中加减乘是符合我们数学的计算逻辑的。这里主要提的就是除法/以及取模%
对于除法如果是整数与整数相除结果如果出现了小数会将小数点后面的数字省略。例如1/3的结果在c语言这里就是0。如果是浮点数相除,在除号的左右两边必须有一方是浮点数结果才会出现小数
+与-加法与减法
#include <stdio.h>
int main()
{
int x = 4 + 22;
int y = 61 - 23;
printf("%d\n", x);
printf("%d\n", y);
return 0;
}
由于加法与减法左右两边涉及两个操作数,这类操作符我们也称作为双目操作符。
*乘法
#include <stdio.h>
int main()
{
int num = 5;
printf("%d\n", num * num); // 输出25
return 0;
}
/除法
#include <stdio.h>
int main()
{
float x = 6 / 4;
int y = 6 / 4;
printf("%f\n", x); // 输出 1.000000
printf("%d\n", y); // 输出 1
return 0;
}
就如同我们上面说的一样整数整数相除结果也会是整数,如果要出现小数结果两方必须有一样有小数点后面的值或者是浮点数类型的变量。
在这里请注意浮点数的打印用%f而整型的打印用%d。
#include <stdio.h>
int main()
{
int score = 5;
score = (score / 20.0) * 100;
return 0;
}
%取模运算
取模运算也叫求余运算。它返回的是两数相除之后的余数。
这个操作符只能应用与整数之间,不能用于浮点数
#include <stdio.h>
int main()
{
int x = 6 % 4; // 2
return 0;
}
有关于负数求模的规则,负数取余只会根据第一个操作符的正负去判断结果的正负
#include <stdio.h>
int main()
{
printf("%d\n", 11 % -5); // 1
printf("%d\n",-11 % -5); // -1
printf("%d\n",-11 % 5); // -1
return 0;
}
6.赋值操作符
在创建变量的时候给它一个值我们叫做变量的初始化,在这之后我们在给一个值我们叫做变量的赋值,这里面就涉及了变量的赋值。
int a =0;
a =3;
在这里=是赋值操作符,它也是一种双目操作符。
复合赋值操作符
我们在写代码的时候可能会有大量的自增自减的操作。
这里面就涉及了一些操作符的联合使用。
int a = 0;
a+=2;
这里面a自己会增加2.
其他自减自乘的方法同理。
这里面是相关的操作符。
7.单目操作符
++和–
这里面的++和–原理相同,听懂一个,另一个也能够明白。
所谓的单目操作符就是操作数只有一个。
所谓的++就是和上面所涉及的+=是一个道理同样的是自增操作。不过它是每次自己增加1.
这里面的++分为两种。
1.后置++
前置++的表达是这样的
a++;
它会先使用在去自增,举个例子,在a=1,b =a++;这句代码中b会先变成1,然后a变为2.
2.前置++
++a;
同样的,用上面的例子,这里a会先变成2,然后再去给b去赋值使b便为2.
3.+和-
这部分和数学的逻辑相同再这里不进行过多赘述。
8.强制类型转换
当我们想把把一个字符型变量赋给一个整型的时候我们可能会报错,这里就需要强制类型转换。
int a = 0;
char b = 'A';
a=(int)b;
b的ascll值是66.a的值就会变为66.
强制类型转换是临时的,只会针对此次使用。
并且是再不得不用的情况我们去考虑强转。