国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【0到1的設(shè)計(jì)之路】從C語言到二進(jìn)制程序

這篇具有很好參考價(jià)值的文章主要介紹了【0到1的設(shè)計(jì)之路】從C語言到二進(jìn)制程序。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

C程序如何從源代碼生成指令序列(二進(jìn)制可執(zhí)行文件)

預(yù)處理 -> 編譯 -> 匯編 -> 鏈接 -> 執(zhí)行

預(yù)處理

預(yù)處理 = 文本粘貼

#include <stdio.h>
#define MSG "Hello \
World!\n"
int main() {
  printf(MSG /* "hi!\n" */);
#ifdef __riscv
  printf("Hello RISC-V!\n");
#endif
  return 0;
}
gcc -E a.c

頭文件是如何找到的?

方法: 閱讀工具的日志(查看是否支持verbose, log等選項(xiàng))

gcc -E a.c --verbose > /dev/null

通過man gcc并搜索-I選項(xiàng)可得知頭文件搜索的順序

echo '#warning I am wrong!' > stdio.h
gcc -E a.c --verbose
mkdir aaa bbb
gcc -E a.c -Iaaa -Ibbb --verbose > /dev/null
echo '#warning I am wrong, too!' > bbb/stdio.h
echo '#define printf(...)' >> bbb/stdio.h
gcc -E a.c -Iaaa -Ibbb --verbose

類函數(shù)宏

#define max(a, b) ((a) > (b) ? (a) : (b))
  • 好的編程習(xí)慣 -> 總是用括號包圍參數(shù)
  • 好的編程習(xí)慣 -> 一個(gè)參數(shù)盡量不要展開多次
define max(a, b) ({ int x = a; int y = b; x > y ? x : y; })

上述代碼使用了GNU C Extension, 跨平臺移植時(shí)需要注意

預(yù)處理的其他工作

  • 去掉注釋
  • 連接因斷行符(行尾的)而拆分的字符串
  • 處理?xiàng)l件編譯 #ifdef/#else/#endif
riscv64-linux-gnu-gcc -E a.c  # apt-get install g++-riscv64-linux-gnu
  • 字符串化 #
  • 標(biāo)識符連接 ##
#define _str(x) #x
#define _concat(a, b) a##b
_concat(pr, intf)(_str(RISC-V));

IOCCC(國際混亂C代碼大賽)

套路: 借助預(yù)處理機(jī)制編寫不可讀代碼

【0到1的設(shè)計(jì)之路】從C語言到二進(jìn)制程序,0到1的設(shè)計(jì)之路,c語言,算法,開發(fā)語言

【0到1的設(shè)計(jì)之路】從C語言到二進(jìn)制程序,0到1的設(shè)計(jì)之路,c語言,算法,開發(fā)語言

編譯

編譯是一個(gè)比較復(fù)雜的過程

詞法分析 -> 語法分析 -> 語義分析 -> 中間代碼生成 -> 優(yōu)化 -> 目標(biāo)代碼生成

借助合適的工具(clang), 我們來看看每一個(gè)階段都在做什么

  • clang功能上等價(jià)于gcc, 但能向我們更好地展示編譯的中間步驟
#include <stdio.h>
int main() { // compute 1 + 2
  int x = 1, y = 2;
  int z = x + y;
  printf("z = %d\n", z);
  return 0;
}

詞法分析

clang -fsyntax-only -Xclang -dump-tokens a.c

識別并記錄源文件中的每一個(gè)token

  • 標(biāo)識符, 關(guān)鍵字, 常數(shù), 字符串, 運(yùn)算符, 大括號, 分號…
  • 還記錄了token的位置(文件名:行號:列號)

C代碼 = 字符串

  • 詞法分析器本質(zhì)上是一個(gè)字符串匹配程序

語法分析

clang -fsyntax-only -Xclang -ast-dump a.c

按照C語言的語法將識別出來的token組織成樹狀結(jié)構(gòu)

  • AST(Abstract Syntax Tree), 可以反映出源程序的層次結(jié)構(gòu)
  • 報(bào)告語法錯(cuò)誤, 例如漏了分號

