首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么++i || ++j && ++k不提供期望值

这个表达式 ++i || ++j && ++k 涉及到C/C++等编程语言中的逻辑运算符和自增运算符的行为。为了理解为什么它不提供期望值,我们需要了解以下几个基础概念:

基础概念

  1. 自增运算符 (++)
    • ++i 表示先将变量 i 的值增加1,然后使用增加后的值。
  • 逻辑运算符 (||&&)
    • || 是逻辑或运算符,只要左边的表达式为真(非零),右边的表达式就不会被执行。
    • && 是逻辑与运算符,只有左边的表达式为真(非零),右边的表达式才会被执行。

运算符优先级

在C/C++中,逻辑与运算符 (&&) 的优先级高于逻辑或运算符 (||)。因此,表达式 ++i || ++j && ++k 实际上会被解析为 ++i || (++j && ++k)

具体分析

假设初始值为:

  • i = 0
  • j = 0
  • k = 0

执行 ++i || ++j && ++k 的步骤如下:

  1. 自增 i
    • ++ii 增加到1。
    • 表达式变为 1 || (++j && ++k)
  • 逻辑或运算
    • 因为 1 是真值(非零),所以 || 右边的表达式 ++j && ++k 不会被执行。

因此,最终结果是:

  • i 变为1。
  • jk 保持不变。

期望值与实际值的差异

如果你期望 i, j, k 都增加1,那么这个表达式显然没有达到预期效果。原因在于逻辑运算符的短路特性:

  • || 运算符在左边为真时,右边不会执行。
  • && 运算符在左边为假时,右边不会执行。

解决方案

如果你希望 i, j, k 都增加1,可以分别使用自增运算符,而不依赖于逻辑运算符的短路特性:

代码语言:txt
复制
++i;
++j;
++k;

或者使用括号明确指定运算顺序:

代码语言:txt
复制
(++i || ++j) && ++k;

但请注意,这种方式仍然可能不符合预期,因为 ++i || ++j 可能会导致 ++k 不被执行。

应用场景

这种表达式通常出现在需要根据条件进行多个操作的场景中。为了避免逻辑运算符的短路特性带来的意外结果,建议明确分开每个操作或使用括号明确指定运算顺序。

示例代码

代码语言:txt
复制
#include <iostream>

int main() {
    int i = 0, j = 0, k = 0;

    // 原始表达式
    ++i || ++j && ++k;

    std::cout << "i: "<< i << ", j: "<< j << ", k: "<< k << std::endl; // 输出: i: 1, j: 0, k: 0

    // 分开操作
    i = j = k = 0;
    ++i;
    ++j;
    ++k;

    std::cout << "i: "<< i << ", j: "<< j << ", k: "<< k << std::endl; // 输出: i: 1, j: 1, k: 1

    return 0;
}

通过这种方式,可以确保每个变量都按预期增加。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

为什么编程里习惯使用 i、j、k 等作为循环变量?

i 可能是 integer 的简写,或者是 int 的简写。有人说是 iterator 的简写,这个有点牵强。早期教材中的示例都是以 i、k、j 作为循环变量,后来这样使用成为了一种习惯。...在 1957 年诞生的 Fortran 编程中,有一个「I—N 规则」,以字母 I,J,K,L,M,N 六个字母开头的变量,如无另外说明均为整型变量,以其它字母开头的变量则为实型变量。...Fortran 更多是一种教学语言,后来诞生的 B 语言、C 语言都借鉴了 i、k、j 的命名规则,久而久之成为了习惯。...关于 I-N 规则,可以查看这里:https://micro.ustc.edu.cn/Fortran/ZJDing/Sec1-4.htm Fortran 支持整型、字符型等类型。

1.1K20

Python 为什么不支持 i++ 自增语法,不提供 ++ 操作符?

这些语言的使用者在接触 Python 时,可能会疑惑为什么它不提供 ++ 或 -- 的操作呢?在我前不久发的《Python的十万个为什么?》里,就有不少同学在调查问卷中表示了对此话题感兴趣。...本期“Python为什么”栏目,我们将会从两个主要的角度来回答:Python 为什么不支持 i++ 自增语法?...所以,我们的问题可以转化成:为什么上面的两种写法会胜过 i++,成为 Python 的最终选择呢?...,那样就没有意义了(总不能按字母表顺序,把 i 变成 j 吧);如果理解成对数字本体的操作,那么情况就会变得复杂:它会产生新的一等公民 1001,因此需要给它分配一个内存地址,此时若占用 1000 的地址...Python 中的可迭代对象/迭代器/生成器提供了非常良好的迭代/遍历用法,能够做到对 i++ 的完全替代。

