找回密码
 register

QQ登录

只需一步,快速开始

[*编程自学*] 第七、八、九课:数据类型转换、运算符

[复制链接]

[*编程自学*] 第七、八、九课:数据类型转换、运算符

[复制链接]
Waylee

主题

0

回帖

7912

积分

仙帝

积分
7912
Waylee 2024-8-1 14:54 | 显示全部楼层 |阅读模式

马上注册,查看网站隐藏内容!!

您需要 登录 才可以下载或查看,没有账号?register

×
数据的混合运算
    数据有不同的类型,不同类型数据之间进行混合运算时必然涉及到类型的转换问题,转换的方法有两种:
自动转换:
    遵循一定的规则,由编译系统自动完成。
强制类型转换:
    把表达式的运算结果强制转换成所需的数据类型
自动转换的原则:
1.占用内存字节数少(值域小)的类型,向占用内存字节数多(值域大)的类型转换,以保证精度不降低。
2.转换方向:
1.jpg
案例:有符号 和 无符号的转换
#include<stdio.h>

void test01()
{
        int data1 = -20;
        unsigned int data2 = 10;
        //有符号data1和无符号data2参加计算的时候 会将data1转换为无符号(-20的补码很大的正数)
        //很大的数 + 10 必然 >0 
        if(data1 + data2 > 0 )
        {
                printf(">0\n");
        }
        else if (data1 + data2 < 0)
        {
                printf("<0\n");
        }
        
}
int main(int argc,char *argv[])
{
        test01();
        return 0;
}

运行结果:>0
案例:int double的类型转换
#include<stdio.h>
void test02()
{
        int data1 = 10;
        printf("%d\n",sizeof(data1+3.14));//8字节
}
int main(int argc,char *argv[])
{
        test02();
        return 0;
}

案例:short和char类型转换
#include<stdio.h>
void test03()
{
        char ch = 'a';
        short data = 20;
        //由于char、short自身字节数过小,很容易溢出
        //只要char、short参加运算 都会将自身转换为int
        printf("%d\n",sizeof(ch + ch));
        printf("%d\n",sizeof(ch + data));
        printf("%d\n",sizeof(data + data));
}
int main(int argc,char *argv[])
{
        test03();
        return 0;
}

强制类型转换
(类型说明符)(表达式)
功能:把表达式的运算结果强制转换成类型说明符所表示的类型
例如:
(float)a; //把a的值转换为实型
int(x+y);//把x+y的结果值转换为整型

注意:类型说明符必须加括号
案例:强制类型转换代码
#include<stdio.h>
void test04()
{
        float x = 3.14f;
        int j = 0;
        //强制类型转换,只是临时的转换,当前语句有效,在后面的语句中不好更改x的值
        j = (int)x;//赋值类型由接受方j决定
        printf("j = %d,x = %f\n",j,x);//输出 j = 3,x = 3.140000
}
int main(int argc,char *argv[])
{
        test04();
        return 0;
}

运行结果:j = 3,x = 3.140000
运算符
用算数运算符将运算对象(也称操作数)连接起来、符合C语法的规则的式子,称为C算数表达式
运算对象包括常量、变量、函数等
例如:a*b / c-1.5 + 'a'
C语言常用运算符
  • 算数运算符: + 、1 、*、 /、 %
  • 关系运算符: >< 、== 、>= 、<= 、!=
  • 逻辑运算符: !、&&、||
  • 位运算符:    << 、>> 、& 、| 、~ 、^
  • 复制运算符: =及其扩展赋值运算符
  • 条件运算符: ?:
  • 逗号运算符: ,
  • 指针运算符:*和&
  • 求字节数运算符:sizeof(类型或变量)
  • 强制类型转换运算符:(变量或常量)
  • 分量运算符:. ->
  • 下标运算符:[]
  • 其他:如函数调用运算符()
知识点
/   取整  a/b(a和b必须都为整数)
% 取余 a%b(a和b必须都为整数)
#include<stdio.h>
void test05()
{
        printf("%d\n",5/2);//取整 2
        printf("%d\n",5%2);//取余 1
}
int main(int argc,char *argv[])
{
        test05();
        return 0;
}

运行结果:
2
1
Press any key to continue

