(仓颉) 仓颉语言入门

news2024/12/24 20:37:14

文章目录

  • ⭐前言
  • 🔠1 基本概念
    • 🔤Hello World
    • 🔤标识符
    • 🔤内置类型
    • 🔤if表达式
    • 🔤for表达式
    • 🔤while表达式
    • 🔤demo 手动计算Π
  • 🔠2 函数
    • 🔤普通函数
    • 🔤lambda
    • 🔤demo 递归遍历目录
  • 🔠3 枚举
    • 🔤enum
    • 🔤match表达式
    • 🔤option 解析数字
    • 🔤demo 计算表达式
  • 🔠4 struct
    • 🔤值类型
    • 🔤二叉树
  • 🔠5 calss
    • 🔤引用类型
    • 🔤继承
    • 🔤prop 属性
  • 🔠6 接口与扩展
    • 🔤interface
    • 🔤extend
    • 🔤泛型
  • 🔠7 异常处理
    • 🔤try catch finally
  • 🔠8 并发编程
    • 🔤Future
  • 🔠9 跨语言互操作
  • 🔠10 宏
    • 🔤macro
  • ⭐END
    • 🌟交流方式

⭐前言

仓颉-鸿蒙原生应用编程语言-华为开发者联盟 (huawei.com)

初识仓颉语言-仓颉编程语言开发指南-学习仓颉语言 - 华为HarmonyOS开发者 (huawei.com)

【原创】仓颉编程语言入门教程

楼主作为主语言C++,副语言python。仅做基础的入门了解。

本文不做任何格外的语法说明,仅在代码中用简短的注释辅助。

下文均为教学视频中的实例demo(上方的视频也出现在官网的视频一栏中)。

本文所有代码均在下方的在线编译器中进行尝试。

除了最后两章,9,10无法进行单文件操作其余均有验证。

仓颉 Playground (zxilly.dev)

https://github.com/Zxilly/playground-cj

仓颉版本 0.54.3

package cangjie

// 编写你的第一个仓颉程序
main(): Int64 {
    println("你好,仓颉!")
    return 0
}

🔠1 基本概念

🔤Hello World

// main 可以没有返回值
main() {
    println("你好,仓颉!")
}

🔤标识符

main() {
    // 普通变量
    let num = 10
    let ___x = "___Str"

    println(num)
    println(___x)

    // 原始表示符
    // 用于将关键字作为标识符
    let `for` = "这是一个将for关键字用作原始标识符"
    println(`for`)
}

🔤内置类型

main() {
    /**
     * 字面量后缀
     * 整形
     * Int8  -> i8
     * Uint8 -> u8
     * 浮点型
     * Float16 -> f16
     */
    let a: Int64 = 2024
    let b = 67u8
    let c: Float64 = 6.21

    let d: Bool = true || false
    println(d)

    // 字符类型,表示一个 unicode 字符
    // 运行下来双引号也可以运行
    let e: Rune = '仓'
    let f: Rune = '\u{9889}'
    println("${e} ${f}")

    // 单行字符串
    let g: String = "Cang" + "jie"
    let h: String = """
        第1行,这是多行字符串
        第2行
"""
    // 插值字符串
    // 要求表达式类型实现了 ToString 接口
    let i: String = "Cangjie${a}"
    println("${h}${i}")

    // 引用类型数组
    let j: Array<UInt8> = [1u8, 2u8]
    // 值类型数组
    // 没有 ToString
    // let k: VArray<Rune, $2> = ['C', 'J']
    let k: VArray<Rune, $2> = [e, f]
    println("引用类型数组${j}")

    // 元组类型
    let l: (Int64, Float64) = (2024, 9.6)
    // expected 'Struct-String', found 'Tuple<Int64, Float64>'
    // println(l)

    // 区间类型
    // 主要用于for in表达式中
    let m: Range<Int64> = 2019..2024
    // expected 'Struct-String', found 'Struct-Range<Int64>'
    // println(m)
}

