导航:
  2.1 算数运算符
  2.2 逻辑运算符
  2.3 位运算
  2.4 赋值运算
  2.5 内存访问符号
----->x<------------->x<--------------->x<--------------->x<------------->x<-----
 
2.1 算数运算符
            -- +, -
                在 +(-) 两边的数据类型,尽量一致.比如: A + B, A和B的类型尽量一致, 在定义加法的时候,可以加小括号(),这样
                可以避免语法逻辑错误 .
 
            -- *, /, %
                在cpu中, 其实是没有 乘法 和 除法 的. cpu只能通过软件模拟的方式, 来翻译这种操作.
                比如 : int a = b *10; cpu会用很多的模拟算法, 来解释 * 这种算法. 效率是非常低的 .
                如果是我们自己开发逻辑程序的话, * 和 / 是无法实现的. 所以 * 和 / 尽量少用 .
                % 是求模. 实际上就是取余数 .
                求模的特性就是
                res = x % n; 那么 res 的范围就是 0 ~ (n-1)
                    什么时候用呢?
                    给一个任意的数字, 可能就是随机数, 这个数字我们要得到一个 1 ~ 100 里面的数,
                    res = x % 100; //0 ~ 99;
                    res += 1;       // 1 ~ 100;
                
        2.2 逻辑运算符
            真 和 假 的选择. ( 非0 和 0 )
            -- |, ||; &, &&
                问: A || B 是否等价于 B || A ??
                答: 不等价. cpu 看到 A 已经是真了, 就不会去计算B的值. 同样 (A && B) != (B && A)
                ----------------------->
                int main (void){
                    int a = 10;
                    int res;
                    res = ((a == 10) || printf("我并不会被执行,因为(a == 10)成立,为真,就不会来判断我了. \n"));
                    return 0;
                }
                -----------------------<
            -- >>, >=, <, <=
                略 .
 
            -- !
                原本如果是真, 加了!号后就是假. 对比取反~ .
                !:  char a = 0x01;   !a ==0x00;                  //原本非零的真,!后就是为0的假 .
                ~: char b = 0x01;   ~b == 11111110 == 0xfe;   //按位取反,0~1 1~0.
            -- ?, :
                常用与三元运算符 .
        2.3 位运算!!!
            位运算是硬件计算必须使用的方法, 要重点掌握!!
            -- <<, >>
                移位.移位是在硬件里面常用到的方法.移位分为 有符号 和 无符号 的移位.
                unsigned char a = oxff;
                左移 n 位, 就是 乘以 2的n次方 . a << 3 -> a* (2的3次方) .
                右移 n 位, 就是 除以 2的n次方 . a >> 3 -> a/ (2的3次方) .
                这种算法速度非常快.
                但是对于有符号位来说,
                第一位是符号位,无论怎么移动, 符号位 是不会改变的 .
            -- &, |, ^
                !!!硬件 设置位 和 屏蔽位 的操作 .
                (1) 屏蔽位 & .
                    char a = 0x34; --> 0011 0100
                                    a & 0xf0:
                                        0011 0100
                                    &   1111 0000
                                    --------------
                                        0011 0000
                    从这边可以知道,因为 a & 0xf0,那我的目的就是保留高4位,屏蔽低 4位.(又称作清零)
                (2) 设置位. | .
                    char a = 0x34; --> 0011 0100
                                    a | 0x02:
                                        0011 0100
                                    |   0000 0010
                                    --------------
                                        0011 0110
                    通过或操作,我已经将 0011 0100 设置成了 0011 0110 .
                (3) 实际应用 .(建议对以下算法用笔算理清楚)
                    有一个硬件资源,8位(0~7) . 它的第2位控制led的开关 ,它的第5位,控制蜂鸣器的开关 .其他位是未知,但是很重要并且不能改变的数据位 .
                    现在,我要让第2位置1打开, 第5位置0关闭 .
                        现在 char a = xx(fm)x x(led)xx
                    第一步: 清零. 无论led现在是什么状态, 先清零, 再置位 .
                        将 0000 0001 << 2 --> 0000 0100
                        取反. 1111 1011
                        &运算 . a & 1111 1011 --> xx(fm)x x0xx    (置零成功)
                    第二步: 置数.
                        将 1 << 2 --> 0000 0100
                        |运算 . xx(fm)x x0xx | 0000 0100 --> xx(fm)x x1xx (置数成功)
                    现在,我们已经在不影响 其它位 的情况下,成功地将 第2位 置1 .
                    同样 将第5位置零,可以参考清零做法 .
                        将 1 << 5 --> 0010 0000
                        取反. 1101 1111
                        &运算 . xx(fm)x x1xx & 1101 1111 --> xx0x x1xx
                    
                (4) 总结: << >> & | 这四种运算搭配工作就是 (清零) 和 (置数) !!!!!
                            
                            先清零 ---> 再置数
                    清零: 我要清零第 n 位. char a ; 
                    a &= ~(1<< n)
                    置数: 在清零的基础上,将第n位置 1.
                    a |= (1<< n)
            -- ~
                按位取反 .
            
        2.4 赋值运算
            =, +=, -+, &=, |= ...
        2.5 内存访问符号
            其实 程序 就是cpu 跟 内存 打交道,但是怎么打交道呢?就是访问内存的意思.于是就有了访问内存的符号 .
            -- ()
                ()有两种用法,一种是限制符,用来划分运算的优先级 3*(2+4)
                另一种就是内存访问的意思,一般用于函数. int func().
            -- []
                很多人看到这个,就能想到数组.其实在我们看来,没有所谓的数组,数组的本质实际上就是一段内存空间 .
                多余的描述只会让人限制了它的意义 .
                int a[16]; a[0] = 1; []的作用是通过 a 的地址,找到a的内存空间,然后根据下标0进行偏移,
                最终锁定a[0]这个内存空间,大小是 int 32位,最后将这个内存 置 1. a[0] = 0x0001;
            -- {}
                (1) 函数体的限制符,限制一个函数体的内存空间大小.
                (2) 结构体 共用体等的空间限制.
            -- ->和.
                ->和. 是 自定义空间(结构体) 不同变量的访问方法 .
                
                -> 是地址访问 .
                . 是变量访问 .
                举例:
                                struct school {
                                    int 校长工资;
                                    struct teacher 李老师;
                                    struct teacher 王老师;
                                };
                                struct teacher {
                                    int 工资;
                                };
                    上面是两个结构体,其中,teacher结构体在school这个结构体中被声明 .
                    使用:
                        struct school 希望小学;
                        希望小学.校长工资 = 1w;         //结构体的直接成员变量可以用 . 来访问 .
                        希望小学 -> 李老师.工资 = 5000;  //如果是跳转到另一个结构体,实际上是访问另一个内存空间,要用地址访问符 ->
                        希望小学 -> 王老师.工资 = 5000; //同上.
            -- &和*
                &后面跟数字是与运算 ,后面跟变量是取地址.
                比如 int a; &a就是取a得地址, 常用于 scanf("%d", &a); 就是从键盘获取一个整形数值,然后赋给a指向的哪个内存空间,也就是a的值.
                * 这可能是最恐怖的,但其实也是最亲切的.竟然有一种看到*我就放心了的感觉...
                * 要区别两种场景  声明 和 使用.
                    --------------------------------------------------
                        首先我要解释一下,什么是 声明 和 使用.
                        声明 就是在内存空间中为一个变量 和常量 开辟一个内存空间.
                            int a;
                            char b;
                            char name[5]; 这些都是声明.叫做 声明变量,也有声明函数的.因为函数也是一段内存空间,这里就先不谈.
                        使用 就是将声明好的变量进行使用 .
                            a = 100;
                            b = 'k';
                            strcpy(name,"kmist",5);等等...
                    ----------------------------------------------------
                指针也分为 声明 和 使用 .
                
    (1) 声明
                        声明指针变量的时候,我们用到*,其意义是告知,这是一个指针变量.
                        int *p;
                        char *chp;  //区别 char ch; 多了一个*号,就是告知,这是一个指针变量 .
                        int func(char *p){....} //多了一个*号,就是告知,这是一个指针变量 .
    (2) 使用
                        在声明中,有*告知这个一个指针,但是在使用中,有 *号,是 "访问 指针 指向 的 内存地址" 的意思.
                        int *age;
                        *age = 100;
                        注意:这里应该这样解读: 我声明的一个指针, 这个指针指向了一个int类型的空间.
                        这个空间的地址,叫做age,这个地址本身是一个内存地址,只不过我为他赋予了一个叫age的名字.
                        至于这个空间里面的具体内容, 就是 *age .

