翁恺 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的值作为当前函数的返回值,返回给调用者

相关推荐
potato_may2 小时前
CC++ 内存管理 —— 程序的“五脏六腑”在哪里?
c语言·开发语言·数据结构·c++·内存·内存管理
ULTRA??2 小时前
C/C++函数指针
c语言·开发语言·c++
不会编程的小寒4 小时前
C and C++ 八股文
c语言·c++·青少年编程
王光环5 小时前
C语言写exe脚本
c语言·开发语言
leoufung5 小时前
图解除法查询问题:用 C 语言和 DFS 实现带权有向图的路径乘积
c语言·开发语言·深度优先
雨落在了我的手上5 小时前
知识扩展:进制的详细介绍
c语言·学习
charlie1145141915 小时前
深入理解CC++的编译与链接技术8:Windows和Linux是如何搜寻动态库的?
c语言·c++·动态库·编译·编译技术
缘三水6 小时前
【C语言】12.指针(2)
c语言·开发语言·指针
dangdang___go6 小时前
文件操作c语言
c语言·开发语言