07-C語言運算子-指趣學院
運算子基本概念
-
和數學中的運算子一樣, C語言中的運算子是告訴程式執行特定算術或邏輯操作的符號
-
例如告訴程式, 某兩個數相加, 相減,相乘等
-
-
什麼是表示式
- 表示式就是利用運算子連結在一起的有意義,有結果的語句;
- 例如: a + b; 就是一個算數表示式, 它的意義是將兩個數相加, 兩個數相加的結果就是表示式的結果
- 注意: 表示式一定要有結果
運算子分類
- 按照功能劃分:
- 算術運算子
- 賦值運算子
- 關係運算子
- 邏輯運算子
- 位運算子
- 按照參與運算的運算元個數劃分:
- 單目運算
- 只有一個運算元 如 : i++;
- 雙目運算
- 有兩個運算元 如 : a + b;
- 三目運算
- C語言中唯一的一個,也稱為問號表示式 如: a>b ? 1 : 0;
- 單目運算
運算子的優先順序和結合性
- 早在小學的數學課本中,我們就學習過"從左往右,先乘除後加減,有括號的先算括號裡面的", 這句話就蘊含了優先順序和結合性的問題
- C語言中,運算子的運算優先順序共分為15 級。1 級最高,15 級最低
- 在C語言表示式中,不同優先順序的運算子, 運算次序按照由高到低執行
- 在C語言表示式中,相同優先順序的運算子, 運算次序按照結合性規定的方向執行
算數運算子
優先順序 | 名稱 | 符號 | 說明 |
---|---|---|---|
3 | 乘法運算子 | * | 雙目運算子,具有左結合性 |
3 | 除法運算子 | / | 雙目運算子,具有左結合性 |
3 | 求餘運算子 (模運算子) | % | 雙目運算子,具有左結合性 |
4 | 加法運算子 | + | 雙目運算子,具有左結合性 |
4 | 減法運算子 | - | 雙目運算子,具有左結合性 |
- 注意事項
- 如果參與運算的兩個運算元皆為整數, 那麼結果也為整數
- 如果參與運算的兩個運算元其中一個是浮點數, 那麼結果一定是浮點數
- 求餘運算子, 本質上就是數學的商和餘"中的餘數
- 求餘運算子, 參與運算的兩個運算元必須都是整數, 不能包含浮點數
- 求餘運算子, 被除數小於除數, 那麼結果就是被除數
- 求餘運算子, 運算結果的正負性取決於被除數,跟除數無關, 被除數是正數結果就是正數,被除數是負數結果就是負數
- 求餘運算子, 被除數為0, 結果為0
- 求餘運算子, 除數為0, 沒有意義(不要這樣寫)
#include <stdio.h>
int main(){
int a = 10;
int b = 5;
// 加法
int result = a + b;
printf("%i\n", result); // 15
// 減法
result = a - b;
printf("%i\n", result); // 5
// 乘法
result = a * b;
printf("%i\n", result); // 50
// 除法
result = a / b;
printf("%i\n", result); // 2
// 算術運算子的結合性和優先順序
// 結合性: 左結合性, 從左至右
int c = 50;
result = a + b + c; // 15 + c; 65;
printf("%i\n", result);
// 優先順序: * / % 大於 + -
result = a + b * c; // a + 250; 260;
printf("%i\n", result);
}
#include <stdio.h>
int main(){
// 整數除以整數, 結果還是整數
printf("%i\n", 10 / 3); // 3
// 參與運算的任何一個數是小數, 結果就是小數
printf("%f\n", 10 / 3.0); // 3.333333
}
#include <stdio.h>
int main(){
// 10 / 3 商等於3, 餘1
int result = 10 % 3;
printf("%i\n", result); // 1
// 左邊小於右邊, 那麼結果就是左邊
result = 2 % 10;
printf("%i\n", result); // 2
// 被除數是正數結果就是正數,被除數是負數結果就是負數
result = 10 % 3;
printf("%i\n", result); // 1
result = -10 % 3;
printf("%i\n", result); // -1
result = 10 % -3;
printf("%i\n", result); // 1
}
賦值運算子
優先順序 | 名稱 | 符號 | 說明 |
---|---|---|---|
14 | 賦值運算子 | = | 雙目運算子,具有右結合性 |
14 | 除後賦值運算子 | /= | 雙目運算子,具有右結合性 |
14 | 乘後賦值運算子 (模運算子) | *= | 雙目運算子,具有右結合性 |
14 | 取模後賦值運算子 | %= | 雙目運算子,具有右結合性 |
14 | 加後賦值運算子 | += | 雙目運算子,具有右結合性 |
14 | 減後賦值運算子 | -= | 雙目運算子,具有右結合性 |
- 簡單賦值運算子
#include <stdio.h>
int main(){
// 簡單的賦值運算子 =
// 會將=右邊的值賦值給左邊
int a = 10;
printf("a = %i\n", a); // 10
}
- 複合賦值運算子
#include <stdio.h>
int main(){
// 複合賦值運算子 += -= *= /= %=
// 將變數中的值取出之後進行對應的操作, 操作完畢之後再重新賦值給變數
int num1 = 10;
// num1 = num1 + 1; num1 = 10 + 1; num1 = 11;
num1 += 1;
printf("num1 = %i\n", num1); // 11
int num2 = 10;
// num2 = num2 - 1; num2 = 10 - 1; num2 = 9;
num2 -= 1;
printf("num2 = %i\n", num2); // 9
int num3 = 10;
// num3 = num3 * 2; num3 = 10 * 2; num3 = 20;
num3 *= 2;
printf("num3 = %i\n", num3); // 20
int num4 = 10;
// num4 = num4 / 2; num4 = 10 / 2; num4 = 5;
num4 /= 2;
printf("num4 = %i\n", num4); // 5
int num5 = 10;
// num5 = num5 % 3; num5 = 10 % 3; num5 = 1;
num5 %= 3;
printf("num5 = %i\n", num5); // 1
}
- 結合性和優先順序
#include <stdio.h>
int main(){
int number = 10;
// 賦值運算子優先順序是14, 普通運算子優先順序是3和4, 所以先計算普通運算子
// 普通運算子中乘法優先順序是3, 加法是4, 所以先計算乘法
// number += 1 + 25; number += 26; number = number + 26; number = 36;
number += 1 + 5 * 5;
printf("number = %i\n", number); // 36
}
自增自減運算子
- 在程式設計中,經常遇到“i=i+1”和“i=i-1”這兩種極為常用的操作。
- C語言為這種操作提供了兩個更為簡潔的運算子,即++和--
優先順序 | 名稱 | 符號 | 說明 |
---|---|---|---|
2 | 自增運算子(在後) | i++ | 單目運算子,具有左結合性 |
2 | 自增運算子(在前) | ++i | 單目運算子,具有右結合性 |
2 | 自減運算子(在後) | i-- | 單目運算子,具有左結合性 |
2 | 自減運算子(在前) | --i | 單目運算子,具有右結合性 |
- 自增
- 如果只有單個變數, 無論++寫在前面還是後面都會對變數做+1操作
#include <stdio.h>
int main(){
int number = 10;
number++;
printf("number = %i\n", number); // 11
++number;
printf("number = %i\n", number); // 12
}
- 如果出現在一個表示式中, 那麼++寫在前面和後面就會有所區別
- 字首表示式:++x, --x;其中x表示變數名,先完成變數的自增自減1運算,再用x的值作為表示式的值;即“先變後用”,也就是變數的值先變,再用變數的值參與運算
- 字尾表示式:x++, x--;先用x的當前值作為表示式的值,再進行自增自減1運算。即“先用後變”,也就是先用變數的值參與運算,變數的值再進行自增自減變化
#include <stdio.h>
int main(){
int number = 10;
// ++在後, 先參與表示式運算, 再自增
// 表示式運算時為: 3 + 10;
int result = 3 + number++;
printf("result = %i\n", result); // 13
printf("number = %i\n", number); // 11
}
#include <stdio.h>
int main(){
int number = 10;
// ++在前, 先自增, 再參與表示式運算
// 表示式運算時為: 3 + 11;
int result = 3 + ++number;
printf("result = %i\n", result); // 14
printf("number = %i\n", number); // 11
}
- 自減
#include <stdio.h>
int main(){
int number = 10;
// --在後, 先參與表示式運算, 再自減
// 表示式運算時為: 10 + 3;
int result = number-- + 3;
printf("result = %i\n", result); // 13
printf("number = %i\n", number); // 9
}
#include <stdio.h>
int main(){
int number = 10;
// --在前, 先自減, 再參與表示式運算
// 表示式運算時為: 9 + 3;
int result = --number + 3;
printf("result = %i\n", result); // 12
printf("number = %i\n", number); // 9
}
- 注意點:
- 自增、自減運算只能用於單個變數,只要是標準型別的變數,不管是整型、實型,還是字元型變數等,但不能用於表示式或常量
- 錯誤用法:
++(a+b); 5++;
- 錯誤用法:
- 企業開發中儘量讓++ -- 單獨出現, 儘量不要和其它運算子混合在一起
- 自增、自減運算只能用於單個變數,只要是標準型別的變數,不管是整型、實型,還是字元型變數等,但不能用於表示式或常量
int i = 10;
int b = i++; // 不推薦
或者
int b = ++i; // 不推薦
或者
int a = 10;
int b = ++a + a++; // 不推薦
- 請用如下程式碼替代
int i = 10;
int b = i; // 推薦
i++;
或者;
i++;
int b = i; // 推薦
或者
int a = 10;
++a;
int b = a + a; // 推薦
a++;
- C語言標準沒有明確的規定,
同一個表示式中同一個變數自增或自減後如何運算
, 不同編譯器得到結果也不同, 在企業開發中千萬不要這樣寫
int a = 1;
// 下列程式碼利用Qt執行時6, 利用Xcode執行是5
// 但是無論如何, 最終a的值都是3
// 在C語言中這種程式碼沒有意義, 不用深究也不要這樣寫
// 特點: 參與運算的是同一個變數, 參與運算時都做了自增自減操作, 並且在同一個表示式中
int b = ++a + ++a;
printf("b = %i\n", b);
sizeof運算子
-
sizeof可以用來計算一個變數或常量、資料型別所佔的記憶體位元組數
- 標準格式: sizeof(常量 or 變數);
-
sizeof的幾種形式
- sizeof( 變數\常量 );
sizeof(10);
char c = 'a'; sizeof(c);
- sizeof 變數\常量;
sizeof 10;
char c = 'a'; sizeof c;
- sizeof( 資料型別);
sizeof(float);
如果是資料型別不能省略括號
- sizeof( 變數\常量 );
-
sizeof面試題:
- sizeof()和+=、*=一樣是一個複合運算子, 由sizeof和()兩個部分組成, 但是代表的是一個整體
- 所以sizeof不是一個函式, 是一個運算子, 該運算子的優先順序是2
#include <stdio.h>
int main(){
int a = 10;
double b = 3.14;
// 由於sizeof的優先順序比+號高, 所以會先計算sizeof(a);
// a是int型別, 所以佔4個位元組得到結果4
// 然後再利用計算結果和b相加, 4 + 3.14 = 7.14
double res = sizeof a+b;
printf("res = %lf\n", res); // 7.14
}
逗號運算子
- 在C語言中逗號“,”也是一種運算子,稱為逗號運算子。 其功能是把多個表示式連線起來組成一個表示式,稱為逗號表示式
- 逗號運算子會從左至右依次取出每個表示式的值, 最後整個逗號表示式的值等於最後一個表示式的值
- 格式:
表示式1,表示式2,… …,表示式n;
- 例如:
int result = a+1,b=3*4;
- 例如:
#include <stdio.h>
int main(){
int a = 10, b = 20, c;
// ()優先順序高於逗號運算子和賦值運算子, 所以先計算()中的內容
// c = (11, 21);
// ()中是一個逗號表示式, 結果是最後一個表示式的值, 所以計算結果為21
// 將逗號表示式的結果賦值給c, 所以c的結果是21
c = (a + 1, b + 1);
printf("c = %i\n", c); // 21
}
關係運算子
- 為什麼要學習關係運算子
- 預設情況下,我們在程式中寫的每一句正確程式碼都會被執行。但很多時候,我們想在某個條件成立的情況下才執行某一段程式碼
- 這種情況的話可以使用條件語句來完成,但是學習條件語句之前,我們先來看一些更基礎的知識:如何判斷一個條件是否成立
- C語言中的真假性
- 在C語言中,條件成立稱為“真”,條件不成立稱為“假”,因此,判斷條件是否成立,就是判斷條件的“真假”
-
怎麼判斷真假呢?C語言規定,任何數值都有真假性,任何非0值都為“真”,只有0才為“假”。也就是說,108、-18、4.5、-10.5等都是“真”,0則是“假”
- 關係運算子的運算結果只有2種:如果條件成立,結果就為1,也就是“真”;如果條件不成立,結果就為0,也就是“假”
優先順序 | 名稱 | 符號 | 說明 |
---|---|---|---|
6 | 大於運算子 | > | 雙目運算子,具有左結合性 |
6 | 小於運算子 | < | 雙目運算子,具有左結合性 |
6 | 大於等於運算子 | >= | 雙目運算子,具有左結合性 |
6 | 小於等於運算子 | <= | 雙目運算子,具有左結合性 |
7 | 等於運算子 | == | 雙目運算子,具有左結合性 |
7 | 不等於運算子 | != | 雙目運算子,具有左結合性 |
#include <stdio.h>
int main(){
int result = 10 > 5;
printf("result = %i\n", result); // 1
result = 5 < 10;
printf("result = %i\n", result); // 1
result = 5 > 10;
printf("result = %i\n", result); // 0
result = 10 >= 10;
printf("result = %i\n", result); // 1
result = 10 <= 10;
printf("result = %i\n", result); // 1
result = 10 == 10;
printf("result = %i\n", result); // 1
result = 10 != 9;
printf("result = %i\n", result); // 1
}
- 優先順序和結合性
#include <stdio.h>
int main(){
// == 優先順序 小於 >, 所以先計算>
// result = 10 == 1; result = 0;
int result = 10 == 5 > 3;
printf("result = %i\n", result); // 0
}
#include <stdio.h>
int main(){
// == 和 != 優先順序一樣, 所以按照結合性
// 關係運算子是左結合性, 所以從左至右計算
// result = 0 != 3; result = 1;
int result = 10 == 5 != 3;
printf("result = %i\n", result); // 1
}
- 練習: 計算result的結果
int result1 = 3 > 4 + 7
int result2 = (3>4) + 7
int result3 = 5 != 4 + 2 * 7 > 3 == 10
- 注意點:
- 無論是float還是double都有精度問題, 所以一定要避免利用==判斷浮點數是否相等
#include <stdio.h>
int main(){
float a = 0.1;
float b = a * 10 + 0.00000000001;
double c = 1.0 + + 0.00000000001;
printf("b = %f\n", b);
printf("c = %f\n", c);
int result = b == c;
printf("result = %i\n", result); // 0
}
邏輯運算子
優先順序 | 名稱 | 符號 | 說明 |
---|---|---|---|
2 | 邏輯非運算子 | ! | 單目運算子,具有右結合性 |
11 | 邏輯與運算子 | && | 雙目運算子,具有左結合性 |
12 | 邏輯或運算子 | || |
雙目運算子,具有左結合性 |
- 邏輯非
- 格式:
! 條件A;
- 運算結果: 真變假,假變真
- 運算過程:
- 先判斷條件A是否成立,如果新增A成立, 那麼結果就為0,即“假”;
- 如果條件A不成立,結果就為1,即“真”
- 使用注意:
- 可以多次連續使用邏輯非運算子
- !!!0;相當於(!(!(!0)));最終結果為1
- 格式:
#include <stdio.h>
int main(){
// ()優先順序高, 先計算()裡面的內容
// 10==10為真, 所以result = !(1);
// !代表真變假, 假變真,所以結果是假0
int result = !(10 == 10);
printf("result = %i\n", result); // 0
}
- 邏輯與
- 格式:
條件A && 條件B;
- 運算結果:一假則假
- 運算過程:
- 總是先判斷"條件A"是否成立
- 如果"條件A"成立,接著再判斷"條件B"是否成立, 如果"條件B"也成立,結果就為1,即“真”
- 如果"條件A"成立,"條件B"不成立,結果就為0,即“假”
- 如果"條件A"不成立,不會再去判斷"條件B"是否成立, 因為邏輯與只要一個不為真結果都不為真
- 使用注意:
- "條件A"為假, "條件B"不會被執行
- 格式:
#include <stdio.h>
int main(){
// 真 && 真
int result = (10 == 10) && (5 != 1);
printf("result = %i\n", result); // 1
// 假 && 真
result = (10 == 9) && (5 != 1);
printf("result = %i\n", result); // 0
// 真 && 假
result = (10 == 10) && (5 != 5);
printf("result = %i\n", result); // 0
// 假 && 假
result = (10 == 9) && (5 != 5);
printf("result = %i\n", result); // 0
}
#include <stdio.h>
int main(){
int a = 10;
int b = 20;
// 邏輯與, 前面為假, 不會繼續執行後面
int result = (a == 9) && (++b);
printf("result = %i\n", result); // 1
printf("b = %i\n", b); // 20
}
- 邏輯或
- 格式:
條件A || 條件B;
- 運算結果:一真則真
- 運算過程:
- 總是先判斷"條件A"是否成立
- 如果"條件A"不成立,接著再判斷"條件B"是否成立, 如果"條件B"成立,結果就為1,即“真”
- 如果"條件A"不成立,"條件B"也不成立成立, 結果就為0,即“假”
- 如果"條件A"成立, 不會再去判斷"條件B"是否成立, 因為邏輯或只要一個為真結果都為真
- 使用注意:
- "條件A"為真, "條件B"不會被執行
- 格式:
#include <stdio.h>
int main(){
// 真 || 真
int result = (10 == 10) || (5 != 1);
printf("result = %i\n", result); // 1
// 假 || 真
result = (10 == 9) || (5 != 1);
printf("result = %i\n", result); // 1
// 真 || 假
result = (10 == 10) || (5 != 5);
printf("result = %i\n", result); // 1
// 假 || 假
result = (10 == 9) || (5 != 5);
printf("result = %i\n", result); // 0
}
#include <stdio.h>
int main(){
int a = 10;
int b = 20;
// 邏輯或, 前面為真, 不會繼續執行後面
int result = (a == 10) || (++b);
printf("result = %i\n", result); // 1
printf("b = %i\n", b); // 20
}
- 練習: 計算result的結果
int result = 3>5 || 2<4 && 6<1;
三目運算子
三目運算子,它需要3個資料或表示式構成條件表示式
-
格式:
表示式1?表示式2(結果A):表示式3(結果B)
- 示例:
考試及格 ? 及格 : 不及格;
- 示例:
-
求值規則:
- 如果"表示式1"為真,三目運算子的運算結果為"表示式2"的值(結果A),否則為"表示式3"的值(結果B)
示例:
int a = 10;
int b = 20;
int max = (a > b) ? a : b;
printf("max = %d", max);
輸出結果: 20
等價於:
int a = 10;
int b = 20;
int max = 0;
if(a>b){
max=a;
}else {
max=b;
}
printf("max = %d", max);
- 注意點
- 條件運算子的運算優先順序低於關係運算子和算術運算子,但高於賦值符
- 條件運算子?和:是一個整體,不能分開使用
#include <stdio.h>
int main(){
int a = 10;
int b = 5;
// 先計算 a > b
// 然後再根據計算結果判定返回a還是b
// 相當於int max= (a>b) ? a : b;
int max= a>b ? a : b;
printf("max = %i\n", max); // 10
}
#include <stdio.h>
int main(){
int a = 10;
int b = 5;
int c = 20;
int d = 10;
// 結合性是從右至左, 所以會先計算:後面的內容
// int res = a>b?a:(c>d?c:d);
// int res = a>b?a:(20>10?20:10);
// int res = a>b?a:(20);
// 然後再計算最終的結果
// int res = 10>5?10:(20);
// int res = 10;
int res = a>b?a:c>d?c:d;
printf("res = %i\n", res);
}
型別轉換
強制型別轉換(顯示轉換) | 自動型別轉換(隱式轉換) |
---|---|
(需要轉換的型別)(表示式) | 1.算數轉換 2.賦值轉換 |
- 強制型別轉換(顯示轉換)
// 將double轉換為int
int a = (int)10.5;
- 算數轉換
- 系統會自動對佔用記憶體較少的型別做一個“自動型別提升”的操作, 先將其轉換為當前算數表示式中佔用記憶體高的型別, 然後再參與運算
// 當前表示式用1.0佔用8個位元組, 2佔用4個位元組
// 所以會先將整數型別2轉換為double型別之後再計算
double b = 1.0 / 2;
- 賦值轉換
// 賦值時左邊是什麼型別,就會自動將右邊轉換為什麼型別再儲存
int a = 10.6;
- 注意點:
- 參與計算的是什麼型別, 結果就是什麼型別
// 結果為0, 因為參與運算的都是整型
double a = (double)(1 / 2);
// 結果為0.5, 因為1被強制轉換為了double型別, 2也會被自動提升為double型別
double b = (double)1 / 2;
- 型別轉換並不會影響到原有變數的值
#include <stdio.h>
int main(){
double d = 3.14;
int num = (int)d;
printf("num = %i\n", num); // 3
printf("d = %lf\n", d); // 3.140000
}
階段練習
- 從鍵盤輸入一個整數, 判斷這個數是否是100到200之間的數
- 表示式 6==6==6 的值是多少?
- 使用者從鍵盤上輸入三個整數,找出最大值,然後輸入最大值
- 用兩種方式交換兩個變數的儲存的值
交換前
int a = 10; int b = 20;
交換後
int a = 20; int b = 10;
配套視訊地址:www.it666.com
相關文章
- c語言-運算子,陣列,指標C語言陣列指標
- Go語言學習(7) - 運算子Go
- Go語言運算子Go
- Go 語言運算子Go
- C語言運算子C語言
- C語言學習筆記--C運算子C語言筆記
- 逍遙自在學C語言 | 算數運算子C語言
- 逍遙自在學C語言 | 關係運算子C語言
- 逍遙自在學C語言 | 邏輯運算子C語言
- Swift 語言的基本運算子Swift
- c語言運算子詳解C語言
- Swift語言指南(九)--基本運算子Swift
- SQL語言運算子與函式SQL函式
- Go語言常用的運算子篇Go
- 逍遙自在學C語言 | 位運算子的基礎用法C語言
- 逍遙自在學C語言 | 位運算子&的高階用法C語言
- 逍遙自在學C語言 | 位運算子^的高階用法C語言
- Solidity語言學習筆記————14、左值運算子Solid筆記
- Solidity語言學習筆記————9、左值運算子Solid筆記
- C語言學習第8篇---位運算子使用探究C語言
- 關於C語言的位運算子C語言
- C 語言運算子優先順序
- C語言運算子優先順序C語言
- C語言學習筆記之指標的運算C語言筆記指標
- GO語言————4.5 基本型別和運算子Go型別
- C語言位運算子及常見用法C語言
- C語言運算子深度解析--超詳細C語言
- 逍遙自在學C語言 位運算子 "|" 的5種高階用法C語言
- Solidity語言學習筆記————8、運算子優先順序Solid筆記
- 手寫程式語言-實現運算子過載
- 《手把手教你學C語言》學習筆記(8)--- 運算子和表示式C語言筆記
- 指標運算子過載(* 和 ->)指標
- go 語言指標學習Go指標
- C語言指標學習C語言指標
- day_07C語言運算子及流程控制C語言
- 為什麼 Go 語言沒有三元運算子Go
- C語言運算子優先順序列表(超詳細)C語言
- C語言常被搞錯的運算子優先順序C語言