C语言基础篇(二)运算符的更多相关文章

  1. php基础篇-二维数组排序 array_multisort

    原文:php基础篇-二维数组排序 array_multisort 对2维数组或者多维数组排序是常见的问题,在php中我们有个专门的多维数组排序函数,下面简单介绍下: array_multisort(a ...

  2. Java语言基础(二) Java关键字

    Java语言基础(二) Java关键字 Java关键字比较多,我就不列举出来了,只记录一些常用的小知识点: ①Java的关键字只有小写. ②then.sizeof都不是Java的关键字,熟悉C++的程 ...

  3. Java语言基础(二)

    Java语言基础(二) 一.变量续 (1).变量有明确的类型 (2).变量必须有声明,初始化以后才能使用 (3).变量有作用域,离开作用域后自动回收 变量作用域在块内有效 (4).在同一定义域中变量不 ...

  4. Go语言基础(二)

    Go语言基础(二) 跟着上篇,继续看Go基础 一.变量作用域 与C类似,有全局变量.局部变量.形参之分 package main import "fmt" // 全局变量 var ...

  5. C语言----输入输出语句(基础篇二)

    今天整理一下自己的基础篇输入和输出的理解,自己没有研究系统输入和输出函数,以后有时间在去深究,之前在别人的博客里面看到这么一句话分享给大家,“学习就是一个不断抄袭,模仿,练习和创新的一个过程”. 使用 ...

  6. Qt入门之基础篇 ( 二 ) :Qt项目建立、编译、运行和发布过程解析

    转载请注明出处:CN_Simo. 题解: 本篇内容主讲Qt应用从创建到发布的整个过程,旨在帮助读者能够快速走进Qt的世界. 本来计划是讲解Qt源码静态编译,如此的话读者可能并不能清楚地知道为何要静态编 ...

  7. docker+k8s基础篇二

    Docker+K8s基础篇(二) docker的资源控制 A:docker的资源限制 Kubernetes的基础篇 A:DevOps的介绍 B:Kubernetes的架构概述 C:Kubernetes ...

  8. Python基础篇(二)_基本数据类型

    Python基础篇——基本数据类型 数字类型:整数类型.浮点数类型.复数类型 整数类型:4种进制表示形式:十进制.二进制.八进制.十六进制,默认采用十进制,其他进制需要增加引导符号 进制种类 引导符号 ...

  9. 黑马程序员_ C语言基础(二)

    ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 概览 今天基础知识分为以下几点内容(注意:循环.条件语句在此不再赘述):   1.Hello W ...

  10. JavaScript笔记基础篇(二)

    基础篇主要是总结一些工作中遇到的技术问题是如何解决的,应为本人属于刚入行阶段技术并非大神如果笔记中有哪些错误,或者自己的一些想法希望大家多多交流互相学习. 1.ToFixed()函数 今天在做Birt ...

随机推荐

  1. Django Rest Framework进阶一

    一.认证 认证请求头 #!/usr/bin/env python # -*- coding:utf-8 -*- from rest_framework.views import APIView fro ...

  2. Azure资源模板化部署,伦家不懒都不好意思了

    如果老板让你在云平台上部署一套系统,你准备怎么做? 嗯,估计得根据具体需求开通或创建一大堆东西:虚拟机.存储.数据库.虚拟网络……别急还没完,接着还要对这些东西的规模.配置等各方面调整和优化.一系列环 ...

  3. SQL中的聚合函数

    聚合函数是对一组值执行计算并返回单一的值的函数,它经常与SELECT语句的GROUP BY子句一同使用,SQL SERVER 中具体的聚合函数如下:1. AVG 返回指定组中的平均值,空值被忽略. 例 ...

  4. Homestead 安装 phpMyAdmin 作为数据库管理客户端 — Laravel 实战 iBrand API 教程

    简介 phpMyAdmin 是一个以PHP为基础,以Web-Base方式架构在网站主机上的MySQL的数据库管理工具,让管理者可用Web接口管理MySQL数据库.借由此Web接口可以成为一个简易方式输 ...

  5. nginx处理HTTP header问题

    在实际开发中遇到http header 自定义key中包含下划线(_)时服务端header丢失的问题,解决办法详细见以下网页内容,感谢原博主 http://blog.csdn.net/dac55300 ...

  6. 【js基础修炼之路】--创建文档碎片document.createDocumentFragment()

          讲这个方法之前,我们应该先了解下插入节点时浏览器会做什么.         在浏览器中,我们一旦把节点添加到document.body(或者其他节点)中,页面就会更新并反映出这个变化,对于 ...

  7. Jerry Wang诚邀广大SAP同仁免费加入我的知识星球,共同探讨SAP技术问题

    大家知道Jerry Wang有一个微信公众号"汪子熙",2017年12月27日,Jerry的这个公众号发布了第一篇文章.到今天2018年10月底为止,正好十个月. 在这10个月的时 ...

  8. .net core 下调用.net framework框架的WCF方法写法

    通过添加服务引用后生成的代码,可以得知首先要设置Basic连接写法的属性,并且设置WCF服务的地址: 我在这里建立工厂类如下: using System; using System.ServiceMo ...

  9. java 生成12位随机数,解决The literal 9999999999999 of type int is out of range 问题

    原本想这样产生一个随机数,但是你会看到,只要数字超过了9位数,就会出问题,提示“The literal 1000000000000 of type int is out of range” 解决方式是 ...

  10. 2017.11.10 web中URL和URI的区别

    URI:Uniform Resource Identifier,统一资源标识符: •URL:Uniform Resource Locator,统一资源定位符: •URN:Uniform Resourc ...