案例:键盘输入一个输,是否能被3整除
#include<stdio.h>
void test07()
{
        //键盘输入一个int数
        int num = 0;
        printf("请输入一个整型数据:");
        scanf("%d",&num);
        //判断是否能被3整除
        if(num%3==0)
        {
                printf("可以被3整除\n");
        }
        else
        {
                printf("不能被3整除\n");
        }
}
int main(int argc,char *argv[])
{
        test07();
        return 0;
}

输出结果:
请输入一个整型数据:6
可以被3整除
Press any key to continue

课后练习:键盘输入一个4位数,请取出每位上的数值
void test09()
{
        printf("%d\n",5/2);//取整
        printf("%f\n",5/2.0f);//除
}

运行结果:
2
2.500000

#include<stdio.h>
void test08()
{
        int num = 0;
        printf("请输入一个四位数整数:");
        scanf("%d",&num);
        if(num <= 999 || num >= 9999)
        {
                printf("您输入的不是一个四位数整数,请重新执行程序\n");
        }
        else
        {
                printf("第一位数:%d\n",num/1000);
                printf("第二位数:%d\n",(num%1000)/100);
                printf("第三位数:%d\n",(num%100)/10);
                printf("第四位数:%d\n",num%10);
        }
        
}
int main(int argc,char *argv[])
{
        test08();
        return 0;
}


逻辑运算符
! 逻辑非  !0 == 真  !真 == 假
#include<stdio.h>
void test10()
{
        printf("%d\n",!1);//0
        printf("%d\n",!0);//1
        
        //C语言中 0为假 其他都为真
        printf("%d\n",!-1);//0
}
int main(int argc,char *argv[])
{
        test10();
        return 0;
}


运行结果:
0
1
0
Press any key to continue


逻辑与 &&
A && B   AB同时为真 整个表达式为真。 AB中只要有一个为假,则整个表达式为
#include<stdio.h>
void test11()
{
        if( (1>2) && (5>4) )
        {
                printf("ok\n");
        }
        else
        {
                printf("no\n");
        }
}
int main(int argc,char *argv[])
{
        test11();
        return 0;
}

运行结果为:no
逻辑&&短路特性:
A&&B 如果A为假,系统不会执行B  这就是&&的短路特性
#include<stdio.h>
void test12()
{
        int num = 10;
        printf("比较之前num = %d\n",num);
        2 > 3 && (num = 100);
        printf("比较之后num = %d\n",num);
}
int main(int argc,char *argv[])
{
        test12();
        return 0;
}


运行结果:
比较之前num = 10
比较之后num = 10
Press any key to continue



逻辑或 ||
A||B 只有A、B任意一个为真,整个表达式为。A、B同时为假,结果才为
逻辑||也有短路特性:只要A为真,编译器不会判断B的真假
#include<stdio.h>
void test13()
{
        int num = 10;
        printf("比较之前num = %d\n",num);
        3 > 1 || (num = 100);
        printf("比较之后num = %d\n",num);
}
int main(int argc,char *argv[])
{
        test13();
        return 0;
}

运行结果:
比较之前num = 10
比较之后num = 10



【位运算符】二进制位操作(重要)
&:按位与
语法:全1为1 其他为0
   1010 1010
& 1111 0000
----------------
   1010 0000
特点:和1相与保持 不变,和0相与 清零
应用场景:将固定位清零。

|:按位或
语法:有1就为1,全0才为0
   1010 1010
|  1111 0000
----------------
   1111 1010
特点:和0相或 保持不变,和1相或 置1
应用场景:将固定位置1
案例:将1010 1010的第2、3位置1,其他位保持不变
   1010 1010
|  0000 1100
----------------
   1010 1110