🔤if表达式

import std.random.*

main() {
    let speed = Random().nextFloat64() + 20.0
    println("${speed} km/s")

    // if 表达式
    // 类似于 gcc 中的大括号表达式
    let level = if (speed > 16.7) {
        "第3宇宙速度"
    } else if (speed > 11.2) {
        "第2宇宙速度"
    } else if (speed > 7.9) {
        "第1宇宙速度"
    } else {
        "第0宇宙速度"
    }

    println(level)
}

🔤for表达式

main() {
    // 1. for
    var sum = 0
    // range(1, 100, 2)
    for (i in 1..99 : 2) {
        sum += i
    }
    println(sum)

    // 2. for
    let arr = [(1, 2), (3, 4)]
    // 元组可以解构
    for ((x, y) in arr) {
        println("x=${x} y=${y}")
    }

    // 3. for
    var num = 2
    // 用 _ 作为占用,避免编译器警告
    for (_ in 0..5) {
        num *= num
    }

    // 4. for
    // 当 where 为 true 才执行循环体
    for (i in 0..10 where i % 2 == 1) {
        println(i)
    }
}

🔤while表达式

main() {
    var result = 0.0
    var lower = 1.0
    var upper = 2.0

    while (upper - lower > 1.0E-10) {
        result = (lower + upper) / 2.0
        if (result ** 2 - 2.0 > 0.0) {
            upper = result
        } else {
            lower = result
        }
    }

    println("√2 ≈ ${result}")
}

🔤demo 手动计算Π

// 在在线仓颉Playground 中运行失败
// from std import random.*
// from std import math.*
import std.random.*
import std.math.*

main() {
    /**
     * 手动计算圆周率
     * 在一个正方形中随机投点
     */
    const N = 10000
    var n: UInt32 = 0
    let random = Random()
    for (_ in 0..N) {
        let x = random.nextFloat64()
        let y = random.nextFloat64()
        if ((x - 0.5) ** 2 + (y - 0.5) ** 2 < 0.25) {
            n++
        }
    }

    let pi = Float64(n) / Float64(N) * 4.0
    println("Π = ${pi}")
    println("deviation: ${abs(Float64.PI - pi)}")
}

🔠2 函数

🔤普通函数

func void() {
    // pass
}

// 将函数作为参数
func node(value: Int32, left!: () -> Unit = void, right!: () -> Unit = void) {
    // 二叉树的中序遍历
    func show() {
        left()
        print(value)
        right()
    }

    return show
}

main() {
    let tree = node(
        0,
        left: node(1, left: node(2, right: node(3))),
        right: node(4, left: node(5), right: node(6))
    )
    tree()
}

🔤lambda

func iter(n: Int64, x0: Float64, f: (Float64) -> Float64) {
    var x = x0
    for (_ in 0..n) {
        print("${x}, ")
        x = f(x)
    }
    println("${x}")
}

main() {
    // lambda 表达式
    // { 参数列表 => 函数体 }
    // { params => block }

    // 周期3
    iter(5, 0.8, {x: Float64 => 1.0 / (1.0 - x)})
    // 没有周期,产生未随机数
    iter(10, 0.8, {x: Float64 => 4.0 * x * (1.0 - x)})
}

🔤demo 递归遍历目录

import std.fs.*

func forEachFileDo(root: Path, handler: (Path) -> Unit): Unit {
    let current = Directory(root)
    for (file in current.files()) {
        handler(file.path)
    }
    for (directory in current.directories()) {
        forEachFileDo(directory.path, handler)
    }
}

main() {
    forEachFileDo(Path("."), {path: Path => println(path)})
}

🔠3 枚举

🔤enum

enum Tree {
    // 枚举项
    Empty | Leaf(Int64) | Node(Int64, Tree, Tree)

    // 成员函数
    public func traverse(): Unit {
        match (this) {
            case Empty => ()
            case Leaf(value) => print(value)
            case Node(value, left, right) =>
                left.traverse()
                print(value)
                right.traverse()
        }
    }

