精华内容
下载资源
问答
  • 条件概率/全概率/贝叶斯公式

    万次阅读 多人点赞 2018-07-17 11:39:05
    1、条件概率公式 设A,B是两个事件,且P(B)>0,则在事件B发生的条件下,事件A发生的条件概率(conditional probability)为: P(A|B)=P(AB)/P(B) 分析:一般说到条件概率这一概念的时候,事...

    参考:https://www.cnblogs.com/ohshit/p/5629581.html

    1、条件概率公式

            设A,B是两个事件,且P(B)>0,则在事件B发生的条件下,事件A发生的条件概率(conditional probability)为:

                         P(A|B)=P(AB)/P(B)

    分析:一般说到条件概率这一概念的时候,事件A和事件B都是同一实验下的不同的结果集合,事件A和事件B一般是有交集的,若没有交集(互斥),则条件概率为0,例如:

    ① 扔骰子,扔出的点数介于[1,3]称为事件A,扔出的点数介于[2,5]称为事件B,问:B已经发生的条件下,A发生的概率是多少?

    也即,做一次实验时,即有可能仅发生A,也有可能仅发生B,也有可能AB同时发生,

    ② 同时扔3个骰子,“三个数都不一样”称为事件A,“其中有一个点数为1”称为事件B。这一题目中,AB也是有交集的。

    用图更能容易的说明上述问题,我们进行某一实验,某一实验所有的可能的样本的结合为Ω(也即穷举实验的所有样本),圆圈A代表事件A所能囊括的所有样本,圆圈B代表事件B所能囊括的所有样本。

    由图再来理解一下这个问题:“B已经发生的条件下,A发生的概率”,这句话中,“B已经发生”就相当于已经把样本的可选范围限制在了圆圈B中,其实就等价于这句话:“在圆圈B中,A发生的概率”,显然P(A|B)就等于AB交集中样本的数目/B的样本数目。为什么这里用的是样本的数目相除,而上面的公式却是用的概率相除,原因很简单,用样本数目相除时,把分子分母同除以总样本数,这就变成了概率相除。

    2、乘法公式

             1.由条件概率公式得:

                           P(AB)=P(A|B)P(B)=P(B|A)P(A)    

                 上式即为乘法公式;

             2.乘法公式的推广:对于任何正整数n≥2,当P(A1A2...An-1) > 0 时,有:

                     P(A1A2...An-1An)=P(A1)P(A2|A1)P(A3|A1A2)...P(An|A1A2...An-1)

    3、全概率公式

            1. 如果事件组B1,B2,.... 满足

                   1.B1,B2....两两互斥,即 Bi ∩ Bj = ∅ ,i≠j , i,j=1,2,....,且P(Bi)>0,i=1,2,....;

                   2.B1∪B2∪....=Ω ,则称事件组 B1,B2,...是样本空间Ω的一个划分

              设 B1,B2,...是样本空间Ω的一个划分,A为任一事件,则:

    题1:

    已知:各个A∩Bi的样本数、Bi的样本数,
    求A的样本数 / 总样本数Ω?

    题2:

    已知:各个A∩Bi的概率、Bi的概率,
    求A的概率?

     

    上图中,某一实验所有的可能的样本的集合为Ω,圆圈A代表事件A所能囊括的所有样本,把总集合Ω分为n个小集合,依次为B1、B2···Bn,这些小集合两两互斥,那么显然,A的样本数目可以通过与Bi的交集来获得,也即=(A∩B1的样本数)+(A∩B2的样本数)+····+(A∩Bn的样本数)。前文已经说过,样本数公式和概率公式,本质上是一样的东西, 题1与题2的是完全相同的题目。

    4、贝叶斯公式

          1.与全概率公式解决的问题相反,贝叶斯公式是建立在条件概率的基础上寻找事件发生的原因(即大事件A已经发生的条件下,分割中的小事件Bi的概率),设B1,B2,...是样本空间Ω的一个划分,则对任一事件A(P(A)>0),有

    上式即为贝叶斯公式(Bayes formula),Bi 常被视为导致试验结果A发生的”原因“,P(Bi)(i=1,2,...)表示各种原因发生的可能性大小,故称先验概率;P(Bi|A)(i=1,2...)则反映当试验产生了结果A之后,再对各种原因概率的新认识,故称后验概率。

    已知:各个A∩Bi的样本数、Bi的样本数,
    求A∩B3的样本数 / A的样本数?

    例子:发报台分别以概率0.6和0.4发出信号“∪”和“—”。由于通信系统受到干扰,当发出信号“∪”时,收报台分别以概率0.8和0.2受到信号“∪”和“—”;又当发出信号“—”时,收报台分别以概率0.9和0.1收到信号“—”和“∪”。求当收报台收到信号“∪”时,发报台确系发出“∪”的概率。

    解析:贝叶斯这一概念,所探讨的问题,也是事件A和事件B都是某一实验的不同的结果集合,然后把事件B这个结果集合分为n小份,每一小份也是结果集合,只不过这些小集合一定位于B集合内部,每一小份结果集合称为Bi(i∈[1,n]),Bi之间两两互斥,所有Bi并起来就是B。
    本例中,实验为“发一次报,收一次报,然后记录发、收的字符”,事件A为“收到了U”,事件B为"发出了信号",事件B1为“发出了U”,事件B2为“发出了—”,显然这里B1∪B2=B,B1∩B2=∅。要想求P(B1 | A),根据条件概率公式,P(B1 | A)=P(B1 A)/P(A),只要分别计算出分子分母就行了,显然分子可以用上面的乘法公式来求,分母为已知(若分母未知,就得用全概率公式来求)。

    贝叶斯公式,根本不用记忆,其实就是条件概率、乘法公式、全概率公式的组合。

     

    总结:(1)以上四个公式的研究对象,都是“同一实验下的不同的结果集合”

    (2)为了容易理解这四个概率公式,可以把用“样本数目公式”来代替“概率公式”,来求概率。

     

    展开全文
  • 注明:上篇文章介绍了springboot+mybatis-plus通用CRUD的用法,这篇文章我们来介绍一下mybatis-plus强大的条件构造器。mybatis-plus的版本为最新版3.0.3 。条件构造器咱们讲述queryWrapper和updateWrapper的用法、...

    注明:上篇文章介绍了springboot+mybatis-plus通用CRUD的用法,这篇文章我们来介绍一下mybatis-plus强大的条件构造器。mybatis-plus的版本为最新版3.0.3 。条件构造器咱们讲述queryWrapper和updateWrapper的用法、关系、以及强大之处。

    首先在这里写下官方文档的链接位置,官方文档说的很详细。如果还想知道在项目中的具体用法请往下看。

    一、条件构造器关系介绍

    在这里插入图片描述

    介绍 :

    1. 上图绿色框为抽象类abstract
    2. 蓝色框为正常class类,可new对象
    3. 黄色箭头指向为父子类关系,箭头指向为父类

    wapper介绍 :

    1. Wrapper : 条件构造抽象类,最顶端父类,抽象类中提供4个方法西面贴源码展示
    2. AbstractWrapper : 用于查询条件封装,生成 sql 的 where 条件
    3. AbstractLambdaWrapper : Lambda 语法使用 Wrapper统一处理解析 lambda 获取 column。
    4. LambdaQueryWrapper :看名称也能明白就是用于Lambda语法使用的查询Wrapper
    5. LambdaUpdateWrapper : Lambda 更新封装Wrapper
    6. QueryWrapper : Entity 对象封装操作类,不是用lambda语法
    7. UpdateWrapper : Update 条件封装,用于Entity对象更新操作

    二、项目实例

    在这里我以QueryWrapper和UpdateWrapper为例,进行测试讲解。我会在上篇博客原有的基础上进行测试,如果不喜欢搭建项目的可直接下载我上个项目,上个项目的博客对应上个项目的讲解
    在这里插入图片描述

    上图表格为条件构造器使用中的各个方法格式和说明,如有不懂可参考官方文档内容

    构造器条件

    package com.lqf.crud;
    
    import com.baomidou.mybatisplus.core.conditions.Wrapper;
    import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
    import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
    import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
    import com.baomidou.mybatisplus.core.metadata.IPage;
    import com.baomidou.mybatisplus.core.toolkit.Constants;
    import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
    import com.lqf.crud.bean.crm.User;
    import com.lqf.crud.dao.crm.UserMapper;
    import com.sun.org.apache.xerces.internal.util.EntityResolverWrapper;
    import org.apache.ibatis.annotations.Param;
    import org.apache.ibatis.session.RowBounds;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.junit4.SpringRunner;
    import org.springframework.web.jsf.el.WebApplicationContextFacesELResolver;
    
    import javax.naming.Name;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class QueryWrapperTests {
    
        @Autowired
        private UserMapper mapper;
    
        /**
         * <p>
         * 根据根据 entity 条件,删除记录,QueryWrapper实体对象封装操作类(可以为 null)
         * 下方获取到queryWrapper后删除的查询条件为name字段为null的and年龄大于等于12的and email字段不为null的
         * 同理写法条件添加的方式就不做过多介绍了。
         * </p>
         */
        @Test
        public void delete() {
            QueryWrapper<User> queryWrapper = new QueryWrapper<>();
            queryWrapper
                    .isNull("name")
                    .ge("age", 12)
                    .isNotNull("email");
            int delete = mapper.delete(queryWrapper);
            System.out.println("delete return count = " + delete);
        }
    
    
        /**
         * <p>
         * 根据 entity 条件,查询一条记录,
         * 这里和上方删除构造条件一样,只是seletOne返回的是一条实体记录,当出现多条时会报错
         * </p>
         */
        @Test
        public void selectOne() {
            QueryWrapper<User> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("name", "lqf");
    
            User user = mapper.selectOne(queryWrapper);
            System.out.println(user);
        }
    
    
        /**
         * <p>
         * 根据 Wrapper 条件,查询总记录数
         * </p>
         *
         * @param queryWrapper 实体对象
         */
        @Test
        public void selectCount() {
            QueryWrapper<User> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("name", "lqf");
    
            Integer count = mapper.selectCount(queryWrapper);
            System.out.println(count);
        }
    
    
        /**
         * <p>
         * 根据 entity 条件,查询全部记录
         * </p>
         *
         * @param queryWrapper 实体对象封装操作类(可以为 null)为null查询全部
         */
        @Test
        public void selectList() {
            List<User> list = mapper.selectList(null);
    
            System.out.println(list);
        }
    
        /**
         * <p>
         * 根据 Wrapper 条件,查询全部记录
         * </p>
         *
         * @param queryWrapper 实体对象封装操作类(可以为 null)
         */
        @Test
        public void selectMaps() {
            QueryWrapper<User> queryWrapper = new QueryWrapper<>();
            queryWrapper.isNotNull("name");
            List<Map<String, Object>> maps = mapper.selectMaps(queryWrapper);
            for (Map<String, Object> map : maps) {
                System.out.println(map);
            }
        }
    
        /**
         * 打印结果
         * {name=lqf, id=1046282328366391406, age=12, email=lqf@163.com, status=false}
         * {name=lqf, id=1046282328366391407, age=12, email=lqf@163.com, status=false}
         * {name=lqf, id=1046282328366391408, age=12, email=lqf@163.com, status=false}
         * {name=lqf, id=1046282328366391409, age=12, email=lqf@163.com, status=false}
         * {name=lqf, id=1046282328366391410, age=12, email=lqf@163.com, status=false}
         * {name=lqf, id=1046282328366391411, age=12, email=lqf@163.com, status=false}
         * {name=lqf, id=1046282328366391412, age=12, email=lqf@163.com, status=false}
         * {name=lqf, id=1046282328366391413, age=12, email=lqf@163.com, status=false}
         * {name=lqf, id=1046282328366391414, age=12, email=lqf@163.com, status=false}
         * {name=lqf, id=1046282328366391415, age=12, email=lqf@163.com, status=false}
         * {name=lqf, id=1046282328366391416, age=12, email=lqf@163.com, status=false}
         * {name=lqf, id=1046282328366391417, age=12, email=lqf@163.com, status=false}
         * {name=lqf, id=1046282328366391418, age=12, email=lqf@163.com, status=false}
         * json类型的键值对模式
         */
    
        /**
         * <p>
         * 根据 entity 条件,查询全部记录(并翻页)
         * </p>
         *
         * @param page         分页查询条件(可以为 RowBounds.DEFAULT)
         * @param queryWrapper 实体对象封装操作类(可以为 null)
         */
        @Test
        public void selectPage() {
            Page<User> page = new Page<>(1, 5);
            QueryWrapper<User> queryWrapper = new QueryWrapper<>();
    
            IPage<User> userIPage = mapper.selectPage(page, queryWrapper);
            System.out.println(userIPage);
        }
    
        /**
         * 打印结果
         * ==>  Preparing: SELECT COUNT(1) FROM user
         * ==> Parameters:
         * <==    Columns: COUNT(1)
         * <==        Row: 100
         * ==>  Preparing: SELECT id,name,age,email,status FROM user LIMIT 0,5
         * ==> Parameters:
         * <==    Columns: id, name, age, email, status
         * <==        Row: 1046282328366391319, lqf, 12, lqf@163.com, 0
         * <==        Row: 1046282328366391320, lqf, 12, lqf@163.com, 0
         * <==        Row: 1046282328366391321, lqf, 12, lqf@163.com, 0
         * <==        Row: 1046282328366391322, lqf, 12, lqf@163.com, 0
         * <==        Row: 1046282328366391323, lqf, 12, lqf@163.com, 0
         * <==      Total: 5
         *
         *
         * 这里需要在项目中加入分页插件
         *   @Bean
         *     public PaginationInterceptor paginationInterceptor() {
         *         return new PaginationInterceptor();
         *     }
         */
    
    
        /**
         * <p>
         * 根据 Wrapper 条件,查询全部记录(并翻页)
         * </p>
         *
         * @param page         分页查询条件
         * @param queryWrapper 实体对象封装操作类
         */
        @Test
        public void selectMapsPage() {
            Page<User> page = new Page<>(1, 5);
            QueryWrapper<User> queryWrapper = new QueryWrapper<>();
    
            IPage<Map<String, Object>> mapIPage = mapper.selectMapsPage(page, queryWrapper);
            System.out.println(mapIPage);
        }
    
        /**
         * 和上个分页同理只是返回类型不同
         */
    
    
        /**
         * <p>
         * 根据 whereEntity 条件,更新记录
         * </p>
         *
         * @param entity        实体对象 (set 条件值,不能为 null)
         * @param updateWrapper 实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句)
         */
        @Test
        public void update() {
    
            //修改值
            User user = new User();
            user.setStatus(true);
            user.setName("zhangsan");
    
            //修改条件s
            UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>();
            userUpdateWrapper.eq("name", "lqf");
    
            int update = mapper.update(user, userUpdateWrapper);
    
            System.out.println(update);
        }
    
        /**
         * 打印结果
         * ==>  Preparing: UPDATE user SET name=?, status=? WHERE name = ?
         * ==> Parameters: zhangsan(String), true(Boolean), lqf(String)
         * <==    Updates: 100
         * Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@56a4f272]
         * 100
         * 2018-10-02 15:08:03.928  INFO 7972 --- [       Thread-2] o.s.w.c.s.GenericWebApplicationContext   : Closing org.springframework.web.context.support.GenericWebApplicationContext@37313c65: startup date [Tue Oct 02 15:08:00 CST 2018]; root of context hierarchy
         * 2018-10-02 15:08:03.937  INFO 7972 --- [       Thread-2] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
         * 2018-10-02 15:08:04.053  INFO 7972 --- [       Thread-2] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
         *
         * Process finished with exit code 0
         */
    
    }
    
    

    上方代码对通过构造器条件进行的查询、删除、修改进行是演示,构造器方法没有做过多演示,但是所有的构造器方法同理使用,如果还有不会用的点开看官方文档查看并按照上方例子使用即可。

    源码下载地址

    上一篇 :(四) springboot + mybatis plus详细拆解CRUD
    下一篇 : (六)springboot + mybatis plus实现多表联查分页3.X版本

    展开全文
  • 条件编译#ifdef的妙用详解_透彻

    万次阅读 多人点赞 2018-03-05 10:44:24
    本文主要介绍c语言中条件编译相关的预编译指令,包括 #define、#undef、#ifdef、#ifndef、#if、#elif、#else、#endif、defined。#define 定义一个预处理宏#undef 取消宏的定义#if 编译预处理中的条件命令,相当于C...

    本文主要介绍c语言中条件编译相关的预编译指令,包括  #define、#undef、#ifdef、#ifndef、#if、#elif、#else、#endif、defined。

    #define            定义一个预处理宏
    #undef            取消宏的定义

    #if                   编译预处理中的条件命令,相当于C语法中的if语句
    #ifdef              判断某个宏是否被定义,若已定义,执行随后的语句
    #ifndef            与#ifdef相反,判断某个宏是否未被定义
    #elif                若#if, #ifdef, #ifndef或前面的#elif条件不满足,则执行#elif之后的语句,相当于C语法中的else-if
    #else              与#if, #ifdef, #ifndef对应, 若这些条件不满足,则执行#else之后的语句,相当于C语法中的else
    #endif             #if, #ifdef, #ifndef这些条件命令的结束标志.
    defined          与#if, #elif配合使用,判断某个宏是否被定义

    二、条件编译

    条件编译是根据实际定义宏(某类条件)进行代码静态编译的手段。可根据表达式的值或某个特定宏是否被定义来确定编译条件。

    最常见的条件编译是防止重复包含头文件的宏,形式跟下面代码类似:

    1 #ifndef ABCD_H
    2 #define ABCD_H
    3 
    4 // ... some declaration codes
    5 
    6 #endif // #ifndef ABCD_H

    在实现文件中通常有如下类似的定义:

    复制代码
     1 #ifdef _DEBUG
     2 
     3 // ... do some operations
     4 
     5 #endif
     6 
     7 #ifdef _WIN32
     8 
     9 // ... use  Win32 API
    10 
    11 #endif
    复制代码

    这些都是条件编译的常用情境。

    三、条件编译中使用的预编译指令

    #define            定义一个预处理宏
    #undef            取消宏的定义

    #if                   编译预处理中的条件命令,相当于C语法中的if语句
    #ifdef              判断某个宏是否被定义,若已定义,执行随后的语句
    #ifndef            与#ifdef相反,判断某个宏是否未被定义
    #elif                若#if, #ifdef, #ifndef或前面的#elif条件不满足,则执行#elif之后的语句,相当于C语法中的else-if
    #else              与#if, #ifdef, #ifndef对应, 若这些条件不满足,则执行#else之后的语句,相当于C语法中的else
    #endif             #if, #ifdef, #ifndef这些条件命令的结束标志.
    defined          与#if, #elif配合使用,判断某个宏是否被定义

    四、预编译指令应用举例

    1. #define、#undef

    #define命令定义一个宏:
    #define MACRO_NAME[(args)] [tokens[(opt)]]
    之后出现的MACRO_NAME将被替代为所定义的标记(tokens)。宏可带参数,而后面的标记也是可选的。

    宏定义,按照是否带参数通常分为对象宏、函数宏两种。
    对象宏: 不带参数的宏被称为"对象宏(objectlike macro)"。对象宏多用于定义常量、通用标识。例如:

    // 常量定义
    #define MAX_LENGTH 100
    // 通用标识,日志输出宏
    #define SLog printf
    // 预编译宏
    #define _DEBUG

    函数宏:带参数的宏。利用宏可以提高代码的运行效率: 子程序的调用需要压栈出栈, 这一过程如果过于频繁会耗费掉大量的CPU运算资源。 所以一些代码量小但运行频繁的代码如果采用带参数宏来实现会提高代码的运行效率。但多数c++程序不推荐使用函数宏,调试上有一定难度,可考虑使用c++的inline代替之。例如:

    // 最小值函数
    #define MIN(a,b) ((a)>(b)? (a):(b))
    // 安全释放内存函数
    #define SAFE_DELETE(p) {if(NULL!=p){delete p; p = NULL;}}

    #undef可以取消宏定义,与#define对应。

    2. defined

    defined用来测试某个宏是否被定义。defined(name): 若宏被定义,则返回1,否则返回0。
    它与#if、#elif、#else结合使用来判断宏是否被定义,乍一看好像它显得多余, 因为已经有了#ifdef和#ifndef。defined可用于在一条判断语句中声明多个判别条件;#ifdef和#ifndef则仅支持判断一个宏是否定义。

    #if defined(VAX) && defined(UNIX) && !defined(DEBUG) 

    和#if、#elif、#else不同,#ifdef、#ifndef、defined测试的宏可以是对象宏,也可以是函数宏。

    3. #ifdef、#ifndef、#else、#endif

    条件编译中相对常用的预编译指令。模式如下:

    复制代码
    #ifdef ABC
    // ... codes while definded ABC
    #elif (CODE_VERSION > 2)
    // ... codes while CODE_VERSION > 2
    #else
    // ... remained cases
    #endif // #ifdef ABC 
    复制代码

    #ifdef用于判断某个宏是否定义,和#ifndef功能正好相反,二者仅支持判断单个宏是否已经定义,上面例子中二者可以互换。如果不需要多条件预编译的话,上面例子中的#elif和#else均可以不写。

    4. #if、#elif、#else、#endif

    #if可支持同时判断多个宏的存在,与常量表达式配合使用。常用格式如下:

    复制代码
    #if 常量表达式1
    // ... some codes
    #elif 常量表达式2
    // ... other codes
    #elif 常量表达式3
    // ...
    ...
    #else
    // ... statement
    #endif
    复制代码

    常量表达式可以是包含宏、算术运算、逻辑运算等等的合法C常量表达式,如果常量表达式为一个未定义的宏, 那么它的值被视为0。

    #if MACRO_NON_DEFINED // 等价于
    
    #if 0

    在判断某个宏是否被定义时,应当避免使用#if,因为该宏的值可能就是被定义为0。而应当使用#ifdef或#ifndef。
    注意: #if、#elif之后的宏只能是对象宏。如果宏未定义,或者该宏是函数宏,则编译器可能会有对应宏未定义的警告。

    五、总结

     

    本文主要介绍c语言中有关预编译的指令。撰写本文的目的在于理清相关概念调用,在后续预编译使用时可以找到最合适的指令及格式。比如同时满足多个宏定义的预编译、多分支预编译、#elif和#else指令的配合等。
     
    一、if条件编译,选择编译

    (1)        

        #if ()
            //*******
        #endif
    (2)
        #if ()
            //******
        #else
            //******
        #endif
    (3)
        #if ()
            //******
        #elif ()
            //******
        #elif ()
            //******
        #endif
    二、注意此处不能加“()”不然会把括号也视为宏定义的字符串
    #define DBG
    三、
    #define  A  C(0、1...)
    四、注意此处不能加“()”不然会把括号也视为宏定义的字符串
    #define  DBG
    #undefine DBG
    五、注意此处不能加“()”不然会把括号也视为宏定义的字符串

    (1)    

        #ifdef  DBG
            #define UNDBG
            #define UNDBG1
        #endif
    (2)
        #ifundef  DBG
            #define UNDBG
            #define UNDBG
        #endif

     

    六、符合条件“&& 和 ||”复合条件下必须加上“()”标准形式如: # if (define (DBG)) || (define (DBG1))
          (1)
          # if define DBG || define DBG1 || define DBG2
                //******
            #endif
    (2)
            #if !define DBG || !define DBG2
                //******
            #endif
     
     

     

     

           1、条件编译

                  请看下面一个例子:

    #include<stdio.h>
    #define BB
    #ifdef AA
    #define HELLO "hello world"
    #elif BB
    #define HELLO "hello CC"
    #endifint main()
    {
            printf("%s\n",HELLO);
            return 1;
    }

     

            如果你觉得这个打印会是hello CC.那你就和我犯了一样的错误了。如果你用gcc -E hello.c -o hello.i 编译,(这条是预编译命令,下面会讲到。)会出现:error: #if with no expression的错误。原因是BB虽然定义了,但是定义的是空值,放在#elif后面就不行。因为#elif不仅仅是检查后面的宏有没有定义,还会检查其值。但是#ifdef就只是检查后面的宏是否定义,而不管其值为多少。读者可以把#define
            BB改成#define AA试一下,结果就会打印hello world了。
            读者如果有兴趣,也可以把#define BB改成#define BB   0  试一试,这时用gcc -E hello.c -o hello.i预编译可以编译通过,但是编译过程就不行了,因为#elif   0为假,HELLO没有定义。
    这几个宏是为了进行条件编译。一般情况下,源程序中所有的行都参加编译。但是有时希望对其中一部分内容只在满足一定条件才进行编译,也就是对一部 分内容指定编译的条件,这就是“条件编译”。有时,希望当满足某条件时对一组语句进行编译,而当条件不满足时则编译另一组语句。
        条件编译命令最常见的形式为:
        #ifdef 标识符
        程序段1
        #else
        程序段2
        #endif
        
        它的作用是:当标识符已经被定义过(一般是用#define命令定义),则对程序段1进行编译,否则编译程序段2。
        其中#else部分也可以没有,即:
        #ifdef
        程序段1
        #denif
        
        这里的“程序段”可以是语句组,也可以是命令行。这种条件编译可以提高C源程序的通用性。如果一个C源程序在不同计算机系统上运行,而不同的计算机又有一定的差异。例如,我们有一个数据类型,在Windows平台中,应该使用long类型表示,而在其他平台应该使用float表示,这样往往需要对源程序作必要的修改,这就降低了程序的通用性。可以用以下的条件编译:
        #ifdef WINDOWS
        #define MYTYPE long
        #else
        #define MYTYPE float
        #endif
        
        如果在Windows上编译程序,则可以在程序的开始加上
        #define WINDOWS
        
        这样则编译下面的命令行:
        #define MYTYPE long
        
        如果在这组条件编译命令之前曾出现以下命令行:
        #define WINDOWS 0
        
        则预编译后程序中的MYTYPE都用float代替。这样,源程序可以不必作任何修改就可以用于不同类型的计算机系统。当然以上介绍的只是一种简单的情况,可以根据此思路设计出其它的条件编译。
        例如,在调试程序时,常常希望输出一些所需的信息,而在调试完成后不再输出这些信息。可以在源程序中插入以下的条件编译段:
        #ifdef DEBUG
        print ("device_open(%p)\n", file);
        #endif
        
        如果在它的前面有以下命令行:
        #define DEBUG
        
        则在程序运行时输出file指针的值,以便调试分析。调试完成后只需将这个define命令行删除即可。有人可能觉得不用条件编译也可达此目的,即在调试时加一批printf语句,调试后一一将printf语句删除去。的确,这是可以的。但是,当调试时加的printf语句比较多时,修改的工作量是很大的。用条件编译,则不必一一删改printf语句,只需删除前面的一条“#define DEBUG”命令即可,这时所有的用DEBUG作标识符的条件编译段都使其中的printf语句不起作用,即起统一控制的作用,如同一个“开关”一样。
        有时也采用下面的形式:
        #ifndef 标识符
        程序段1
        #else
        程序段2
        #endif
        
        只是第一行与第一种形式不同:将“ifdef”改为“ifndef”。它的作用是:若标识符未被定义则编译程序段1,否则编译程序段2。这种形式与第一种形式的作用相反。
        以上两种形式用法差不多,根据需要任选一种,视方便而定。
        还有一种形式,就是#if后面的是一个表达式,而不是一个简单的标识符:
        #if 表达式
        程序段1
        #else
        程序段2
        #endif
        
        它的作用是:当指定的表达式值为真(非零)时就编译程序段1,否则编译程序段2。可以事先给定一定条件,使程序在不同的条件下执行不同的功能。
        例如:输入一行字母字符,根据需要设置条件编译,使之能将字母全改为大写输出,或全改为小写字母输出。
        #define LETTER 1
        main()
        {
        char str[20]="C Language",c;
        int i="0";
        while((c=str[i])!='\0'){
        i++;
        #if LETTER
        if(c>='a'&&c<='z') c="c-32";
        #else
        if(c>='A'&&c<='Z') c="c"+32;
        #endif
        printf("%c",c);
        }
        }
        
        运行结果为:C LANGUAGE
        现在先定义LETTER为1,这样在预处理条件编译命令时,由于LETTER为真(非零),则对第一个if语句进行编译,运行时使小写字母变大写。如果将程序第一行改为:
        #define LETTER 0
        
        则在预处理时,对第二个if语句进行编译处理,使大写字母变成小写字母(大写字母与相应的小写字母的ASCII代码差32)。此时运行情况为:
        c language
        有人会问:不用条件编译命令而直接用if语句也能达到要求,用条件编译命令有什么好处呢?的确,此问题完全可以不用条件编译处理,但那样做目标程序长(因为所有语句都编译),而采用条件编译,可以减少被编译的语句,从而减少目标的长度。当条件编译段比较多时,目标程序长度可以大大减少。


    浅谈#ifdef在软件开发中的妙用

      笔者从事UNIX环境下某应用软件的开发与维护工作,用户分布于全国各地,各用户需要的基本功能都是一样的,但在某些功能上要随着需求变化,不断加以升级,要想实现全国各地用户的升级工作是很困难的,而我们则只是利用E-mail发送补丁程序给用户,这些补丁程序都是在一套软件的基础上不断地修改与扩充而编写的,并由不同的标志文件转入到不同的模块,虽然程序体积在不断扩大,但丝毫不影响老用户的功能,这主要是得益于C程序的#ifdef/#else/#endif的作用。


      我们主要使用以下几种方法,假设我们已在程序首部定义#ifdef DEBUG与#ifdef TEST:

      1.利用#ifdef/#endif将某程序功能模块包括进去,以向某用户提供该功能。

      在程序首部定义#ifdef HNLD:

      #ifdef HNLD

      include"n166_hn.c"

      #endif

      如果不许向别的用户提供该功能,则在编译之前将首部的HNLD加一下划线即可。

      2.在每一个子程序前加上标记,以便追踪程序的运行。

      #ifdef DEBUG

      printf(" Now is in hunan !");

      #endif

      3.避开硬件的限制。有时一些具体应用环境的硬件不一样,但限于条件,本地缺乏这种设备,于是绕过硬件,直接写出预期结果。具体做法是:

      #ifndef TEST

      i=dial();

      //程序调试运行时绕过此语句

      #else

      i=0;

      #endif

      调试通过后,再屏蔽TEST的定义并重新编译,即可发给用户使用了。

    # ifdef  #ifndef 等用法(转)

      头件的中的#ifndef,这是一个很关键的东西。比如你有两个C文件,这两个C文件都include了同一个头文件。而编译时,这两个C文件要一同编译成一个可运行文件,于是问题来了,大量的声明冲突。

    还是把头文件的内容都放在#ifndef和#endif中吧。不管你的头文件会不会被多个文件引用,你都要加上这个。一般格式是这样的:

    #ifndef <标识>
    #define <标识>

    ......
    ......

    #endif

    <标识>在理论上来说可以是自由命名的,但每个头文件的这个“标识”都应该是唯一的。标识的命名规则一般是头文件名全大写,前后加下划线,并把文件名中的“.”也变成下划线,如:stdio.h

    #ifndef _STDIO_H_
    #define _STDIO_H_

    ......

    #endif

    2.在#ifndef中定义变量出现的问题(一般不定义在#ifndef中)。

    #ifndef AAA
    #define AAA
    ...
    int i;
    ...
    #endif
    里面有一个变量定义
    在vc中链接时就出现了i重复定义的错误,而在c中成功编译。

    结论:

    (1).当你第一个使用这个头的.cpp文件生成.obj的时候,int i 在里面定义了当另外一个使用这个的.cpp再次[单独]生成.obj的时候,int i 又被定义然后两个obj被另外一个.cpp也include 这个头的,连接在一起,就会出现重复定义.

    (2).把源程序文件扩展名改成.c后,VC按照C语言的语法对源程序进行编译,而不是C++。在C语言中,若是遇到多个int i,则自动认为其中一个是定义,其他的是声明。

    (3).C语言和C++语言连接结果不同,可能(猜测)是在进行编译的时候,C++语言将全局
    变量默认为强符号,所以连接出错。C语言则依照是否初始化进行强弱的判断的。(参考)

    解决方法:

    (1).把源程序文件扩展名改成.c。

    (2).推荐解决方案:
    .h中只声明 extern int i;在.cpp中定义

    <x.h>
    #ifndef __X_H__
    #define __X_H__
    extern int i;
    #endif //__X_H__
    <x.c>
    int i;

    注意问题:

    (1).变量一般不要定义在.h文件中。

     

     

    展开全文
  • 在Golang中,这里的条件是指布尔值(bool),所以下面先介绍一下条件操作符 条件操作符一览 条件操作符是指作用于一个或两个值,结果是布尔值的操作符。可以细分成两种: 关系运算符 ==等于 !=不等于 >大于....

    视频: https://www.bilibili.com/video/BV16r4y1A7jG/

    条件分支

    至今为止,我们接触的程序结构都是顺序结构,是从上到下,依次执行的:

    下面介绍另外一种结构——选择结构:

    根据条件的不同,使程序走向不同的流程

    在Golang中,这里的条件是指布尔值(bool),所以下面先介绍一下条件操作符

    条件操作符一览

    条件操作符是指作用于一个或两个值,结果是布尔值的操作符。可以细分成两种:

    • 关系运算符
      • == 等于
      • != 不等于
      • > 大于
      • >= 大于或等于
      • < 小于
      • <= 小于或等于
    • 逻辑运算符(作用于布尔值)
      • && 逻辑与,两者皆为true时,结果为true,否则为false(具有短路特性)
      • || 逻辑或,两者其一为true时,结果为true,否则为false(具有短路特性)
      • ! 取反,true变false,false变true

    看个例子:

    If语句

    单独的If语句有如下格式:

    condition(条件)必须是一个布尔值,如果为true时,则执行花括号内的代码块,否则不执行

    举个例子,比如成绩大于90分为"优秀":

    成绩大于或等于70且小于90为"中等":

    这里的 score >= 70 && score < 90 最终结果是一个布尔值true,因为:

    1. score >= 70 为 true
    2. score < 90 为 true
    3. true && true 为 true

    等价于下面例子:

    If-Else

    If-Else语句有如下格式:

    condition(条件)必须是一个布尔值,如果为true时,则执行if代码块,否则执行else代码块

    举个例子,成绩大于60为"及格",否则"不及格":

    尝试改动score的值,看看流程的走向:

    If-ElseIf-Else

    If-ElseIf-Else语句有如下格式:

    condition(条件)必须是一个布尔值,可以有多个else if,从上到下依次检测条件是否为true,为true则执行对应代码块

    比如一个完整的成绩判别大概是这样的:

    尝试改动score的值,看看流程的走向:

    If的前置语句

    Golang允许在条件判断之前先执行一个语句(statement),称为前置语句,格式如下:

    举个例子:

    先执行了fmt.Println(1),判别条件1<2为true继而执行了fmt.Println(2)

    但Gopher们(Golang开发者)一般用前置语句来声明初始化变量,比如:

    但是上面代码与下面代码效果是不一样的:

    试一下,注意观察不同之处:

    1. 在if前置语句中声明的变量作用域只在if代码块中有效(变量作用域的知识后面再讲)
    2. 在if前置语句中只能用短声明语法来声明变量

    总结

    下节介绍Golang中另一种选择结构 —— Switch语句

    bye~

    原文地址: https://nbody1996.gitee.io/becoming_gopher/posts/010/

    展开全文
  • 1、使用Specification+JPA不... * 生成全属性条件查询通用Specification * * @param tableMap 属性参数 * @param clazz 要查询的实体类或vo类 * @param map 外键关联查询 * @param <S> * @param <T>
  • mysql 联合索引生效的条件、索引失效的条件

    万次阅读 多人点赞 2019-02-23 10:11:30
    1.联合索引失效的条件 联合索引又叫复合索引。两个或更多个列上的索引被称作复合索引。 对于复合索引:Mysql从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份,但只能是最左侧部分。例如索引是key...
  • 看上图 where可以重复被调用 需要注意的是字符串条件只支持一次
  • 详述 Elasticsearch 通过范围条件查询索引数据的方法

    万次阅读 多人点赞 2019-04-05 11:15:59
    在使用 Elasticsearch 的时候,我们可能会遇到需要**以范围为条件查询索引数据**的需求。有两种方法可以实现我们的需求: - 第一种:在服务器或者终端,使用命令来查询索引数据; - 第二种:编写程序,通过 Elastic...
  • 本文主要探讨优化问题中强、弱对偶性以及KKT条件的证明。
  • SQL语法——left join on 多条件

    万次阅读 多人点赞 2018-03-30 22:22:30
    left join on +多条件与where区别 重点 先匹配,再筛选where条件。 本文将通过几个例子说明两者的差别。 表1:product id amount 1 100 2 200 3 300 4 400 表2:product_details...
  • 动态规划之没有条件创造条件

    万次阅读 2020-06-27 12:19:27
    动态规划之没有条件创造条件   一个问题需要使用动态规划,则需要满足几个条件,这些条件在先前的文章中也都列举过。其中 有些条件是可以适当放缩的,有的条件是绝对需要满足的,那就是无后效性,通俗来说就是当前...
  • 在求解最优化问题中,拉格朗日乘子法(Lagrange Multiplier)和KKT(Karush Kuhn Tucker)条件是两种最常用的方法。在有等式约束时使用拉格朗日乘子法,在有不等约束时使用KKT条件。  我们这里提到的最优化问题...
  • 关于充分条件、必要条件、充分必要条件这三个概念一直没弄明白,今天总算开窍了、哈哈。 PS:关于这三个概念,网上很多地方有讲(有对的,有错的),现在我将正确的概念贴出来,希望大家少走弯路。 充分条件 如果A...
  • bpmn条件

    千次阅读 2020-07-14 19:11:43
    本文章主要讲解了bpmn的条件,系列文章包含工作流、工作流系统、工作流引擎的相关讲解,涉及的到Camunda BPM、BPMN规范、activit、 flowable的基础性知识,对于流程自动化、业务流程等进行了深入研究探讨。
  • INSERT 语句 增加条件条件成立插入,否则不插入

    万次阅读 热门讨论 2017-06-07 03:09:29
    遇到一个sql插入的场景,就是在sql插入新数据的时候,直接在sql中判断条件是否满足,如果条件不满足则不插入新数据,某则插入新数据。 这里的场景是给用户发放金币,那么就有两个问题是需要注意的 1、用户可以领取...
  • 前置条件与后置条件

    万次阅读 2018-05-08 19:41:01
    前置条件类型承担某些职责的时候需要一定的资源,即:前置条件,如果不满足前置条件,则说明:调用代码有问题。后置条件客户遵守了条件,类型必须兑现其承诺,即:后置条件,如果不满足后置条件·:则说明·:业务...
  • for(条件1;条件2;条件3)

    千次阅读 2016-08-07 10:54:32
    for(条件1;条件2;条件3) { //语句 } 执行顺序是条件1->条件2->语句->条件3->条件2->语句->条件3->条件2…….. 如果条件2为true,则一直执行。如果条件2位false,则for循环结束
  • Lipschitz 条件

    千次阅读 2020-04-07 17:36:46
    对于, 如果存在常数使得对于的某个领域内所有的和,则有 成立,则称在点满足Lipschitz条件,称为Lipschitz常数。...Lipschitz条件,即利普希茨连续条件(Lipschitz continuity)。其定义为:...
  • HBase高性能复杂条件查询引擎

    万次阅读 多人点赞 2014-06-17 20:10:36
    该方案设计之初仅寄希望于通过二级索引提升查询性能,由于在前期架构时充分考虑了通用性以及对复杂条件的支持,在后来的演变中逐渐被剥离出来形成了一个通用的查询引擎。HBase在大数据领域的应用越来越广泛,成为...
  • C++ 条件运算符和条件表达式

    万次阅读 2017-02-04 11:41:48
    条件运算符是C++中唯一一个三元运算符,要求有三个操作对象,条件表达式的一般形式为:表达式1?表达式2:表达式3条件运算符的执行顺序是,先求解表达式1,若为真则求解表达式2,此时表达式2的值作为整个条件表达式...
  • 条件编译

    千次阅读 多人点赞 2019-07-03 18:26:27
    条件编译是根据实际定义宏(某类条件)进行代码静态编译的手段。可根据表达式的值或某个特定宏是否被定义来确定编译条件。 1.条件编译中使用的预编译指令 #define 定义一个预处理宏 #undef 取消宏的定义 #if 编译...
  • 充分条件:  只要有A,就一定能达成B,A是B的充分条件。 充分不必要条件:  有A,一定能达到B;就算没有A,也有可能达到B。  举例:某次考试,试卷满分为100分。小明考了90分。对于“及格”这件事来说,90分...
  • 条件运算符和条件表达式

    千次阅读 2017-06-04 22:17:04
    如果在条件语句中,只执行单个的赋值语句时,可使用条件表达式来实现。条件运算符为“?”,它是一个三目运算符,即有三个参与运算的量。 由条件运算符组成的条件表达式的一般形式为: 表达式1?表达式2:表达式3...
  • 条件变量

    千次阅读 热门讨论 2018-09-04 11:26:14
    1、条件变量概述:   条件变量是用来等待线程而不是上锁的,条件变量通常和互斥锁一起使用。条件变量之所以要和互斥锁一起使用,主要是因为互斥锁的一个明显的特点就是它只有两种状态:锁定和非锁定,而条件变量...
  • KKT条件

    千次阅读 2019-07-31 16:19:54
    设目标函数为f(x),有k个等式约束条件h(x),等式约束条件有k个系数为λk,使用拉格朗日函数法求最优解。构造拉格朗日函数: 对变量求偏导,可以得到k+1个方程,方程组的解就是函数极值。 3、不等式约束条件 ...
  • 条件概率与条件期望

    千次阅读 2018-10-15 20:30:37
    一道条件概率题: A coin, having probability **p** of landing heads, is continually flipped until at least one head and one tail have been flipped. (a) Find the expected number of flips needed. (b) Find...
  • Python的并列和或者条件

    万次阅读 2017-06-29 16:44:36
    对Python 同时符合两个的条件的语句,用and连接,不能用&&(会报错); 也可以用or表示或者。 代码如下: print '开始测试' a = 12 b = 13 c = 1 a_s = '12' b_s = '13' if a < b and a_s < b_s...
  • 充分条件和必要条件

    千次阅读 2017-01-10 00:01:54
    如果条件A是结论B的充分条件:A与其它条件是并联关系,即A、C、D...中任意一个存在都可以使得B成立,如下图: 用法: 1.如果条件A成立,则结论B肯定成立,即 由条件A能推导出结论 B; 2.如果结论B不成立,则条件A...
  • dataframe 按条件筛选行

    万次阅读 多人点赞 2018-09-18 14:54:39
    筛选和排序是Excel中使用频率最多的功能,通过这个功能可以很方便的对数据表中的数据使用指定的条件进行筛选和计算,以获得需要的结果。在Pandas中通过.sort和.loc函数也可以实现这两 个功能。.sor...
  • 例如 List list = NEW ArrayList(); people p = new Peple();...给定条件“1” 我要筛选出List中age字段值是1的对象 不要用简单的for循环 如 fro(...){ xx.eques(1) } 有没有什么高性能的方法或者算法?

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 784,803
精华内容 313,921
关键字:

条件