語義分析

按照C語言的語義確定AST中每個(gè)表達(dá)式的類型

  • 相容的類型將根據(jù)C語言標(biāo)準(zhǔn)規(guī)范進(jìn)行類型轉(zhuǎn)換
    • 算術(shù)類型轉(zhuǎn)換
  • 報(bào)告語義錯(cuò)誤
    • 未定義的引用
    • 運(yùn)算符的操作數(shù)類型不匹配(如struct + int)
    • 函數(shù)調(diào)用參數(shù)的類型和數(shù)量不匹配

但大多數(shù)編譯器并沒有嚴(yán)格按階段進(jìn)行詞法分析, 語法分析, 語義分析

  • clang的-ast-dump把語義信息也一起輸出了

    • man clang可以得知clang的階段劃分

靜態(tài)程序分析

在不運(yùn)行程序的情況下對其進(jìn)行分析

  • 本質(zhì)就是分析AST中的信息

AST(Abstract Syntax Tree)是源代碼的抽象語法結(jié)構(gòu)的樹狀表現(xiàn)形式,也就是源代碼的抽象語法結(jié)構(gòu)的一種樹狀圖表示。
在編譯原理中,AST是源代碼和編譯器之間的一種數(shù)據(jù)結(jié)構(gòu)。編譯器將源代碼轉(zhuǎn)換為AST,然后對AST進(jìn)行一系列的轉(zhuǎn)換,最終生成目標(biāo)代碼。AST的結(jié)構(gòu)和形式是由源代碼的語法決定的,因此AST也被稱為源代碼的抽象語法。
AST可以用于靜態(tài)分析,即在程序運(yùn)行之前對其進(jìn)行分析。通過分析AST,可以了解程序的結(jié)構(gòu)、語法錯(cuò)誤、潛在的邏輯錯(cuò)誤等等。例如,一些代碼質(zhì)量檢查工具、代碼格式化工具、編譯器優(yōu)化等都可以使用AST進(jìn)行分析。
在不運(yùn)行程序的情況下對其進(jìn)行分析,本質(zhì)就是分析AST中的信息。通過解析源代碼生成AST,然后對AST進(jìn)行分析,可以獲取程序的各種信息,如變量使用情況、函數(shù)調(diào)用關(guān)系、代碼覆蓋率等等。這些信息可以用于代碼質(zhì)量評估、性能優(yōu)化、錯(cuò)誤檢測和修復(fù)等等。

可以檢查/分析以下方面

  • 語法錯(cuò)誤,
  • 代碼風(fēng)格和規(guī)范,
  • 潛在的軟件缺陷,
  • 安全漏洞,
  • 性能問題
#include <stdlib.h>
int main() {
  int *p = malloc(sizeof(*p) * 10);
  free(p);
  *p = 0;
  return 0;
}
clang use-after-free.c --analyze -Xanalyzer -analyzer-output=text

中間代碼生成

clang -S -emit-llvm a.c

中間代碼(也稱中間表示, IR) = 編譯器定義的, 面向編譯場景的指令集

define dso_local i32 @main() #0 {
  %1 = alloca i32, align 4
  %2 = alloca i32, align 4
  %3 = alloca i32, align 4
  %4 = alloca i32, align 4
  store i32 0, i32* %1, align 4
  store i32 1, i32* %2, align 4
  store i32 2, i32* %3, align 4
  %5 = load i32, i32* %2, align 4
  %6 = load i32, i32* %3, align 4
  %7 = add nsw i32 %5, %6
  store i32 %7, i32* %4, align 4
  %8 = load i32, i32* %4, align 4
  %9 = call i32 (i8*, ...) @printf(i8* noundef getelementptr inbounds ([8 x i8], [8 x i8]* @.str, i64 0, i64 0), i32 noundef %8)
  ret i32 0
}

將C語言狀態(tài)機(jī)翻譯成IR狀態(tài)機(jī)

  • 變量 -> %1, %2, %3, %4, …
  • 語句 -> alloca, store, load, add, call, ret, …

中間代碼作為抽象層

為什么不直接翻譯到處理器ISA?