    public static func generate(depth: UInt8): Tree {
        if (depth == 1) {
            return Leaf(1)
        }
        return Node(
            Int64(depth),
            generate(depth - 1),
            generate(depth - 1)
        )
    }
}

main() {
    let tree = Node(
        1,
        Node(2, Node(3, Empty, Leaf(4)), Empty),
        Node(5, Leaf(6), Leaf(7))
    )
    tree.traverse()
    println()
    let fullTree = Tree.generate(5)
    fullTree.traverse()
}

🔤match表达式

func fib(n: Int64): Int64 {
    // math 表达式
    match (n) {
        case 0 | 1 => n
        case other where other > 0 => fib(other - 1) + fib(other - 2)
        case _ => 0
    }
}

main() {
    println(fib(-1))
    for (i in 1..=10) {
        print("${fib(i)} ")
    }
}

🔤option 解析数字

func parseInt(text: String): Option<Int64> {
    if (text.isEmpty() || text == ".") {
        return None
    }
    var sign = if (text[0] == 45u8) {
        1
    } else {
        0
    }
    var sum = 0
    for (i in sign..text.size) {
        if (text[i] > 57u8 || text[i] < 48u8) {
            return None
        }
        let digit = Int64(text[i] - 48u8)
        sum = 10 * sum + digit
    }

    // 自动包装为 option
    return if (sign == 1) {
        -sum
    } else {
        sum
    }
}

main() {
    let number = parseInt("-123456")
    // getOrThrow 从 Option 取值
    println(number.getOrThrow())

    let result = parseInt("123-456")
    if (result.isNone()) {
        println("parse failed")
    }
}

🔤demo 计算表达式

enum Expr {
    Num(Float64)
    | Add(Expr, Expr)
    | Sub(Expr, Expr)
    | Mul(Expr, Expr)
    | Div(Expr, Expr)

    public func calc(): Float64 {
        match (this) {
            case Num(number) => number
            case Add(a, b) => a.calc() + b.calc()
            case Sub(a, b) => a.calc() - b.calc()
            case Mul(a, b) => a.calc() * b.calc()
            case Div(a, b) => a.calc() / b.calc()
        }
    }

    public operator func +(that: Expr): Expr {
        return Add(this, that)
    }
    public operator func -(that: Expr): Expr {
        return Sub(this, that)
    }
    public operator func *(that: Expr): Expr {
        return Mul(this, that)
    }
    public operator func /(that: Expr): Expr {
        return Div(this, that)
    }
}

main() {
    let x = Num(1.2) + Num(3.4) + Num(2.0) - Num(1.0) / Num(2.0)
    println(x.calc())
}

🔠4 struct

🔤值类型

struct Point {
    static let name = "Point"

    // 主构造函数
    // 自动成为成员变量
    Point(private var x: Float64, private var y: Float64) {
        println("Create a point: (${x}, ${y})")
    }

    public func copy() {
        return this
    }

    // 用 mut 修饰可以使用 this 引用当前实例
    public mut func set(x: Float64, y: Float64) {
        this.x = x
        this.y = y
    }

    public func show() {
        println("Visit the point: (${x}, ${y})")
    }
}

main() {
    println(Point.name)
    let p1 = Point(3.0, 4.0)
    var p2 = p1.copy()
    p2.set(1.0, 2.0)
    p1.show()
    p2.show()
}

🔤二叉树

struct Node {
    public Node(var value: Int32, let left!: ?Node = None, let right!: ?Node = None) {
    }

    public func traverse(): Unit {
        // Option 类型的语法糖
        left?.traverse()
        print(value)
        right?.traverse()
    }

    static let name: String
    // 静态构造函数
    static init() {
        name = "Binary Tree"
    }

    public static func intro() {
        println(name)
    }
}