1.7K30
  • CRF++代码分析

    期望值的计算 节点期望值 所谓的节点期望值指的是节点对应的特征函数关于条件分布 ? 的数学期望。 ? calcExpectation具体实现是: ? 第一个for对应下式的求和 ?...第二个for对应边的期望值。 边的期望值 ? 对应下式的求和 ? 这样就得到了条件分布的数学期望: ? 梯度计算 ? –expected表示模型期望(条件分布)减去观测期望,得到目标函数的梯度: ?...x_.size(); ++i)    {        for (size_t j = 0; j j)        {            double bestc = -1e37..._[i][j]->bestCost = best ? ...这也就是代码中为什么要自加这两项的原因了:         thread[0].obj += (alpha[k] * alpha[k] / (2.0 * C));        thread[0].expected

    2K50

    EM算法学习(番外篇):HMM的参数估计

    ,v(m)},并且t在[1,T]之间. 3:B=bj(k)是输出符号的概率分布 bj(k)表示在状态j时输出符号v(k)的概率,即bj(k)=P(vk | j),k属于[1,M],j属于[1,N] 4:...对于HMM的第三个问题(学习问题),隐含变量自然就是状态的变量,要求状态变量的期望值实际上就是求在t时刻随机变量X所处状态qt = i的概率,为了求这个概率,我们引入了向前变量和向后变量. 1:向前变量...那么将t带入上式,就有表示为状态i转移出去的次数的期望值,后部分表示为从状态i到状态j的次数的期望值. 4:M步 π(i)是表示在初始时刻出现状态i的频率的期望值,即有: ?...则同理可得: a(i,j)表示的是从状态i到状态j的次数的期望值除以从状态i转移出去的次数的期望值,既有: ?...bj(k)是在状态为j的情况下观察到输出值为k的次数的期望值除以其他所有状态转移到状态j的次数的期望值,即有: ? 并且有: ?

    1.6K110

    EM算法学习(番外篇):HMM的参数估计

    ,v(m)},并且t在[1,T]之间. 3:B=bj(k)是输出符号的概率分布 bj(k)表示在状态j时输出符号v(k)的概率,即bj(k)=P(vk | j),k属于[1,M],j属于[1,N] 4:...对于HMM的第三个问题(学习问题),隐含变量自然就是状态的变量,要求状态变量的期望值实际上就是求在t时刻随机变量X所处状态qt = i的概率,为了求这个概率,我们引入了向前变量和向后变量. 1:向前变量...那么将t带入上式,就有表示为状态i转移出去的次数的期望值,后部分表示为从状态i到状态j的次数的期望值. 4:M步 π(i)是表示在初始时刻出现状态i的频率的期望值,即有: 则同理可得: a(i,j)表示的是从状态...i到状态j的次数的期望值除以从状态i转移出去的次数的期望值,既有: bj(k)是在状态为j的情况下观察到输出值为k的次数的期望值除以其他所有状态转移到状态j的次数的期望值,即有: 并且有: 这样就引入新的参数...λ = (A,B,π)再来计算向前变量at(i),向后变量Bt(i),ξ(i,j),然后这样如此的循环迭代,直到前后两次参数的变化量小于某个值为止. 5:算法的实现: 在这个部分,引用上边的Baum-Welch

    92270

    BZOJ4008: 亚瑟王(期望dp)

    作为一个非 洲人,同时作为一个前 OIer,小 K 自然是希望最大化造成伤害的期望值。...2.3如果这张卡牌已经是最后一张(即 i 等于n),则结束这一轮;否则, 考虑下一张卡牌。  请帮助小 K 求出这一套卡牌在一局游戏中能造成的伤害的期望值。 ...Output  对于每组数据,输出一行,包含一个实数,为这套卡牌在这一局游戏中造成的 伤害的期望值。...对于每一行输出,只有当你的输出和标准答案的相对误差不超过 10^-8时——即|a-o|/a<=10-8时(其中a是标准答案,o是输出),你的输出才会被判为正确。 建议输出10 位小数。 ...造成伤害的期望值为概率与对应伤害乘积之和,为 3.266025。

    31010

    【概率期望动态规划】

    因为目的是求出期望值——什么是期望值?好吧,暂时可以理解为“权值 x 概率”。因此期望Dp的转移是有代价的,而不像概率Dp那样简单统计了。...另外一个问题,类似于上文的机器人分身,当前状态的期望值有多个转移方向,所以此处要乘上概率——也就是选择这一步的概率P,如下: f[i][j]—>f[i+1][j+1]: P1=(n-i)*(s-j)/...那就是不踩任何地雷。可是怎么写转移方程式才能满足这个条件呢?由于同时满足所有地雷都不踩较为困难,所以尝试分步。     ...=f[i][i]*p1+p3—————————————① 1jk+1:f[i][j]=f[i][j-1]*p1+f[i-1][j-1]*p2+p3 ————② kj:f[i][j]=f[i][...所以我们得到了f[i][i]的值,再根据方程式推出其他的值就很容易了。      为什么这样做呢?

    1K10

    【Simulink】粒子群算法(PSO)整定PID参数(附代码和讲解)

    对于第 j j j个粒子,第 k + 1 k+1 k+1次迭代(第 k + 1 k+1 k+1代)的位置 X k + 1 ( j ) \color{blue}{X_{k+1}^{(j)}} Xk+1(j...若将评价函数小视为自适应度高,则调整过后的系统参数总是在期望值附近调整,并尽量满足$所有参数都小于期望值的情况。因为在期望值附近上升速率是越来越慢而下降速率是越来越快的,而参数最小只能取到0。...因此,有多个参数大于期望值而有少个参数小于期望值的和会比有少个参数大于期望值而多个参数小于期望值的和要大得多。...\qquad 根据1.2的算法步骤我们可以编写出粒子群算法,而PID并行仿真引擎的编写需要参考上文提供的连接。...这里我们用调节期望值的方法做一个示范: \qquad 之前的期望值为: σ n ∗ = 0.1 % , t s n ∗ = 1 , σ i ∗ = 20 % , t s i ∗ = 0.005

    1.6K20

    【java并发编程实战2】无锁编程CAS与atomic包1、无锁编程CAS2、 atomic族类

    通俗的理解就是CAS操作需要我们提供一个期望值,当期望值与当前线程的变量值相同时,说明还没线程修改该值,当前线程可以进行修改,也就是执行CAS操作,但如果期望值与当前线程不符,则说明该值已被其他线程修改...,此时不执行更新操作,但可以选择重新读取该变量再尝试再次修改该变量,也可以放弃操作,原理图如下 ?...= 0; j j++) { executorService.execute(() -> { add();...(); } } 上面的代码就是线程安全的,运行输出 i=1000,这是为什么呢。...尽管线程one的CAS操作成功,但是不代表这个过程就是没有问题的。如果链表的头在变化了两次后恢复了原值,但是不代表链表就没有变化。

    62930

    控制算法之PID算法 | 从入门到理解到应用 (一发入魂)

    二、二位式控制算法 2.1 为什么要解释二位式控制算法 二位式控制算法在某种程度上可谓是PID算法的前身,了解原理便可更好的理解PID算法。...X1、X2、X3 … Xn-1、Xn; 第k时刻的 偏差:e(k)=Expect — Xk; e(k)>0 :控制系统还未达到期望值; e(k)=0 :控制系统已经达到期望值; e(k)期望值...过去大部分时间段已经达到期望值; ∑ei>0 :控制系统在 过去大部分时间段已经超过期望值; I环节的第k时刻的输出:u(k)=Ki * ∑ei 。...(Ki:i比例系数) 在控制系统刚启动时,由于I环节的 偏差累积效应,可以 更快的达到期望值。...ಠ_ಠ 不想写了,我觉得没人有耐心看到这里了 ▄█▀█● 不写了直接放文档吧,以后有心情了再更一篇[我鸽了,时隔这么久我还是没写?

    15.4K65
    领券