基于抽象層進(jìn)行優(yōu)化很容易

可以支持多種源語言和目標(biāo)語言(硬件指令集)

【0到1的設(shè)計(jì)之路】從C語言到二進(jìn)制程序,0到1的設(shè)計(jì)之路,c語言,算法,開發(fā)語言
clang使用的中間代碼叫LLVM IR, gcc的叫GIMPLE

  • 我們不需要理解其中的細(xì)節(jié), 研究它是編譯專家的事情
  • 知道一些基本概念, 會連蒙帶猜看一看即可(可RTFM了解更多)

優(yōu)化

如果兩個(gè)狀態(tài)機(jī)在某種意義上 “相同”, 就可以用 “簡單”的替代 “復(fù)雜”的

  • “簡單” = 狀態(tài)少(變量少), 激勵事件少(語句少)…

  • 最 “復(fù)雜” = 嚴(yán)格按照語句的語義來翻譯(嚴(yán)格的狀態(tài)轉(zhuǎn)移)

  • “相同” = 程序的可觀測行為(C99 5.1.2.3節(jié)第6點(diǎn))的一致性

  • 對volatile修飾變量的訪問需要嚴(yán)格執(zhí)行

  • 程序結(jié)束時(shí), 寫入文件的數(shù)據(jù)需要與嚴(yán)格執(zhí)行時(shí)一致

  • 交互式設(shè)備的輸入輸出(stdio.h)需要與嚴(yán)格執(zhí)行時(shí)一致

這給編譯器優(yōu)化提供了非常廣闊的空間

  • 也是因?yàn)樘珡V闊, 以至于編譯器里面有很多bug
  • 理論上來說, “判斷任意兩個(gè)程序的可觀測行為是否一致”是不可判定的
  • 如果這個(gè)問題可判定, 那么借助它可判定圖靈停機(jī)問題(閱讀材料)

例: 常數(shù)傳播

clang -S -foptimization-record-file=- a.c
clang -S -foptimization-record-file=- a.c -O1

加個(gè)volatile試試

#include <stdio.h>
int main() { // compute 1 + 2
  int x = 1, y = 2;
  volatile int z = x + y;
  printf("z = %d\n", z);
  return 0;
}

目標(biāo)代碼生成

clang -S a.c
clang -S a.c --target=riscv32-linux-gnu
gcc -S a.c   # 也可以用gcc生成


# apt-get install g++-riscv64-linux-gnu
riscv64-linux-gnu-gcc -march=rv32g -mabi=ilp32 -S a.c

將IR狀態(tài)機(jī)翻譯成處理器ISA狀態(tài)機(jī)

  • %1, %2, %3, %4, … -> {R,M}
  • alloca, store, load, add, call, ret, … -> ISA的指令
  • 同時(shí)進(jìn)行目標(biāo)ISA相關(guān)的優(yōu)化
    • 把經(jīng)常使用的變量放到寄存器, 不太常用的變量放到內(nèi)存
    • 選擇指令數(shù)量較少的指令序列
    • 有很多優(yōu)化的空間, 這里不深入討論

可以通過time report觀察clang嘗試了哪些優(yōu)化工作

clang -S a.c -ftime-report

踏入二進(jìn)制的世界

匯編

gcc -c a.c
riscv64-linux-gnu-gcc -march=rv32g -mabi=ilp32 -c a.c
# alias rv32gcc="riscv64-linux-gnu-gcc -march=rv32g -mabi=ilp32"

根據(jù)指令集手冊, 把匯編代碼(指令的符號化表示)翻譯成二進(jìn)制目標(biāo)文件(指令的編碼表示)

二進(jìn)制文件不能用文本編輯器打開來閱讀了

  • 需要binutils(Binary Utilities)或者llvm的工具鏈
objdump -d a.o
riscv64-linux-gnu-objdump -d a.o
# alias rvobjdump="riscv64-linux-gnu-objdump"
llvm-objdump -d a.o # llvm的工具鏈可以自動識別目標(biāo)文件的架構(gòu), 用起來更方便

鏈接