main() {
    Node.intro()
    let root = Node(
        1,
        left: Node(2, left: Node(3, right: Node(4))),
        right: Node(5, left: Node(6), right: Node(7))
    )
    root.traverse()
}

🔠5 calss

🔤引用类型

class Point {
    static let name = "Point"
    public Point(private var x: Float64, private var y: Float64) {
        println("Create a point: {${x}, ${y}}")
    }

    // this 是当前的引用
    public func ref() {
        return this
    }

    public func set(x: Float64, y: Float64) {
        this.x = x
        this.y = y
    }

    public func show() {
        println("Visit the point: (${x}, ${y})")
    }
}

main() {
    println(Point.name)
    let p1 = Point(3.0, 4.0)
    var p2 = p1.ref()
    p2.set(1.0, 2.0)
    p1.show()
    p2.show()
}

🔤继承

// 使用了 open 关键字的才能被继承
open class NodeA {
    public NodeA(
        protected var value: String,
        protected let left!: ?NodeA = None,
        protected let right!: ?NodeA = None
    ) {
    }

    // 中序遍历
    public open func traverse(): Unit {
        left?.traverse()
        print(value)
        right?.traverse()
    }
}

class NodeB <: NodeA {
    public init(
        value: String,
        left!: ?NodeA = None,
        right!: ?NodeA = None
    ) {
        super(value, left: left, right: right)
    }

    // 前序遍历
    public func traverse(): Unit {
        print(value)
        left?.traverse()
        right?.traverse()
    }
}

main() {
    let root = NodeA(
        'a',
        left: NodeA('b', left: NodeA('c', right: NodeA('d'))),
        right: NodeB('e', left: NodeB('f'), right: NodeB('g'))
    )
    root.traverse()
}

🔤prop 属性

class Node {
    private var value: Int64 = 0
    public Node(
        private var name: String,
        private let left!: ?Node = None,
        private let right!: ?Node = None
    ) {
    }

    // 是 class 不是 struct
    // 属性,mut 中才能定义set
    // 此处属性名:param
    // 这里的目的是和成员变量 value 进行关联
    public mut prop param: Int64 {
        get() {
            value
        }
        set(number) {
            value = number
            update()
            left?.param = number / 2
            right?.param = number / 2
        }
    }

    private func update() {
        println("${name} has been updated to ${value}")
    }
}

main() {
    var root = Node(
        'a',
        left: Node('b', left: Node('c', right: Node('d'))),
        right: Node('e', left: Node('f'), right: Node('g'))
    )
    println(root.param)
    root.param = 128
}

🔠6 接口与扩展

🔤interface

import std.math.*

interface Slot {
    func compute(t: Float64): Float64
    operator func <<(that: Slot): Slot {
        return this
    }
    operator func >>(that: Slot): Slot {
        that << this
        return this
    }
}

extend Float64 <: Slot {
    public func compute(t: Float64): Float64 {
        return this
    }
}

class Wave <: Slot {
    public Wave(let freq: Float64, let phi: Float64) {}
    public func compute(t: Float64): Float64 {
        return sin(2.0 * Float64.PI * freq * t + phi)
    }
}

class Mut <: Slot {
    public Mut(let a: Slot, let b: Slot) {}
    public func compute(t: Float64): Float64 {
        a.compute(t) * b.compute(t)
    }
}

class Integrator <: Slot {
    var input: ?Slot = None
    var sum = 0.0
    public Integrator(let dt: Float64) {}
    public func compute(t: Float64): Float64 {
        sum += dt * input.getOrThrow().compute(t)
        return sum
    }
    public operator func <<(that: Slot): Slot {
        input = Some(that)
        this
    }
}

main() {
    const DT = 0.001
    let left = 1.0 >> Integrator(DT)
    let right = Wave(0.5 / Float64.PI, 0.0)
    let flow = Mut(left, right) >> Integrator(DT)
    for (t in 0..1000) {
        println(flow.compute(Float64(t) * DT))
    }
}

🔤extend

