C語言操作符詳解:從基礎到進階

在C語言中,操作符是構建表達式的基礎,掌握各類操作符的用法、優先級及特性,對寫出高效且正確的代碼至關重要。本文將系統梳理C語言操作符的核心知識點,包含實例代碼與詳細解析,助你徹底搞懂操作符。

1. 操作符的分類

C語言操作符可按功能分為以下幾類,清晰的分類有助于理解其特性:

類別操作符
算術操作符+-*/%
移位操作符<<>>
位操作符&|^~
賦值操作符=+=-=*=/=%=<<=>>=&=|=^=
單目操作符!++--&*+-~sizeof(類型)(強制類型轉換)
關系操作符>>=<<===!=
邏輯操作符&&||
條件操作符? :
逗號表達式,
下標引用[]
函數調用()
結構成員訪問操作符.->

2. 二進制與進制轉換

計算機底層使用二進制存儲數據,掌握進制轉換是理解位操作的基礎。

2.1 二進制與十進制轉換

  • 二進制轉十進制:按權重展開求和(權重為20,21,22,...2^0, 2^1, 2^2,...20,21,22,...,從右向左)。
    例:二進制1101轉十進制:
    1×23+1×22+0×21+1×20=8+4+0+1=131×2^3 + 1×2^2 + 0×2^1 + 1×2^0 = 8 + 4 + 0 + 1 = 131×23+1×22+0×21+1×20=8+4+0+1=13

  • 十進制轉二進制:除2取余,余數倒序排列。
    例:十進制125轉二進制:
    125 ÷ 2 = 62 余1
    62 ÷ 2 = 31 余0
    31 ÷ 2 = 15 余1
    15 ÷ 2 = 7 余1
    7 ÷ 2 = 3 余1
    3 ÷ 2 = 1 余1
    1 ÷ 2 = 0 余1
    結果:1111101

2.2 二進制與八/十六進制轉換

  • 二進制轉八進制:從右向左每3位一組,不足補0,每組對應1個八進制數(0-7)。
    例:二進制01101011 → 分組01 101 011 → 轉換為八進制153(前綴0表示八進制)。

  • 二進制轉十六進制:從右向左每4位一組,不足補0,每組對應1個十六進制數(0-9, a-f)。
    例:二進制01101011 → 分組0110 1011 → 轉換為十六進制0x6b(前綴0x表示十六進制)。

3. 原碼、反碼、補碼

整數在內存中以補碼存儲,原因是:統一符號位與數值位處理,簡化加法運算(CPU僅需加法器)。

  • 原碼:直接表示符號位(0正1負)和數值位。
    例:int a = 3 → 原碼00000000 00000000 00000000 00000011
    int b = -3 → 原碼10000000 00000000 00000000 00000011

  • 反碼:原碼符號位不變,數值位取反。
    例:-3的反碼11111111 11111111 11111111 11111100

  • 補碼:反碼+1(負數補碼);正數原碼=反碼=補碼。
    例:-3的補碼11111111 11111111 11111111 11111101

4. 移位操作符

移位操作符僅作用于整數,分為左移和右移。

4.1 左移操作符 <<

  • 規則:左邊丟棄,右邊補0。
  • 示例
#include <stdio.h>
int main() {int num = 10; // 二進制:00000000 00000000 00000000 00001010int n = num << 1; // 左移1位:00000000 00000000 00000000 00010100 → 20printf("n = %d\n", n); // 輸出:20printf("num = %d\n", num); // 輸出:10(原變量不變)return 0;
}

4.2 右移操作符 >>

  • 邏輯右移:左邊補0,右邊丟棄(無符號數)。
  • 算術右移:左邊補符號位,右邊丟棄(有符號數,主流編譯器采用)。

示例(算術右移):

#include <stdio.h>
int main() {int num = -1; // 補碼:11111111 11111111 11111111 11111111int n = num >> 1; // 算術右移1位:11111111 11111111 11111111 11111111 → 仍為-1printf("n = %d\n", n); // 輸出:-1return 0;
}

?? 注意:禁止移動負數位(如num >> -1,行為未定義)。

5. 位操作符

位操作符直接對二進制位進行操作,操作數為整數。

操作符功能示例(二進制)
`&`按位與(同1則1)1010 & 0111 = 0010
`|`按位或(有1則1)1010 | 0111 = 1111
`^`按位異或(不同則1)1010 ^ 0111 = 1101
`~`按位取反(0變1,1變0)~1010 = 0101(假設4位)
|