注意:二进制数的位数是从右到左开始编号的,通常第一个位称为第零位(0位

~:按位取反
语法:0变1  1变0
~1010 1010 == 0101 0101
应用场景:配合&|操作

^:按位异或

语法:相同为0,不同为1

    1010 1010
^  0000 1111
-----------------
   1010 0101
特点:0异或保持不变,和1异或取反
应用场景:将固定的位发生高低电频翻转
案例:将1010 1010 的第0位发生反转
    1010 1010
^  0000 0001
------------------
    1010 1011
<<左移运算符:左边丢弃,右边补0
注意:移动的位数 不要超过 自身长度
1010 1100 << 2
001.jpg

>>右移运算符:
1010 1100 >>2
002.jpg
右移分类:逻辑右移 算术右移
逻辑右移:右边丢弃,左边补0
算术右移:
               无符号数:右边丢弃,左边补0
               有符号数:
                      正数:右边丢弃,左边补0
                      负数右边丢弃,左边补1
右移基本上是右边丢弃左边补0,只有负数且算术右移 左边才会补1.
逻辑右移和算术右移 是编译器决定,但是我们可以检测
作业:自己写代码 判断你的编译器 是逻辑右移还是算术右移?
综合训练:
#include<stdio.h>
//将data的1、5清0,第3、4位 置1, 其他位保持不变
void test15()
{
        unsigned char data = 0xaa; //1010 1010
        //将data的1、5清0
        //1101 1101 = ~(0010 0010) = ~(0010 0000 | 0000 0010)
        //0010 0000 = 0000 0001 << 5
        //0000 0010 = 0000 0001 << 1
        //1101 1101 = ~(0x01<<5|0x01<<1)
        data = data & ~(0x01<<5|0x01<<1);

        //第3、4位置1:
        //data = data|0001 1000;
        //0001 1000 = 0001 0000|0000 1000
        //                = 0x01<<4|0x01<<3
        data = data |(0x01<<4|0x01<<3);
}
int main(int argc,char *argv[])
{
        test14();
        return 0;
}


知识点 三目运算符 ?:
表达式1 ? 值1:值2
语法:如果表达式1为真 整个表达式的值为“值1”否则为“值2”
案例:
#include<stdio.h>
void test16()
{
        int ret = 0; 
        ret = 3>2?5:6;
        printf("ret = %d\n",ret);
}
int main(int argc,char *argv[])
{
        test16();
        return 0;
}

输出结果:
ret = 5
Press any key to continue

逗号运算符:
案例:
#include<stdio.h>
void test17()
{
        int data1 = 0;
        int data2 = 0;
        data1 = 3,4,5,6;
        data2 = (3,4,5,6);
        printf("data1 = %d\n",data1); //输出3
        printf("data2 = %d\n",data2); //输出6
}
int main(int argc,char *argv[])
{
        test17();
        return 0;
}

复合运算符
+= -= *= /= %=  等等
a += b;  ==>  a = a +b;
a *=b;    ==>  a = a * b;
注意: =号 的右边必须看成一个整理
#include<stdio.h>
void test18()
{
        int data = 3;
        //将=号 右边看成一个整体
        data *=3+5;  //data = data * (3+5)
        printf("data = %d\n",data);
}
int main(int argc,char *argv[])
{
        test18();
        return 0;
}

自增、自减运算符 【++ -- 运算符】
++i  或者 --i   先 加、减 使用
i++ 或者 i--    先使用,后加、减
代码案例:
#include<stdio.h>
void test19()
{
        int i=3;
        int j=0;
        //++左边 先加 后使用
        j = ++i; // i = i+1;  j=i;
        printf("i == %d,j == %d\n",i,j);//输出结果 i == 4,j == 4
}
int main(int argc,char *argv[])
{
        test19();
        return 0;
}


案例:
#include<stdio.h>
void test28()
{
        int i = 3;
        int j = 0;
        j = i++;
        printf("i = %d,j = %d\n",i,j);
}
int main(int argc,char *argv[])
{
        test28();
        return 0;
}


注意:i++ 或 ++i 作为单独的指令 没有区别

运算符的优先级:
C语言中,运算符的优先级共分15级。
1级最高,15级最低。
优先级较高的先于优先级降低的进行运算
在一个运算量两侧的运算符优先级相同时,则按运算符的结合性所规定的结合方向处理。
各运算符的结合性:
  • 左结合性(从左至右):+-*/
  • 右结合性(从右至左):= ++ --

图片1.png
图片2.png
自己写代码,尽量加()

雪舞知识库 | 浙ICP备15015590号-1 | 萌ICP备20232229号|浙公网安备33048102000118号 |网站地图|天天打卡

GMT+8, 2024-11-24 10:12 , Processed in 0.068164 second(s), 10 queries , Redis On.

Powered by XueWu Licensed

Copyright © Tencent Cloud.

快速回复 返回顶部 返回列表