// 默认情况下,扩展仅在当前包中有效
extend String {
    operator func >>(n: Int64): String {
        if (n <= 0) {
            return this.clone()
        }
        let size = this.size
        let offset = size - n % size
        this[offset..size] + this[0..offset]
    }
}

main() {
    let text = "Cangjie2024"
    println(text >> 2 >> 2)
}

🔤泛型

class Node<T> where T <: ToString {
    public Node(
        protected var value: T,
        protected let left!: ?Node<T> = None,
        protected let right!: ?Node<T> = None
    ) {
    }

    // 中序遍历
    public func traverse(): Unit {
        left?.traverse()
        print(value)
        right?.traverse()
    }
}

main() {
    let tree1 = Node(
        'a',
        left: Node('b', left: Node('c', right: Node('d'))),
        right: Node('e', left: Node('f'), right: Node('g'))
    )
    tree1.traverse()

    println()

    let tree2 = Node(
        1,
        left: Node(2, left: Node(3, right: Node(4))),
        right: Node(5, left: Node(6), right: Node(7))
    )
    tree2.traverse()
}

🔠7 异常处理

🔤try catch finally

class ParseException <: Exception {
    public init() {
        super("Parse Failed")
    }
}

func parseInt(text: String): Int64 {
    if (text.isEmpty() || text == ".") {
        throw ParseException()
    }
    var sign = if (text[0] == 45u8) {
        1
    } else {
        0
    }
    var sum = 0
    for (i in sign..text.size) {
        if (text[i] > 57u8 || text[i] < 48u8) {
            throw ParseException()
        }
        let digit = Int64(text[i] - 48u8)
        sum = 10 * sum + digit
    }

    // 自动包装为 option
    return if (sign == 1) {
        -sum
    } else {
        sum
    }
}

main() {
    println(parseInt("-123456"))
    let number = try {
        parseInt("123-456")
    } catch (e: ParseException) {
        println("not an integer")
        0
    }
    println(number)

    try {
        parseInt("123x456")
        println(parseInt("-123456"))
    } catch (e: ParseException) {
        println(e.message)
    } finally {
        println("clean up")
    }

    // parseInt("x123456")
    println("end")
}

🔠8 并发编程

🔤Future

import std.collection.*
import std.random.*
import std.math.*

const M = 200000
const N = 16

func task(): Int64 {
    var n: Int64 = 0
    let random = Random()
    for (_ in 0..M) {
        let x = random.nextFloat64()
        let y = random.nextFloat64()
        if ((x - 0.5) ** 2 + (y - 0.5) ** 2 < 0.25) {
            n++
        }
    }
    return n
}

main() {
    let futures = ArrayList<Future<Int64>>()
    for (_ in 0..N) {
        let future = spawn {task()}
        futures.append(future)
    }

    var n = 0
    for (future in futures) {
        n += future.get()
    }

    let pi = Float64(n) / Float64(M * N) * 4.0
    println("Π = ${pi}")
    println("deviation: ${abs(Float64.PI - pi)}")
}

🔠9 跨语言互操作

🔠10 宏

🔤macro

// macro.cj
// 宏需要定义在宏包
macro package meta
import std.ast.*

public macro transform(tokens: Tokens): Tokens {
    for (token in tokens) {
        println("${token.value}\t\t${token.kind}")
    }
    println("--------------")
    return tokens
}

// main.cj
import meta.*

@transform
func add(x: Int64, y: Int64) {
    return x + y
}

main() {
    @transform(add(1, 2))
}



⭐END

🌟交流方式

⭐交流方式⭐ |C/C++|算法|设计模式|软件架构-CSDN社区

关注我,学习更多C/C++,python,算法,软件工程,计算机知识

B站:

👨‍💻主页:天赐细莲 bilibili

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2112222.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【LeetCode】05.最长回文子串

