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

相关推荐
fufu03118 分钟前
Linux环境下的C语言编程(五十二)
java·linux·c语言
yyy(十一月限定版)30 分钟前
C语言——堆
c语言·开发语言·算法
黎雁·泠崖31 分钟前
C 语言动态内存管理入门:malloc/calloc/realloc/free 核心函数详解
c语言·开发语言
Yue丶越34 分钟前
【C语言】文件操作
服务器·c语言·开发语言
枫叶丹41 小时前
【Qt开发】Qt事件(三)-> QMouseEvent 鼠标事件
c语言·开发语言·c++·qt·microsoft·计算机外设
Suckerbin10 小时前
C语言简介
c语言
charlie11451419115 小时前
嵌入式现代C++教程:C++98——从C向C++的演化(3)
c语言·开发语言·c++·笔记·学习·嵌入式
程序员zgh15 小时前
C语言 指针用法与区别(指针常量、常量指针、指针函数、函数指针、二级指针)
c语言·开发语言·jvm·c++
superman超哥16 小时前
仓颉借用检查器工作原理深度解析
c语言·开发语言·c++·python·仓颉
ComputerInBook17 小时前
C++编程语言:标准库:第43章——C语言标准库(Bjarne Stroustrup)
c语言·c++·c语言标准库