目錄
- 運算子劃分
- 運算子的優先級表
- 結合性簡單介紹
- 算數運算子表
- 取模運算子的注意點
- 算術運算子的結合性
- 算術運算子的優先級和結合性同時存在時
- 型別轉換
- 賦值運算子
- 自增,自減運算子
- sizeof運算子
- 逗號運算子
- 關系運算子
- 邏輯運算子
- 三目運算子
運算子劃分
-
按照功能劃分:
- 算術運算子
- 關系運算子
- 邏輯運算子
- 按位運算子
-
按照參與運算的操作個數進行劃分
-
單目運算子
- 只有一個運算元 如:i++
-
雙目運算子
- 有兩個運算元 如:a+b
-
三目運算子
- 有三個運算元 如:a > b ? 1:0 如果a>b時,a = 1,如果a<b時,a = 0
-
運算子的優先級表
-
運算子的優先級分為15級別,1級最高,15級最低
-
在運算式中優先級高的優先于優先級低的先運算
-
在一個運算量兩側的,優先級一樣時按照運算子的結合性所規定的方向進行運算
優先級 運算子 名稱或含義 使用形式 結合方向 說明 1 [] 陣列下標 陣列名[常量運算式] 左到右 () 圓括號 (運算式)/函式名(形參表) . 成員選擇(物件) 物件.成員名 -> 成員選擇(指標) 物件指標->成員名 2 - 負號運算子 -運算式 右到左 單目運算子 (型別) 強制型別轉換 (資料型別)運算式 ++ 自增運算子 ++變數名/變數名++ 單目運算子 -- 自減運算子 --變數名/變數名-- 單目運算子 * 取值運算子 *指標變數 單目運算子 & 取地址運算子 &變數名 單目運算子 ! 邏輯非運算子 !運算式 單目運算子 ~ 按位取反運算子 ~運算式 單目運算子 sizeof 長度運算子 sizeof(運算式) 3 / 除 運算式/運算式 左到右 雙目運算子 * 乘 運算式*運算式 雙目運算子 % 余數(取模) 整型運算式/整型運算式 雙目運算子 4 + 加 運算式+運算式 左到右 雙目運算子 - 減 運算式-運算式 雙目運算子 5 << 左移 變數<<運算式 左到右 雙目運算子 >> 右移 變數>>運算式 雙目運算子 6 > 大于 運算式>運算式 左到右 雙目運算子 >= 大于等于 運算式>=運算式 雙目運算子 < 小于 運算式<運算式 雙目運算子 <= 小于等于 運算式<=運算式 雙目運算子 7 == 等于 運算式==運算式 左到右 雙目運算子 != 不等于 運算式!= 運算式 雙目運算子 8 & 按位與 運算式&運算式 左到右 雙目運算子 9 ^ 按位異或 運算式^運算式 左到右 雙目運算子 10 | 按位或 運算式|運算式 左到右 雙目運算子 11 && 邏輯與 運算式&&運算式 左到右 雙目運算子 12 || 邏輯或 運算式||運算式 左到右 雙目運算子 13 ?: 條件運算子 運算式1? 運算式2: 運算式3 右到左 三目運算子 14 = 賦值運算子 變數=運算式 右到左 /= 除后賦值 變數/=運算式 *= 乘后賦值 變數*=運算式 %= 取模后賦值 變數%=運算式 += 加后賦值 變數+=運算式 -= 減后賦值 變數-=運算式 <<= 左移后賦值 變數<<=運算式 >>= 右移后賦值 變數>>=運算式 &= 按位與后賦值 變數&=運算式 ^= 按位異或后賦值 變數^=運算式 |= 按位或后賦值 變數|=運算式 15 , 逗號運算子 運算式,運算式,… 左到右 從左向右順序運算 -
雖然說運算子有很多,但是不用記住,使用小括號()擴起來就好了
結合性簡單介紹
- c語言中有兩種結合性,一種是左結合型,一種是右結合性
- 左結合性--自左至右運算,右結合性--自右至左運算
- 左結合性 例如:x + y -z,先計算x+y,計算后的結果再減z
- 右結合性 例如:x = y = z, 將z的值賦值給y,再將y的值賦值給x
算數運算子表
| 運算子 | 術語 | 示例 | 結果 |
|---|---|---|---|
| + | 正號 | +3 | 3 |
| - | 負號 | -3 | -3 |
| + | 加 | 10 + 5 | 15 |
| - | 減 | 10 - 5 | 5 |
| * | 乘 | 10 * 5 | 50 |
| / | 除 | 10 / 5 | 2 |
| % | 取模(取余) | 10 % 3 | 1 |
| ++ | 前自增 | a=2; b=++a; | a=3; b=3; |
| ++ | 后自增 | a=2; b=a++; | a=3; b=2; |
| -- | 前自減 | a=2; b=--a; | a=1; b=1; |
| -- | 后自減 | a=2; b=a--; | a=1; b=2; |
#include <stdio.h>
int main(int argc, const char * argv[]) {
/*
+ 加法
- 減法
* 乘法
/ 除法
% 取模(取余)
*/
int result;
result = 1 + 1;
printf("加法結果:result = %i\n",result);
result = 1 - 1;
printf("減法結果:result = %i\n",result);
result = 2 * 3;
printf("乘法結果:result = %i\n",result);
result = 10 / 2;
printf("除法結果:result = %i\n",result); // result = 5
result = 10 % 3;
printf("取模結果:result = %i\n",result); // result = 1
return 0;
}
取模運算子的注意點
- 注意:取模運算只能對整數取模,不能對實數取模
// 注意取模運算只能是整數取模不能是實數取模
// result = 10.5 % 3; // 直接報錯
- 注意:取模運算的正負性,取決于左邊的運算元
// 取模運算的正負性,取決于左邊的運算元
result = 10 % -3;
printf("取模正負性結果:result = %i\n",result); // result = 1
result = -10 % -3;
printf("取模正負性結果:result = %i\n",result); // result = -1
result = -10 % 3;
printf("取模正負性結果:result = %i\n",result); // result = -1
result = -0 % -3;
printf("取模正負性結果:result = %i\n",result); // result = 0
- 注意:如果取模運算中,左邊運算元小于右邊運算元,那結果直接就是左邊運算元,不會進行計算了
// 如果取模運算中,左邊運算元小于右邊運算元,那結果直接就是左邊運算元,不會進行計算了
result = 10 % 100;
printf("取模結果:result = %i\n",result); // result = 10
算術運算子的結合性
// 算術運算子的結合性
result = 3 + 4 + 5 + 6;
printf("result的值是%i",result);
算術運算子的優先級和結合性同時存在時
- 先優先級,再按照結合性
// 優先級+結合性
result = 2 + 3 * 4 -4;
printf("result的值是%i\n",result); // 先計算乘法,再從左至右的結合性計算
型別轉換
- 隱式轉換
// 系統自動進行的轉換
int number = 10.8;
printf("number的值是%i\n",number); // number = 10,
// 大型別的轉換成小型別的,系統會自動進行轉換,由大型別轉換為小型別,丟失精度
- 顯式轉換
// 顯式轉換-只需要在值前面加(型別)
int value = https://www.cnblogs.com/zcyd/archive/2020/11/18/(int)10.8;
printf("value的值是%i\n",value); // 10;
// 大型別的轉換成小型別的,系統會自動進行轉換,由大型別轉換為小型別,丟失精度
- 在算術運算中,型別不一致時,系統會先將型別統一,統一成大型別進行計算
// 在算術運算中,型別不一致時,系統會先將型別統一,統一成大型別進行計算
int value2 = 10 + 9.9;
// 10是int型別,9.9是double型別,int型別占4個位元組,9.9占8個位元組,所以先將int轉為double型別
// int value2 = 10.0 + 9.9
// int value2 = 19.9
// value2 是一個int型別,但是右邊的19.9是double型別,這時候系統會做隱式轉換,大型別轉為小型別,既結果為19
printf("value2的值是%i\n",value2); // 19;
- 算術運算子的注意點-參與運算的運算元是什么型別,那么計算出來的結果就是什么型別
// 算術運算子的注意點-參與運算的運算元是什么型別,那么計算出來的結果就是什么型別
int value3 = 1 / 2;
printf("value3的值是%i\n",value3); // 列印出來的是0
// 此時你會不會覺得是因為定義的變數是int型別導致的呢?那我就換成double型別的看看
double value3 = 1 / 2;
printf("value3的值是%lf\n",value3); // 列印出來的是0.000000 此時還是0
// 是因為右側參與運算的都是整數,那么計算的結果肯定是整數
// 那么如果需要列印出0.5該怎么辦呢?
double value4 = 1.0 / 2; // 此時一個double除以int型別,肯定是都先轉換為doublee型別,計算出的結果就是double型別,i定義的變數也是double型別不需要轉換所以列印出的是0.500000
printf("value4的值是%.1lf\n",value4);
int value5 = 1.0 / 2;
printf("value5的值是%i\n",value5); // 0
- 新手注意常犯的錯誤
// 新手注意飯的錯誤
double value6 = (double)(1 / 2);
// 右邊先計算括號中的1 / 2,那么兩個整數相除,結果肯定是整數,所以是0 ,由強轉為double型別,為0.000000
printf("value6的值是%lf",value6); // 0.000000
- 在算術運算子中,實數的計算都是double型別,不是float型別
賦值運算子
- 最簡單的賦值運算子,將等號右邊的值賦值給等號左邊的變數
- 賦值運算子的結合性是右結合性
int main(int argc, const char * argv[]) {
// 最簡單的賦值運算子,將等號右邊的值賦值給等號左邊的變數
// 賦值運算子的結合性是右結合性
int number = 10;
int a;
int b;
a = b = 5;
printf("a的值是%i,b的值是%i\n",a,b);
return 0;
}
- 符合賦值運算子
- 定義:在賦值符“=”加上其他的二目運算子可構成復合賦值運算子
賦值運算子的作用是將常量、變數或運算式的值賦給某一個變數,
| 運算子 | 術語 | 示例 | 結果 |
|---|---|---|---|
| = | 賦值 | a=2; b=3; | a=2; b=3; |
| += | 加等于 | a=0; a+=2; a = a + 2 | a=2; |
| -= | 減等于 | a=5; a-=3; a = a - 3 | a=2; |
| *= | 乘等于 | a=2; a*=2; a = a * 2 | a=4; |
| /= | 除等于 | a=4; a/=2; a = a / 2 | a=2; |
| %= | 模等于 | a=3; a%2; a = a % 2 | a=1; |
int a = 0;
a += 3; // 這種是直接進行賦值,運算效率要好
a = a +3; // 這一種是不是先計算再賦值給a
printf("a的結果是%i\n",a);
// 復合賦值運算,會先進行右邊的運算式得到的值在賦值給左邊的變數
自增,自減運算子
- 自增自減的第一種寫法: 變數++,變數--
int result = 10;
result++;
result++;
printf("變數++,自增后的result值為:%i\n",result); // 12
// 如果想讓某一個數減1,可以使用變數--,--變數
int value = https://www.cnblogs.com/zcyd/archive/2020/11/18/5;
value--;
printf("變數--,自增后的value值為:%i\n",value); // 4
- 自增自減的第二種寫法: --變數,++變數
// 第二種寫法:++變數,--變數
int result1 = 10;
++result1;
printf("++變數,自增后的result1值為:%i\n",result1); // 11
int result2 = 5;
--result2;
printf("++變數,自增后的result1值為:%i\n",result2); // 4
- ? ++,-- 在變數前面和++,-- 在變數后面的區別(在變數之前先運算再自增,在變數之后先自增再運算)
// ++,-- 在變數前面和++,-- 在變數后面的區別
// ++ , -- 在后面時,先參與運算然后再自增
int a = 10;
int b = a++;
printf("a的值是%i,b的值是%i\n",a,b);// a的值是11,b的值是10 注意看b的值是10,而不是11,這里是a先賦值給b,然后再自增的
// ++ --在變數之前時,是先自增再賦值
int c = 10;
int d = ++c;
printf("c的值是%i,d的值是%i\n",c,d); // c的值是11,d的值是11 注意看這里d的值同樣是11,所以c是先自增再賦值給d
- 自增,自減練習
// 練習
/*
int a = 10;
int b = (a++) + (++a);
// b = a++ ,此時a++的結果是11, 后面++a在a=11的基礎上再自增,那么a的值就是12了,10+12
// a =12
printf("b的值是%i,a的值是%i\n",b,a);
*/
/*
int a = 10;
int b = (a++) + (a++);
printf("b的值是%i,a的值是%i\n",b,a); // b = 10 + 11 , a = 12
*/
/*
int a = 10;
int b = (++a) + (++a);
printf("b的值是%i,a的值是%i\n",b,a); // b = 11 + 12 ,a = 12
*/
/*
int a = 10;
int b = (++a) + (a++);
printf("b的值是%i,a的值是%i\n",b,a); // b = 11 + 11, a = 12
*/
int a = 10;
int b = (a++) + (a--);
printf("b的值是%i,a的值是%i\n",b,a); // b = 10 + 11 , a = 10
- 自增的拆分
// 自增的拆分
int a = 10;
int b = a++;
// 拆分:
// 1, int b = a;
// 2, int a = a+1;
printf("b的值是%i,a的值是%i\n",b,a); // b = 10,a = 11
int c = 10;
int d = ++c;
// 拆分
// 1,int c = c + 1;
// 2,int d = c;
printf("d的值是%i,c的值是%i\n",d,c);
// 拆分之后,只是兩個運算式的順序反了. 如果有時確實難懂的話不妨拆分一下
sizeof運算子
-
介紹:sizeof運算子可以用來計算一個變數或一個常量,一種資料型別所占的記憶體節數
-
格式:sizeof(變數/常量/資料型別)
-
注意:sizeof 不是一個函式而是一個運算子(只要是運算子就會有一個回傳值)
-
計算常量的記憶體位元組
// 使用 sizeof 計算常量的記憶體位元組
int number = sizeof(10.9);
printf("10.9的e記憶體位元組是%i\n",number); // 8
- 計算變數的記憶體位元組
int a = 10;
// int number = sizeof(a); // 只要是運算子就會有回傳值
int number = sizeof a; // 不加s括號e也可以
printf("a的記憶體位元組是%i\n",number);
- 計算資料型別的記憶體位元組(sizeof的括號不能省略)
// 使用 sizeof 計算資料型別的記憶體位元組
int numChar = sizeof(char);
printf("char 資料型別占用%i個位元組\n",numChar); // 1
int numInt = sizeof(int);
printf("int 資料型別占用%i個位元組\n",numInt); // 4
int numDouble = sizeof(double);
printf("double 資料型別占用%i個位元組\n",numDouble); // 8
int numFloat = sizeof(float);
printf("float 資料型別占用%i個位元組\n",numFloat); // 8
逗號運算子
-
在 C 語言中逗號也是一個運算子,稱之為逗號運算子,其功能是把多個運算式連接起來組成一個運算式,成為逗號運算式
-
格式: 運算式 1,運算式 2,運算式....運算式 n;
-
例如:a = a + 1,b = 3*4;
-
結合性:從左到右結合性
// 逗號運算子,從左到右依次計算運算式的結果,只要是運算子就會有結果,逗號運算子也不例外
int a = 10;
int b = 5;
int result;
a = a + 10,b = b - 1,result = a + b;
printf("a的值是%i,b的值是%i,result 的值是%i\n",a,b,result);
- 逗號運算式的結果是最后一個運算式的結果
// 定一個一個變數 number 來接收逗號運算式的結果,每個運算式用括號括起來,整體再括起來,逗號運算式的結果是最后一個逗號運算式的結果
int number = ((a = a + 10),(b = b - 1),(result = a + b));
printf("a 的值是%i,b 的值是%i,result 的值是%i,number 的值是%i\n",a,b,result,number);
關系運算子
- 在 c 語言中條件成立為真,條件不成立為假,判斷條件是否成立就是判斷條件的真偽
- 怎么判斷條件的真偽呢? C 語言中規定任何數值都有自己的真偽性,任何非 0 的都為真,也就是說 100,-50,2.3這些都是真,只有 0 是假的
- 關系運算子的結果只有兩個結果,真和假
C 語言的比較運算中, “真”用數字“1”來表示, “假”用數字“0”來表示,
| 運算子 | 術語 | 示例 | 結果 |
|---|---|---|---|
| == | 相等于 | 4 == 3 | 0 |
| != | 不等于 | 4 != 3 | 1 |
| < | 小于 | 4 < 3 | 0 |
| > | 大于 | 4 > 3 | 1 |
| <= | 小于等于 | 4 <= 3 | 0 |
| >= | 大于等于 | 4 >= 1 | 1 |
- 關系運算子的回傳值要么真要么假
// > , < , >= , <= , == , !=
int a = 10;
int b = 5; // 怎么知道 a>b 呢? 任何的運算子都有結果
int c = 20;
int result = a > b;
int result1 = a > c;
printf("result的值是%i\n",result); // 1
printf("result1的值是%i\n",result1); // 0
- 關系運算子的優先級: > < >= <=的優先級大于 == , !=
// 關系運算子的優先級: > < >= <=的優先級大于 == , !=
int a = 10;
int b = 5;
int result = 1 == a > b; // 先計算 a 是否大于 b,再拿這個結果與 1 是否相等,
printf("result 的值是%i",result); // 1
- 算術運算子的優先級大于關系運算子(比較運算子)
// 算術運算子的優先級大于關系運算子
int result = 1 + 1 > 2+2;
printf("result 的值是%i\n",result); // 0,先計算 1+1,在計算 2+2,再拿 2>4?
- 關系運算子的結合性是左結合性
// 關系運算子的結合性是左結合性
int result = 10 > 5 > 20;
printf("result 的值是%i\n",result); // 0,先計算 10>5,再拿這個值與 20做比較
- 如果優先級和結合性同時存在,那就先優先級,再結合性
// 如果優先級和結合性同時存在,那就先優先級,再結合性
int result = 10 + 1 > 5 + 4 == 3 > 1;
// 先計算 10+1,再計算 5+4,這兩個算術運算子,得出 11 > 9 == 3>1
// 再計算 11 > 9 ,和 3 > 1 這兩個優先級比較高的比較運算子運算式,
// 最后計算 1 == 1 等于的運算式
printf("result 的值是%i\n",result); // 11 > 9 == 3 > 1 ---> 1 == 1 ---> 1
- 開發中沒有人會按照上面那么寫的
int result1 = (10+1) > (5+4) == (3>1);
printf("result1 的值是%i\n",result1); // h實際開發中為了閱讀,還是加上括號
邏輯運算子
-
有時候我們需要滿足多個條件同時成立才能執行代碼,比如登錄:需要輸入正確的用戶名,和正確的密碼,才能登錄.所以c 語言提供了邏輯運算子
-
C 語言中提供了三個邏輯運算子
- && 邏輯與 運算式 1 && 運算式 2
- || 邏輯非 運算式 1 || 運算式 2
- ! 邏輯非 ! 運算式 2
-
邏輯運算子的運算結果只有兩個真和假
-
邏輯與:只有運算式都為真,結果才是真,其余都是假
- 結合性:從左至右
// 邏輯與(一假則假)
int result = 10 > 7 && 5 > 3; // 10>7為真,5>3 為真
printf("result = %i\n",result); // 1
int result1 = 10 > 90 && 8 >1; // 10 > 90為假
printf("result1 = %i\n",result1); // 0
- 邏輯或:只要有一個運算式為真,結果就是真,如果運算式都是假,結果才是假
- 結合性:從左至右
// 邏輯或 (一真則真)
int result = 10 > 8 || 9 > 7;
printf("result = %i\n",result); // 都為真--真
int result1 = 10 > 8 || 9 > 10;
printf("result1 = %i\n",result1); // 一個為真--真
int result2 = 10 > 11 || 9 > 10;
printf("result2 = %i\n",result2); // 都為假--假
int result3 = 10 > 11 || 9 > 8; // 一個為真--真
printf("result3 = %i\n",result3);
- 邏輯非(如果運算式為真,則為假,如果運算式為假,則為真)---取反
- 結合性:從右至左
// 邏輯非
int result = ! 10; // 0
int result1 = ! 0; // 1
printf("result = %i\n",result);
printf("result1 = %i\n",result1);
- 注意點;C 語言規定,任何數值都有真偽性,非 0 既真,所有的邏輯運算子可以直接約數值進行計算
- 邏輯與的特點是一假則假,所以如果前面的運算式是假的話,那么后面的運算式就不會計算了
int a = 10;
int result = 10 < 8 && a++ > 5; // a = 10,result = 0
// 由于 10 < 8 為假,所以后面的運算式就不會計算了,a++ 后,a 的值就沒有自增
int b = 20;
int result1 = 10 > 8 && b++ >5; // 10 > 8 為真,后面的運算式繼續計算,所以 b 的值是 21
printf("a = %i,result = %i\n",a,result);
printf("b = %i,result1 = %i\n",b,result1);
- 邏輯或的特點是一真則真,所以如果前面的運算式是真的話,那么后面的運算式就不會計算了
int a = 10;
int result = 10 > 8 || a++ > 5; // a = 10,result = 0
// 由于 10 > 8 為真,所以后面的運算式就不會計算了,a++ 后,a 的值就沒有自增
int b = 20;
int result1 = 10 < 8 || b++ >5; // 10 < 8 為假,后面的運算式繼續計算,所以 b 的值是 21
printf("a = %i,result = %i\n",a,result);
printf("b = %i,result1 = %i\n",b,result1);
-
以上兩個邏輯運算子的特點稱之為:邏輯運算子的短路
-
判斷一個數值是否在一個范圍內
int a = 10;
if (a > 3 && a < 100){
printf("a在 3-100 之間");
} else{
printf("a 不在 3-100 之間");
}
三目運算子
-
格式: 條件運算式 ? 結果 A: 結果 B
- 如果運算式為真,回傳結果 A,如果運算式為假,回傳結果 B
-
結合性:左結合性
// 三目運算子
int a = 10;
int b = 20;
int result = a > b;
printf("result = %i\n",result);
// 如果我想獲取兩個數之間的最大數呢?
if (a>b){
printf("a 和 b 之間最大數是%i\n",a);
}else{
printf("a 和 b 之間最大數是%i\n",b);
}
// 可是上面的辦法太麻煩了,x要寫這么多行代碼
int maxNum = a > b ? a:b; // 這句話的意思是,如果a> b,那就回傳 a,如果 a 不大于 b 的話,那就回傳 b
printf("a 和 b 之間最大數是%i\n",maxNum);
- 三目運算子練習
// 從控制臺輸入三個整數,回傳最大的整數
printf("請輸入三個整數以逗號隔開,回車結束\n");
int num1,num2,num3;
scanf("%i,%i,%i",&num1,&num2,&num3);
int temp = num1 > num2 ? num1 : num2; // 比較 num1 和num2 中的最大值
int maxNum = temp > num3 ? temp : num3; // 拿到 num1 和 num2 的最大值再與 num3 做比較,回傳最大值
printf("num1,num2,num3 之間的最大值是:%i\n",maxNum);
int maxNum1 = (num1 > num2 ? num1 : num2) > num3 ? (num1 > num2 ? num1 : num2) : num3;
// 不推薦這種寫法是因為,問號之前計算了一次num1 和num2 的最大值,問號運算式之后又計算了一次,無疑消耗了性能
printf("num1,num2,num3 之間的最大值是:%i\n",maxNum1);
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/224445.html
標籤:其他