题目要求 解题思路 这一类型&#xff08;回文子串&#xff09;主要有两种解决方法&#xff0c;一种是动态规划&#xff0c;另一种是中心拓展算法。 动态规划&#xff1a; 本质问题就是在i-j区间是不是回文的。这样的话我们在 i 和 j 位置的值相等时&#xff0c;判断如下三种情…

最直接显示 ubuntu 版本号的命令

有时候去看ubuntu版本号&#xff0c;去网上查&#xff0c;很多文章都列出一堆命令&#xff0c;复制命令运行一下&#xff0c;都是打印一些不相关的信息&#xff0c;我只是想看ubuntu版本号而已&#xff0c;能否直接列出版本号就可以了。 有&#xff0c;下面这条命令就是直接的…

STM32+ESP8266+MQTT协议连接阿里云实现温湿度上传

前期步骤: ESP8266下载固件→连接阿里云-CSDN博客 keil文件&#xff1a;大家可以直接下载&#xff0c;也可以在后台私信我获取 《STM32ESP8266MQTT协议连接阿里云实现温湿度上传》 keil文件源码 一、代码修改部分 1、mqtt.h文件中的修改 2、wifi.h文件中的修改 3、main.…

Matplotlib 画布及Figure文字注释添加详解

text() 若要给画布对象或者Figure对象添加注释,常用的为text()方法,分别可以用Figure对象.text()或者画布对象.text()添加文字注释 x, y, s, fontdictNone 上述为text()函数的参数x,y为注释所在的坐标,s为要添加的注释,fontdict为字体样式字典,键包括常见的样式,如‘color’…

微积分直觉:隐含微分

目录 一、介绍 二、梯子问题 三、结论 四、一个额外的例子 一、介绍 让我们想象一个半径为 5 的圆&#xff0c;以 xy 平面为中心。现在假设我们想在点 &#xff08;3,4&#xff09; 处找到一条切线到圆的斜率。 好吧&#xff0c;为了做到这一点&#xff0c;我们必须非常接近圆和…

Qt-布局管理

布局管理 Qt布局系统提供了一种简单而强大的方式&#xff0c;可以自动在窗口组件中排列子窗口组件&#xff0c;以确保它们充分利用可用空间。 介绍 Qt包含了一组布局管理类&#xff0c;用于描述窗口组件在应用程序用户界面中的布局方式。当可用空间发生变化时&#xff0c;这…

Typora 写文章时修改图片保存位置

文章目录 为什么要修改图片位置修改图片位置1.打开偏好设置2.修改路径3.再写文章发现图片已经变成了相对路径 为什么要修改图片位置 默认位置不好找 如何修改呢&#xff1f; 修改图片位置 1.打开偏好设置 文件 > 偏好设置 2.修改路径 图像 > 插入图片时 按照下图…

C# 集合(Collection)

集合&#xff08;Collection&#xff09;类是专门用于数据存储和检索的类。这些类提供了对栈&#xff08;stack&#xff09;、队列&#xff08;queue&#xff09;、列表&#xff08;list&#xff09;和哈希表&#xff08;hash table&#xff09;的支持。大多数集合类实现了相同…

超市售货管理系统小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;会员管理&#xff0c;供应商信息管理&#xff0c;商品管理&#xff0c;出入库管理&#xff0c;公告管理&#xff0c;轮播图信息 微信端账号功能包括&#xff1a;系统首页&#xff0c;公告&#xff0c;…

Midjourney 随机风格 (Style Random),开启奇幻视觉之旅

作者:老余捞鱼 原创不易,转载请标明出处及原作者。 写在前面的话: Midjourney 最近推出了 "Style Random"(随机风格),这项功能可以让我们使用独特的随机 sref 代码创建图像,从而每次都能获得不同的美感。通过对这些功能的探索和尝试,我发现了一些很棒…

vscode安装使用plantuml插件

使用 VSCode 插件 如果你在 Visual Studio Code 中使用 PlantUML 插件&#xff0c;你可以按照以下步骤生成图片&#xff1a; 安装 PlantUML 插件&#xff1a; 在 VSCode 的扩展市场中搜索并安装 PlantUML 插件。 配置插件&#xff1a; 打开设置&#xff0c;确保插件配置正确。…