gcc a.c
riscv64-linux-gnu-gcc a.c  # apt默認(rèn)不安裝rv32的glibc庫, 無法鏈接到glibc, 這里用rv64演示

合并多個(gè)目標(biāo)文件, 生成可執(zhí)行文件

  • 哪里來的多個(gè)目標(biāo)文件呢?

讓我們來看日志!

gcc a.c --verbose
gcc a.c --verbose 2>&1 | tail -n 2 | head -n 1 | tr ' ' '\n' | grep '\.o$'

有很多crtxxx.o的文件

crt = C runtime, C程序的運(yùn)行時(shí)環(huán)境(的一部分)
可以通過objdump確認(rèn)
問題: printf()的代碼在哪里呢?

執(zhí)行

./a.out

# 通過一些配置工作, RISC-V的可執(zhí)行文件也可以在本地執(zhí)行
# apt-get install qemu-user qemu-user-binfmt
# mkdir -p /etc/qemu-binfmt
# ln -s /usr/riscv64-linux-gnu/ /etc/qemu-binfmt/riscv64
file a.out
a.out: ELF 64-bit LSB pie executable, UCB RISC-V, version 1 (SYSV)...
./a.out # 實(shí)際上是在QEMU模擬器中執(zhí)行

把可執(zhí)行文件加載到內(nèi)存, 跳轉(zhuǎn)到程序, 執(zhí)行編譯出的指令序列

Q: 誰來加載?

A: 運(yùn)行時(shí)環(huán)境(宿主操作系統(tǒng)/QEMU)

實(shí)現(xiàn)定義行為和ABI

【0到1的設(shè)計(jì)之路】從C語言到二進(jìn)制程序,0到1的設(shè)計(jì)之路,c語言,算法,開發(fā)語言

【0到1的設(shè)計(jì)之路】從C語言到二進(jìn)制程序,0到1的設(shè)計(jì)之路,c語言,算法,開發(fā)語言
正確做法: 通過日志觀察工具的行為

  • 程序相同, 但編譯選項(xiàng)可能影響程序的解釋 -> 看AST!
clang -fno-color-diagnostics -fsyntax-only -Xclang -ast-dump -w -std=c90 -m32 a.c

RTFM: ABI中定義的基本數(shù)據(jù)類型

  • System V ABI for i386 - 32位x86 Linux遵循的ABI:https://math-atlas.sourceforge.net/devel/assembly/abi386-4.pdf
  • ABI for RISC-V:https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc

ABI,全稱為Application Binary Interface,即應(yīng)用程序二進(jìn)制接口。它定義了應(yīng)用程序與操作系統(tǒng)之間進(jìn)行交互的方式和規(guī)范,確保不同的軟件組件能夠正確地協(xié)同工作。ABI包括了函數(shù)調(diào)用約定、寄存器的使用、參數(shù)傳遞方式、系統(tǒng)調(diào)用接口等內(nèi)容,為軟件開發(fā)者提供了一個(gè)穩(wěn)定和一致的編程接口。

為什么還要學(xué)習(xí)C語言?

“使用語言”和 “學(xué)習(xí)計(jì)算機(jī)”的目的不完全相同

  • 使用語言的目標(biāo)是提高效率

    • 開發(fā)者友好的語言特性, 更抽象也更安全的功能, 各種開箱即用的庫
      • 例 - 數(shù)組越界不再是UB, 而是由運(yùn)行環(huán)境馬上報(bào)錯(cuò)
      • 這些功能需要更復(fù)雜的翻譯環(huán)境和運(yùn)行環(huán)境來支撐

作為計(jì)算機(jī)的使用者, 我們應(yīng)該掌握1~2門現(xiàn)代語言提升工作效率
python, bash, go, rust, …

  • 學(xué)習(xí)計(jì)算機(jī)的目標(biāo)是理解程序如何在計(jì)算機(jī)上運(yùn)行
    • 語言越接近底層硬件, 越有利于我們學(xué)習(xí)其中的細(xì)節(jié)
      • 例 - ISA狀態(tài)機(jī)沒有數(shù)組越界的概念
    • 作為計(jì)算機(jī)的設(shè)計(jì)者, 我們應(yīng)該掌握C語言, 理解計(jì)算機(jī)的基本原理

