翁恺 6.3.1逻辑运算-函数

本质还是1和0

!(逻辑非)的优先级高于 <(关系运算符),因此!age<20会先计算!age(对变量age取逻辑非,结果只有 0 或 1),再判断 "!age的结果是否小于 20"

想要的是 "age<20这个条件不成立",需通过括号改变运算顺序

用逻辑非否定条件:!(age < 20)先计算age < 20的结果(0 或 1),再对结果取逻辑非,即 "age 小于 20" 的否定。

1. 逻辑运算符的优先级规则

在 C 语言中,逻辑运算符的优先级从高到低为:!(逻辑非) > &&(逻辑与) > ||(逻辑或)。

  • 优先级越高的运算符,会优先参与运算,无需额外括号限定顺序。

2. 表达式!done && (count > MAX)的运算逻辑

该表达式的运算顺序由优先级和括号共同决定:

  1. 先执行!done!优先级最高,对变量done进行逻辑非运算,得到done取反后的布尔值(0 或 1)。
  2. 再执行括号内的count > MAX:括号的优先级高于&&,先计算该关系运算的布尔值。
  3. 最后执行&&运算:判断 "!done的结果" 与 "count > MAX的结果" 是否同时为真,仅当两者都为真时,整个表达式的结果才为真。

条件运算符是 C 语言中唯一的三目运算符 (需三个操作数),用于简化简单的二分支逻辑,其功能与基础的if-else语句等价。

1. 语法结构

格式为:条件 ? 条件满足时的表达式 : 条件不满足时的表达式

  • 执行逻辑:先判断 "条件" 的真假(C 语言中,非 0 值为真,0 值为假);
  • 若条件为真,取 "条件满足时的表达式" 的结果;
  • 若条件为假,取 "条件不满足时的表达式" 的结果;
  • 最终结果可直接参与运算或赋值。
2. 图片中表达式的解析

表达式:count = (count > 20) ? count - 10 : count + 10;

  • 步骤 1:判断条件count > 20是否成立;
  • 步骤 2:若条件成立(即count大于 20),执行count - 10,并将结果赋值给count
  • 步骤 3:若条件不成立(即count小于等于 20),执行count + 10,并将结果赋值给count

表达式1, 表达式2, 表达式3从左到右依次执行所有表达式,最终整个 "逗号表达式" 的结果 = 最后一个表达式的结果

唯一的用处:

用逗号运算符同时完成两个变量的初始化

函数

把这个值交给调用这个函数的地方,即见上面的素数函数,计算得到一个ret,然后返回ret作为isPrime函数的结果参与后面的运算

可有多个return可这么做但不符单一出口原则

函数声明

当把函数定义放在int main下面时,需在一开始进行声明

函数调用与参数传递

C 语言里这种参数传递是「值传递」