【Unity小工具】Image组件宽度、高度自适应

Unity开发中&#xff0c;用同一个Image进行动态加载不同尺寸的图片&#xff0c;在显示上会有形变此工具可以进行Image的宽度、高度自适应 实现原理 获取Image原始尺寸&#xff08;sizeDelta&#xff09;获取图片原始尺寸&#xff08;spriteSizeDelta&#xff09;公式&#xff…

PDF标准详解(四)——图形操作符

上一节&#xff0c;我们了解了PDF中cm操作符&#xff0c;它是定义变换矩阵的。同时也了解到re是创建一个矩阵的。上一节也说过&#xff0c;它用来构建一个路径&#xff0c;具体什么是路径&#xff0c;路径有什么作用呢&#xff1f;这些将在本节给出解释 图形操作符是用来在pdf…

移远通信高端5G智能模组SG560D-NA率先通过PTCRB认证

近日&#xff0c;移远通信宣布&#xff0c;其基于高通QCM6490平台打造的高端5G智能模组SG560D-NA顺利通过PTCRB认证。 在此之前&#xff0c;该模组还获得了美国FCC和加拿大IC认证&#xff0c;这意味着&#xff0c;其已完全满足北美地区的相关标准和规定&#xff0c;能够支持相关…

pdf压缩到指定大小需要怎么压缩?2024快速进行文件压缩的软件合集

pdf压缩到指定大小需要怎么压缩&#xff1f;2024快速进行文件压缩的软件合集 当你需要将PDF文件压缩到指定的大小时&#xff0c;选择适当的软件和方法可以帮助你在保持文件质量的同时&#xff0c;尽可能地减小文件体积。以下是五款可以帮助你快速压缩PDF文件并控制其大小的软件…

芯片散热设计

目录 摘要 散热方式分类 1.传导 2.对流 对流换热系数 对流方式 3.辐射 热阻 散热器 作用 材质 底部厚度 鳍片 表面处理 压力设计 界面材料 相关标准 摘要 散热设计是硬件设计中的进阶内容&#xff0c;掌握散热原理和设计要点是很有必要的。 散热方式分类 散…

【C++二分查找】1818. 绝对差值和

本文涉及的基础知识点 C二分查找 LeetCode1818. 绝对差值和 给你两个正整数数组 nums1 和 nums2 &#xff0c;数组的长度都是 n 。 数组 nums1 和 nums2 的 绝对差值和 定义为所有 |nums1[i] - nums2[i]|&#xff08;0 < i < n&#xff09;的 总和&#xff08;下标从 …

Java获取小程序码示例(三种小程序码)

首先我们可以看到官方文档上是有三种码的 获取小程序码 这里特别要注意的是第一种和第三种是有数量限制的&#xff0c;所以大家生成的时候记得保存&#xff0c;也不要一直瞎生成 还有一点要注意的是第一种和第二种是太阳码 第三种是方形码 好了直接上代码 这里要注意&#xff…

南京网站设计手机用的网站

近年来&#xff0c;随着移动互联网的快速发展&#xff0c;越来越多的用户通过手机浏览网页&#xff0c;这使得网站设计逐渐向移动端倾斜。在南京&#xff0c;网站设计特别注重适配手机端&#xff0c;这不仅是用户体验的提升&#xff0c;也是市场竞争的需要。一个响应式的网站能…

深度评测热门翻译工具,携手你的翻译得力助手

随着互联网技术的飞速发展&#xff0c;全球化交流日益频繁&#xff0c;跨语言沟通的需求也随之激增。对于外语水平有限的朋友来说&#xff0c;翻译器是一个必不可少的工具。今天我就分享几款我用的翻译器吧。 1.福晰在线翻译 链接直达>>https://fanyi.pdf365.cn/doc …