總結(jié)—從C代碼到指令序列

  • 預(yù)處理 -> 編譯 -> 匯編 -> 鏈接 -> 執(zhí)行

  • 編譯 = 詞法分析 -> 語法分析 -> 語義分析 -> 中間代碼生成 -> 優(yōu)化 -> 目標(biāo)代碼生成

  • 學(xué)會使用工具和日志理解其中的細(xì)節(jié)

  • C語言標(biāo)準(zhǔn)中除了確切的行為, 還包含

    • Unspecified Behavior
    • Implementation-defined Behavior
    • Undefined Behavior
  • 通過ABI手冊了解Implementation-defined Behavior的選擇

    • 同時(shí)認(rèn)識C語言標(biāo)準(zhǔn), 編譯器, 操作系統(tǒng), 運(yùn)行庫, 處理器之間的協(xié)助
    • 程序的運(yùn)行結(jié)果與源代碼和上述因素都有關(guān)系

內(nèi)容來自:一生一芯_余子濠_從C語言到二進(jìn)制程序文章來源地址http://www.zghlxwxcb.cn/news/detail-818621.html

到了這里,關(guān)于【0到1的設(shè)計(jì)之路】從C語言到二進(jìn)制程序的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 力扣67. 二進(jìn)制求和算法

    力扣67. 二進(jìn)制求和算法

    這道題需要,給你兩個(gè)字符串比如 答案是:\\\"10101\\\" 然后需要你給出計(jì)算結(jié)果,那么我們很容易想到兩種做法 1. 調(diào)庫做法:直接轉(zhuǎn)化為整數(shù),然后用內(nèi)置函數(shù)做進(jìn)制轉(zhuǎn)換直接計(jì)算出結(jié)果 2. 計(jì)算做法:將十進(jìn)制思維移植過來,對每一位加并且做carry操作,最后得出結(jié)果 筆者最初

    2024年01月16日
    瀏覽(27)
  • 【算法題】67. 二進(jìn)制求和

    給你兩個(gè)二進(jìn)制字符串 a 和 b ,以二進(jìn)制字符串的形式返回它們的和。 示例 1: 輸入:a = \\\"11\\\", b = \\\"1\\\" 輸出:\\\"100\\\" 示例 2: 輸入:a = \\\"1010\\\", b = \\\"1011\\\" 輸出:\\\"10101\\\" 提示: 1 = a.length, b.length = 10^4 a 和 b 僅由字符 \\\'0\\\' 或 \\\'1\\\' 組成 字符串如果不是 \\\"0\\\" ,就不含前導(dǎo)零

    2024年01月23日
    瀏覽(21)
  • C語言:二進(jìn)制、八進(jìn)制、十六進(jìn)制整數(shù)的書寫及輸出

    C語言:二進(jìn)制、八進(jìn)制、十六進(jìn)制整數(shù)的書寫及輸出

    目錄 一、整型數(shù)據(jù)類型 二、二進(jìn)制、八進(jìn)制、十六進(jìn)制的書寫 1)二進(jìn)制 以 0b / 0B 開頭,不區(qū)分大小寫(數(shù)字0,而非字母o,下同) 2)八進(jìn)制 以數(shù)字 0 開頭 ????????3)十六進(jìn)制 以 0x / 0X 開頭, 三、二進(jìn)制、八進(jìn)制和十六進(jìn)制的輸出 八進(jìn)制? ?(%o): 十六進(jìn)制? ?(%x):

    2024年02月05日
    瀏覽(99)
  • 二進(jìn)制算法題+回文鏈表

    先計(jì)算兩個(gè)字符串公共的部分,需要維護(hù)三個(gè)變量:兩個(gè)數(shù)組的指針idx+一個(gè)進(jìn)位變量up 注意,這里用StringBuffer來存儲結(jié)果,先存儲的是個(gè)位,所以最后需要reverse一下。 21分鐘 如何看一個(gè)字符是否在變化?維護(hù)一個(gè)temp變量來記錄他上一次的結(jié)果。 模擬十進(jìn)制轉(zhuǎn)二進(jìn)制:先對

    2024年02月07日
    瀏覽(86)
  • C語言二進(jìn)制數(shù)據(jù)和16進(jìn)制字符串互轉(zhuǎn)

    知識點(diǎn):結(jié)構(gòu)體中的“伸縮型數(shù)組成員”(C99新增) C99新增了一個(gè)特性:伸縮型數(shù)組成員(flexible array member),利用這項(xiàng)特性聲明的結(jié)構(gòu),其最后一個(gè)數(shù)組成員具有一些特性。第1個(gè)特性是,該數(shù)組不會立即存在。第2個(gè)特性是,使用這個(gè)伸縮型數(shù)組成員可以編寫合適的代碼,就

    2024年02月13日
    瀏覽(28)
  • C語言文本模式和二進(jìn)制模式

    本篇文章介紹一下C語言的文本模式和二進(jìn)制模式 從宏觀上看,無論是文本文件還是二進(jìn)制文件,文件中保存的都是 0和1的序列 ,因?yàn)榇疟P只有這兩種狀態(tài)。不同的文件只是對0、1序列的解釋不同, 如果文件內(nèi)容是以字符編碼的方式保存到文件中的 ,無論是以哪種編碼方式,

    2024年02月05日
    瀏覽(19)
  • 【c語言】二進(jìn)制文件的讀寫操作

    【c語言】二進(jìn)制文件的讀寫操作

    創(chuàng)作不易,本篇文章如果幫助到了你,還請點(diǎn)贊 關(guān)注支持一下???)!! 主頁專欄有更多知識,如有疑問歡迎大家指正討論,共同進(jìn)步! ??c語言系列專欄:c語言之路重點(diǎn)知識整合 ?? 給大家跳段街舞感謝支持!? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 本文基

    2024年02月12日
    瀏覽(23)
  • 【C語言】求二進(jìn)制位中一的個(gè)數(shù)

    【C語言】求二進(jìn)制位中一的個(gè)數(shù)

    原題鏈接:??途W(wǎng) 題目內(nèi)容: 寫一個(gè)函數(shù)返回參數(shù)二進(jìn)制中 1 的個(gè)數(shù),負(fù)數(shù)使用補(bǔ)碼表示。 比如: 15????0000 1111????4 個(gè) 1 方法一: NumberOf1函數(shù)的實(shí)現(xiàn)比較簡單,它使用了一個(gè)循環(huán),不斷將n除以2,并判斷余數(shù)是否為1。如果余數(shù)為1,則說明n的二進(jìn)制表示中最低位為1,計(jì)

    2024年02月09日
    瀏覽(26)
  • 算法leetcode|67. 二進(jìn)制求和(rust重拳出擊)

    給你兩個(gè)二進(jìn)制字符串 a 和 b ,以二進(jìn)制字符串的形式返回它們的和。 1 = a.length, b.length = 10 4 a 和 b 僅由字符 \\\'0\\\' 或 \\\'1\\\' 組成 字符串如果不是 \\\"0\\\" ,就不含前導(dǎo)零 面對這道算法題目,二當(dāng)家的再次陷入了沉思。 直接用API將字符串按照2進(jìn)制轉(zhuǎn)成整型,相加,然后再按照2進(jìn)制轉(zhuǎn)

    2024年02月14日
    瀏覽(25)
  • 深入解析位運(yùn)算算法:探索數(shù)字的二進(jìn)制秘密

    位運(yùn)算是計(jì)算機(jī)科學(xué)中的重要概念,用于在二進(jìn)制數(shù)字層面進(jìn)行各種操作。本文將深入介紹位運(yùn)算的基本操作,以及它在判斷、計(jì)算和處理數(shù)字中的應(yīng)用,包括判斷2的冪次方、位圖法、位掩碼和尋找缺失數(shù)字等。 位操作是通過對數(shù)字的二進(jìn)制表示進(jìn)行操作,實(shí)現(xiàn)各種功能。

    2024年02月11日
    瀏覽(21)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包