一、获取数据储存大小
使用sizeof 可以获取数据类型或变量、字面量的存储大小,单位是字节。sizeof返回一个size_t类型的无符号整数值,格式占位符是 %zu
1.基本类型的大小
int main()
{
// sizeof:可以检查出 类型 占得内存大小->字节
printf("char=%zu\n", sizeof(char));
printf("short=%zu\n", sizeof(short));
printf("int=%zu\n", sizeof(int));
printf("long=%zu\n", sizeof(long));
printf("long long=%zu\n", sizeof(long long));
printf("float=%zu\n", sizeof(float));
printf("double=%zu\n", sizeof(double));
printf("long double=%zu\n", sizeof(long double));
return 0 ;
}
2.变量所占内存大小
int main()
{
// sizeof:可以检查出 变量 占得内存大小->字节
char ch = 'a';
int a = 12306;
double num = 3.14;
printf("a=%zu\n", sizeof(a));
// 检测对应变量的时候,小括号可以省略
printf("ch=%zu\n", sizeof ch);
printf("num=%zu\n", sizeof num);
return 0;
}
3.检测字面量和字符的大小
// 检测字面量
// 字符本质即为整数=97->默认int类型
//6.6是小数默认为double类型
printf("字符a=%zu\n", sizeof 'a');
printf("小数6.6=%zu\n", sizeof 6.6);
二、类型自动转换
1.自动类型转换
(1)不同类型整数进行运算,窄类型整数自动转换为宽类型整数。
(2)不同类型浮点数进行运算,精度小的类型自动转换为精度大的类型。
(3)整数与浮点数进行运算,整数自动转换为浮点数。
int main()
{
//整数:short int long long
short a = 12;
int b = 88;
printf("%d\n", a + b);
printf("a+b=%zu\n", sizeof(a + b));
int num = 99;
long num1 = 23;
printf("%ld\n", num + num1);
printf("num+num1=%zu\n",sizeof(num + num1));
//浮点数:float double long double
float a = 8.8;
double b = 9.9;
printf("小数a+b=%lf\n",a + b);
printf("所占内存大小=%zu\n",sizeof(a + b));
//整数与小数运算符
int a = 110;
double b = 6.68;
printf("a+b=%.2lf\n",a + b);
printf("a+b=%zu\n",sizeof(a + b));
//有符号与无符号计算->无符号的!!!
int a = -100;
unsigned int b = 98;
printf("%u", a + b);
return 0;
}
2.强制类型转换
自动类型转换(隐式类型转换)中的宽类型赋值给窄类型,编译器是会产生警告的,提示程序存在潜在的隐患,如果非常明确地希望转换数据类型,就需要用到强制(或显式)类型转换。
#include <stdio.h>
int main()
{
// 类型->double类型小数
double a = 3.6;
double b = 8.88721;
//(int)a:把double类型强转换为int类型进行计算
int result = (int)a + (int)b;
printf("%d\n", result);
return 0;
}
提示:在变量前面加上(转变类型)不然无法转换会报错
三、运算符
运算符是一种特殊的符号,用以用于数据的运算、赋值和比较等。按照操作数个数分类分为:一元运算符(一目运算符)二元运算符(二目运算符)三元运算符(三目运算符)。按照功能分类:算术运算符、赋值运算符、关系运算符、逻辑运算符、位运算符。
1.算数运算符
运算符 | 描述 | 操作数个数 | 组成的表达式的值 | 副作用 |
+ | 正号 | 1 | 操作数本身 | 无 |
- | 负号 | 1 | 操作数符号取反 | 无 |
+ | 加号 | 2 | 两个操作数之和 | 无 |
- | 减号 | 2 | 两个操作数之差 | 无 |
* | 乘号 | 2 | 两个操作数之积 | 无 |
/ | 除号 | 2 | 两个操作数之商 | 无 |
% | 取模(取余) | 2 | 两个操作数相除的余数 | 无 |
++ | 自增 | 1 | 操作数自增前或自增后的值 | 有 |
- - | 自减 | 1 | 操作数自减前或自减后的值 | 有 |
#include <stdio.h>
int main()
{
// + -:正负符号
// int a = 19;
// int b = -123;
// printf("%d %d\n", a, b);
//+ - * / %
int a = 10;
int b = 4;
printf("a+b=%d\n", a + b);
printf("a-b=%d\n", a - b);
printf("a*b=%d\n", a * b);
// 整数相除小数部分没了!!!
printf("a/b=%d\n", a / b);
printf("a%b=%d\n", b % a);
//这些数学运算对于变量ab没有影响的
printf("a=%d\n",a);
/**
*
* ++ 自增
* -- 自减
* 这两个符号一般出现在变量前面或者后面 加上1或者减去1
*
* ++:如果出现在变量前面(++a),当前这一次操作,在使用之前就加上1了!!!
* --:如果出现在变量前面(--a),当前这一次操作,在使用之前就减去1了!!!
*
* ++:如果出现在变量后面(a++),当前这一次操作,在使用之后就加上1了!!!
* --:如果出现在变量后面(a--),当前这一次操作,在使用之后就减去1了!!!
*/
int num = 9;
// 使用变量进行操作
printf("++num=%d\n", ++num); // 第二次10
printf("num=%d\n", num);//第三次 10
int a = 89;//第一次
// 使用变量进行操作
printf("a++=%d\n", a++);//第二次
printf("a=%d\n",a);//第三次
int c = 51; // 第一次
printf("%d\n", --c); // 第二次
printf("%d\n",c);//第三次
int d = 67;//第一次
printf("d--=%d\n",d--);//第二次
printf("d=%d\n",d);//第三次
int num = 10;
int result = num++ + 7;
printf("result=%d\n", result);
printf("%d\n",num);
return 0;
}
自增自减运算符尤为重要,要根据代码自行一个一个尝试,理解前置和后置所表现出来的不同效果,为以后的控制循环语句提供准备。
2.比较运算符及关系运算符
#include <stdio.h>
int main()
{
// 比较运算符(6) == != > >= < <=
//对于变量没有副作用
//比较运算最终的结果:数字0(不成立)|数字1(成立)
int a = 99;
int b = 37;
printf("a==b:结果%d\n", a == b);
printf("a!=b:结果%d\n", a != b);
printf("a>b:结果%d\n", a > b);
printf("a>=b:结果%d\n", a >= b);
printf("%d\n", 3 >= 3);
printf("a<=b:结果%d\n", a <= b);
printf("a<b:结果%d\n", a < b);
// 逻辑运算符:&&->两个同时为真,才为真![串联图]
int a = 99;
int b = 55;
printf("a&&b:结果%d\n", a && b);
printf("数字1&&数字2:结果%d\n", 0 && b);
printf("数字1&&数字2:结果%d\n", 12 && 0);
printf("表达式1&&表达式2:结果%d\n", a > 10 && ++b);
// 逻辑或:||->两者只要有一个为真,即为真【并联图】
int num = 0;
printf("数字1||数字2:结果%d\n", 3 || 0);
printf("数字1||数字2:结果%d\n", ++num || 0);
printf("表达式1||表达式2:结果%d\n", 3 > 8 || 100 > 99);
// 逻辑非:!取反
printf("%d\n", !0);
printf("%d\n", !99);
printf("%d\n", !!!67);
// 练习
int result = (3 > 8 && 3 < 9) || 0;
printf("结果:%d\n", result);
return 0;
}
3.赋值运算符
#include <stdio.h>
int main()
{
// 赋值运算符: = += -= *= /= %=
int a = 123;
a += 6; // 相当于 a = a + 6 等于129
a -= 8; // 相当于 a = a - 8 等于121
a *= 2; // 相当于 a = a * 2 等于242
a /= 3; // 相当于 a = a / 3 等于80
a %= 3; // 相当于 a = a % 3 等于2
printf("a=%d\n", a);
return 0;
}
4.位运算符
运算符 | 描述 | 操作数个数 | 副作用 |
& | 按位与 | 2 | 无 |
| | 按位或 | 2 | 无 |
^ | 按位异或 | 2 | 无 |
~ | 按位取反 | 1 | 无 |
<< | 按位左移 | 2 | 无 |
>> | 按位右移 | 2 | 无 |
注意:操作数进行位运算的时候,以它的补码形式进行运算。
0为假 1为真
&运算符
两个数字都要为1才能得到真,只要有一个是假就是0
int a = 22;
int b = -19;
原码 反码 补码
22 0001 0110 0001 0110 0001 0110
-19 1001 0011 1110 1100 1110 1101
---------------------------------------
4 0000 0100
printf("a & b = %d\n", a & b);/*因为数字都是在255以内所以只列了8位进行运算可以不止 是八位16位三十二位都可以看计算的数字大小*/
| 运算符
有1即为真也就是说两个数字里面只要有一个1就是真的也就是得1。
int a =22; int b =-19; 原码 反码 补码 22 0001 0110 0001 0110 0001 0110 -19 1001 0011 1110 1100 1110 1101 --------------------------------------- -1 1000 0001 1111 1110 1111 1111 printf("a | b = %d\n", a | b); //往下运算符举例都是a=22 b=-19
^运算符
或与运算符是两个数字不同为真,相同为假
22 0001 0110 0001 0110 0001 0110
-19 1001 0011 1110 1100 1110 1101
---------------------------------------
-5 1000 0101 1111 1010 1111 1011
printf("a ^ b = %d\n", a ^ b);
~按位取反符
/* 原码 反码 补码
22 0001 0110 0001 0110 0001 0110
-19 1001 0011 1110 1100 1110 1101
---------------------------------------
~a 1001 0111 1110 1000 1110 1001 -23
~b 0001 0010 0001 0010 0001 0010 5
*/
printf("~a:结果位%d\n", ~a);
printf("~a:结果位%d\n", ~b);
补码直接按位取反,如果取完反得到的是负数也就是符号位是1,记得计算出原码
>> <<按位左移、按位右移
正数按位左移和右移都是补0,负数右移时记得补的是1
//-----------------左移动,右移动----------//
/* 原码 反码 补码
22 0001 0110 0001 0110 0001 0110
-19 1001 0011 1110 1100 1110 1101
---------------------------------------
a<<2 0101 1000 0101 1000 0101 1000 88
b<<2 1100 1100 1011 0011 1011 0100 -76
a>>2 0000 0101 0000 0101 0000 0101 5
b>>2 1000 0101 1111 1010 1111 1011 -5
*/
printf("a<<2:结果为%d\n", a << 2);
printf("b<<2:结果位%d\n", b << 2);
printf("a>>2:结果位%d\n", a >> 2);
printf("b>>2:结果位%d\n", b >> 2);
return 0;
5.三元运算符
基本语法:条件表达式? 表达式1: 表达式2;
如果条件表达式为非0(真),整个表达式的值是表达式;如果条件表达式为0(假),整个表达式的值是表达式2;
int num = 6;
int num1 = 9;
printf("三元运算:结果%d\n", 1 ? num : num1);
printf("三元运算:结果计算出谁大:%d\n", num > num1 ? num : num1);
6.运算符优先级
优先级 | 运算符 | 名称或含义 | 结合方向 |
1 | [] | 数组下标 | 左到右 |
() | 圆括号 | ||
. | 成员选择(对象) | ||
-> | 成员选择(指针) | ||
2 | - | 负号运算符 | 右到左 |
(类型) | 强制类型转换 | ||
++ | 自增运算符 | ||
-- | 自减运算符 | ||
* | 取值运算符 | ||
& | 取地址运算符 | ||
! | 逻辑非运算符 | ||
~ | 按位取反运算符 | ||
sizeof | 长度运算符 | ||
3 | / | 除 | 左到右 |
* | 乘 | ||
% | 余数(取模) | ||
4 | + | 加 | 左到右 |
- | 减 | ||
5 | << | 左移 | 左到右 |
>> | 右移 | ||
6 | > | 大于 | 左到右 |
>= | 大于等于 | ||
< | 小于 | ||
<= | 小于等于 | ||
7 | == | 等于 | 左到右 |
!= | 不等于 | ||
8 | & | 按位与 | 左到右 |
9 | ^ | 按位异或 | 左到右 |
10 | | | 按位或 | 左到右 |
11 | && | 逻辑与 | 左到右 |
12 | || | 逻辑或 | 左到右 |
13 | ?: | 条件运算符 | 右到左 |
14 | = | 赋值运算符 | 右到左 |
/= | 除后赋值 | ||
*= | 乘后赋值 | ||
%= | 取模后赋值 | ||
+= | 加后赋值 | ||
-= | 减后赋值 | ||
<<= | 左移后赋值 | ||
>>= | 右移后赋值 | ||
&= | 按位与后赋值 | ||
^= | 按位异或后赋值 | ||
|= | 按位或后赋值 | ||
15 | , | 逗号运算符 | 左到右 |