經典案例

  1. 不創建臨時變量交換兩數
#include <stdio.h>
int main() {int a = 10, b = 20;a = a ^ b; // a = 10^20b = a ^ b; // b = (10^20)^20 = 10a = a ^ b; // a = (10^20)^10 = 20printf("a = %d, b = %d\n", a, b); // 輸出:a=20, b=10return 0;
}
  1. 求二進制中1的個數
// 方法3(最優):每次消去最后一個1,循環次數=1的個數
#include <stdio.h>
int count_one(int num) {int count = 0;while (num) {num &= num - 1; // 消去最后一個1count++;}return count;
}
int main() {printf("%d\n", count_one(10)); // 1010 → 2個1 → 輸出2return 0;
}

6. 單目操作符

單目操作符僅需一個操作數,重點如下:

操作符功能示例
!邏輯非(真變假,假變真)!0 = 1!5 = 0
++自增(前置先增后用,后置先用后增)int a=3; printf("%d", ++a); // 4
--自減(類似++)int a=3; printf("%d", a--); // 3
sizeof求類型/變量所占字節數sizeof(int) = 4sizeof(a) = 4(a為int)
(類型)強制類型轉換(int)3.14 = 3

7. 逗號表達式

形式:exp1, exp2, ..., expN

  • 執行順序:從左到右依次執行。
  • 結果:最后一個表達式的值。

示例:

#include <stdio.h>
int main() {int a = 1, b = 2;int c = (a > b, a = b + 10, a, b = a + 1); // 執行:a>b(假)→ a=12 → 取a=12 → b=13 → 結果c=13printf("c = %d\n", c); // 輸出:13return 0;
}

8. 下標訪問與函數調用

  • 下標訪問[]:操作數為數組名+索引,如arr[3]等價于*(arr+3)

    int arr[5] = {1,2,3,4,5};
    printf("%d\n", arr[2]); // 輸出:3(訪問第3個元素)
    
  • 函數調用():操作數為函數名+參數列表。

    #include <stdio.h>
    void print_hello() {printf("Hello, C!\n");
    }
    int add(int a, int b) {return a + b;
    }
    int main() {print_hello(); // 函數調用,無參數printf("3+5 = %d\n", add(3, 5)); // 函數調用,有參數 → 輸出8return 0;
    }
    

9. 結構體成員訪問

結構體成員訪問有兩種方式:

  • .:直接訪問(結構體變量)。
  • ->:間接訪問(結構體指針)。

示例:

#include <stdio.h>
#include <string.h>// 定義學生結構體
struct Stu {char name[20];int age;
};int main() {struct Stu s = {"張三", 20}; // 結構體變量struct Stu* ps = &s; // 結構體指針// 訪問成員printf("name: %s, age: %d\n", s.name, s.age); // .訪問 → 張三, 20strcpy(ps->name, "李四"); // ->訪問:修改姓名ps->age = 22; // ->訪問:修改年齡printf("name: %s, age: %d\n", s.name, s.age); // 李四, 22return 0;
}

10. 操作符的優先級與結合性

表達式求值由優先級和結合性決定:

  • 優先級:決定操作順序(如*優先級高于+)。
    例:3 + 4 * 5 → 先算4*5=20,再算3+20=23

  • 結合性:優先級相同時,左結合(從左到右)或右結合(從右到左,如賦值=)。
    例:5 * 6 / 2 → 左結合,先算5*6=30,再算30/2=15

優先級簡表(從高到低)

優先級操作符結合性
1()[].->左結合
2++--!~sizeof右結合
3*/%左結合
4+-(算術)左結合
5<<>>左結合
6<><=>=左結合
7==!=左結合
8&左結合
9^左結合
10``
11&&左結合
12`
13? :右結合
14=+=-=右結合

11. 表達式求值注意事項

11.1 整型提升

長度小于int的整型(如charshort)在運算時會提升為intunsigned int,避免精度丟失。
例:char a = 127, b = 1; int c = a + b;

  • a提升為00000000 00000000 00000000 01111111
  • b提升為00000000 00000000 00000000 00000001
  • 相加后c = 128(若直接存char會溢出)。

11.2 避免歧義表達式

部分表達式因優先級/結合性無法確定唯一執行順序,結果依賴編譯器,應避免:

  • c + --c:無法確定+左右操作數的求值順序。
  • (++i) + (++i) + (++i):不同編譯器結果不同(如GCC輸出10,VS輸出12)。

總結

操作符是C語言的基礎,掌握其分類、特性及求值規則,能幫助我們寫出更高效、無歧義的代碼。重點關注位操作符的靈活應用(如交換變量、統計1的個數)、補碼的存儲邏輯,以及優先級對表達式的影響。實際開發中,復雜表達式建議用括號明確順序,減少歧義。

希望本文對你理解C語言操作符有幫助,歡迎留言交流! 😊

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/90898.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/90898.shtml
英文地址,請注明出處:http://en.pswp.cn/web/90898.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

鴻蒙平臺運行Lua腳本

1. 目標 使用 rust 在移動端實現 Lua 腳本的運行。 2. 核心步驟 [Rust Host App]│├── [mLua VM] (通過 mlua 或 rlua 庫嵌入)│ ├── 獨立Lua狀態&#xff08;隔離執行&#xff09;│ ├── 受限標準庫&#xff08;禁用危險函數&#xff09;│ └── 內存/CPU限…

【Ubuntu】發展歷程

Ubuntu 是一個基于 Debian 的 Linux 發行版&#xff0c;由 Canonical 公司開發和維護。它以其易用性、穩定性和強大的社區支持而著稱。以下是 Ubuntu 從發布以來的主要版本和發展歷程&#xff1a;1. Ubuntu 4.10 "Warty Warthog" (2004)發布日期&#xff1a;2004年10…

k8s下springboot-admin 監控服務部署,客戶端接入

踩坑及解決以下問題 1、客戶端監控信息不顯示,需要暴露監控檢查接口路徑 2、服務端不顯示客戶端日志,需要啟用日志,并指定日志路徑 3、解決在k8s下,客戶端多實例注冊id相同,如2個實例只顯示一個 整體架構 springboot-admin 由服務端和客戶端組成 服務端負責 1、提供 We…

git刪除遠程分支和本地分支

1. git刪除遠程分支 git push origin --delete [branch_name]2. 刪除本地分支 2.1 git branch -d 會在刪除前檢查merge狀態&#xff08;其與上游分支或者與head&#xff09;。 git branch -d [branch_name] 2.2 git branch -D 直接刪除 git branch -D 是 git branch --delete…

Go 的時間包:理解單調時間與掛鐘時間

Go 的時間包&#xff1a;理解單調時間與掛鐘時間 &#x1f4c5; 引言 Go 語言自版本 1.9 起在 time.Time 中同時支持 “掛鐘時間&#xff08;wall?clock&#xff09;” 和 “單調時間&#xff08;monotonic clock&#xff09;”&#xff0c;用于分別滿足時間戳與時間間隔測量…

Android啟動時間優化大全

1 修改Android mksh默認的列長度 不修改這個參數&#xff0c;adb shell后&#xff0c;輸入超過80個字符&#xff0c;就不能看到完整的命令行。external/mksh/src/sh.h EXTERN mksh_ari_t x_cols E_INIT(80); EXTERN mksh_ari_t x_lins E_INIT(24);2 Kernel優化 2.1 內核驅動模塊…

matplotlib.pyplot: 底層原理簡析與進階技巧

文章目錄 1 底層實現原理 1.1 核心架構 1.1 渲染流程 2 基礎用法 2.1 基本繪圖 2.2 多子圖系統 2.3 高階用法 2.3.1 自定義Artist對象 2.3.2 高級動畫技術 2.3.3 事件處理系統 2.3.4 混合渲染技術 3 性能優化技巧 4 擴展模塊 5 總結 5.1 底層原理關鍵點 5.2 進階技巧 1 底層實現…

深入理解現代前端開發中的 <script type=“module“> 與構建工具實踐

引言&#xff1a;模塊化開發的演進在早期的前端開發中&#xff0c;JavaScript 缺乏原生的模塊化支持&#xff0c;開發者不得不依賴 IIFE&#xff08;立即調用函數表達式&#xff09;或第三方庫&#xff08;如 RequireJS&#xff09;來實現代碼組織。隨著 ES6&#xff08;ES2015…

yolo--qt可視化開發

qt5可能不支持我們的cuda版本&#xff0c;改用qt6 YOLO11QT6OpencvC訓練加載模型全過程講解_yolov11 模型轉換成opencv c模型-CSDN博客 下面是qt5版本的案例&#xff0c;和yolo及cuda有沖突 安裝qt 切換到虛擬環境&#xff0c;例如pyqt&#xff0c;conda activate pyqt pip …

SQL性能優化

show [session|global] status : 查看服務器狀態 show global status like Com_ : 查看各種語句的執行次數 開啟慢查詢: 在 MySQL 配置文件&#xff08;/etc/my.cnf&#xff09;配置: #開啟MySQL慢日志查詢開關 slow_query_log1 #設置慢日志的時間為2秒&#xff0c;SQL語句執…

ctfshow pwn40

目錄 1. 分析程序 2. 漏洞編寫 3. 漏洞驗證 1. 分析程序 首先檢查程序相關保護&#xff0c;發現程序為32位且只開啟了一個NX保護 checksec pwn 使用IDA進行逆向分析代碼&#xff0c;查看漏洞觸發點&#xff1a; 在main函數中&#xff0c;有一個ctfshow函數&#xff0c;這里…

SQL173 店鋪901國慶期間的7日動銷率和滯銷率

SQL173 店鋪901國慶期間的7日動銷率和滯銷率 SQL題解&#xff1a;店鋪動銷率與滯銷率計算 關鍵&#xff1a;只要當天任一店鋪有任何商品的銷量就輸出該天的結果&#xff0c;即使店鋪901當天的動銷率為0。 潛臺詞&#xff1a;?輸出邏輯與店鋪901的銷售情況無關&#xff0c;只取…

PytorchLightning最佳實踐基礎篇

PyTorch Lightning&#xff08;簡稱 PL&#xff09;是一個建立在 PyTorch 之上的高層框架&#xff0c;核心目標是剝離工程代碼與研究邏輯&#xff0c;讓研究者專注于模型設計和實驗思路&#xff0c;而非訓練循環、分布式配置、日志管理等重復性工程工作。本文從基礎到進階&…

Apache Flink 實時流處理性能優化實踐指南

Apache Flink 實時流處理性能優化實踐指南 隨著大數據和實時計算需求不斷增長&#xff0c;Apache Flink 已經成為主流的流處理引擎。然而&#xff0c;在生產環境中&#xff0c;高并發、大吞吐量和低延遲的業務場景對 Flink 作業的性能提出了更高要求。本文將從原理層面深入解析…

ubuntu上將TempMonitor加入開機自動運行的方法

1.新建一個TempMonitor.sh文件&#xff0c;內容如下&#xff1a;#!/bin/bashcd /fjrobot/ ./TempMonitor &2.執行以下命令chmod x TempMonitor chmod x TempMonitor.sh rm -rf /etc/rc2.d/S56TempMonitor rm -rf /etc/init.d/TempMonitor cp /fjrobot/TempMonitor.sh /etc/…

速賣通自養號測評技術解析:IP、瀏覽器與風控規避的實戰方案

一、速賣通的“春天”來了&#xff0c;賣家如何抓住機會&#xff1f;2025年的夏天&#xff0c;速賣通的風頭正勁。從沙特市場躍升為第二大電商平臺&#xff0c;到8月大促返傭力度升級&#xff0c;平臺對優質商家的扶持政策越來越清晰。但與此同時&#xff0c;競爭也愈發激烈——…

adb: CreateProcessW failed: 系統找不到指定的文件

具體錯誤 adb devices * daemon not running; starting now at tcp:5037 adb: CreateProcessW failed: 系統找不到指定的文件。 (2) * failed to start daemon adb.exe: failed to check server version: cannot connect to daemon 下載最新的platform-tools-windows 下載最新…

Centos安裝HAProxy搭建Mysql高可用集群負載均衡

接上文MYSQL高可用集群搭建–docker https://blog.csdn.net/weixin_43914685/article/details/149647589?spm1001.2014.3001.5501 連接到你搭建的 Percona XtraDB Cluster (PXC) 數據庫集群&#xff0c;實現高可用性和負載均衡&#xff0c;建議使用一個中間件來管理這些連接。…

Sql server開掛的OPENJSON

以前一直用sql server2008&#xff0c;自從升級成sql server2019后&#xff0c;用OPENJSON的感覺像開掛&#xff0c;想想以前表作為參數傳輸時的痛苦&#xff0c;不堪回首。一》不堪回首 為了執行效率&#xff0c;很多時候希望將表作為參數傳給數據庫的存儲過程。存儲過程支持自…

【數據結構】隊列和棧練習

1.用隊列實現棧 225. 用隊列實現棧 - 力扣&#xff08;LeetCode&#xff09; typedef int QDatatype; typedef struct QueueNode {struct QueueNode *next;QDatatype data; }QNode;typedef struct Queue {QNode* head;QNode* tail;QDatatype size; }Que;typedef struct {Que…