main里的a=5b=6想象成 **"原件",调用swap(a,b)时,相当于 把原件复印了一份 **(复制的值传给swap里的形参ab

swap函数里交换的,只是复印件(形参 a、b) 的值,而main里的 "原件(实参 a、b)" 根本没被碰过。等swap执行完,复印件就被销毁了,所以main里打印的还是原来的 5 和 6

函数里的ab是参数,调用时传的是值

  1. 变量作用域问题 变量i是在if语句的代码块({})内部定义的,属于本地变量 ,其作用域仅局限于该if代码块内。
  2. 变量未定义错误 当执行到代码块外部的i++时,i已经超出了它的作用域(if代码块结束后,i会被销毁),编译器会判定此处的i是 "未定义的标识符",从而报错。

总结:

1. 本地变量是定义在块内的(函数块、语句块、任意大括号块)

复制代码
// 函数块内的本地变量
void func() {
    int a = 10; // 定义在函数块内
}

int main() {
    // 语句块(if)内的本地变量
    if (1) {
        int b = 20; // 定义在if语句块内
    }
    // 任意大括号块内的本地变量
    {
        int c = 30; // 随便拉一对大括号定义
    }
    return 0;
}

2. 进入块前变量不存在,离开块变量消失(生命周期)

复制代码
#include <stdio.h>
int main() {
    printf("进入块前:d不存在\n");
    {
        int d = 5;
        printf("块内:d = %d(已创建)\n", d); // 正常输出5
    }
    // printf("块外:d = %d\n", d); // 报错!离开块后d已销毁
    return 0;
}

3. 块外定义的变量,在块内仍有效

复制代码
#include <stdio.h>
int main() {
    int num = 100; // 块外变量
    if (1) {
        printf("块内用外部变量:num = %d\n", num); // 输出100
    }
    return 0;
}

4. 块内同名变量会 "掩盖" 块外变量

复制代码
#include <stdio.h>
int main() {
    int num = 100; // 外部num
    {
        int num = 200; // 块内同名num
        printf("块内:num = %d\n", num); // 输出200(用自己的)
    }
    printf("块外:num = %d\n", num); // 输出100(恢复外部的)
}

5. 一个块内不能定义同名变量

复制代码
int main() {
    {
        int a = 10;
        // int a = 20; // 编译报错:重复定义变量a
    }
    return 0;
}

6. 本地变量不会被默认初始化

复制代码
#include <stdio.h>
int main() {
    {
        int e; // 未初始化的本地变量
        printf("e的值:%d\n", e); // 输出随机"垃圾值"(比如123456)
    }
    return 0;
}

"默认初始化" 是指:变量定义时,如果你没手动给它写初始值,系统会自动给它分配一个默认初始值的行为,而全局变量(定义在所有函数外面的变量)静态变量(加了 static 的变量) :会被系统默认初始化为0

7. 函数参数在进入函数时被初始化

复制代码
#include <stdio.h>
void func(int x) { // x是函数的本地变量(参数)
    printf("x的值:%d\n", x); // 进入函数时,x已被实参初始化
}

int main() {
    func(5); // 调用时,实参5初始化参数x
    return 0; // 输出5
}

用(void)

再套一层括号,就会先做逗号运算

复合声明语句,同时完成了两项操作:

  • 声明了两个整型变量ij

  • 声明了一个函数 :函数名为sum,参数是两个int类型(ab),返回值类型是int

    int i; // 变量i,int类型
    int j; // 变量j,int类型
    int sum(int a, int b); // 函数sum,返回值int类型,参数int类型

return (i)是函数的返回语句 ,作用是将变量i的值作为当前函数的返回值,返回给调用者

相关推荐
知南x9 分钟前
【Ascend C系列课程(高级)】(1) 算子调试+调优
c语言·开发语言
2的n次方_2 小时前
Runtime 执行提交机制:NPU 硬件队列的管理与任务原子化下发
c语言·开发语言
凡人叶枫3 小时前
C++中智能指针详解(Linux实战版)| 彻底解决内存泄漏,新手也能吃透
java·linux·c语言·开发语言·c++·嵌入式开发
凡人叶枫4 小时前
C++中输入、输出和文件操作详解(Linux实战版)| 从基础到项目落地,避坑指南
linux·服务器·c语言·开发语言·c++
傻乐u兔5 小时前
C语言进阶————指针3
c语言·开发语言
CodeSheep程序羊7 小时前
拼多多春节加班工资曝光,没几个敢给这个数的。
java·c语言·开发语言·c++·python·程序人生·职场和发展
I'mChloe7 小时前
PTO-ISA 深度解析:PyPTO 范式生成的底层指令集与 NPU 算子执行的硬件映射
c语言·开发语言
2的n次方_7 小时前
Runtime 内存管理深化:推理批处理下的内存复用与生命周期精细控制
c语言·网络·架构
嵌入小生0077 小时前
标准IO---核心函数接口延续(嵌入式Linux)
c语言·vscode·vim·嵌入式·小白·标准io·函数接口
历程里程碑8 小时前
Linux20 : IO
linux·c语言·开发语言·数据结构·c++·算法